python小游戏-坦克大战

  1. 完整的游戏状态管理:
  • 生命值系统
  • 得分系统
  • 游戏结束条件
  • 重新开始功能
  1. 增强的坦克功能:
  • 坦克旋转
  • 无敌时间
  • 不同类型的坦克(玩家/敌人)
  1. 改进的碰撞系统:
  • 子弹与墙壁碰撞
  • 子弹与坦克碰撞
  • 子弹与基地碰撞
  1. 游戏机制的完善:
  • 敌人AI
  • 自动生成新敌人
  • 可破坏和不可破坏的墙壁
  1. 用户界面改进:
  • 显示得分
  • 显示生命值
  • 游戏结束画面
python 复制代码
import pygame
import random
import os

# 初始化pygame和混音器
pygame.init()
pygame.mixer.init()

# 屏幕设置
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("坦克大战增强版")

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)

# 游戏常量
TANK_SIZE = 40
BULLET_SIZE = 10
WALL_SIZE = 40

# 加载图片和音效
def load_image(name):
    return pygame.image.load(os.path.join('images', name)).convert_alpha()

def load_sound(name):
    return pygame.mixer.Sound(os.path.join('sounds', name))

# 游戏状态
class GameState:
    def __init__(self):
        self.score = 0
        self.lives = 3
        self.level = 1
        self.game_over = False
        self.paused = False

# 坦克基类
class BaseTank(pygame.sprite.Sprite):
    def __init__(self, color, x, y):
        super().__init__()
        self.original_image = pygame.Surface((TANK_SIZE, TANK_SIZE))
        self.original_image.fill(color)
        self.image = self.original_image
        self.rect = self.image.get_rect()
        self.rect.center = (x, y)
        self.speed = 5
        self.direction = "up"
        self.shoot_delay = 500  # 射击延迟(毫秒)
        self.last_shot = pygame.time.get_ticks()

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

# 玩家坦克
class PlayerTank(BaseTank):
    def __init__(self, x, y):
        super().__init__(GREEN, x, y)
        self.lives = 3
        self.invincible = False
        self.invincible_timer = 0

    def update(self, keys, current_time):
        if self.invincible:
            if current_time - self.invincible_timer > 3000:  # 3秒无敌时间
                self.invincible = False

        if keys[pygame.K_LEFT]:
            self.rect.x = max(0, self.rect.x - self.speed)
            self.direction = "left"
            self.rotate(90)
        if keys[pygame.K_RIGHT]:
            self.rect.x = min(SCREEN_WIDTH - self.rect.width, self.rect.x + self.speed)
            self.direction = "right"
            self.rotate(-90)
        if keys[pygame.K_UP]:
            self.rect.y = max(0, self.rect.y - self.speed)
            self.direction = "up"
            self.rotate(0)
        if keys[pygame.K_DOWN]:
            self.rect.y = min(SCREEN_HEIGHT - self.rect.height, self.rect.y + self.speed)
            self.direction = "down"
            self.rotate(180)

# 敌人坦克
class EnemyTank(BaseTank):
    def __init__(self, x, y):
        super().__init__(RED, x, y)
        self.speed = 3
        self.direction_timer = pygame.time.get_ticks()
        self.direction_change_delay = 1000

    def update(self, current_time):
        # 随机改变方向
        if current_time - self.direction_timer > self.direction_change_delay:
            self.direction = random.choice(["up", "down", "left", "right"])
            self.direction_timer = current_time

        # 根据方向移动
        if self.direction == "left":
            self.rect.x = max(0, self.rect.x - self.speed)
            self.rotate(90)
        elif self.direction == "right":
            self.rect.x = min(SCREEN_WIDTH - self.rect.width, self.rect.x + self.speed)
            self.rotate(-90)
        elif self.direction == "up":
            self.rect.y = max(0, self.rect.y - self.speed)
            self.rotate(0)
        elif self.direction == "down":
            self.rect.y = min(SCREEN_HEIGHT - self.rect.height, self.rect.y + self.speed)
            self.rotate(180)

        # 随机射击
        if random.random() < 0.02:  # 2%的概率射击
            return True
        return False

