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

外星人入侵(python设计小游戏)

这个游戏简而言之就是操作一个飞机对前方的飞船进行射击,和一款很久之前的游戏很像,这里是超级低配版那个游戏,先来看看效果图:

由于设计的是全屏的,所以电脑不能截图。。。。

下面的就是你操控的飞船,上面的是要消灭的外星舰队,左上角是剩余的生命,中间是历史最高分,右边是当前分数以及当前阶段。

每当你消灭完整个外星舰队时,就会进入下一阶段,各种属性都会得到提升。下面话不多说,直接展示完整代码:

1.image

首先是图片素材,我都放在了image这个文件夹里面:

可以直接复制我这个图片,我这个后缀是bmp,如果用网上找的图片的话要注意一下后缀问题,不然有一部分代码会报错的,需要自己更改

2.alian_invasion.py

这个是整个项目的主文件,运行的时候要在这个文件下面运行,里面注释写的比较完整,可以直接看详细的注释,相关代码如下:

import sys
import pygame

from settings import Settings
from ship import Ship
from bullet import Bullet
from alien import  Alien
from time import sleep
from game_stats import GameStats
from button import Button
from scoreboard import Scoreboard

class AlienInvasion():
    """管理游戏资源和行为的类"""
    def __init__(self):
        """初始化游戏并创建游戏资源"""
        pygame.init()
        self.clock = pygame.time.Clock()
        self.settings = Settings()

        self.screen = pygame.display.set_mode((0,0),pygame.FULLSCREEN)
        self.settings.screen_width = self.screen.get_rect().width
        self.settings.screen_height = self.screen.get_rect().height
        pygame.display.set_caption("Alien Invasion")

        #创建一个用于存储游戏统计信息的实例
        self.stats = GameStats(self)
        self.sb = Scoreboard(self)

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

        #游戏启动后处于非存活状态
        self.game_active = False

        #创造play按钮
        self.play_button = Button(self,"play")


    def run_game(self):
        """开始游戏的主循环"""
        while True:
            self._check_events()

            if self.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()
            self._update_screen()

            self.clock.tick(60)

    def _check_events(self):
        # 监听键盘和鼠标事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)

    def _check_play_button(self,mouse_pos):
        """在玩家点击play时开始新的游戏"""
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.game_active:
            #还原游戏设置
            self.settings.initialize_dynamic_settings()
            #重置游戏的统计信息
            self.stats.reset_stats()
            self.sb.prep_score()
            self.sb.prep_level()
            self.sb.prep_ships()
            self.game_active = True

            #清空外星人列表和子弹列表
            self.bullets.empty()
            self.aliens.empty()

            #创造一个新的外星舰队,并将飞船放在屏幕下方的中央
            self._create_fleet()
            self.ship.center_ship()

            #隐藏光标
            pygame.mouse.set_visible(False)


    def _check_keydown_events(self,event):
        """响应按下"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _fire_bullet(self):
        """创造一个子弹,并将其加入编组buttle"""
        if len(self.bullets) < self.settings.bullet_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _check_keyup_events(self,event):
        """响应释放"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False
    def _update_screen(self):
        # 每次循环都重绘屏幕
        self.screen.fill(self.settings.bg_color)
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.ship.blitme()
        self.aliens.draw(self.screen)

        #显示得分
        self.sb.show_score()

        #如果游戏处于非存活状态,就绘制play按钮
        if not self.game_active:
            self.play_button.draw_button()

        # 让最近绘制的屏幕可见
        pygame.display.flip()

    def _update_bullets(self):
        self.bullets.update()

        # 删除已消失的子弹
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

        self._check_bullet_alien_collisions()

    def _create_fleet(self):
        """创造外星舰队"""
        #创造一个外星人
        alien = Alien(self)
        alien_width,alien_height = alien.rect.size

        current_x,current_y = alien_width,alien_height
        while current_y < (self.settings.screen_height - 3 * alien_height):
            while current_x < (self.settings.screen_width - 2 * alien_width):
                self._creat_alien(current_x,current_y)
                current_x += 2 * alien_width

            #添加一个外星人后,重置x值并递增y值
            current_x = alien_width
            current_y += 2 * alien_height

    def _creat_alien(self,x_position,y_position):
        """创造一个外星人,并将其放入外星舰队"""
        new_alien = Alien(self)
        new_alien.x = x_position
        new_alien.rect.x = x_position
        new_alien.rect.y = y_position
        self.aliens.add(new_alien)

    def _check_fleet_edges(self):
        """有外星人到达边界时采取响应的措施"""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """将整个外星舰队向下移动,并改变方向"""
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _update_aliens(self):
        """更新外星人的位置"""
        self._check_fleet_edges()
        self.aliens.update()

        #检测外星人和飞船之间的碰撞
        if pygame.sprite.spritecollideany(self.ship,self.aliens):
            self._ship_hit()

        #检查是否有外星人到达了屏幕的下边缘
        self._check_aliens_bottom()

    def _check_bullet_alien_collisions(self):
        # 检测是否有子弹击中了外星人
        # 如果是,就删除相应的子弹和外星人
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)

        if collisions:
            for aliens in collisions.values():
                self.stats.score += self.settings.alien_points * len(aliens)
            self.sb.prep_score()
            self.sb.check_high_score()

        if not self.aliens:
            # 删除现有的子弹创造一个新的外星舰队
            self.bullets.empty()
            self._create_fleet()
            self.settings.increase_speed()

            #提高等级
            self.stats.level += 1
            self.sb.prep_level()

    def _ship_hit(self):
        """响应飞船和外星人的碰撞"""
        if self.stats.ships_left > 0:
            #将ships_left减1并更新计分板
            self.stats.ships_left -= 1
            self.sb.prep_ships()
            self.bullets.empty()
            self.aliens.empty()

            self._create_fleet()
            self.ship.center_ship()

            sleep(0.5)
        else:
            self.game_active = False
            pygame.mouse.set_visible(True)

    def _check_aliens_bottom(self):
        """检查是否有外星人到达了屏幕的下边缘"""
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= self.settings.screen_height:
                #像飞船一样被处理
                self._ship_hit()
                break

if __name__ == '__main__':
    #创建游戏实例并运行游戏
    ai = AlienInvasion()
    ai.run_game()

3.alien.py

这个是管理外星人的类,详细代码如下:

import pygame
from pygame.sprite import Sprite

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

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

        #加载外星人图像并设置其rect属性
        self.image = pygame.image.load('image/alien.bmp')
        self.rect = self.image.get_rect()

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

        #存储外星人的精确位置
        self.x = float(self.rect.x)

    def check_edges(self):
        """如果外星人位于屏幕边界,返回true"""
        screen_rect = self.screen.get_rect()
        return (self.rect.right >= screen_rect.right) or (self.rect.left <= 0)

    def update(self):
        """向右移动外星人"""
        self.x += self.settings.alien_speed * self.settings.fleet_direction
        self.rect.x = self.x

4.bullet.py

管理飞船发射子弹的类,详细的代码如下:

import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
    """管理飞船所发射子弹的类"""

    def __init__(self,ai_game):
        super().__init__()
        self.screen = ai_game.screen
        self.settings = ai_game.settings
        self.color = self.settings.bullet_color

        #在(0,0)处创造一个表达子弹的矩形,再设置正确的位置
        self.rect = pygame.Rect(0,0,self.settings.bullet_width,
                                self.settings.bullet_height)
        self.rect.midtop = ai_game.ship.rect.midtop
        self.y = float(self.rect.y)

    def update(self):
        """向上移动子弹"""
        self.y -= self.settings.bullet_speed
        #更新表示子弹的rect的位置
        self.rect.y = self.y

    def draw_bullet(self):
        """再屏幕上绘制子弹"""
        pygame.draw.rect(self.screen,self.color,self.rect)

5.button.py

管理游戏创造按钮的类,下面是详细的代码:

import pygame.font

class Button:
    """为游戏创造按钮的类"""

    def __init__(self,ai_game,msg):
        """初始化按钮的属性"""
        self.screen = ai_game.screen
        self.screen_rect = self.screen.get_rect()

        #按钮尺寸和其他属性
        self.width,self.height = 200,50
        self.button_color = (0,135,0)
        self.text_colot = (255,255,255)
        self.font = pygame.font.SysFont(None,48)

        #创造按钮的rect对象,并使其居中
        self.rect = pygame.Rect(0,0,self.width,self.height)
        self.rect.center = self.screen_rect.center

        #按钮标签只需要创造一次
        self._prep_msg(msg)

    def _prep_msg(self,msg):
        """将msg渲染成图像爱过你,并将其在按钮上居中"""
        self.msg_image = self.font.render(msg,True,self.text_colot,self.button_color)
        self.msg_image_rect = self.msg_image.get_rect()
        self.msg_image_rect.center = self.rect.center

    def draw_button(self):
        """绘制一个用颜色填充的按钮,再绘制文本"""
        self.screen.fill(self.button_color,self.rect)
        self.screen.blit(self.msg_image,self.msg_image_rect)

6.game_stats.py

管理游戏信息的类,详细的代码如下:

class GameStats:
    """跟踪游戏的统计信息"""

    def __init__(self,ai_game):
        """统计初始信息"""
        self.settings = ai_game.settings
        self.reset_stats()
        #在任何情况下都不应该重置最高分
        self.high_score = 0

    def reset_stats(self):
        """初始化在游戏运行期间可能变化的统计信息"""
        self.ships_left = self.settings.ship_limit
        self.score = 0
        self.level = 1

7.scoreboard.py

关于游戏得分的类,详细代码如下:

import pygame.font
from pygame.sprite import Group

from ship import Ship
class Scoreboard:
    """显示游戏得分的类"""
    def __init__(self,ai_game):
        """初始化显示得分的属性"""
        self.ai_game = ai_game
        self.screen = ai_game.screen
        self.screen_rect = self.screen.get_rect()
        self.settings =ai_game.settings
        self.stats = ai_game.stats

        #显示得分信息时用的字体
        self.text_color = (30,30,30)
        self.font = pygame.font.SysFont(None,48)

        #准备初始得分图像
        self.prep_score()
        self.prep_high_score()
        self.prep_level()
        self.prep_ships()

    def prep_score(self):
        """将得分渲染成图像"""
        rounded_score = round(self.stats.score,-1)
        score_str = f"{rounded_score:,}"
        self.score_image = self.font.render(score_str,True,
                                            self.text_color,self.settings.bg_color)

        #在屏幕右上角显示得分
        self.score_rect = self.score_image.get_rect()
        self.score_rect.right = self.screen_rect.right - 20
        self.score_rect.top = 20

    def show_score(self):
        """在屏幕上显示得分"""
        self.screen.blit(self.score_image,self.score_rect)
        self.screen.blit(self.high_score_image,self.high_score_rect)
        self.screen.blit(self.level_image,self.level_rect)
        self.ships.draw(self.screen)

    def prep_high_score(self):
        """将最高分渲染成图像"""
        high_score = round(self.stats.high_score,-1)
        high_score_str = f"{high_score:,}"
        self.high_score_image = self.font.render(high_score_str,
                                                 True,self.text_color,
                                                 self.settings.bg_color)

        #将最高分放在屏幕顶部的中央
        self.high_score_rect = self.high_score_image.get_rect()
        self.high_score_rect.centerx = self.screen_rect.centerx
        self.high_score_rect.top = self.score_rect.top

    def check_high_score(self):
        """检查是否产生了新高分"""
        if self.stats.score > self.stats.high_score:
            self.stats.high_score = self.stats.score
            self.prep_high_score()

    def prep_level(self):
        """将等级渲染成图像"""
        level_str = str(self.stats.level)
        self.level_image = self.font.render(level_str,True,
                                            self.text_color,self.settings.bg_color)

        #将等级放在得分下面
        self.level_rect = self.level_image.get_rect()
        self.level_rect.right = self.score_rect.right
        self.level_rect.top = self.score_rect.bottom + 10

    def prep_ships(self):
        """显示还剩下多少飞船"""
        self.ships = Group()
        for ship_number in range(self.stats.ships_left):
            ship = Ship(self.ai_game)
            ship.rect.x = 10 + ship_number * ship.rect.width
            ship.rect.y = 10
            self.ships.add(ship)

8.settings.py

关于游戏设置的类,详细代码如下:

