Как мне вызвать врагов со всех сторон экрана pygame? - PullRequest
2 голосов
/ 05 мая 2020

Я работал над некоторым игровым кодом для школы, работал с некоторыми учебными пособиями и выяснил, как заставить спрайт игрока отслеживать мышь, но теперь у меня возникли проблемы с выяснением, как вызывать врагов со всех сторон экран, а не только верх. (Для пояснения код состоит из двух частей / файлов, также совершенно не связанных). Мне также было интересно, как я могу заставить мобов / NPC преследовать и вращаться к игроку?

import random
import math
import pygame as py
from PlayerSprite import *

WIDTH = 800
HEIGHT = 600
FPS = 60

# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

# initialize pygame and create window
py.init()
py.mixer.init()
screen = py.display.set_mode((WIDTH, HEIGHT))
py.display.set_caption("Dimensional Drifter")
clock = py.time.Clock()

all_sprites = py.sprite.Group()
NPCs = py.sprite.Group()
player = Player()
all_sprites.add(player)
for i in range(8):
    n = NPC()
    all_sprites.add(n)
    NPC.add(n)
# Game loop
running = True
while running:
    # keep loop running at the right speed
    clock.tick(FPS)

    for event in py.event.get():
        # check for closing window
        if event.type == py.QUIT:
            running = False

    # Update
    all_sprites.update()
    #
    mouse_x, mouse_y = py.mouse.get_pos()
    player.rotate(mouse_x, mouse_y)
    # render
    screen.fill(BLACK)
    all_sprites.draw(screen)
    # flip the display
    py.display.flip()

py.quit()
import pygame as py
import math
import random

WIDTH = 800
HEIGHT = 600
FPS = 60

# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)


class Player(py.sprite.Sprite):
    def __init__(self):
        py.sprite.Sprite.__init__(self)
        self.image = py.Surface((50, 50), py.SRCALPHA)
        self.image.fill(GREEN)
        self.rect = self.image.get_rect()
        self.rect.centerx = WIDTH / 2
        self.rect.bottom = HEIGHT / 2
        self.Yspeed = 0
        self.rotatableimage = self.image

    def update(self):
        self.Xspeed = 0
        self.Yspeed = 0
        # line below allow for key press to equate to move of sprite
        keypreesed = py.key.get_pressed()
        if keypreesed[py.K_a]:
            self.Xspeed = - 11
        if keypreesed[py.K_d]:
            self.Xspeed = 11
        if keypreesed[py.K_w]:
            self.Yspeed = - 11
        if keypreesed[py.K_s]:
            self.Yspeed = 11
        self.rect.x += self.Xspeed
        self.rect.y += self.Yspeed
        # line below allow the sprite to wrap around the screen
        if self.rect.left > WIDTH:
            self.rect.right = 0
        if self.rect.right < 0:
            self.rect.left = WIDTH
        if self.rect.top > HEIGHT:
            self.rect.top = 0
        if self.rect.bottom < 0:
            self.rect.bottom = HEIGHT

    def rotate(self, mouse_x, mouse_y):
        rel_x = mouse_x - self.rect.x
        rel_y = mouse_y - self.rect.y
        angle = (180 / math.pi) * -math.atan2(rel_y, rel_x)

        self.image = py.transform.rotate(self.rotatableimage, int(angle))
        self.rect = self.image.get_rect(center=(self.rect.centerx, self.rect.centery))
        return


class NPC(py.sprite.Sprite):
    def __init__(self):
        py.sprite.Sprite.__init__(self)
        self.image = py.Surface((30, 30))
        self.image.fill(RED)
        self.rect = self.image.get_rect()
        self.rect.x = random.randrange(WIDTH - self.rect.width)
        self.rect.y = random.randrange(-100, -40)
        self.Yspeed = random.randrange(1, 8)

    def update(self):
        self.rect.y += self.Yspeed
        if self.rect.top > HEIGHT + 10:
            self.rect.x = random.randrange(WIDTH - self.rect.width)
            self.rect.y = random.randrange(-100, -40)
            self.Yspeed = random.randrange(1, 8)

Заранее спасибо.

1 Ответ

3 голосов
/ 05 мая 2020

Вы должны добавить случайное направление и отдельную скорость (self.Xspeed, self.Yspeed) для направлений x и y:

self.direction = random.randrange(4)

и установить self.rect.x, self.rect.y, self.Xspeed и self.Yspeed в зависимости от случайного направления:

