【问题标题】:Is there a way to call the only important arguments of a sprite class? [duplicate]有没有办法调用精灵类的唯一重要参数? [复制]
【发布时间】:2021-04-25 11:29:27
【问题描述】:

所以我最近用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, posX, posY):
        self.rect.center = [posX, posY]


class Target(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 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), random.randrange(15, screen_height),
                           (127, 255, 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'

另外我是新人,无论如何谢谢。

【问题讨论】:

    标签: python pygame


    【解决方案1】:

    函数调用运算符必须在实例对象 (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, posX, 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 downHow to get keyboard input in pygame?

    使用pygame.time.Clock 控制每秒帧数,从而控制游戏速度。 pygame.time.Clock 对象的 tick() 方法以这种方式延迟游戏,即循环的每次迭代消耗相同的时间段。见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, width, height, posX, posY, 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, posX, posY):
            self.x += posX
            self.y += posY
            self.rect.center = round(self.x), round(self.y)
    
    class Target(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 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), random.randrange(15, screen_height),
                               (127, 255, 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()
    

    【讨论】:

    • 啊,我明白了,谢谢。
    • 箭头按预期工作,但这次我似乎无法让 WASD 工作。我该怎么做才能解决这个问题?
    • @colappse 例如对于“d”:if keys[pygame.K_d]: 对于“向下”或“d”:if keys[pygame.K_DOWN] or keys[pygame.K_d]:
    猜你喜欢
    • 1970-01-01
    • 2022-09-27
    • 2011-06-12
    • 1970-01-01
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多