让敌人射击玩家

huangapple go评论73阅读模式
英文:

Make enemies shoot the player

问题

现在敌人已经随机移动并瞄准玩家了,现在我想让敌人射击玩家,但我不知道为什么子弹会随机飞射,正如您在下面的GIF中所看到的(按左Ctrl键射击)。

以下是玩家类(Player class):

class Player:
    # 初始化玩家
    def __init__(self, x, y, player):
        self.x = x
        self.y = y
        self.image = first_player_spaceship_image
        self.life = 6
        self.original_player_image = first_player_spaceship_image
        self.angle = 0
        self.rect = self.image.get_rect()

    # 移动玩家
    def movePlayer(self):
        # ...(此处省略了一些代码,用于处理玩家移动)
    
    # 旋转玩家以瞄准鼠标指向的方向
    def rotate(self):
        # ...(此处省略了一些代码,用于旋转玩家角度)

    # 绘制玩家
    def drawPlayer(self):
        screen.blit(self.image, self.rect.topleft)

这是我的敌人类(Enemy class):

class ShootingEnemy:
    # 初始化敌人
    def __init__(self):
        # ...(此处省略了一些代码,用于初始化敌人)

    # 继续移动射击敌人
    def continueMoveShootingEnemy(self):
        # ...(此处省略了一些代码,用于移动敌人)

    # 旋转射击敌人以瞄准玩家
    def rotate(self):
        # ...(此处省略了一些代码,用于旋转敌人角度)

    def drawShootingEnemies(self):
        screen.blit(self.image, (self.x, self.y))

这是我的子弹类(Bullet class):

class BulletEnemyShooting:
    # 初始化敌人射击的子弹
    def __init__(self, shooting_enemy):
        # ...(此处省略了一些代码,用于初始化子弹)

    # 移动子弹
    def MoveBulletEnemyShooting(self):
        # ...(此处省略了一些代码,用于移动子弹)

    def drawBulletEnemyShooting(self):
        screen.blit(self.image, (self.x, self.y))

    # 旋转子弹以适应新的角度
    def rotate(self):
        # ...(此处省略了一些代码,用于旋转子弹)

请注意,我在代码中省略了一些与移动和旋转有关的代码,以确保尽可能保持清晰度。如果您希望进一步了解如何实现子弹的正确射击,请检查与子弹移动和旋转相关的代码部分,以确保它们按照您的预期进行。

英文:

I have made the enemies to move randomly and look at the player, now I would like to get the enemies to shoot the player, I do not know why but the shots go totally random, as you can see in the gif below(you shoot by pressing left ctrl).

Anyway this is the Player class:

class Player:
# inizialize the player
def __init__(self, x, y, player):
    self.x = x
    self.y = y
    self.image = first_player_spaceship_image
    self.life = 6
    self.original_player_image = first_player_spaceship_image
    self.angle = 0
    self.rect = self.image.get_rect()

# move the player
def movePlayer(self):
    if key[0]:
        self.x -= 10
    elif key[1]:
        self.x += 10
    if key[2]:
        self.y -= 10
    elif key[3]:
        self.y += 10

    # check borders
    if self.x <= 0:
        self.x = 0
    if self.x + shooting_enemy_image.get_width() >= display_width:
        self.x = display_width - first_player_spaceship_image.get_width()
    if self.y <= 0:
        self.y = 0
    if self.y + first_player_spaceship_image.get_height() >= display_height:
        self.y = display_height - first_player_spaceship_image.get_height()

# rotate the player where the mouse is aiming
def rotate(self):
    mouse_x, mouse_y = pygame.mouse.get_pos()
    rel_x, rel_y = mouse_x - self.x, mouse_y - self.y
    self.angle = (180 / math.pi) * -math.atan2(rel_y, rel_x) - 90
    self.image = pygame.transform.rotate(self.original_player_image, int(self.angle))
    orig_center = self.original_player_image.get_rect(topleft=(self.x, self.y)).center
    self.rect = self.image.get_rect(center=orig_center)

# draw the player
def drawPlayer(self):
    screen.blit(self.image, self.rect.topleft)

This is my Enemy class:

