I am starting to use pygame. My first task is to make a sprite and to make it move. So far I am doing fine until I get the error:
Traceback (most recent call last):
File "C:\Users\tom\Documents\python\agame.py", line 33, in <module>
YOU = Player(RED ,20, 30)
NameError: name 'RED' is not defined
My main code so far:
import pygame
import sys
from player import Player
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
init_result = pygame.init()
# Create a game window
game_window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
# Set title
pygame.display.set_caption("agame")
#game_running keeps loopgoing
game_running = True
while game_running:
# Game content
# Loop through all active events
YOU = Player(RED ,20, 30)
for event in pygame.event.get():
#exit through the X button
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#change background colour to white
game_window.fill((255,255,255))
#update display
pygame.display.update()
As you can see this is the very start of making a sprite.
My sprite class:
import pygame
#creating sprite class
class Player(pygame.sprite.Sprite):
def __init__(self, color, width, height):
# Call the parent class (Sprite) constructor
super().__init__()
# Pass in the color of the Player, and its x and y position, width and height.
# Set the background color
self.image = pygame.Surface([width, height])
self.image.fill(WHITE)
self.image.set_colorkey(WHITE)
# Draw player (a rectangle!)
pygame.draw.rect(self.image, color, [0, 0, width, height])
This has been made in the .py file called player. I am following the tutorials HERE and making my own changes as I go along. I do not understand this error. I am very new to pygame so forgive me if this is obvious.
You have to define the colors RED and WHITE. For instance:
RED = (255, 0, 0)
WHITE = (255, 255, 255)
Or create pygame.Color objects:
RED = pygame.Color("red")
WHITE = pygame.Color("white")
Furthermore you have to use the color argument in the constructor of Player:
class Player(pygame.sprite.Sprite):
def __init__(self, color, width, height):
# Call the parent class (Sprite) constructor
super().__init__()
# Pass in the color of the Player, and its x and y position, width and height.
# Set the background color
self.image = pygame.Surface([width, height])
self.image.fill(color)
Related
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. [...]
This question already has an answer here:
How to convert the background color of image to match the color of Pygame window?
(1 answer)
Closed 2 years ago.
I need to Make a class that draws the character at the
center of the screen and match the background color of the image to the background color of the screen, or vice versa. I have already set a value for the background color of Pygame screen to blue, but when I do the same in my DrawCharacter class, it just opens the screen with the background color of the image (white). I might just be placing the bg_color attribute at the wrong place in my class.
game_character.py
import sys
import pygame
class DrawCharacter():
bg_color = ((0, 0, 255))
def __init__(self, screen):
"""Initialize the superman and set starting position"""
self.screen = screen
# Load image and get rect
self.image = pygame.image.load("Images/supermen.bmp")
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
# Start each new supermen at the center of the screen
self.rect.centerx = self.screen_rect.centerx
self.rect.centery = self.screen_rect.centery
def blitme(self):
"""Draw the superman at its current location"""
self.screen.blit(self.image, self.rect)
blue_sky.py
import sys
import pygame
from game_character import DrawCharacter
def run_game():
# Initialize game and make screen object
pygame.init()
screen = pygame.display.set_mode((1200, 800))
pygame.display.set_caption("Blue Sky")
bg_color = (0, 0, 255)
# Make superman
superman = DrawCharacter(screen)
# Start the main loop for the game
while True:
# Check for keyboard and mouse events
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# Redraw screen during each loop pass
screen.fill(bg_color)
superman.blitme()
# make the most recently drawn screen visible
pygame.display.flip()
run_game()
I expected the background color of the image to be the same as the background color of the Pygame screen, but it is not. The first block of code is for my class file, while the second is for the pygame file
if the image has a transparent background try doing the following in game_Character.py:
# Load image and get rect
self.image = pygame.image.load("Images/supermen.bmp").convert_alpha()
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
If it has a white background you probably want to set the colorkey like so:
# Load image and get rect
self.image = pygame.image.load("Images/supermen.bmp").convert()
self.image.set_colorkey((255, 255, 255))
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
I'm at the very beginning of a chess program and want to print the board on the screen. However, I am having trouble at the first hurdle and cannot even get it to print the squares of the board. It just comes up with a black screen and doesn't put the sprite on it.
I've tried looking at some code from a previous project where it worked, but I can't find any differences in this part of the program.
import pygame
import os
import time
pygame.init()
WHITE = (0, 30, 0)
BLACK = (200, 200, 200)
screen_width = 1400
screen_height = 800
square_size = screen_height/10
screen = pygame.display.set_mode([screen_width, screen_height])
os.environ['SDL_VIDEO_WINDOWS_POS'] = '10,10'
class square(pygame.sprite.Sprite):
def __init__(self, colour, x, y):
super().__init__()
self.image = pygame.Surface([square_size, square_size])
pygame.draw.rect(self.image, colour, [0, 0, square_size, square_size])
self.colour = colour
self.rect = self.image.get_rect()
squares = pygame.sprite.Group()
s = square(WHITE, 20, 20)
squares.add(s)
squares.draw(screen)
time.sleep(3)
I would expect this to output one white square in the top left hand corner of the screen, but only a black screen appears.
You need an event.get loop, and to update your display using pygame.display.update() after the squares.draw(screen):
import pygame
import os
import time
pygame.init()
WHITE = (0, 30, 0)
BLACK = (200, 200, 200)
screen_width = 1400
screen_height = 800
square_size = screen_height/10
screen = pygame.display.set_mode([screen_width, screen_height])
os.environ['SDL_VIDEO_WINDOWS_POS'] = '10,10'
class square(pygame.sprite.Sprite):
def __init__(self, colour, x, y):
super().__init__()
self.image = pygame.Surface([square_size, square_size])
pygame.draw.rect(self.image, colour, [0, 0, square_size, square_size])
self.colour = colour
self.rect = self.image.get_rect()
for event in pygame.event.get():
pass
squares = pygame.sprite.Group()
s = square(WHITE, 20, 20)
squares.add(s)
squares.draw(screen)
pygame.display.update()
time.sleep(3)
Also note, an RGB value of (0, 30, 0) is not white, it's a dark green, if you want bright white try (255, 255, 255).
Most likely, your problem is that you didn't flip/update the screen.
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).
To improve my skill with objects, I'm trying to make a game in python to learn how to handle objects in which a I have a sprite called Player that displays an image taken from a file called image.gif using this class:
class Player(pygame.sprite.Sprite):
def __init__(self, width, height):
super().__init__()
self.rect = pygame.Rect(width, height)
self.image = pygame.Surface([width, height])
self.image = pygame.image.load("image.gif").convert_alpha()
# More sprites will be added.
I then used that class for the following code:
import Pysprites as pys
pygame.init()
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GRAY = (255,255,255)
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Game")
all_sprites_list = pygame.sprite.Group()
player = pys.Player(44,22)
all_sprites_list.add(player)
carryOn = True
clock=pygame.time.Clock()
while carryOn:
for event in pygame.event.get():
if event.type==pygame.QUIT:
carryOn=False
all_sprites_list.update()
clock.tick(60)
all_sprites_list.draw(screen)
pygame.display.flip()
pygame.display.update()
pygame.quit()
and got the error:
Traceback (most recent call last):
File "Game1.py", line 14, in <module>
player = pys.Player(44,22)
File "Pysprites.py", line 9, in __init__
self.rect = pygame.Rect(width, height)
TypeError: Argument must be rect style object
What am I doing wrong? How can I make a sprite with an image without encountering this error?
The pygame.Rect() documentation says it only accepts one of 3 different combinations of arguments, none of which involves only providing two values as you're attempting to do.
I think you should have used self.rect = pygame.Rect(0, 0, width, height) in the Player__init__() method to provide the left, top, width, and height argument combination it expects.