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