当前位置: 首页 > article >正文

python小游戏-坦克大战

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


http://www.kler.cn/a/570572.html

相关文章:

  • yolo初体验
  • 【AI深度学习基础】Pandas完全指南入门篇:数据处理的瑞士军刀 (含完整代码)
  • 智慧农业中光谱相机对土壤成分的无损检测应用‌
  • 网络空间安全(7)攻防环境搭建
  • 初识C语言之操作符详解(下)
  • 服务器时间同步
  • spring boot + vue 搭建环境
  • 关于服务器cpu过高的问题排查
  • 物理竞赛中的线性代数
  • SELinux 安全加固
  • 【鸿蒙Next】鸿蒙与flutter使用自定义iconfont的ttf字体库对比总结
  • 基于GTID的主从复制
  • 静态时序分析:SDC约束命令set_clock_jitter详解
  • 学习笔记-DeepSeek在开源第四天发布DualPipe和EPLB两项技术
  • C#中泛型的协变和逆变
  • 关于常规模式下运行VScode无法正确执行“pwsh”问题
  • Ubuntu 下 nginx-1.24.0 源码分析 - ngx_init_cycle 函数 - 详解(10)
  • 【算法刷题】leetcode hot 100 动态规划
  • 探秘基带算法:从原理到5G时代的通信变革【四】Polar 编解码(一)
  • 【JavaScript/JS】事件回调函数this指向不到Vue/Class 实例上下文的变量或者方法的问题