pygame飞机大战小游戏(python大作业)

 一、项目背景

python大作业,在查看了老师给的链接发现教学视频不完整,所以借用了同学的《Python编程 从入门到实践》中的一个项目,学习模仿。

二、游戏具体介绍

  • 这是一款由辉辉亲自打造的太空对战小游戏。
  • 游戏背景:在广袤无垠的太空里有一群蓝精灵(不是)有一群邪恶的坏人,你的任务就是驾驶飞船摧毁他们。摧毁一群外星人,你的等级会高一级,同时你的子弹速度以及敌人也会变得更快,努力去超过那个最高分吧!
  • 生命:一共四条,珍惜生命!
  • 玩法:点击键盘的a向左走,点击键盘的d向右走,点击鼠标左键发射子弹。
  • 功能(不建议多按,因为会出死机):i键:控制背景音乐;o键:控制音效;q键:停止游戏。
  • 彩蛋:w键:连续发射子弹;p键:可以召唤超级武器;

三、主要代码

主函数:

# -*- coding: utf-8 -*-
"""
Created on Tue Nov 29 17:44:22 2022

@author: 18705
"""
'''self就是创建可以引用的一个值
可以传递的实参,其他形参靠他。
同时,self.name是属性,self.name()是方法。super是父类等等。'''

import sys
from time import sleep

import pygame

from settings import Settings
from game_stats import GameStats
from scoreboard import Scoreboard
from button import Button
from buttonhelp import ButtonHelp
from ship import Ship
from bg import Bg
from bullet import Bullet
from alien import Alien
from music import Music

