关于类的Python pygame运动问题

标签 python pygame

我正在尝试从我的敌人类实现移动以跟随玩家类。目前,敌人类只向左直线移动。这里有一些代码可以更好地理解我的问题。

这是播放器类

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((50, 40))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect()
        self.rect.left = 25
        self.rect.bottom = HEIGHT / 2
        self.speedx = 0
        self.speedy = 0

这里是敌人类
class Enemy(pygame.sprite.Sprite):
    def __init__(self2):
        pygame.sprite.Sprite.__init__(self2)
        self2.image = pygame.Surface((50, 40))
        self2.image.fill(RED)
        self2.rect = self2.image.get_rect()
        self2.rect.x = random.randrange(680, 750)
        self2.rect.y = random.randrange(HEIGHT - self2.rect.height)
        self2.speedx = random.randrange(-5, -3)
        self2.speedy = random.randrange(-5, 5)
        self2.min_dist = 200

    def update(self2):
        self2.speedy = 0
        self2.rect.x += self2.speedx
        self2.rect.y += self2.speedy
        if self2.rect.left < -25 or self2.rect.top < -25 or self2.rect.bottom > HEIGHT + 10:
            self2.rect.x = random.randrange(680, 750)
            self2.rect.y = random.randrange(HEIGHT - self2.rect.height)
            self2.speedx = random.randrange(-5, -3)

    def move_towards_Player(self2, Player):
        delta_x = Player.rect.x - self2.rect.x
        delta_y = Player.rect.y - self2.rect.y
        if abs(delta_x) <= self2.min_dist and abs(delta_y) <= self2.min_dist:
            enemy_move_x = abs(delta_x) > abs(delta_y)
        if abs(delta_x) > self2.speedx and abs(delta_x) > self2.speedx:
            enemy_move_x = random.random() < 0.5
        if enemy_move_x:
            self2.rect.x += min(delta_x, self2.speedx) if delta_x > 0 else max(delta_x, -self2.speedx)
        else:
            self2.rect.y += min(delta_y, self2.speedy) if delta_y > 0 else max(delta_y, -self2.speedy)
all_sprites = pygame.sprite.Group()
enemies = pygame.sprite.Group()
player = Player()
all_sprites.add(player)

for i in range(3):
    e = Enemy()
    all_sprites.add(e)
    enemies.add(e)

running = True
while running:

    clock.tick(FPS)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    all_sprites.update()
    #Draw render
    screen.fill(BLACK)
    all_sprites.draw(screen)
    pygame.display.flip()

pygame.quit()
quit()

抱歉,代码中的大帖子只是想为此获得最佳答案。

问题 1) 这可能是一个非常简单的问题,但是为什么当 all_sprites.Group 在循环中更新时为什么 move_towards 播放器没有更新?

问题 2)我尝试让更新继承 Player,就像这样
def update(self2, Player):

为什么这不起作用?

问题 3) 如何让 move_towards_Player 在循环中得到更新?

最佳答案

how come when the all_sprites.Group get updated in the loop why doesn't the move_towards player get updated?



你问为什么move_towards_Player函数没有调用?因为你从不调用它,它也不会被任何东西神奇地调用。 update Group 的功能将调用 update其所有 Sprite 的功能。而已。

I tried letting the update inherit Player, like this ... why doesn't this work?


update Group 的功能将所有参数传递给 update其所有 Sprite 的功能。所以你可以这样称呼它:
all_sprites.update(player)

并确保所有 Sprite 类都有它们的 update函数在 self 旁边多了一个参数.

How can I make the move_towards_Player get updated in the loop?



只需从敌人的update 中调用它功能。

你可以从这样的事情开始:
import pygame
import random
GREEN=(0,255,0)
RED=(255,0,0)
BLACK=(0,0,0)
HEIGHT=600
WIDTH=800
FPS=120

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((50, 40))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect()
        self.rect.left = 25
        self.rect.bottom = HEIGHT / 2
        self.speedx = 0
        self.speedy = 0

class Enemy(pygame.sprite.Sprite):
    def __init__(self, target):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((50, 40))
        self.image.fill(RED)
        self.rect = self.image.get_rect()
        self.rect.x = random.randrange(680, 750)
        self.rect.y = random.randrange(HEIGHT - self.rect.height)
        self.target = target
        self.speed = random.randint(4, 6)

    def update(self, dt):
        self.move_towards_Player(dt)

    def move_towards_Player(self, dt):
        pos = pygame.Vector2(self.rect.center)
        v = pygame.Vector2(self.target.rect.center) - pos
        if (v.length() < 5):
            self.kill()
        else:
            v.normalize_ip()
            v *= self.speed * dt/10
            pos += v
            self.rect.center = round(pos.x), round(pos.y)

all_sprites = pygame.sprite.Group()
enemies = pygame.sprite.Group()
player = Player()
all_sprites.add(player)

for i in range(3):
    e = Enemy(player)
    all_sprites.add(e)
    enemies.add(e)
clock=pygame.time.Clock()

pygame.init()
screen=pygame.display.set_mode([WIDTH, HEIGHT])
running = True
while running:

    dt=clock.tick(FPS)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    all_sprites.update(dt)
    #Draw render
    screen.fill(BLACK)
    all_sprites.draw(screen)
    pygame.display.flip()

pygame.quit()
quit()

注意:
  • 我改名 self2self .按照惯例,方法的第一个参数应该被称为 self .坚持下去。
  • 我通过Player实例到 Enemy -class' __init__函数并将其存储在类成员中。这样,我们就不必“污染”update功能
  • 我使用 pygame 的 Vector2类来处理数学。
  • 我将增量时间传递给更新函数,因此即使帧速率不是
  • ,移动速度也是恒定的。

    关于关于类的Python pygame运动问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60331349/

    相关文章:

    python - Unicode解码错误: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

    python - pandas pivot_table 最后一个实例应用 aggfunc

    python - 如何仅在一定时间内显示文本?

    python - 使用 Pygame 查找歌曲的长度

    python - 我如何获得opencv中显示的图像坐标

    python - Pygame 捕捉输入按钮

    python - 为什么我的 pygame 应用程序循环不能正常工作?

    Python、Matplotlib : Suptitle with arbitrary number of vertical figures

    python - 如何从对象访问值

    python - Numpy - 按第一个数组的单轴对两个 ndarray 进行排序