首页 > 解决方案 > 在 python/pygame 中射击坦克子弹

问题描述

我现在正在使用 pygame 库处理 python 项目,我需要帮助我制作的这个项目。我想让我的坦克发射子弹,这样子弹就会从墙上弹射出来。最好的方法是什么?

很抱歉我的代码看起来很乱,我一直在看不同的 youtube 教程,它们的做法都不同。

这是我的代码

import pygame

pygame.init()

# ======================= Variables =======================

# ------------------------ Screen -------------------------

screenWidth = 1060
screenHeight = 798
screenSize = (screenWidth, screenHeight)
display = pygame.display.set_mode((screenWidth, screenHeight))
pygame.display.set_caption("Tank game")

bg = pygame.image.load("sprites/background/background1.png")
bg = pygame.transform.scale(bg, (screenWidth, screenHeight))

# ------------------------ Player -------------------------


# ------------------------ Enemy -------------------------


# ----------------------- Other ---------------------------

red = (155, 0, 0)

clock = pygame.time.Clock()
fps = 60


# ========================= Clases ========================


class player(pygame.sprite.Sprite):
    def __init__(self, location, angle, vel, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("sprites/player/player_tank.png")

        self.x = x
        self.y = y
        self.vel = vel
        self.angle = angle
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = location

        if self.angle == 360:
            self.angle = 0

    def rotate(self):
        rot_image = pygame.transform.rotate(self.image, self.angle)
        rot_rect = rot_image.get_rect(center=self.rect.center)
        return rot_image, rot_rect

    def moving_after_angle_change(self):
        x = round(math.cos(math.radians(self.angle + 90)), 1) * self.vel
        y = round(math.sin(math.radians(self.angle - 90)), 1) * self.vel
        return x, y


class enemy(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height, end):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("sprites/enemy/enemy_tank.png")

        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.end = end
        self.path = [self.x, self.y, self.end]
        self.vel = 5

    def draw(self, display):
        self.move()
        display.blit(self.image, (self.x, self.y))

    def move(self):
        if self.vel > 0:
            pass


# Bullet
bullet = pygame.image.load("sprites/bullet/bullet.png")
bullet = pygame.transform.scale(bullet, (16, 16))
bullet_x = 0
bullet_y = 480
bullet_x_change = 0
bullet_y_change = 10
bullet_state = 'ready'


# ======================= Functions =======================

def redrawGameWindow():
    display.blit(bg, (0, 0))
    display.blit(player_tank.image, player_tank.rect)
    display.blit(enemy_tank.image, (enemy_tank.x, enemy_tank.y))
    #display.blit(bullet, (player_tank.x + 160, player_tank.y + 100))

    pygame.display.flip()


def fireBullet(x, y):
    global bullet_state
    bullet_state = 'fire'
    display.blit(bullet, (x + 16, y + 10))


player_location = [70, 570]
player_angle = 270
player_angle_change = 0
player_vel = 0
player_x_change = 0
player_y_change = 0
player_tank_x_change_store = 0
player_tank_y_change_store = 0

run = True

while run:
    clock.tick(fps)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                player_vel = 2
            elif event.key == pygame.K_DOWN:
                player_vel = -2
            elif event.key == pygame.K_LEFT:
                player_angle_change = 2
            elif event.key == pygame.K_RIGHT:
                player_angle_change = -2

            if event.key == pygame.K_SPACE:
                display.blit(bullet, (player_tank.x + 160, player_tank.y + 100))

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_UP:
                player_vel = 0
            elif event.key == pygame.K_DOWN:
                player_vel = 0
            elif event.key == pygame.K_LEFT:
                player_angle_change = 0
            elif event.key == pygame.K_RIGHT:
                player_angle_change = 0

    player_angle += player_angle_change

    player_tank = player(player_location, player_angle, player_vel, player_x_change, player_y_change)

    enemy_tank = enemy(800, 170, 64, 64, 700)

    player_tank.image, player_tank.rect = player_tank.rotate()

    player_tank.x_change, player_tank.y_change = player_tank.moving_after_angle_change()

    player_tank_x_change_store += player_tank.x_change
    player_tank_y_change_store += player_tank.y_change
    player_tank.rect.centerx += player_tank_x_change_store
    player_tank.rect.centery += player_tank_y_change_store

    # Bullet movement
    if bullet_state == "fire":
        fireBullet(player_tank.x, bullet_y)
        bullet_y -= bullet_y_change

    redrawGameWindow()

pygame.quit()
quit()

标签: pythonpygame

解决方案


一种方法是让子弹在撞到墙上时速度翻转。现在我假设墙壁是屏幕的边缘,所以你需要做的是在循环中,检查子弹是否即将撞到墙壁(屏幕边缘),如果是,翻转它的x_changeand y_change。所以是这样的:

if bullet_y <= 0:
    bullet_y_change *= -1
    bullet_y = 0
if bullet_y >= screenHeight:
    bullet_y_change *= -1
    bullet_y = screenHeight
if bullet_x <= 0:
    bullet_x_change *= -1
    bullet_x = 0
if bullet_x >= screenWidth:
    bullet_x_change *= 1
    bullet_x = screenWidth

推荐阅读