class AlienInvasion:
    '''管理游戏资源和行为的类'''
    def __init__(self):
        '''初始化游戏并且创建游戏资源'''
        pygame.init()
        
        self.settings = Settings()
        
        self.screen = pygame.display.set_mode((self.settings.screen_width,self.settings.screen_height),pygame.RESIZABLE)
        icon = pygame.image.load("images/plant.png")
        pygame.display.set_icon(icon)
        pygame.display.set_caption("星球大战")
        #创建一个用于统计游戏信息的示例
        #并创建记分牌
        self.stats = GameStats(self)
        self.sb = Scoreboard(self)
        #外星飞船
        self.bg =Bg(self)
        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()
        self.music = Music(self)
        #背景音乐
        #背景音乐的播放不能放到主循环里面
        self.music.bgm2()
        #尝试换音乐,失败了
        '''
        self.control_bgm_t = True
        if self.control_bgm_t:
            self.music.bgm2()
        else:
            self.music.bgm1()
        '''
        self.control_bgm = False
        self.n=False
        #设置背景颜色
        #self.bg_color = (230,230,230)
        #创建外星人群
        self._create_fleet()
        
        #创建Play按钮
        self.play_button = Button(self,'play')
        #创建Help按钮
        self.help_button = ButtonHelp(self,'help')
        #连发子弹
        self.control_bullet = False
        #关闭音效
        self.control_sound = True
        self.nn = False
        #大子弹
        self.control_bullet_big = False
        
    def run_game(self):
        '''开始游戏的主循环'''
        
        while True:
            self._check_events()
            if self.stats.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()
                
            self._update_screen()
            #自动发射子弹
            if self.control_bullet:
                self._fire_bullet()
            #控制bgm开关
            if self.control_bgm:
                self.music.bgm_pause()
                self.n=True
            elif not self.control_bgm and self.n==True:
                self.music.bgm_unpause()
                self.n= not self.n
    def _check_events(self):
            #监视键盘和鼠标事件
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    #将高分添加到txt中
                    with open('high_score.txt','w') as file_object:
                        file_object.write(str(self.stats.high_score))
                    file_object.close()
                    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:
                    self._check_mousebuttondown_events(event)
                    
    def _check_keydown_events(self,event):
        '''相应按键'''
        if event.key == pygame.K_d:
        #向右移动飞船
            self.ship.moving_right = True
        elif event.key == pygame.K_a:
        #向左移动飞船
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            #将高分添加到txt中
            with open('high_score.txt','w') as file_object:
                file_object.write(str(self.stats.high_score))
            file_object.close()
            pygame.quit()
            sys.exit()
        elif event.key == pygame.K_w:
            self.control_bullet =not self.control_bullet 
        elif event.key == pygame.K_i:
            self.control_bgm = not self.control_bgm           
        elif event.key == pygame.K_o:
            self.control_sound = not self.control_sound 
        #elif event.key == pygame.K_p:
            #self.control_bgm_t = not self.control_bgm_t
        elif event.key == pygame.K_p:
            self.control_bullet_big = not self.control_bullet_big
            
    def _check_keyup_events(self,event):
        '''响应松开'''
        if event.key == pygame.K_d:
        #向右移动飞船
            self.ship.moving_right = False
        elif event.key == pygame.K_a:
        #向右移动飞船
            self.ship.moving_left = False
    
    def _check_mousebuttondown_events(self,event):
        '''响应鼠标'''
        if event.button == 1:
            self._fire_bullet()
        #设置play的功能和help的功能,其实应该封装一下的,哈哈哈哈。偷懒了
        button_clicked = self.play_button.rect.collidepoint(event.pos)
        buttonhelp_clicked = self.help_button.rect.collidepoint(event.pos)
        if button_clicked and not self.stats.game_active:
            #重置游戏设置
            self.settings.initialize_dynamic_settings()
            #重置游戏统计·信息
            self.stats.reset_stats()
            self.stats.game_active = True 
            self.sb.prep_score()
            self.sb.prep_level()
            self.sb.prep_ships()
            #清空余下的外星人和子弹
            self.aliens.empty()
            self.bullets.empty()
            
            #创建一群新外星人并且居中
            self._create_fleet()
            self.ship.center_ship()
            
            #隐藏鼠标光标
            pygame.mouse.set_visible(False)
        if buttonhelp_clicked and not self.stats.game_active:
            with open('help.txt',encoding='utf-8') as helptext:
                content = helptext.read()
            print(content)
            helptext.close()
    def _fire_bullet(self):
        if len(self.bullets)<self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)
            #控制子弹音效
            if self.control_sound:
                self.music.bullet()
                self.nn = True
            elif not self.control_sound and self.nn:
                self.music.bullet_stop()
                self.nn = not self.nn
    def _update_bullets(self):
         self.bullets.update()
            
            #删除消失的子弹
         for bullet in self.bullets.copy():
             if bullet.rect.bottom <=0:
                 self.bullets.remove(bullet)
         #print(len(self.bullets))
         #检查是否有子弹击中外星人
         self._check_bullet_alien_collisions()
    
    def _check_bullet_alien_collisions(self):
        '''响应子弹和外星人碰撞'''
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)
        if collisions:
            for aliens in collisions.values():
                #控制子弹和外星人碰撞音效
                if self.control_sound:
                    self.music.alien()
                    self.nn = True
                elif not self.control_sound and self.nn:
                    self.music.alien_stop()
                    self.nn = not self.nn
                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 _update_aliens(self):
        '''更新外星人位置'''
        self._check_fleet_edges()
        self.aliens.update()
        
        #检测外星人和飞船之间的碰撞
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            #print("Ship hit!!!")
            self._ship_hit()
        
        #检查是否有外星人到达了屏幕底端
        self._check_aliens_bottom()
        
    def _create_fleet(self):
        '''创建外星人群。'''
        alien = Alien(self)
        alien_width,alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (2*alien_width)
        number_aliens_x = available_space_x // (2*alien_width)
        
        #计算屏幕可以容纳多少外星人
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - (3*alien_height) 
                             - ship_height)#每行不超过79个字符
        number_rows = available_space_y // (2*alien_height)
        
        #创建外星人群
        for row_number in range(number_rows):
            for alien_number in range(number_aliens_x):
                self._create_alien(alien_number,row_number)
            
    def _create_alien(self,alien_number,row_number):
        alien = Alien(self)
        alien_width,alien_height = alien.rect.size
        alien.x = alien_width + 2*alien_width*alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2*alien.rect.height*row_number
        self.aliens.add(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 _ship_hit(self):
        '''响应飞船被外星人撞到'''
        if self.stats.ships_left >0:
            
        #将ship_left减一并更新记分牌
            self.stats.ships_left -=1
            self.sb.prep_ships()
        #清空余下的外星人和子弹
            self.aliens.empty()
            self.bullets.empty()
        
        #创建一群新的外星人,并将飞船放到屏幕底端的中央
            self._create_fleet()
            self.ship.center_ship()
        #爆炸效果
            self.music.blitme()
            pygame.display.flip()
            #控制飞船和外星人碰撞音效
            if self.control_sound:
                self.music.bow()
                self.nn = True
            elif not self.control_sound and self.nn:
                self.music.bow_stop()
                self.nn = not self.nn
            
        #暂停
            sleep(2)
        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)
    
    def _check_aliens_bottom(self):
        '''检查外星人是否到达了屏幕底端'''
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >=screen_rect.bottom:
                #像飞船悲壮一样处理
                self._ship_hit()
                break
        
    
    def _update_screen(self):
                
            #每次循环都重绘屏幕
            self.screen.fill(self.settings.bg_color)
            self.bg.action()
            # 绘制元素图片
            self.bg.blitme()
            #self.bg.blitme()
            self.ship.blitme()
            #让最近绘制的屏幕可见
            for bullet in self.bullets.sprites():
                bullet.draw_bullet()
            self.aliens.draw(self.screen)
            
            #显示得分
            self.sb.show_score()
            
            #如果游戏处于非活动状态,就绘制Play按钮
            if not self.stats.game_active:
                self.play_button.draw_button()
            if not self.stats.game_active:
                self.help_button.draw_button()
            
            pygame.display.flip()
        
if __name__ == '__main__':
    #创建游戏实例并运行游戏
    ai = AlienInvasion()
    ai.run_game()

子弹函数:

# -*- coding: utf-8 -*-
"""
Created on Tue Nov 29 21:42:02 2022

@author: 18705
"""

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.control_bullet_b = ai_game.control_bullet_big
        if  not self.control_bullet_b:
            
            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)
        else:
            self.color = self.settings.bullet_color_s
        #在(0,0)处创建一个表示子弹的矩形,再设置正确的位置
            self.rect = pygame.Rect(0,0,self.settings.bullet_width_s,self.settings.bullet_height_s)
            self.rect.midtop = ai_game.ship.rect.midtop
        #存储用小鼠表示的子弹位置
            self.y = float(self.rect.y)
            
    def update(self):
        self.y -= self.settings.bullet_speed
        self.rect.y = self.y
        
    def draw_bullet(self):
        pygame.draw.rect(self.screen, self.color, self.rect)

飞船函数:

# -*- coding: utf-8 -*-
"""
Created on Tue Nov 29 19:41:00 2022

@author: 18705
"""

import pygame
from pygame.sprite import Sprite

class Ship(Sprite):
    '''管理飞船的类'''
    #ai_game就是主函数,可能因为这个函数是个子函数
    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('images/ship.bmp')
        #self.image = pygame.transform.scale(self.image, (128, 128))
        self.rect = self.image.get_rect()
        
        #对于没搜辛飞船,都将其放在屏幕底部中央
        self.rect.midbottom = self.screen_rect.midbottom
        
        #在飞船的x属性中存储小数值
        #self.x=float(self.rect.x)
        
        #移动标志
        self.moving_right = False
        self.moving_left = False
    
    def update(self):
        '''根据移动标志调整飞船的位置'''
        #更新飞船而不是rect对象的x值
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.rect.x += 1
        if self.moving_left and self.rect.left > 0:
            self.rect.x -= 1
        
        #根据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)

设置函数:

# -*- coding: utf-8 -*-
"""
Created on Tue Nov 29 19:19:42 2022

@author: 18705
"""

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_width =5
        self.bullet_height =20
        self.bullet_color =(255,215,0)
        self.bullets_allowed = 15
        
        #超级武器设置
        self.bullet_width_s =600
        self.bullet_height_s =40
        self.bullet_color_s =(255,0,0)
        #外星人设置
        
        self.fleet_drop_speed =10
        
        #加快游戏节奏的速度
        self.speedup_scale = 1.2
        #外行人分数提高速度
        self.score_scale = 2
        
        self.initialize_dynamic_settings()
        
    def initialize_dynamic_settings(self):
        '''初始化随游戏进行而变化的设置'''
        #self.ship_speed = 1.5
        self.bullet_speed =1.5
        self.alien_speed = 1.0
        self.bg_speed = 0.2
         #1是向右,-1是向左
        self.fleet_direction = 1
        #计分
        self.alien_points = 1
        
        
    def increase_speed(self):
        '''提高速度设置和外星人分数'''
        #self.ship_speed *= self.speedup_scale
        self.bullet_speed *= self.speedup_scale
        self.alien_speed *= self.speedup_scale
        self.bg_speed *= self.speedup_scale
        
        self.alien_points = int(self.alien_points * self.score_scale)

想要全部的代码包(记得给我个小星星star哦):

GitHub - huihuihenqiang/aircraft-battle-python-: 这是个用pygame编写的python小游戏,仅供学习使用这是个用pygame编写的python小游戏,仅供学习使用. Contribute to huihuihenqiang/aircraft-battle-python- development by creating an account on GitHub.https://github.com/huihuihenqiang/aircraft-battle-python-

四、github上传项目

点击右上角的“+”

然后选择New repository

 

 填写自己项目的Repository name 和 Description,其他的默认即可。

 最后点击这个绿色的玩意儿就行。

 然后点击上传自己的项目就完成了。当然你也可以修改自己的read.me来介绍自己的项目。

猜你喜欢

转载自blog.csdn.net/m0_57491181/article/details/128250997