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

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

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

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

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

1.image

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

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

2.alian_invasion.py

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

python 复制代码
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

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

python 复制代码
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

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

python 复制代码
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

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

python 复制代码
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

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

python 复制代码
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

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

python 复制代码
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

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

python 复制代码
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

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

python 复制代码
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仓库里面,需要的可以自取。

相关推荐
火云牌神20 分钟前
本地大模型编程实战(32)用websocket显示大模型的流式输出
python·websocket·llm·fastapi·流式输出
让我们一起加油好吗2 小时前
【第十六届蓝桥杯省赛】比赛心得与经验分享(PythonA 组)
经验分享·python·算法·蓝桥杯
eqwaak02 小时前
基于DrissionPage的实习信息爬虫改造与解析
爬虫·python·语言模型·性能优化·drissionpage
小米渣ok3 小时前
TensorFlow2.x环境安装(win10系统,使用Anaconda安装)
人工智能·python·tensorflow
阿俊仔(摸鱼版)3 小时前
CentOS上搭建 Python 运行环境并使用第三方库
linux·python·centos
未来之窗软件服务4 小时前
创意Python爱心代码分享
开发语言·python·仙盟创梦ide·程序员表白
Lounger664 小时前
23.合并k个升序序链表- 力扣(LeetCode)
python·leetcode·链表
暴力袋鼠哥6 小时前
基于YOLOv8的人流量识别分析系统
人工智能·python·opencv·yolo·机器学习
Zach_ZSZ7 小时前
神经网络基础-从零开始搭建一个神经网络
人工智能·python·深度学习·神经网络
正在走向自律7 小时前
Python面向对象编程实战:从类定义到高级特性的进阶之旅(2/10)
开发语言·python·面向对象·python基础知识