if self.direction == 0:
    self.rect.x = random.randrange(WIDTH - self.rect.width)
    self.rect.y = random.randrange(-100, -40)
    self.Xspeed = 0
    self.Yspeed = random.randrange(1, 8)
elif self.direction == 1:
    # [...]
elif self.direction == 2:
    # [...]
elif self.direction == 3:
    # [...]

Создайте метод spawn, который порождает врага со случайным направлением и случайной скоростью и вызывает его в конструкторе NPC:

class NPC(py.sprite.Sprite):
    def __init__(self):
        # [...]        

        self.spawn()

    def spawn(self):
        self.direction = random.randrange(4)
        if self.direction == 0:
            # [...]

В update скорость должна быть и отдельно для позиций x и y:

self.rect.x += self.Xspeed
self.rect.y += self.Yspeed

Кроме того, если объект находится вне окна, необходимо оцениваться в зависимости от direction. Если объект находится вне окна, вызовите spawn() снова, таким образом, объект получит новое случайное направление, положение и скорость:

if self.direction == 0:
    if self.rect.top > HEIGHT + 10:
        self.spawn()
elif self.direction == 1:
    if self.rect.bottom < -10:
        self.spawn()
elif self.direction == 2:
    if self.rect.left > WIDTH + 10:
        self.spawn()
elif self.direction == 3:
    if self.rect.right < -10:
        self.spawn()

Чтобы повернуть изображение, вы должны создать поверхность с точностью до пикселя. альфа (convert_alpha()) и сохранить исходную поверхность:

self.image = py.Surface((30, 30)).convert_alpha()
self.image.fill(RED)
self.originalimage = self.image  

Вычислить угол от врага до игрока и повернуть изображение на pygame.transform.rotate(): (См. Также Как повернуть треугольник на определенный угол в pygame? )

dir_x, dir_y = player.rect.x - self.rect.x, player.rect.y - self.rect.y
self.rot = (180 / math.pi) * math.atan2(-dir_x, -dir_y)
self.image = py.transform.rotate(self.originalimage, self.rot)

Class NPC:

class NPC(py.sprite.Sprite):
    def __init__(self, player):
        py.sprite.Sprite.__init__(self)
        self.player = player 
        self.image = py.Surface((30, 30)).convert_alpha()
        self.image.fill(RED)
        self.originalimage = self.image
        self.rect = self.image.get_rect()
        self.spawn()

    def spawn(self):
        self.direction = random.randrange(4)
        if self.direction == 0:
            self.rect.x = random.randrange(WIDTH - self.rect.width)
            self.rect.y = random.randrange(-100, -40)
            self.Xspeed = 0
            self.Yspeed = random.randrange(1, 8)
        elif self.direction == 1:
            self.rect.x = random.randrange(WIDTH - self.rect.width)
            self.rect.y = random.randrange(HEIGHT, HEIGHT+60)
            self.Xspeed = 0
            self.Yspeed = -random.randrange(1, 8)
        elif self.direction == 2:
            self.rect.x = random.randrange(-100, -40)
            self.rect.y = random.randrange(HEIGHT - self.rect.height)
            self.Xspeed = random.randrange(1, 8)
            self.Yspeed = 0
        elif self.direction == 3:
            self.rect.x = random.randrange(WIDTH, WIDTH+60)
            self.rect.y = random.randrange(HEIGHT - self.rect.height)
            self.Xspeed = -random.randrange(1, 8)
            self.Yspeed = 0

    def update(self):
        self.rect.x += self.Xspeed
        self.rect.y += self.Yspeed

        dir_x, dir_y = self.player.rect.x - self.rect.x, self.player.rect.y - self.rect.y
        self.rot = (180 / math.pi) * math.atan2(-dir_x, -dir_y)
        self.image = py.transform.rotate(self.originalimage, self.rot)

        if self.direction == 0:
            if self.rect.top > HEIGHT + 10:
                self.spawn()
        elif self.direction == 1:
            if self.rect.bottom < -10:
                self.spawn()
        elif self.direction == 2:
            if self.rect.left > WIDTH + 10:
                self.spawn()
        elif self.direction == 3:
            if self.rect.right < -10:
                self.spawn()
player = Player()
all_sprites.add(player)
for i in range(8):
    n = NPC(player)
    all_sprites.add(n)
    NPC.add(n)
...