以下是Python实现坦克大战的完整代码:
import pygame
from random import randint
# 初始化Pygame库
pygame.init()
# 定义游戏窗口大小和标题
screen_width, screen_height = 640, 480
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Tank Battle")
# 加载图像资源
tank_img = pygame.image.load('tank.png').convert_alpha()
bullet_img = pygame.image.load('bullet.png').convert_alpha()
explosion_imgs = [pygame.image.load('explosion1.png').convert_alpha(),
pygame.image.load('explosion2.png').convert_alpha(),
pygame.image.load('explosion3.png').convert_alpha()]
# 定义颜色常量
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
# 定义游戏对象类
class GameObject:
def __init__(self, x, y):
self.x = x
self.y = y
def draw(self):
pass
# 定义坦克类,继承自GameObject类
class Tank(GameObject):
def __init__(self, x, y):
super().__init__(x, y)
self.direction = 'up'
self.speed = 5
# 根据方向移动坦克位置,并检查是否越界或碰到墙壁
def move(self):
if self.direction == 'up':
if self.y > 0:
self.y -= self.speed
else:
self.y = 0
elif self.direction == 'down':
if self.y < screen_height - tank_img.get_height():
self.y += self.speed
else:
self.y = screen_height - tank_img.get_height()
elif self.direction == 'left':
if self.x > 0:
self.x -= self.speed
else:
self.x = 0
elif self.direction == 'right':
if self.x < screen_width - tank_img.get_width():
self.x += self.speed
else:
self.x = screen_width - tank_img.get_width()
# 发射子弹
def fire(self):
bullet_x, bullet_y = 0, 0
# 根据坦克方向计算子弹位置
if self.direction == 'up':
bullet_x = self.x + tank_img.get_width() / 2 - bullet_img.get_width() / 2
bullet_y = self.y
elif self.direction == 'down':
bullet_x = self.x + tank_img.get_width() / 2 - bullet_img.get_width() / 2
bullet_y = self.y + tank_img.get_height()
elif self.direction == 'left':
bullet_x = self.x
bullet_y =self. y + tank_img.get_height() / 2 - bullet_img.get_height() / 2
elif self.direction == 'right':
bullet_x =self. x +tank_ img. get_ width ()
bullet_y= sel f. y +tank_ img. get_ height ()/2- bul let _i mg. ge t_hei ght()/2
return Bullet(bullet_x, bullet_y, direction=self.direction)
# 绘制坦克图像到屏幕上
def draw(self):
rotated_tank_image, rotated_tank_rect = self.rotate_image(tank_img, (self.x, self.y), self.direction)
screen.blit(rotated_tank_image, rotated_tank_rect)
# 根据方向旋转坦克图像
def rotate_image(self, image, pos, direction):
if direction == 'up':
return image, pygame.Rect(pos[0], pos[1], image.get_width(), image.get_height())
elif direction == 'down':
return pygame.transform.flip(image, False, True), pygame.Rect(pos[0], pos[1], image.get_width(), image.get_height())
elif direction == 'left':
return pygame.transform.rotate(image, 90), pygame.Rect(pos[0], pos[1], image.get_height(), image.get_width())
elif direction == 'right':
return pygame.transform.rotate(image, -90), pygame.Rect(pos[0], pos[1], image.get_height(), image.get_width())
# 定义子弹类,继承自GameObject类
class Bullet(GameObject):
def __init__(self, x, y, direction='up'):
super().__init__(x, y)
self.speed = 10
self.direction = direction
# 移动子弹位置,并检查是否越界或碰到墙壁
def move(self):
if self.direction == 'up':
if self.y > 0:
self.y -= self.speed
else:
return False
elif self.direction == 'down':
if self.y < screen_height - bullet_img.get_height():
self.y += self.speed
else:
return False
elif self.direction == 'left':
if self.x > 0:
self.x -= self.speed
else:
return False
elif self.direction == 'right':
if self.x < screen_width - bullet_img.get_width():
self.x += self.speed
else:
return False
return True
# 绘制子弹图像到屏幕上
def draw(self):
screen.blit(bullet_img, (self.x, self.y))
# 定义爆炸类,继承自GameObject类
class Explosion(GameObject):
def __init__(self, x, y):
super().__init__(x, y)
self.frame_index = 0
self.frame_count = len(explosion_imgs)
self.frame_duration = 3
self.frame_timer = 0
# 更新爆炸动画帧
def update(self):
self.frame_timer += 1
if self.frame_timer >= self.frame_duration:
if self.frame_index < self.frame_count - 1:
self.frame_index += 1
else:
return False
self.frame_timer = 0
return True
# 绘制当前爆炸动画帧到屏幕上
def draw(self):
screen.blit(explosion_imgs[self.frame_index], (self.x, self.y))
# 定义障碍物类,继承自GameObject类
class Obstacle(GameObject):
def __init__(self, x, y):
super().__init__(x, y)
# 绘制障碍物图像到屏幕上
def draw(self):
pygame.draw.rect(screen, black, (self.x, self.y, 30, 30))
# 创建游戏对象实例:坦克、敌方坦克、子弹、爆炸和障碍物
player_tank = Tank(screen_width/2-tank_img.get_width()/2, screen_height-tank_img.get_height())
enemy_tank = Tank(randint(0, screen_width - tank_img.get_width()), 0)
enemy_bullet = None
explosion = None
obstacles = []
for i in range(10):
obstacles.append(Obstacle(randint(0, screen_width-30), randint(0, screen_height-30))))
# 定义游戏循环变量和时钟对象
running = True
clock = pygame.time.Clock()
# 游戏循环
while running:
# 处理事件:按键、关闭窗口等
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
player_tank.direction = 'up'
elif event.key == pygame.K_DOWN:
player_tank.direction = 'down'
elif event.key == pygame.K_LEFT:
player_tank.direction = 'left'
elif event.key == pygame.K_RIGHT:
player_tank.direction ='right'
elif event.key == pygame.K_SPACE and enemy_bullet is None:
enemy_bullet= enemy _tank.fire()
# 移动坦克和子弹位置,并检查是否发生碰撞或越界等情况,处理相关逻辑
if enemy_bullet is not None and not enemy_bullet.move():
if player_tank.x < enemy_bullet.x + bullet_img.get_width() < player_tank.x + tank_img.get_width() and \
player_tank.y < enemy_bullet.y + bullet_img.get_height() < player_tank.y + tank_img.get_height():
explosion = Explosion(player_tank.x, player_tank.y)
player_tank.x = screen_width / 2 - tank_img.get_width() / 2
player_tank.y = screen_height - tank_img.get_height()
enemy_bullet = None
if enemy_tank is not None and randint(0, 100) > 95:
enemy_bullet = enemy_tank.fire()
if enemy_bullet is not None and not enemy_bullet.move():
if player_tank.x < enemy_bullet.x + bullet_img.get_width() < player_tank.x + tank_img.get_width() and \
player_tank.y < enemy_bullet.y + bullet_img.get_height() < player_tank.y + tank_img.get_height():
explosion = Explosion(player_tank.x, player_tank.y)
player_tank.x = screen_width/2-tank_img.get_width()/2
player _tank. y=screen_ height-tan k_i mg. get_ height ()
elif (enemy_bullet.x<0 or enemy_bullet.x>screen_width or
enemy _bullet .y<0 or ene my_bul let .y>scr een_ heig ht):
enemy _bullet=None
for obstacle in obstacles:
if (obstacle. x<player _tank. x+ta nk_i mg. get_ width ()and
obstacle. x+3 0>pla yer_ tank .x and
obstacle .y<pl ayer_ta nk.y+t ank_i mg.g et_hei ght( )and
obs tacle .y+30>p layer_ tan k.y ):
if pl ayer_ta nk.di rect ion=='up':
play er_ta nk. y=obstacle . y+t ank_i mg.ge t_ height ()
elif player_tank.direction=='down':
player _tank. y= obstacle.y- tank_img. get_height()
elif player_tank.direction =='left':
player _tank. x=obstacle .x+30
elif pla yer_ta nk.di rect ion=='right':
play er_ta nk.x=o bs tac le.x-t an k_i mg. get_ width ()
if (enemy_bullet is not None and
obstacle .x<en emy_b ul let .x+b ullet _img.get_ widt h()and
obs tacle .x+3 0>ene my_bul let .x and
obstacle.y < enemy_bullet.y + bullet_img.get_height() < obstacle.y + 30):
explosion = Explosion(obstacle.x, obstacle.y)
obstacles.remove(obstacle)
enemy_bullet = None
if explosion is not None:
if not explosion.update():
explosion = None
# 绘制游戏场景和对象
screen.fill(white)
for obstacle in obstacles:
obstacle.draw()
if enemy_tank is not None:
enemy_tank.move()
enemy_tank.draw()
if enemy_bullet is not None:
enemy_bullet.draw()
if explosion is not None:
explosion.draw()
player_tank.move()
player_tank.draw()
pygame.display.update()
# 设置游戏帧率
clock.tick(60)
# 退出Pygame库
pygame.quit()
以上代码实现了基本的坦克大战游戏功能,包括坦克移动、发射子弹、障碍物碰撞检测等。但仍有很多改进和扩展的空间,例如增加多个敌方坦克、支持双人游戏模式等。