Python вопрос о пигментном движении о занятиях - PullRequest
4 голосов
/ 21 февраля 2020

Я пытаюсь реализовать движение из своего вражеского класса, чтобы следовать за классом игрока. В настоящее время вражеский класс движется только по прямой линии влево. Вот код, чтобы лучше понять мой вопрос.

Вот класс игрока

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 обновляется в l oop, почему игрок move_towards не обновляется?

Вопрос 2) Я пытался позволить обновлению наследовать Player, как это

def update(self2, Player):

, почему это не работает?

Вопрос 3) Как я могу сделать обновление move_towards_Player в l oop

1 Ответ

1 голос
/ 21 февраля 2020

как получается, когда группа all_sprites.Group обновляется в l oop, почему не обновляется игрок move_towards?

Вы спрашиваете, почему функция move_towards_Player не называется? Потому что ты никогда не называешь это, и это ничем не волшебным образом называется. Функция update для Group вызовет функцию update для всех ее спрайтов. Ничего больше.

Я пытался позволить обновлению наследовать Player, вот так ... почему это не работает?

Функция update Group передаст все аргументы функции update всех ее спрайтов. Таким образом, вы можете назвать это так:

all_sprites.update(player)

и убедиться, что у всех классов спрайтов есть функция update, принимающая дополнительный аргумент помимо self.

Как я могу сделать так, чтобы move_towards_Player обновлялся в l oop?

Просто вызовите его из функции 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()

Обратите внимание:

  • Я переименовал self2 в self. По соглашению первый аргумент метода должен называться self. Придерживайтесь этого.
  • Я передаю экземпляр Player в функцию Enemy -class '__init__ и сохраняю его в члене класса. Таким образом, нам не нужно «загрязнять» функцию update
  • Я использую класс Pygame Vector2 для обработки математики.
  • Я передаю время дельты функции обновления поэтому скорость движения постоянна, даже если частота кадров не равна
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...