问题描述
所以我最近在 python 中做了一个游戏,玩家收集绿点。未完成,稍后我会在游戏中实现更多。
但是我有一个问题。我希望我的精灵使用箭头键移动,根据使用的键更改 X 和 Y 的位置并忽略其余部分。但它给了我一个错误,说我缺少其他参数。有没有办法解决这个问题?
代码:
import pygame
import sys
import random
class Player(pygame.sprite.Sprite):
def __init__(self,width,height,posX,posY,color):
super().__init__()
self.image = pygame.Surface([width,height])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.center = [posX,posY]
self.eat = pygame.mixer.sound("audio/Apple_Bite-Simon_Craggs-1683647397.mp3")
def __call__(self,posY):
self.rect.center = [posX,posY]
class Target(pygame.sprite.Sprite):
def __init__(self,posY]
self.eat = pygame.mixer.sound("audio/Apple_Bite-Simon_Craggs-1683647397.mp3")
def eat(self):
self.eat.play()
pygame.sprite.spritecollide(player,target_group,True)
pygame.init()
screen_width = 600
screen_height = 400
screen = pygame.display.set_mode((screen_width,screen_height))
player = Player(50,50,300,250,(0,255,127))
player_group = pygame.sprite.Group()
player_group.add(player)
player_group.update()
target_group = pygame.sprite.Group()
for target in range(6):
target_sprite = Target(25,25,random.randrange(15,screen_width),screen_height),(127,0))
target_group.add(target_sprite)
run = True
while run:
screen.fill((0,16,16))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
change_pos = Player(posX=-0,posY=+0.4)
if event.key == pygame.K_UP:
change_pos = Player(posX=-0,posY=-0.4)
player_group.draw(screen)
player_group.update()
target_group.draw(screen)
target_group.update()
pygame.display.update()
它给了我这个错误仅供参考:
TypeError: __init__() missing 3 required positional arguments: 'width','height',and 'color'
另外,我是新来的,无论如何谢谢。
解决方法
函数调用运算符必须在实例对象 (player
) 上执行,而不是在类 (Player
) 上执行:
Player(posX=-0,posY=+0.4)
player(posX=-0,posY=+0.4)
如果要以浮点精度存储对象位置,则必须将对象的位置分别存储在单独的变量和属性中,并同步 pygame.Rect
对象。 round
坐标并将其分配给矩形的位置(例如 .center
):
class Player(pygame.sprite.Sprite):
def __init__(self,width,height,posX,posY,color):
super().__init__()
# [...]
self.x = posX
self.y = posY
self.rect.center = round(self.x),round(self.y)
def __call__(self,posY):
self.x += posX
self.y += posY
self.rect.center = round(self.x),round(self.y)
另见Pygame doesn't let me use float for rect.move,but I need it。
键盘事件(参见 pygame.event 模块)仅在键的状态改变时发生一次。 KEYDOWN
事件在每次按下键时发生一次。 KEYUP
每次释放键时出现一次。将键盘事件用于单个操作或逐步移动。
如果要实现连续运动,则必须使用pygame.key.get_pressed()
。 pygame.key.get_pressed()
返回一个包含每个键状态的列表。如果某个键被按下,则该键的状态为 True
,否则为 False
。使用 pygame.key.get_pressed()
评估按钮的当前状态并获得连续移动:
run = True
while run:
# [...]
keys = pygame.key.get_pressed()
if keys[pygame.K_DOWN]:
player(posX=-0,posY=+0.4)
if keys[pygame.K_UP]:
player(posX=-0,posY=-0.4)
另见How can I make a sprite move when key is held down和How to get keyboard input in pygame?
使用 pygame.time.Clock
控制每秒帧数,从而控制游戏速度。 tick()
对象的方法 pygame.time.Clock
以这种方式延迟游戏,即循环的每次迭代消耗相同的时间段。见pygame.time.Clock.tick()
:
这个方法应该每帧调用一次。
run = True
clock = pygame.time.Clock()
while run:
clock .tick(100)
# [...]
另见Pygame clock and event loops。
完整示例:
import pygame
import sys
import random
class Player(pygame.sprite.Sprite):
def __init__(self,color):
super().__init__()
self.image = pygame.Surface([width,height])
self.image.fill(color)
self.rect = self.image.get_rect()
self.x = posX
self.y = posY
self.rect.center = round(self.x),round(self.y)
self.eat = pygame.mixer.Sound("audio/Apple_Bite-Simon_Craggs-1683647397.mp3")
def __call__(self,round(self.y)
class Target(pygame.sprite.Sprite):
def __init__(self,height])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.center = [posX,posY]
self.eat = pygame.mixer.Sound("audio/Apple_Bite-Simon_Craggs-1683647397.mp3")
def eat(self):
self.eat.play()
pygame.sprite.spritecollide(player,target_group,True)
pygame.init()
screen_width = 600
screen_height = 400
screen = pygame.display.set_mode((screen_width,screen_height))
player = Player(50,50,300,250,(0,255,127))
player_group = pygame.sprite.Group()
player_group.add(player)
player_group.update()
target_group = pygame.sprite.Group()
for target in range(6):
target_sprite = Target(25,25,random.randrange(15,screen_width),screen_height),(127,0))
target_group.add(target_sprite)
run = True
clock = pygame.time.Clock()
while run:
clock .tick(100)
screen.fill((0,16,16))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
sys.exit()
keys = pygame.key.get_pressed()
if keys[pygame.K_DOWN]:
player(posX=-0,posY=+1)
if keys[pygame.K_UP]:
player(posX=-0,posY=-1)
player_group.draw(screen)
player_group.update()
target_group.draw(screen)
target_group.update()
pygame.display.update()