# 子弹类
class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y, direction, owner):
        super().__init__()
        self.image = pygame.Surface((BULLET_SIZE, BULLET_SIZE))
        self.image.fill(YELLOW)
        self.rect = self.image.get_rect()
        self.rect.center = (x, y)
        self.direction = direction
        self.speed = 10
        self.owner = owner  # 'player' 或 'enemy'

    def update(self):
        if self.direction == "up":
            self.rect.y -= self.speed
        elif self.direction == "down":
            self.rect.y += self.speed
        elif self.direction == "left":
            self.rect.x -= self.speed
        elif self.direction == "right":
            self.rect.x += self.speed

        # 移除屏幕外的子弹
        if (self.rect.bottom < 0 or self.rect.top > SCREEN_HEIGHT or 
            self.rect.right < 0 or self.rect.left > SCREEN_WIDTH):
            self.kill()

# 墙壁类
class Wall(pygame.sprite.Sprite):
    def __init__(self, x, y, destructible=True):
        super().__init__()
        self.image = pygame.Surface((WALL_SIZE, WALL_SIZE))
        self.image.fill(BLUE if destructible else WHITE)
        self.rect = self.image.get_rect()
        self.rect.topleft = (x, y)
        self.destructible = destructible

# 基地类
class Base(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((WALL_SIZE, WALL_SIZE))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect()
        self.rect.topleft = (x, y)

# 游戏管理器
class Game:
    def __init__(self):
        self.state = GameState()
        self.all_sprites = pygame.sprite.Group()
        self.players = pygame.sprite.Group()
        self.enemies = pygame.sprite.Group()
        self.bullets = pygame.sprite.Group()
        self.walls = pygame.sprite.Group()
        self.bases = pygame.sprite.Group()
        
        # 创建玩家
        self.player = PlayerTank(SCREEN_WIDTH // 2, SCREEN_HEIGHT - 60)
        self.all_sprites.add(self.player)
        self.players.add(self.player)

        # 创建基地
        self.base = Base(SCREEN_WIDTH // 2 - WALL_SIZE // 2, SCREEN_HEIGHT - WALL_SIZE)
        self.all_sprites.add(self.base)
        self.bases.add(self.base)

        # 创建初始敌人
        self.spawn_enemies()

        # 创建墙壁
        self.create_walls()

        # 加载音效
        # self.shoot_sound = load_sound('shoot.wav')
        # self.explosion_sound = load_sound('explosion.wav')

    def spawn_enemies(self):
        for _ in range(5):
            x = random.randint(0, SCREEN_WIDTH - TANK_SIZE)
            enemy = EnemyTank(x, 50)
            self.all_sprites.add(enemy)
            self.enemies.add(enemy)

    def create_walls(self):
        # 创建一些随机的墙壁
        for _ in range(20):
            x = random.randint(0, SCREEN_WIDTH - WALL_SIZE)
            y = random.randint(100, SCREEN_HEIGHT - 100)
            wall = Wall(x, y)
            self.all_sprites.add(wall)
            self.walls.add(wall)

    def handle_collisions(self):
        # 子弹与墙壁碰撞
        for bullet in self.bullets:
            wall_hits = pygame.sprite.spritecollide(bullet, self.walls, False)
            for wall in wall_hits:
                if wall.destructible:
                    wall.kill()
                bullet.kill()
                # self.explosion_sound.play()

        # 子弹与坦克碰撞
        for bullet in self.bullets:
            if bullet.owner == 'player':
                enemy_hits = pygame.sprite.spritecollide(bullet, self.enemies, True)
                if enemy_hits:
                    bullet.kill()
                    self.state.score += 100
                    # self.explosion_sound.play()
            elif bullet.owner == 'enemy':
                player_hits = pygame.sprite.spritecollide(bullet, self.players, False)
                if player_hits and not self.player.invincible:
                    bullet.kill()
                    self.player.lives -= 1
                    if self.player.lives <= 0:
                        self.state.game_over = True
                    else:
                        self.player.invincible = True
                        self.player.invincible_timer = pygame.time.get_ticks()
                    # self.explosion_sound.play()

        # 子弹与基地碰撞
        base_hits = pygame.sprite.spritecollide(self.base, self.bullets, True)
        if base_hits:
            self.state.game_over = True

    def update(self):
        current_time = pygame.time.get_ticks()
        
        # 更新玩家
        keys = pygame.key.get_pressed()
        self.player.update(keys, current_time)

        # 更新敌人
        for enemy in self.enemies:
            if enemy.update(current_time):
                bullet = Bullet(enemy.rect.centerx, enemy.rect.centery, 
                              enemy.direction, 'enemy')
                self.all_sprites.add(bullet)
                self.bullets.add(bullet)
                # self.shoot_sound.play()

        # 更新子弹
        self.bullets.update()

        # 处理碰撞
        self.handle_collisions()

        # 检查是否需要生成新的敌人
        if len(self.enemies) < 5:
            self.spawn_enemies()

    def draw(self):
        screen.fill(BLACK)
        self.all_sprites.draw(screen)
        
        # 绘制得分和生命值
        font = pygame.font.Font(None, 36)
        score_text = font.render(f'Score: {self.state.score}', True, WHITE)
        lives_text = font.render(f'Lives: {self.player.lives}', True, WHITE)
        screen.blit(score_text, (10, 10))
        screen.blit(lives_text, (10, 40))

        if self.state.game_over:
            game_over_text = font.render('GAME OVER', True, RED)
            screen.blit(game_over_text, 
                       (SCREEN_WIDTH//2 - game_over_text.get_width()//2, 
                        SCREEN_HEIGHT//2 - game_over_text.get_height()//2))

        pygame.display.flip()

def main():
    clock = pygame.time.Clock()
    game = Game()
    running = True

    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_SPACE and not game.state.game_over:
                    bullet = Bullet(game.player.rect.centerx, 
                                  game.player.rect.centery,
                                  game.player.direction, 'player')
                    game.all_sprites.add(bullet)
                    game.bullets.add(bullet)
                    # game.shoot_sound.play()
                elif event.key == pygame.K_r and game.state.game_over:
                    game = Game()  # 重新开始游戏

        if not game.state.game_over:
            game.update()
        game.draw()
        clock.tick(60)

    pygame.quit()

if __name__ == "__main__":
    main() 
相关推荐
Leo来编程3 分钟前
python学习第三天
开发语言·python
痕51726 分钟前
VM+CentOS虚拟机
开发语言
每天减 1/5kg31 分钟前
创建者——建造者模式
开发语言·python·建造者模式
码道功成34 分钟前
快速创建基于Scala的flink开发项目
开发语言·flink·scala
New_Teen37 分钟前
C++小课堂——变量的声明,赋值和初始化
开发语言·c++·笔记·学习
练习&两年半1 小时前
C语言:51单片机 程序设计基础
c语言·开发语言·单片机·51单片机
橘猫云计算机设计1 小时前
基于微信小程序的疫情互助平台(源码+lw+部署文档+讲解),源码可白嫖!
java·大数据·开发语言·spring boot·微信小程序·小程序·汽车
m0_672449601 小时前
使用Java操作Excel
java·python·excel
张琪杭1 小时前
PyTorch大白话解释算子二
人工智能·pytorch·python
weixin_307779131 小时前
PySpark实现获取Cloud Storage上Parquet文件的数据结构,并自动在Google BigQuery里建表和生成对应的建表和导入数据的SQL
数据仓库·python·spark·云计算·googlecloud