簡體   English   中英

關於類的Python pygame運動問題

[英]Python pygame movement question about classes

我正在嘗試從我的敵人類實現移動以跟隨玩家類。 目前,敵人類只向左直線移動。 這里有一些代碼可以更好地理解我的問題。

這是播放器類

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 在循環中得到更新?

為什么當 all_sprites.Group 在循環中更新時為什么 move_towards 播放器沒有更新?

你問為什么不調用move_towards_Player函數? 因為你從不調用它,它也不會被任何東西神奇地調用。 update的功能Group將調用update其所有精靈的功能。 而已。

我試着讓更新繼承 Player,就像這樣......為什么這不起作用?

Groupupdate函數會將所有參數傳遞給其所有精靈的update函數。 所以你可以這樣稱呼它:

all_sprites.update(player)

並確保所有精靈類都有他們的update函數在self旁邊有一個額外的參數。

我怎樣才能讓 move_towards_Player 在循環中得到更新?

只需從 Enemy 的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()

注意:

  • 我將self2self2self 按照慣例,方法的第一個參數應該稱為self 堅持下去。
  • 我將Player實例傳遞給Enemy -class' __init__函數並將其存儲在類成員中。 這樣,我們就不必“污染” update功能
  • 我使用 pygame 的Vector2類來處理數學。
  • 我將增量時間傳遞給更新函數,因此即使幀速率不是,移動速度也是恆定的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM