鱼C论坛

 找回密码
 立即注册
查看: 28|回复: 1

[技术交流] pygame自制射击游戏改进

[复制链接]
发表于 3 小时前 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

描述

描述

屏幕截图 2026-06-03 154316.png
自己用pygame自制的射击游戏
下面是源代码和相关素材
ship.png alien.png
alienInvasion.py
  1. import sys
  2. import pygame
  3. from settings import Settings
  4. from ship import Ship
  5. from bullet import Bullet
  6. from alien import Alien

  7. class AlienInvasion:
  8.     def __init__(self):
  9.         #初始化游戏资源
  10.         pygame.init()
  11.         self.settings = Settings()
  12.         self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
  13.         pygame.display.set_caption("Alien Invasion")
  14.         self.ship = Ship(self)
  15.         self.bullets = pygame.sprite.Group()
  16.         self.aliens = pygame.sprite.Group()
  17.         self._create_fleet()

  18.     def run_game(self):
  19.         #开始游戏的主循环
  20.         while True:
  21.             self._check_events()
  22.             self.ship.update()
  23.             self._update_bullets()
  24.             self._update_aliens()
  25.             self._update_screen()

  26.     def _check_events(self):
  27.         """响应按键和鼠标事件"""
  28.         for event in pygame.event.get():
  29.             if event.type == pygame.QUIT:
  30.                 sys.exit()
  31.             elif event.type == pygame.KEYDOWN:
  32.                 self._check_keydown_events(event)
  33.             elif event.type == pygame.KEYUP:
  34.                 self._check_keyup_events(event)
  35.    
  36.     def _check_keydown_events(self, event):
  37.         """响应按键"""
  38.         if event.key == pygame.K_RIGHT:
  39.             self.ship.moving_right = True
  40.         elif event.key == pygame.K_LEFT:
  41.             self.ship.moving_left = True
  42.         elif event.key == pygame.K_ESCAPE:
  43.             sys.exit()
  44.         elif event.key == pygame.K_SPACE:
  45.             self._fire_bullet()

  46.     def _check_keyup_events(self, event):
  47.         """响应松开"""
  48.         if event.key == pygame.K_RIGHT:
  49.             self.ship.moving_right = False
  50.         elif event.key == pygame.K_LEFT:
  51.             self.ship.moving_left = False

  52.     def _fire_bullet(self):
  53.         """创建一颗子弹,并将其加入编组bullets中"""
  54.         new_bullet = Bullet(self)
  55.         self.bullets.add(new_bullet)

  56.     def _update_bullets(self):
  57.         """更新子弹的位置,并删除已消失的子弹"""
  58.         #更新子弹位置
  59.         self.bullets.update()
  60.         #删除已消失的子弹
  61.         for bullet in self.bullets.copy():
  62.             if bullet.rect.bottom <= 0:
  63.                 self.bullets.remove(bullet)
  64.         #检查是否有子弹击中了外星人
  65.         #如果是这样,就删除相应的子弹和外星人
  66.         collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)
  67.    
  68.     def _create_fleet(self):
  69.         """创建外星人群"""
  70.         #创建一个外星人,并计算一行可以容纳多少外星人
  71.         #外星人的间距为外星人宽度
  72.         alien = Alien(self)
  73.         alien_width, alien_height = alien.rect.size
  74.         available_space_x = self.settings.screen_width - (3 * alien_width)
  75.         number_aliens_x = available_space_x // (3 * alien_width)
  76.         #计算屏幕可容纳多少行外星人
  77.         ship_height = self.ship.rect.height
  78.         available_space_y = (self.settings.screen_height - (3 * alien_height) - ship_height)
  79.         number_rows = available_space_y // (4 * alien_height)
  80.         #创建外星人群
  81.         for row_number in range(number_rows):
  82.             for alien_number in range(number_aliens_x):
  83.                 self._create_alien(alien_number, row_number)

  84.     def _create_alien(self, alien_number, row_number):
  85.         """创建一个外星人并将其加入当前行"""
  86.         alien = Alien(self)
  87.         alien_width, alien_height = alien.rect.size
  88.         alien.x = alien_width + 3 * alien_width * alien_number
  89.         alien.rect.x = alien.x
  90.         alien.rect.y = alien_height + 3 * alien_height * row_number
  91.         self.aliens.add(alien)

  92.     def _update_aliens(self):
  93.         """检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""
  94.         self._check_fleet_edges()
  95.         self.aliens.update()

  96.     def _check_fleet_edges(self):
  97.         """有外星人到达边缘时采取相应的措施"""
  98.         for alien in self.aliens.sprites():
  99.             if alien.check_edges():
  100.                 self._change_fleet_direction()
  101.                 break
  102.    
  103.     def _change_fleet_direction(self):
  104.         """将整群外星人下移,并改变它们的移动方向"""
  105.         for alien in self.aliens.sprites():
  106.             alien.rect.y += self.settings.fleet_drop_speed
  107.         self.settings.fleet_direction *= -1

  108.     def _update_screen(self):
  109.         """更新屏幕上的图像,并切换到新屏幕"""     
  110.         self.screen.fill(self.settings.bg_color)
  111.         self.ship.blitme()
  112.         for bullet in self.bullets.sprites():
  113.             bullet.draw_bullet()
  114.         self.aliens.draw(self.screen)
  115.         #让最近绘制的屏幕可见
  116.         pygame.display.flip()


  117. if __name__ == '__main__':
  118.     ai = AlienInvasion()
  119.     ai.run_game()
复制代码

settings.py
  1. class Settings:
  2.     def __init__(self):
  3.         """存储游戏的所有设置的类"""
  4.         #屏幕设置
  5.         self.screen_width = 1200
  6.         self.screen_height = 800
  7.         self.bg_color = (0, 0, 0)
  8.         #飞船设置
  9.         self.ship_speed = 1.5
  10.         #子弹设置
  11.         self.bullet_speed = 1.0
  12.         self.bullet_width = 100
  13.         self.bullet_height = 15
  14.         self.bullet_color = (255, 255, 0)
  15.         #外星人设置
  16.         self.alien_speed = 1.0
  17.         self.fleet_drop_speed = 10
  18.         #fleet_direction为1表示向右移,为-1表示向左移
  19.         self.fleet_direction = 1
复制代码


ship.py
  1. import pygame

  2. class Ship:
  3.     """管理飞船的类"""

  4.     def __init__(self, ai_game):
  5.         """初始化飞船并设置其初始位置"""
  6.         self.screen = ai_game.screen
  7.         self.settings = ai_game.settings
  8.         self.screen_rect = ai_game.screen.get_rect()

  9.         #加载飞船图像并获取其外接矩形
  10.         self.image = pygame.image.load('images/ship.png')
  11.         self.rect = self.image.get_rect()
  12.         
  13.         #对于每艘新飞船,都将其放在屏幕底部中央
  14.         self.rect.midbottom = self.screen_rect.midbottom

  15.         #在飞船的属性x中存储小数值
  16.         self.x = float(self.rect.x)

  17.         #移动标志
  18.         self.moving_right = False
  19.         self.moving_left = False

  20.     def update(self):
  21.         """根据移动标志调整飞船的位置"""
  22.         #更新飞船而不是rect对象的x值
  23.         if self.moving_right and self.rect.right < self.screen_rect.right:
  24.             self.x += self.settings.ship_speed
  25.         if self.moving_left and self.rect.left > 0:
  26.             self.x -= self.settings.ship_speed
  27.         #根据self.x更新rect对象
  28.         self.rect.x = self.x
  29.    
  30.     def blitme(self):
  31.         """在指定位置绘制飞船"""
  32.         self.screen.blit(self.image, self.rect)
复制代码


bullet.py
  1. import pygame
  2. from pygame.sprite import Sprite

  3. class Bullet(Sprite):
  4.     """一个对飞船发射的子弹进行管理的类"""

  5.     def __init__(self, ai_game):
  6.         """在飞船所在的位置创建一个子弹对象"""
  7.         super().__init__()
  8.         self.screen = ai_game.screen
  9.         self.settings = ai_game.settings
  10.         self.color = self.settings.bullet_color

  11.         #在(0, 0)处创建一个表示子弹的矩形,再设置正确的位置
  12.         self.rect = pygame.Rect(0, 0, self.settings.bullet_width, self.settings.bullet_height)
  13.         self.rect.midtop = ai_game.ship.rect.midtop

  14.         #存储用小数表示的子弹位置
  15.         self.y = float(self.rect.y)
  16.    
  17.     def update(self):
  18.         """向上移动子弹"""
  19.         #更新表示子弹位置的小数值
  20.         self.y -= self.settings.bullet_speed
  21.         #更新表示子弹的rect的位置
  22.         self.rect.y = self.y
  23.    
  24.     def draw_bullet(self):
  25.         """在屏幕上绘制子弹"""
  26.         pygame.draw.rect(self.screen, self.color, self.rect)
复制代码


alien.py
  1. import pygame
  2. from pygame.sprite import Sprite

  3. class Alien(Sprite):
  4.     """表示单个外星人的类"""

  5.     def __init__(self, ai_game):
  6.         """初始化外星人并设置其起始位置"""
  7.         super().__init__()
  8.         self.screen = ai_game.screen
  9.         self.settings = ai_game.settings

  10.         #加载外星人图像,并设置其rect属性
  11.         self.image = pygame.image.load('images/alien.png')
  12.         self.rect = self.image.get_rect()

  13.         #每个外星人最初都在屏幕左上角附近
  14.         self.rect.x = self.rect.width
  15.         self.rect.y = self.rect.height

  16.         #存储外星人准确水平位置
  17.         self.x = float(self.rect.x)

  18.     def check_edges(self):
  19.         """如果外星人位于屏幕边缘,就返回True"""
  20.         screen_rect = self.screen.get_rect()
  21.         if self.rect.right >= screen_rect.right or self.rect.left <= 0:
  22.             return True
  23.    
  24.     def update(self):
  25.         """向右移动外星人"""
  26.         self.x += (self.settings.alien_speed * self.settings.fleet_direction)
  27.         self.rect.x = self.x
复制代码

没有子弹图片,子弹是用pygame.draw画的矩形
屏幕刷新有点怪怪的,有知道原因的人吗
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 3 小时前 | 显示全部楼层
您目前的代码已经实现了外星人入侵游戏的基本框架:飞船移动、发射子弹、外星人群创建和移动、子弹与外星人碰撞检测。但还没加入游戏结束、计分、飞船生命、音效等经典元素。下面列出几个实用的改进方向,您可以根据兴趣逐步添加。

  • 添加游戏结束条件  
    目前外星人飞到屏幕底部或撞到飞船时没有反应。可以在外星人更新后检测是否越界或与飞船碰撞。  
    示例:在 _update_aliens 方法中加入  
    1.   
    2. for alien in self.aliens.sprites():  
    3.     if alien.rect.bottom >= self.settings.screen_height:  
    4.         self._end_game()  
    5.     if pygame.sprite.spritecollideany(self.ship, self.aliens):  
    6.         self._end_game()  
    复制代码

    _end_game 可以打印信息并退出,或重新开始。
  • 增加计分系统  
    消灭一个外星人加多少分,显示在屏幕左上角。需要创建 Scoreboard 类,并在碰撞代码中更新分数。  
    碰撞处(groupcollide)返回一个字典,根据键(子弹)对应的值(外星人列表长度)累加分数。
  • 飞船生命 / 重试机制  
    给飞船初始 3 条命,被外星人撞到或外星人到达底部时减少一条命并重置位置。  
    需要添加 self.ship_hit() 方法:清空子弹和外星人,飞船回到底部中央,生命数减1,生命归0时结束游戏。
  • 外星人移动加速  
    随着游戏进行或每消灭一定数量外星人,提高外星人的移动速度。可以在 Settings 中设置 speedup_scale 并在 _update_bullets 检测到外星人为空时调用 _increase_speed 方法。
  • 限制子弹数量  
    防止玩家按住空格一直发射。在 Settings 中添加 bullet_allowed 属性,在 _fire_bullet 中检查 len(self.bullets) < self.settings.bullet_allowed
  • 添加游戏状态管理  
    例如用一个 game_active 标志控制主循环是否暂停。当游戏结束时设为 False,并显示“Game Over”文字,按某个键重新开始。
  • 优化子弹碰撞与爆炸效果  
    目前碰撞后子弹和外星人瞬间消失,可以添加短暂动画或粒子效果(用精灵组实现简单的缩放或颜色闪烁)。
  • 音效  
    使用 pygame.mixer 添加射击、爆炸、背景音乐。注意提前加载并控制音量。


这些改进不需要大改现有结构,每个功能独立,可以挑选最感兴趣的先实现。如果某个部分需要更详细的代码示例,请告诉我,我会针对性地给您写出具体的 BBCode 格式代码段。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-6-3 19:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表