[英]How do I assign an image to each sprite?
I want an image to be in the place of the rectangle.我想要一个图像代替矩形。
The class Block
is used to make a 'food' square, enemy square, and player square. class Block
用于制作“食物”方块、敌人方块和玩家方块。 I need help reformatting Block
to also accept an image in the color
attributes place.我需要帮助重新格式化Block
以在color
属性位置接受图像。
import pygame
import random
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0,0,255)
GREEN = (0,255,0)
class Block(pygame.sprite.Sprite):
"""
This class represents the ball.
It derives from the "Sprite" class in Pygame.
"""
def __init__(self, color, width, height):
""" Constructor. Pass in the color of the block,
and its size. """
# Call the parent class (Sprite) constructor
super().__init__()
# Create an image of the block, and fill it with a color.
# This could also be an image loaded from the disk.
self.image = pygame.Surface([width, height])
self.image.fill(color)
# Fetch the rectangle object that has the dimensions of the image
# image.
# Update the position of this object by setting the values
# of rect.x and rect.y
self.rect = self.image.get_rect()
class Player(pygame.sprite.Sprite):
""" The class is the player-controlled sprite. """
# -- Methods
def __init__(self, x, y):
"""Constructor function"""
# Call the parent's constructor
super().__init__()
# Set height, width
self.image = pygame.Surface([15, 15])
self.image.fill(BLUE)
# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
# -- Attributes
# Set speed vector
self.change_x = 0
self.change_y = 0
def changespeed(self, x, y):
""" Change the speed of the player"""
self.change_x += x
self.change_y += y
def update(self):
""" Find a new position for the player"""
if self.rect.x < 0:
self.rect.x += 3
wall.play()
if self.rect.x > 685:
self.rect.x-=3
wall.play()
if self.rect.y < 0:
self.rect.y += 3
wall.play()
if self.rect.y > 384:
self.rect.y -= 3
wall.play()
else:
self.rect.x += self.change_x
self.rect.y += self.change_y
# Initialize Pygame
pygame.init()
# Set the height and width of the screen
screen_width = 700
screen_height = 400
screen = pygame.display.set_mode([screen_width, screen_height])
# This is a list of 'sprites.' Each block in the program is
# added to this list. The list is managed by a class called 'Group.'
good_block_list = pygame.sprite.Group()
bad_block_list = pygame.sprite.Group()
collision_sound_good = pygame.mixer.Sound("good_block.wav")
collision_sound_bad = pygame.mixer.Sound("bad_block.wav")
wall = pygame.mixer.Sound("bump.wav")
# This is a list of every sprite.
# All blocks and the player block as well.
all_sprites_list = pygame.sprite.Group()
for i in range(50):
# This represents a block
block = Block(GREEN, 20, 15)
# Set a random location for the block
block.rect.x = random.randrange(screen_width)
block.rect.y = random.randrange(screen_height)
# Add the block to the list of objects
good_block_list.add(block)
all_sprites_list.add(block)
for i in range(50):
# This represents a block
block = Block(RED, 20, 15)
# Set a random location for the block
block.rect.x = random.randrange(screen_width)
block.rect.y = random.randrange(screen_height)
# Add the block to the list of objects
bad_block_list.add(block)
all_sprites_list.add(block)
# Create a RED player block
player = Player(100,50)
all_sprites_list.add(player)
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
score = 0
# -------- Main Program Loop -----------
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Set the speed based on the key pressed
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player.changespeed(-3, 0)
elif event.key == pygame.K_RIGHT:
player.changespeed(3, 0)
elif event.key == pygame.K_UP:
player.changespeed(0, -3)
elif event.key == pygame.K_DOWN:
player.changespeed(0, 3)
# Reset speed when key goes up
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player.changespeed(3, 0)
elif event.key == pygame.K_RIGHT:
player.changespeed(-3, 0)
elif event.key == pygame.K_UP:
player.changespeed(0, 3)
elif event.key == pygame.K_DOWN:
player.changespeed(0, -3)
# Game Logic
# This calls update on all the sprites
all_sprites_list.update()
# Clear the screen
screen.fill(WHITE)
good_blocks_hit_list = pygame.sprite.spritecollide(player, good_block_list, True)
bad_blocks_hit_list = pygame.sprite.spritecollide(player, bad_block_list, True)
# Check the list of collisions.
for block in good_blocks_hit_list:
collision_sound_good.play()
score += 1
print(score)
for block in bad_blocks_hit_list:
collision_sound_bad.play()
score -= 1
print(score)
font = pygame.font.SysFont(None, 45)
text = font.render(str(score), True, BLACK)
screen.blit(text, (54, 350))
# Draw all the spites
all_sprites_list.draw(screen)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Limit to 60 frames per second
clock.tick(60)
pygame.quit()
There are 3 different kinds of blocks that need a separate image.有 3 种不同类型的块需要单独的图像。 The blocks are added to sprite group, so I don't think it is possible to Blit the image in the loop.这些块被添加到精灵组中,所以我认为不可能在循环中对图像进行 Blit。
Question Answered已回答的问题
I would modify the Block
constructor such that the color
parameter was just a parameter representing the appearance
of the sprite.我将修改Block
构造函数,使color
参数只是代表精灵appearance
的参数。 It might be a string filename, or a colour-tuple.它可能是字符串文件名或颜色元组。 This can be tested at run-time.这可以在运行时进行测试。
def __init__(self, appearance, width, height):
""" Create a new sprite sized <width> by <height>.
The sprite is, either a coloured block where <appearance> is a
RGB colour-tuple, OR an image loaded from a file """
# Call the parent class (Sprite) constructor
super().__init__()
# appearance is either an RGB tuple, or a filename str
if ( type( appearance ) is tuple ):
# Create an image of the block, and fill it with a color
self.image = pygame.Surface([width, height])
self.image.fill( appearance )
else:
# The parameter <appearance> holds an image filename
bitmap = pygame.image.load( appearance ).convert()
self.image = pygame.transform.smoothscale( bitmap, ( width, height ) )
# Fetch the rectangle object that has the dimensions of the image image.
# Update the position of this object by setting the values
# of rect.x and rect.y
self.rect = self.image.get_rect()
I'm not really sure this is the best approach of doing this sort of thing.我不确定这是做这种事情的最佳方法。 I guess maybe it could allow for a debug-fallback if the image resources are not found or suchlike.我想如果找不到图像资源等,它可能允许调试回退。
This allows the code to:这允许代码:
new_sprite = Block( ( 182, 128, 0 ), 64, 64 )
[...]
new_sprite = Block( "sandstone.png", 64, 64 )
Soo I may have an answer for my own question...所以我可能对我自己的问题有一个答案......
class Block(pygame.sprite.Sprite):
"""
This class represents the ball.
It derives from the "Sprite" class in Pygame.
"""
def __init__(self, imageFile, width, height):
""" Constructor. Pass in the color of the block,
and its size. """
# Call the parent class (Sprite) constructor
super().__init__()
# Create an image of the block, and fill it with a color.
# This could also be an image loaded from the disk.
#self.image = pygame.Surface([width, height])
#self.image.fill(color)
self.image = pygame.image.load(imageFile).convert()
# Fetch the rectangle object that has the dimensions of the image
# image.
# Update the position of this object by setting the values
# of rect.x and rect.y
self.rect = self.image.get_rect()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.