在python/pygame中射击坦克子弹

在python/pygame中射击坦克子弹,python,pygame,Python,Pygame,我现在正在使用pygame库进行python项目,我需要帮助完成这个项目。我想让我的坦克射出子弹,所以那些子弹会从墙上弹出来。最好的方法是什么 很抱歉,我的代码看起来很混乱,我一直在看不同的youtube教程,它们都做得不同 这是我的密码 import pygame pygame.init() # ======================= Variables ======================= # ------------------------ Screen -----

我现在正在使用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()

一种方法是使子弹撞击墙壁时速度翻转。现在我假设墙壁是屏幕的边缘,所以你需要做的是在循环中,检查子弹是否要击中墙壁(屏幕的边缘),如果是,翻转它的
x\u change
y\u 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
如果bullet_y=屏幕高度:
bullet_y_change*=-1
bullet_y=屏幕高度
如果bullet_x=屏幕宽度:
bullet_x_change*=1
bullet_x=屏幕宽度

以下是一个完整的示例,基于一个旧的:

导入pygame
职业玩家(pygame.sprite.sprite):
定义初始化(自):
super()。\uuuu init\uuuuu()
self.image=pygame.Surface((32,32))
self.image.fill((0,0,0))
self.image.set_colorkey((0,0,0))
pygame.draw.polygon(self.image,pygame.Color('dodgerblue'),((0,0)、(32,16)、(0,32)))
self.org_image=self.image.copy()
自转角=0
self.direction=pygame.Vector2(1,0)
self.rect=self.image.get_rect(中心=(200200))
self.pos=pygame.Vector2(self.rect.center)
def更新(自身、事件、dt):
对于事件中的e:
如果e.type==pygame.KEYDOWN:
如果e.key==pygame.K_空间:
self.groups()[0]。添加(投射(self.rect.center,self.direction.normalize())
pressed=pygame.key.get_pressed()
如果按下[pygame.K_a]:
自转角+=3
如果按下[pygame.K_d]:
自转角-=3
self.direction=pygame.Vector2(1,0)。旋转(-self.angle)
self.image=pygame.transform.rotate(self.org\u image,self.angle)
self.rect=self.image.get_rect(中心=self.rect.center)
类射弹(pygame.sprite.sprite):
定义初始(自身、位置、方向):
super()。\uuuu init\uuuuu()
self.image=pygame.Surface((8,8))
self.image.fill((0,0,0))
self.image.set_colorkey((0,0,0))
pygame.draw.circle(self.image,pygame.Color('orange'),(4,4),4)
self.rect=self.image.get_rect(中心=pos)
方向
self.pos=pygame.Vector2(self.rect.center)
self.lifes=15
def更新(自身、事件、dt):
#屏幕边框
screen_r=pygame.display.get_surface().get_rect()
#我们下一步要去哪里
下一个位置=self.pos+self.direction*dt
#我们撞到了一个大厅
如果屏幕不包含(self.rect):
#15次命中后,摧毁自我
self.lifes-=1
如果self.lifes==0:
返回self.kill()
#水平反射
如果下一个位置x>右屏幕或下一个位置x<左屏幕:
self.direction.x*=-1
#垂直反射
如果下一个位置y>屏幕底部或下一个位置y<屏幕顶部:
自我方向y*=-1
#应用反射后移动
下一个位置=self.pos+self.direction*dt
#设置新位置
self.pos=下一个位置
self.rect.center=self.pos
def main():
pygame.init()
screen=pygame.display.set_模式((500500))
sprites=pygame.sprite.Group(Player())
clock=pygame.time.clock()
dt=0
尽管如此:
events=pygame.event.get()
对于事件中的e:
如果e.type==pygame.QUIT:
返回
sprites.update(事件,dt)
屏幕填充((30,30,30))
精灵。绘制(屏幕)
pygame.display.update()
dt=时钟滴答声(60)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()

了解如何使用
Vector2
类使此类任务非常容易解决


另外,请查看
Sprite
类的正确用法。每个
Sprite
处理自己的事务:
Player
类处理旋转播放器和创建投射物,
sparket
处理移动投射物和墙壁反弹

谢谢你的帮助!我能再问你一件事吗?你们能在我的代码中实现你们的代码吗?因为我是pygame新手,不能以正确的方式实现。代码如下:
import pygame

class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((32, 32))
        self.image.fill((0, 0, 0))
        self.image.set_colorkey((0, 0, 0))
        pygame.draw.polygon(self.image, pygame.Color('dodgerblue'), ((0, 0), (32, 16), (0, 32)))
        self.org_image = self.image.copy()
        self.angle = 0
        self.direction = pygame.Vector2(1, 0)
        self.rect = self.image.get_rect(center=(200, 200))
        self.pos = pygame.Vector2(self.rect.center)

    def update(self, events, dt):
        for e in events:
            if e.type == pygame.KEYDOWN:
                if e.key == pygame.K_SPACE:
                    self.groups()[0].add(Projectile(self.rect.center, self.direction.normalize()))
        pressed = pygame.key.get_pressed()
        if pressed[pygame.K_a]:
            self.angle += 3
        if pressed[pygame.K_d]:
            self.angle -= 3

        self.direction = pygame.Vector2(1, 0).rotate(-self.angle)
        self.image = pygame.transform.rotate(self.org_image, self.angle)
        self.rect = self.image.get_rect(center=self.rect.center)

class Projectile(pygame.sprite.Sprite):
    def __init__(self, pos, direction):
        super().__init__()
        self.image = pygame.Surface((8, 8))
        self.image.fill((0, 0, 0))
        self.image.set_colorkey((0, 0, 0))
        pygame.draw.circle(self.image, pygame.Color('orange'), (4, 4), 4)
        self.rect = self.image.get_rect(center=pos)
        self.direction = direction
        self.pos = pygame.Vector2(self.rect.center)
        self.lives = 15

    def update(self, events, dt):
        # Bounding box of the screen
        screen_r = pygame.display.get_surface().get_rect()

        # where we would move next
        next_pos = self.pos + self.direction * dt

        # we hit a hall
        if not screen_r.contains(self.rect):

            # after 15 hits, destroy self
            self.lives -= 1
            if self.lives == 0:
                return self.kill()

            # horizontal reflection
            if next_pos.x > screen_r.right or next_pos.x < screen_r.left:
                self.direction.x *= -1

            # vertical reflection
            if next_pos.y > screen_r.bottom or next_pos.y < screen_r.top:
                self.direction.y *= -1

            # move after applying reflection
            next_pos = self.pos + self.direction * dt

        # set the new position
        self.pos = next_pos
        self.rect.center = self.pos

def main():
    pygame.init()
    screen = pygame.display.set_mode((500, 500))
    sprites = pygame.sprite.Group(Player())
    clock = pygame.time.Clock()
    dt = 0

    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return
        sprites.update(events, dt)
        screen.fill((30, 30, 30))
        sprites.draw(screen)
        pygame.display.update()
        dt = clock.tick(60)

if __name__ == '__main__':
    main()