I am making my own game with pygame for the first time, and I'm using sprites. I'm trying to blit an image onto the screen but it doesn't work. All it shows is a blank white screen.
Here is the code:
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
class SpriteSheet(object):
def __init__(self, file_name):
self.sprite_sheet = pygame.image.load(file_name).convert()
def get_image(self, x, y, width, height):
image = pygame.Surface([width, height]).convert()
image.blit(self.sprite_sheet, (0, 0), (x, y, width, height))
image.set_colorkey(BLACK)
return image
class Bomb(pygame.sprite.Sprite):
change_x =0
change_y = 0
def __init__(self):
image = pygame.Surface([256, 256]).convert()
sprite_sheet = SpriteSheet("Bomb_anim0001.png")
image = sprite_sheet.get_image(0, 0, 256, 256)
pygame.init()
screen_width = 700
screen_height = 400
screen = pygame.display.set_mode([screen_width, screen_height])
pygame.display.set_caption("Game")
clock = pygame.time.Clock()
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(WHITE)
bomb = Bomb()
clock.tick(60)
pygame.display.flip()
pygame.quit()
This is the image:
Click on this link.
Any help will be highly appreciated. Thanks!
You must blit the image on the screen Surface.
But there is more to be done. Add a rect attribute to the Bomb class:
class Bomb(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
sprite_sheet = SpriteSheet("Bomb_anim0001.png")
self.image = sprite_sheet.get_image(0, 0, 256, 256)
self.rect = self.image.get_rect(topleft = (x, y)
self.change_x = 0
self.change_y = 0
Create a pygame.sprite.Group and add the bomb to the Group. draw all the sprites in the Group on the screen:_
bomb = Bomb(100, 100)
all_sprites = pygame.sprite.Group()
all_sprites.add(bomb)
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(WHITE)
all_sprites.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
pygame.sprite.Group.draw() and pygame.sprite.Group.update() are methods which are provided by pygame.sprite.Group.
The former delegates the to the update mehtod of the contained pygame.sprite.Sprites - you have to implement the method. See pygame.sprite.Group.update():
Calls the update() method on all Sprites in the Group [...]
The later uses the image and rect attributes of the contained pygame.sprite.Sprites to draw the objects - you have to ensure that the pygame.sprite.Sprites have the required attributes. See pygame.sprite.Group.draw():
Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect. [...]
Related
I just learned how to group stuff in pygame but when I try to use it to draw a sprite it says: " ExternalError: TypeError: Cannot read property 'left' of undefined on line 32"
Here is my code:
import pygame
from pygame import *
screen = pygame.display.set_mode((600, 600))
blocks = pygame.sprite.Group()
class Block():
def __init__(self, x, y, w, h, typ):
super().__init__()
self.x = x
self.y = y
self.w = w
self.h = h
self.typ = typ
def draw(self):
pygame.draw.rect(screen, (0, 0, 0), (self.x, self.y, self.w, self.h))
class Player():
def __init__(self, x, y):
super().__init__()
self.x = x
self.y = y
self.accX = 0
self.accY = 0
def draw(self):
pygame.draw.rect(screen, (0, 0, 0), (self.x, self.y, 20, 20))
player = Player(0, 0)
while True:
Blocks = Block(0, 0, 100, 50, 1)
blocks.add(Blocks)
blocks.draw(screen)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
pygame.display.update()
pygame.sprite.Group.draw() and pygame.sprite.Group.update() are methods which are provided by pygame.sprite.Group.
The former delegates the to the update method of the contained pygame.sprite.Sprites - you have to implement the method. See pygame.sprite.Group.update():
Calls the update() method on all Sprites in the Group [...]
The later uses the image and rect attributes of the contained pygame.sprite.Sprites to draw the objects - you have to ensure that the pygame.sprite.Sprites have the required attributes. See pygame.sprite.Group.draw():
Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect. [...]
This means Block and Player must to be derived from pygame.sprite.Sprite and has to have the attributes rect and image. Add the Block and Player instances to a Group and us the darw() method to draw them.
Complete example:
import pygame
from pygame import *
screen = pygame.display.set_mode((600, 600))
class Block(pygame.sprite.Sprite):
def __init__(self, x, y, w, h, typ):
super().__init__()
self.image = pygame.Surface((w, h))
self.image.fill((127, 127, 127))
self.rect = self.image.get_rect(topleft = (x, y))
class Player(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((20, 20))
self.image.fill((255, 255, 0))
self.rect = self.image.get_rect(topleft = (x, y))
blocks = pygame.sprite.Group()
objects = pygame.sprite.Group()
block = Block(0, 0, 100, 50, 1)
blocks.add(block)
player = Player(0, 0)
objects.add(player)
clock = pygame.time.Clock()
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
screen.fill((0, 0, 0))
blocks.draw(screen)
objects.draw(screen)
pygame.display.update()
pygame.quit()
I'm starting to code and have been following a series of videos to create a game with pygame. However, even when I've followed everything the guy in the video said, and after checking many times mine and his code, I got this error:
File "C:/Users/sdf/PycharmProjects/pygame1/pygametutorial 2/tutorail 1 template.py", line 43, in
all_sprites.update()
TypeError: update() missing 1 required positional argument: 'self'
this is the code I've programmed so far:
import pygame
import random
import sprites as sprites
height = 360
width = 480
FPS = 30
White = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Tutorial")
clock = pygame.time.Clock()
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill(green)
self.rect = self.image.get_rect()
self.rect.center = (height / 2, width / 2)
all_sprites = pygame.sprite.Group
player = Player()
all_sprites.add(player)
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
all_sprites.update()
screen.fill(black)
sprites.draw(screen)
# after every drawing flip the display
pygame.display.flip()
Im not sure what import sprites as sprites is, is it another file you made? Is it meant to be import pygame.sprite.Sprite as sprite?
all_sprites = pygame.sprite.Group
Group is a class so you need the brackets
all_sprites = pygame.sprite.Group()
now you are calling it and all_sprites is a group object, not referencing the class
now i changed sprites.draw(screen) to all_sprites.draw(screen) as not don't have sprites, and not sure what is is.
I am following a video about pygame and I saw this code
crosshair = pygame.sprite.Group()
Could someone explain me this?
Read the documentation of pygame.sprite.Group.
pygame.sprite.Group.update() and pygame.sprite.Group.draw() are methods which are provided by pygame.sprite.Group.
The former delegates the to the update method of the contained pygame.sprite.Sprites - you have to implement the method.
pygame.sprite.Group.update()
Calls the update() method on all Sprites in the Group.
The later uses the image and rect attributes of the contained pygame.sprite.Sprites to draw the objects - you have to ensure that the pygame.sprite.Sprites have the required attributes
pygame.sprite.Group.draw()
Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect for the position.
The Sprites in the Groups can be removed and thus destroyed by calling pygame.sprite.Sprite.kill. When the object is no longer referenced, it is destroyed:
The Sprite is removed from all the Groups that contain it. This won't change anything about the state of the Sprite. It is possible to continue to use the Sprite after this method has been called, including adding it to Groups.
See also Sprite Groups
Minimal example:
import pygame
class Player(pygame.sprite.Sprite):
def __init__(self, center_pos):
super().__init__()
self.image = pygame.Surface((40, 40))
self.image.fill((255, 255, 0))
self.rect = self.image.get_rect(center = center_pos)
class Bullet(pygame.sprite.Sprite):
def __init__(self, center_pos):
super().__init__()
self.image = pygame.Surface((20, 10))
self.image.fill((0, 255, 255))
self.rect = self.image.get_rect(center = center_pos)
def update(self):
self.rect.x += 10
if self.rect.right > 300:
self.kill()
pygame.init()
window = pygame.display.set_mode((400, 300))
clock = pygame.time.Clock()
player = Player((25, window.get_height() // 2))
all_sprites = pygame.sprite.Group(player)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
all_sprites.add(Bullet(player.rect.center))
all_sprites.update()
print(len(all_sprites))
window.fill(0)
pygame.draw.rect(window, (255, 0, 0), (300, 0, 10, window.get_height()))
all_sprites.draw(window)
pygame.display.flip()
pygame.quit()
exit()
I am following a video about pygame and I saw this code
crosshair = pygame.sprite.Group()
Could someone explain me this?
Read the documentation of pygame.sprite.Group.
pygame.sprite.Group.update() and pygame.sprite.Group.draw() are methods which are provided by pygame.sprite.Group.
The former delegates the to the update method of the contained pygame.sprite.Sprites - you have to implement the method.
pygame.sprite.Group.update()
Calls the update() method on all Sprites in the Group.
The later uses the image and rect attributes of the contained pygame.sprite.Sprites to draw the objects - you have to ensure that the pygame.sprite.Sprites have the required attributes
pygame.sprite.Group.draw()
Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect for the position.
The Sprites in the Groups can be removed and thus destroyed by calling pygame.sprite.Sprite.kill. When the object is no longer referenced, it is destroyed:
The Sprite is removed from all the Groups that contain it. This won't change anything about the state of the Sprite. It is possible to continue to use the Sprite after this method has been called, including adding it to Groups.
See also Sprite Groups
Minimal example:
import pygame
class Player(pygame.sprite.Sprite):
def __init__(self, center_pos):
super().__init__()
self.image = pygame.Surface((40, 40))
self.image.fill((255, 255, 0))
self.rect = self.image.get_rect(center = center_pos)
class Bullet(pygame.sprite.Sprite):
def __init__(self, center_pos):
super().__init__()
self.image = pygame.Surface((20, 10))
self.image.fill((0, 255, 255))
self.rect = self.image.get_rect(center = center_pos)
def update(self):
self.rect.x += 10
if self.rect.right > 300:
self.kill()
pygame.init()
window = pygame.display.set_mode((400, 300))
clock = pygame.time.Clock()
player = Player((25, window.get_height() // 2))
all_sprites = pygame.sprite.Group(player)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
all_sprites.add(Bullet(player.rect.center))
all_sprites.update()
print(len(all_sprites))
window.fill(0)
pygame.draw.rect(window, (255, 0, 0), (300, 0, 10, window.get_height()))
all_sprites.draw(window)
pygame.display.flip()
pygame.quit()
exit()
I create a clicker game and I have a transparent image (that I set in Mask for Pixel Perfect Collision ) but when I also click on the transparent part, the MOUSEBUTTONDOWN event is detected.
Actually, my code in the Player Class is:
self.image = pygame.image.load(str(level) + ".png").convert_alpha()
self.mask = pygame.mask.from_surface(self.image)
self.image_rect = self.image.get_rect(center=(WW, HH))
and this, in the main loop:
x, y = event.pos
if my_player.image_rect.collidepoint(x, y):
my_player.click()
So I would like the click event to be triggered only when I click on the colored part of the image and not on the transparent background.
Thanks,
In addition to my_player.image_rect.collidepoint(x, y), check also for Mask.get_at:
get_at()
Returns nonzero if the bit at (x,y) is set.
get_at((x,y)) -> int
Note that you have to translate the global mouse position to the position on the mask.
Here's a runnable example:
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
class Cat:
def __init__(self):
self.image = pygame.image.load('cat.png').convert_alpha()
self.image = pygame.transform.scale(self.image, (300, 200))
self.rect = self.image.get_rect(center=(400, 300))
self.mask = pygame.mask.from_surface(self.image)
running = True
cat = Cat()
while running:
for e in pygame.event.get():
if e.type == pygame.QUIT:
running = False
pos = pygame.mouse.get_pos()
pos_in_mask = pos[0] - cat.rect.x, pos[1] - cat.rect.y
touching = cat.rect.collidepoint(*pos) and cat.mask.get_at(pos_in_mask)
screen.fill(pygame.Color('red') if touching else pygame.Color('green'))
screen.blit(cat.image, cat.rect)
pygame.display.update()
Also, self.image_rect should be named self.rect by convention. It's not absolutly necessary; but it's still a good idea and enables you to work with pygame's Sprite class (not shown in the example).