class ShootingEnemy:
# inizialize the enemy
def __init__(self):
    self.image = shooting_enemy_image
    self.new_shooting_enemy_image = shooting_enemy_image
    self.x = display_width // 2
    self.y = 0
    self.begin_down = True
    self.choices = 0
    self.timer = 51
    self.left_again = False
    self.right_again = False
    self.up_again = False
    self.down_again = False
    self.rect = shooting_enemy_image.get_rect()
    self.angle = 0

# draw the shooting enemy
def continueMoveShootingEnemy(self):
    if self.y < 30:
        self.y += 1
    if self.y == 30:
        self.begin_down = False
        self.y += 1
    else:
        if not self.begin_down and self.timer > 20:
            self.choices = random.choice([1, 2, 3, 4])
            self.timer = 0
        self.timer += 1
        if self.left_again:
            self.x += 1
            self.left_again = False
        if self.right_again:
            self.x -= 1
            self.right_again = False
        if self.up_again:
            self.y += 0
            self.up_again = False
        if self.down_again:
            self.y -= 1
            self.down_again = False
        else:
            if self.choices == 1:
                if self.x >= display_width:
                    self.timer = 21
                    self.right_again = True
                else:
                    if self.y < 140 and self.y > 10:
                        self.y += 1
                        self.x += 4
                    else:
                        self.x += 4
            if self.choices == 2:
                if self.x <= 0:
                    self.timer = 21
                    self.left_again = True
                else:
                    if self.y < 140 and self.y > 10:
                        self.y += 1
                        self.x -= 4
                    else:
                        self.x -= 4
            if self.choices == 3:
                if self.y >= 150:
                    self.timer = 21
                    self.down_again = True
                else:
                    self.y += 2
            if self.choices == 4:
                if self.y <= 0:
                    self.timer = 21
                    self.up_again = True
                else:
                    self.y -= 2

# rotate the shooting enemy where the player is
def rotate(self):
    temp_x, temp_y = player_one_istance.x - self.x, player_one_istance.y - self.y
    self.angle = (180 / math.pi) * -math.atan2(temp_y, temp_x) - 90
    self.image = pygame.transform.rotate(self.new_shooting_enemy_image, int(self.angle))
    orig_center = self.new_shooting_enemy_image.get_rect(topleft=(self.x, self.y)).center
    self.rect = self.image.get_rect(center=orig_center)

def drawShootingEnemies(self):
    screen.blit(self.image, (self.x, self.y))

And this is my Bullet class:

class BulletEnemyShooting:
# initialize the bullet for the enemy shooting
def __init__(self, shooting_enemy):
    self.x = shooting_enemy.x
    self.y = shooting_enemy.y
    self.image = laser_bullet
    self.original_image = laser_bullet
    self.angle = shooting_enemy.angle
    self.vel_x = math.cos(self.angle) * 45
    self.vel_y = math.sin(self.angle) * 45
    self.rect = self.image.get_rect()

# draw the bullet
def MoveBulletEnemyShooting(self):
    self.x += self.vel_x
    self.y += self.vel_y
    if self.x < -laser_bullet.get_width() or self.x >= display_width + laser_bullet.get_width() \
            or self.y < -laser_bullet.get_height() or self.y >= display_height + laser_bullet.get_height():
        enemy_shooting_bullets_list.pop(enemy_shooting_bullets_list.index(self))

def drawBulletEnemyShooting(self):
    screen.blit(self.image, (self.x, self.y))

# rotate the bullet to the new angle
def rotate(self):
    self.image = pygame.transform.rotate(self.original_image,
                                         ((180 / math.pi) * -math.atan2(self.vel_y, self.vel_x) - 90))
    self.rect = self.image.get_rect()

In case you want to test the code I have eliminated unnecessary things:
https://pastebin.com/HT93hUzt

You can download replacement images to test the code here (remember to change the image load string!):

https://www.flaticon.com/free-icon/spaceship_1702089?term=spaceship&page=1&position=12

https://www.flaticon.com/free-icon/spaceship_1114531

https://www.flaticon.com/search?word=laserbeam

让敌人射击玩家

答案1

得分: 1

我自己找到了答案,对于那些感兴趣的人,我将代码放在这里:

