将精灵向Pygame中的玩家移动(使用pygame向量)

时间:2018-12-31 12:06:44

标签: python pygame

我正在做游戏,对手应该向玩家射击子弹。

我希望子弹在子弹射击时朝着玩家所在的方向移动(玩家可以移动,但子弹朝恒定的方向移动。)

但是子弹只是在对手身上闪烁。

我使用pygame的Vector2来控制子弹的移动。

这是一个子弹拼写示例:

bulletspell = Spell(
    pygame.image.load("Sprites/lightblue-glowey.png"),
    ((0, pygame.Vector2(-0.5, 1) * 4), #these vectors show the bullet shooting pattern
     (0, pygame.Vector2(0, 1) * 4),
     (0, pygame.Vector2(0.5, 1) * 4)),
    10, 8, 340
    )

我尝试的向量是(player.image.get_rect(topleft=(player.rect.x, player.rect.y)).x, 1)

我不是在寻找要修改的整个代码,我有太多的修改并且我的代码可以运行,我只需要帮助找出向量即可。

下面是代码(仅供参考):

import pygame

class Player(pygame.sprite.Sprite):
    sprite = pygame.image.load("Sprites/player.png")

    def __init__(self, *groups):
        super().__init__(*groups)
        self.image = Player.sprite
        self.rect = self.image.get_rect(topleft=(445, 550))
        self.pos = pygame.Vector2(self.rect.topleft)

    def update(self):
        key = pygame.key.get_pressed()
        dist = 3
        if key[pygame.K_DOWN]:
            self.rect.y += dist
        elif key[pygame.K_UP]:
            self.rect.y -= dist
        if key[pygame.K_RIGHT]:
            self.rect.x += dist
        elif key[pygame.K_LEFT]:
            self.rect.x -= dist
class Spell:

    def __init__(self, bullet, pattern, speed, loop, tick_delay):
        self.bullet = bullet
        self.pattern = pattern
        self.speed = speed
        self.loop = loop
        self.tick_delay = tick_delay


class Opponent(pygame.sprite.Sprite):

    def __init__(self, sprite, sequence, *groups):
        super().__init__(*groups)
        self.image = sprite
        self.rect = self.image.get_rect(topleft=(425, 30))
        self.start_time = pygame.time.get_ticks()
        self.sequence = sequence
        self.spellno = 0
        self.currentspell = sequence[self.spellno]

    def update(self):
        time_gone = pygame.time.get_ticks() - self.start_time

        if self.currentspell is not None and time_gone > self.currentspell.tick_delay:
            self.start_time = pygame.time.get_ticks()
            for bullet in self.currentspell.pattern:
                if bullet[0] <= time_gone:
                    Bullet(self.rect.center, bullet[1], self.currentspell.bullet, sprites, bullets)

            self.currentspell.loop -= 1
            if self.currentspell.loop <= 0:
                self.spellno += 1
                if self.spellno >= len(self.sequence):
                    self.currentspell = None
                else:
                    self.currentspell = self.sequence[self.spellno]


class Bullet(pygame.sprite.Sprite):

    def __init__(self, pos, direction, image, *groups):
        super().__init__(*groups)
        self.image = image
        self.rect = self.image.get_rect(topleft=pos)
        self.direction = direction
        self.pos = pygame.Vector2(self.rect.topleft)

    def update(self):
        self.pos += self.direction
        self.rect.topleft = (self.pos.x, self.pos.y)
        if not screen.get_rect().colliderect(self.rect):
            self.kill()


sprites = pygame.sprite.Group()
bullets = pygame.sprite.Group()

opponentgroup = pygame.sprite.Group()


img3 = pygame.image.load("Sprites/minty.png")
player = Player(sprites)

#I tried:    
mi3 = Spell(
    pygame.image.load("Sprites/purple-glowey.png"),
    ((0, pygame.Vector2(player.image.get_rect(topleft=(player.rect.x, player.rect.y)).x, 1) * 4),
    ), 4, 8, 340)

minty_spells = [mi1, mi3]

Minty = Opponent(img3, minty_spells, opponentgroup)
sprites.add(Minty)

pygame.init()
SCREENWIDTH = 1000
SCREENHEIGHT = 650
screen = pygame.display.set_mode([SCREENWIDTH, SCREENHEIGHT])
screen.fill((255, 123, 67))
pygame.draw.rect(screen, (0, 255, 188), (50, 50, 900, 575), 0)
background = screen.copy()
clock = pygame.time.Clock()

#main循环在这里

任何帮助将不胜感激

谢谢:)

2 个答案:

答案 0 :(得分:6)

目前实例化子弹的方向需要为:

(Player.pos - Opponent.pos).normalise()

这将为您提供一个单位向量(长度为1的向量),在子弹发射时从对手指向玩家。您需要在每次更新时将其添加到项目符号的位置。

答案 1 :(得分:3)

我建议稍微改变一下代码结构,然后将这些咒语转换为Spell的子类(看看state pattern)。将更多与射击相关的代码移到Spell类中,并为它提供一个update方法(用于更新计时器)和一个shoot方法(用于创建项目符号)。

应该以玩家为目标的咒语shoot方法可以被覆盖,以便它瞄准玩家的位置而不是使用预定义的方向之一。

update的{​​{1}}方法中,您只需要检查当前咒语是否已完成(当Opponent为0时),然后通过创建一个新实例来切换该咒语并在每帧中调用其loop方法。

update