class Settings:
    """初始化游戏的静态设置"""
    def __init__(self):
        """初始化游戏设置"""
        #屏幕设置
        self.screen_width = 1200
        self.screen_height = 800
        self.bg_color = (230,230,230)

        #飞船的设置
        self.ship_speed = 1.5
        self.ship_limit = 3

        #子弹设置
        self.bullet_speed = 2.5
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = (60,60,60)
        self.bullet_allowed = 3

        #外星人设置
        self.alien_speed = 1.0
        self.fleet_drop_speed = 10
        #fleet_direction为1表示向右移动,-1表示向左移动
        self.fleet_direction = 1

        #以什么速度加快游戏的节奏
        self.speedup_scale = 1.1
        #外星人分数的提高速度
        self.score_scale = 1.5
        self.initialize_dynamic_settings()


    def initialize_dynamic_settings(self):
        """初始化随游戏进行而变化的设置"""
        self.ship_speed = 1.5
        self.bullet_speed = 2.5
        self.alien_speed = 1.0

        #fleet_direction为1表示向右,-1向左
        self.fleet_direction = 1

        # 记分设置
        self.alien_points = 50

    def increase_speed(self):
        """提高速度设置的值"""
        self.ship_speed *= self.speedup_scale
        self.bullet_speed *= self.speedup_scale
        self.alien_speed *= self.speedup_scale

        self.alien_points = int(self.alien_points * self.score_scale)

9.ship.py

关于飞船的类,详细代码如下:

import pygame
from pygame.sprite import Sprite
class Ship(Sprite):
    """管理飞船的类"""
    def __init__(self,ai_game):
        """初始化飞船并设置其初始位置"""
        super().__init__()
        self.screen = ai_game.screen
        self.settings = ai_game.settings
        self.screen_rect = ai_game.screen.get_rect()

        #加载飞船图像并获取外部形状
        self.image = pygame.image.load('image/ship.bmp')
        self.rect = self.image.get_rect()

        #每艘飞船都放在屏幕底部的中央
        self.rect.midbottom = self.screen_rect.midbottom

        #在飞船的属性中储存一个浮点数
        self.x = float(self.rect.x)

        #移动标志
        self.moving_right = False
        self.moving_left = False

    def update(self):
        """根据移动标志调整飞船位置"""
        if self.moving_right and self.moving_right < self.screen_rect.right:
            self.x += self.settings.ship_speed
        if self.moving_left and self.moving_left > 0:
            self.x -= self.settings.ship_speed

        #根据self.x更新rect对象
        self.rect.x = self.x

    def blitme(self):
        """在指定位置绘制飞船"""
        self.screen.blit(self.image,self.rect)

    def center_ship(self):
        """把飞船放在屏幕中间"""
        self.rect.midbottom = self.screen_rect.midbottom
        self.x = float(self.rect.x)

以上就是本项目的完整代码,可以把他们放在同一个文件夹下面来运行试试。

如果遇到了一些报错,在本地运行不了的情况,可以去这个连接直接下载我的完整项目,不过正常情况应该是不得报错的,https://github.com/00paning/alian-invasion,我把整个项目放在了我这个GitHub仓库里面,需要的可以自取。


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

相关文章:

  • PS 切割图片
  • C语言中的位域:节省内存的标志位管理技术
  • 数据结构和算法简介 以及 顺序表
  • 如何使用RK平台的spi驱动 spidev
  • 自动化发布工具CI/CD实践Jenkins各配置功能介绍和管理!
  • 质检LIMS系统在化肥生产企业的应用 化肥质量管理的数字化中枢
  • Python学习第二十六天
  • Spring Data审计利器:@LastModifiedDate详解!!!
  • PDF处理控件Spire.PDF系列教程:Java 给现有的 PDF 文档添加页眉页脚
  • PyTorch 深度学习实战(27):扩散模型(Diffusion Models)与图像生成
  • java替换html中的标签
  • 《深度剖析SQL数据类型转换:隐式与显式的奥秘》
  • WPF 附加属性
  • 在海量数据中精准定位:BloomFilter的工作原理与实战指南
  • OmniGraffle Pro for Mac思维导图
  • 自行车模型与汽车模型的混合策略在自动驾驶中的多维度协同优化
  • 测试模版12
  • 从链上到现实:Python如何重塑区块链供应链管理
  • 【DeepSeek学C++】移动构造函数
  • 127. 单词接龙【 力扣(LeetCode) 】