class BulletEnemyShooting:
    def __init__(self, temp_angle, pos, target):
        self.image = enemy_laser_bullet_image
        self.original_image = enemy_laser_bullet_image
        # `pos` 参数是子弹 rect 的中心。
        self.rect = self.image.get_rect(center=pos)
        self.position = Vector2(pos)  # 子弹的位置。

        # 此向量指向从射击敌人位置到目标位置
        direction = target - pos
        # 方向向量的极坐标。
        radius, angle = direction.as_polar()
        # 通过负角度旋转图像(因为y轴翻转了)。
        self.image = pygame.transform.rotozoom(self.image, -angle, 1)
        # 速度是归一化的方向向量,缩放到所需的长度。
        self.velocity = direction.normalize() * 11

    def update(self):
        # 移动子弹
        self.position += self.velocity  # 更新位置向量。
        self.rect.center = self.position  # 以及 rect。

    def drawBulletEnemyShooting(self):
        screen.blit(self.image, self.rect)

    # 检查敌人射击子弹是否与玩家碰撞,如果是,则减少生命。
    def collisionBulletShootingEnemy(self, shooting_enemy, shooting_enemy_image):
        global score
        shooting_enemy_rect = pygame.Rect(shooting_enemy.x, shooting_enemy.y, shooting_enemy_image.get_width(), shooting_enemy_image.get_height())
        bullet_rect = pygame.Rect(self.x, self.y, laser_bullet.get_width(), laser_bullet.get_height())
        # 检查碰撞
        if shooting_enemy_rect.colliderect(bullet_rect):
            bullets_list.pop(bullets_list.index(self))
            shooting_enemy.x = 5000
            score += 1

# 这必须在游戏的主循环中完成,因此每次都必须重新计算目标。
if enemy_shooting_bool:
    for shooting_enemy in shooting_enemies_list:
        target = Vector2(player_one_istance.x, player_one_istance.y)
        bullet = BulletEnemyShooting(shooting_enemy.angle, (shooting_enemy.x, shooting_enemy.y), target)
        enemy_bullets_list.append(bullet)
        enemy_shooting_bool = False

我希望这对某人有所帮助

<details>
<summary>英文:</summary>

I found the answer on my own, for those interested, I put the code here:

    class BulletEnemyShooting:
    def __init__(self, temp_angle, pos, target):
        self.image = enemy_laser_bullet_image
        self.original_image = enemy_laser_bullet_image
        # The `pos` parameter is the center of the bullet.rect.
        self.rect = self.image.get_rect(center=pos)
        self.position = Vector2(pos)  # The position of the bullet.

        # This vector points from the shooting_enemy position to target position
        direction = target - pos
        # The polar coordinates of the direction vector.
        radius, angle = direction.as_polar()
        # Rotate the image by the negative angle (because the y-axis is flipped).
        self.image = pygame.transform.rotozoom(self.image, -angle, 1)
        # The velocity is the normalized direction vector scaled to the desired length.
        self.velocity = direction.normalize() * 11

    def update(self):
        #move the bullet
        self.position += self.velocity  # Update the position vector.
        self.rect.center = self.position  # And the rect.

    def drawBulletEnemyShooting(self):
        screen.blit(self.image, self.rect)

    #check if the enemy shooting bullet collides with player and in that case decrement the life
    def collisionBulletShootingEnemy(self, shooting_enemy, shooting_enemy_image):
        global score
        shooting_enemy_rect = pygame.Rect(shooting_enemy.x, shooting_enemy.y, shooting_enemy_image.get_width(), shooting_enemy_image.get_height() )
        bullet_rect = pygame.Rect(self.x, self.y, laser_bullet.get_width(), laser_bullet.get_height() )
        # check collision
        if shooting_enemy_rect.colliderect(bullet_rect):
            bullets_list.pop(bullets_list.index(self))
            shooting_enemy.x = 5000
            score += 1

And this has to be done in the main loop of the game, so the target has to be recalculated each time:

        if enemy_shooting_bool:
        for shooting_enemy in shooting_enemies_list:
            target = Vector2(player_one_istance.x, player_one_istance.y)
            bullet = BulletEnemyShooting(shooting_enemy.angle, (shooting_enemy.x, shooting_enemy.y), target)
            enemy_bullets_list.append(bullet)
            enemy_shooting_bool = False

I hope this can help someone!

</details>



huangapple
  • 本文由 发表于 2020年1月6日 18:58:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/59610856.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定