PYTHON入门级游戏开发:宇宙飞船游戏两万字详析

2023-12-27 06:52

本文主要是介绍PYTHON入门级游戏开发:宇宙飞船游戏两万字详析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

手讲解超详细python入门游戏项目‘打外星飞船’手把(一)

由于内容比较多,这里会分为五篇文章来讲解,从页面的创建、飞船控制、射击、外星人创建、射杀外星人五片来展开。

做一个窗口和设置响应用户

import sysimport pygame
''' '''
""" 我们先创建一个新的文件,保存的名字就叫做主函数吧,main.py。首先我们应该导入两个模块sys和pygame,pygame是用来开发游戏所需要的功能的,sys是我们退出的时候,我们需要用到的 """"from settings import Settings
#这个是我们在后面创建一个settings用来管理设置,后年会补充
class AlienInvasion:"""我们先创建一个类,用它来管理游戏资源和行为的类。"""def __init__(self):"""这个我们开始游戏的主循环"""pygame.init()#在这个类中,我们先定义一个函数,调用函数pygame.init()初始化背景设置,让他能够正常的工作self.settings = Settings()self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))#在主程序文件中打入settings类调用pygames in it(),创建一个settings实力并付给self.settings,这个时候我们把它的属性宽度和高度复给主函数pygame.display.set_caption("Alien Invasion")def run_game(self):"""开始游戏的主循环了,在这个循环中,我们不断的进行一个循环,并且管理屏幕更新的代码。比如说按键或移动鼠标的时候就是要响应一次,作为一次响应事件,就是一个循环。"""while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()#在循环中,如果我们检测到了退出的指令,我们就用       sys.exit()来退出self.screen.fill(self.settings.bg_color)#调用方法fill(),用这种背景色填充屏幕。方法fill()用于处理surface只接受一个实参一种颜色pygame.display.flip()
# 让最近绘制的屏幕可见,在这里我们通过不断的循环都会绘制一个空的屏幕,并且插去就的屏幕,所以让新的屏幕可见就行,成了动画
if __name__ == '__main__':# 创建游戏实例,并且开始运行游戏ai = AlienInvasion()ai.run_game()

这里重新建立一个文件,可以命名为settings.py

class Settings:"""我们开始编写一个名为settings的模块,在这个模块中,所有的设置都储存在这里,以免在代码中到处添加设置。创建另外一个文件,命名为settings.py。
"""def __init__(self):"""这里我们建立一个函数"""# 如果只是一个默认的屏幕,就太没有意思了,在现在我们把屏幕的颜色改成白色
颜色是由RGB指定的,比如说25500表示红色;02550表示绿色;这里我们把背景色设为白色self.screen_width = 1200self.screen_height = 800self.bg_color = (230, 230, 230)

这里重新建立一个文件,可以命名为ship.py。我们在这里会先创立一ship的模块.,我们用这个模块来管理飞船的大部分行为。

import pygameclass Ship:"""管理飞船的类"""def __init__(self, ai_game):"""初始化飞船并且初始化的他的位置"""self.screen = ai_game.screen#在定义这个类之前,我要导入模块pygame
在一处的话,将屏幕付给了sheep的一个属性,方便这个类的所有方法后面的轻松访问self.screen_rect = ai_game.screen.get_rect()# 加载飞船图像self.image = pygame.image.load('images/ship.bmp')#在这里我们需要把飞船的图像添加进去,一般来说,图像的格式都是JPGGIF多一点在这里我们用的是bmp的格式. 我把飞船的图片放在下面,注意在你建立文档的时候,一定要把图片放在一个名为images的文件夹下,并且我其他项目是同一个文件夹。self.rect = self.image.get_rect()self.rect.midbottom = self.screen_rect.midbottom#我们都把它放在屏幕底部的中央因为这里我们要把非常放在底部的中央,所以我们应该用的属性叫做 midbottomdef blitme(self):self.screen.blit(self.image, self.rect)#现在我们要把这个飞船的图像调用出来,括号里面的是非常的位置

这个是我们要导入的图片
在这里插入图片描述

这个是我们最终建立好的游戏界面
在这里插入图片描述

手把手讲解超详细python入门游戏项目‘打外星飞船’(二)

上次我们在(一)中创建了游戏的背景,现在我们这里将要实现用键盘控制飞船的移动、射击子弹,但是在此之前我们还有一个非常重要的部分–重构。

重构

在大型项目中,经常需要添加新代码重构旧的代码,简单来说就把一些代码整理成函数,用函数之前的代码就变成了一句函数。这里我们就需要把之前的run_game()拆分成两个辅助方法,基本上辅助方法要以单个下划线打头。
我们直接回顾上此的代码

   def run_game(self):while True:#这里把管理事件的代码移动到这两个函数里面了,代码在下面self._check_events()self._update_screen()def _check_events(self):
#这个是之前按键和鼠标的代码for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()def _update_screen(self):#更新图像,切换到新屏幕self.screen.fill(self.settings.bg_color)self.ship.blitme()pygame.display.flip()

飞船的控制

这里我开始把按键链接到电脑,每一次按下一个按键,pygame上都会注册一个事件,这里每次按下都会注册一个KEYDOWN事件,如果检测到这个事件就会移动

def _check_events(self):for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type == pygame.KEYDOWN: #检测到了按键被按下      if event.type == pygame.K_RIGHT:#按下的键是右键self.ship.rect.x +=1#这里的距离+1,即右边移

左右持续移动

        # 添加左右的移动的标志,立flag是好个方法,简化代码过程self.moving_right = Falseself.moving_left = False

但检测到左右移动键按下后,flag变成1

      if event.key == pygame.K_RIGHT:self.ship.moving_right = Trueelif event.type == pygame.KEYUP:if event.key == pygame.K_RIGHT:self.ship.moving_right = False

这个时候我们在主运行加入移动函数,update()

    def run_game(self):"""Start the main loop for the game."""while True:self._check_events()self.ship.update()#控制移动self._update_screen()

下面这个就是移动函数

    def update(self):if self.moving_right:self.ship.rect.x +=1#右移动加一if self.moving_left:self.ship.rect.x -=1#左移动减一

调整数独、限制活动范围
这里我们就整体展现下ship加工部分了。

import pygameclass Ship:def __init__(self, ai_game):self.screen = ai_game.screenself.settings = ai_game.settings#这里添加一个settings属性,等会要在update用self.screen_rect = ai_game.screen.get_rect()        self.image = pygame.image.load('images/ship.bmp')self.rect = self.image.get_rect()    self.rect.midbottom = self.screen_rect.midbottom#这里有个方法是储存小数值,因为飞船移动的是像素,所以这里要要把位置赋给能够储存小数值的变量self.x = float(self.rect.x)# 移动的flagself.moving_right = Falseself.moving_left = Falsedef update(self):if self.moving_right and self.rect.right < self.screen_rect.right:#飞船未飞出右边的边缘self.x += self.settings.ship_speed#移动的速度会不断地加一个像素的大小,注意:主函数中已经设置了速度为self.ship_speed=1.5if self.moving_left and self.rect.left > 0:#如果飞船未飞出左侧,左侧是0self.x -= self.settings.ship_speed#根据self.x更新rect对象self.rect.x = self.x

再次重构
因为一句添加了不少内容,所以

    def _check_events(self):"""Respond to keypresses and mouse events."""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)def _check_keydown_events(self, event):#这是刚才的语句,写进了这个句子if event.key == pygame.K_RIGHT:self.ship.moving_right = Trueelif event.key == pygame.K_LEFT:self.ship.moving_left = Truedef _check_keyup_events(self, event):#同样的if event.key == pygame.K_RIGHT:self.ship.moving_right = Falseelif event.key == pygame.K_LEFT:self.ship.moving_left = False

按Q键退出

    def _check_keydown_events(self, event):"""Respond to keypresses."""if event.key == pygame.K_RIGHT:self.ship.moving_right = Trueelif event.key == pygame.K_LEFT:self.ship.moving_left = True#这里我们设置的按键Q退出,接受到Q键反应接受后执行sys模块的退出指令elif event.key == pygame.K_q:sys.exit()

全屏运行

    def __init__(self):"""Initialize the game, and create game resources."""pygame.init()self.settings = Settings()#游戏开始时传入的是(00)以及参数pygame.FULLSCREEN,这个指令是覆盖整个屏幕self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)#这里使用屏幕的高和宽更新数据self.settings.screen_width = self.screen.get_rect().widthself.settings.screen_height = self.screen.get_rect().height

手把手讲解超详细python入门游戏项目‘打外星飞船’(三)

第三部分我们讲解一下飞船需要射出子弹,那么子弹的部分是怎么操作呢?接下来我直接把项目的四个文件展示出来,以注释的形式在旁边讲解。因为有很多代码在前面都已经打过注释 了,这次我们就只在新加的代码旁边打注释了

任务三:按空格键的时候发射子弹,一个屏幕上最多发射三颗子弹,子弹向上飞行,到屏幕后消失

主文件()

import sysimport pygamefrom settings import Settings
from ship import Ship
#这里我们创建了管理子弹的类,要引入主文件使用
from bullet import Bulletclass AlienInvasion:def __init__(self):pygame.init()self.settings = Settings()self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)self.settings.screen_width = self.screen.get_rect().widthself.settings.screen_height = self.screen.get_rect().heightpygame.display.set_caption("Alien Invasion")self.ship = Ship(self)#这里创建用于储存子弹控制的编组self.bullets = pygame.sprite.Group()def run_game(self):while True:self._check_events()self.ship.update()#把子弹的函数加入主文件self._update_bullets()self._update_screen()def _check_events(self):for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()#这里是键盘按到空格键会返回KEYDOWN,此时调用开火函数elif event.type == pygame.KEYDOWN:self._check_keydown_events(event)elif event.type == pygame.KEYUP:self._check_keyup_events(event)def _check_keydown_events(self, event):if event.key == pygame.K_RIGHT:self.ship.moving_right = Trueelif event.key == pygame.K_LEFT:self.ship.moving_left = Trueelif event.key == pygame.K_q:sys.exit()elif event.key == pygame.K_SPACE:self._fire_bullet()def _check_keyup_events(self, event):if event.key == pygame.K_RIGHT:self.ship.moving_right = Falseelif event.key == pygame.K_LEFT:self.ship.moving_left = Falsedef _fire_bullet(self):#这是一个判断语句,如果子弹数小于三,我们就可以执行下面的函数if len(self.bullets) < self.settings.bullets_allowed:#创建一个子弹新的bullet,把它加入到编组bullet储存new_bullet = Bullet(self)self.bullets.add(new_bullet)def _update_bullets(self):# 更新子弹的位置函数self.bullets.update()#不断循环删除子弹,子弹这里是他的y轴超出了屏幕,我们就删除for bullet in self.bullets.copy():if bullet.rect.bottom <= 0:self.bullets.remove(bullet)def _update_screen(self):self.screen.fill(self.settings.bg_color)self.ship.blitme()for bullet in self.bullets.sprites():bullet.draw_bullet()pygame.display.flip()if __name__ == '__main__':ai = AlienInvasion()ai.run_game()

子弹的控制类

import pygame
from pygame.sprite import Spriteclass Bullet(Sprite):"""创建一个管理子弹的类"""def __init__(self, ai_game):"""在飞船的当前所在的位置创建出一个子弹的图像"""super().__init__()self.screen = ai_game.screenself.settings = ai_game.settingsself.color = self.settings.bullet_color# 现在原点处创建一颗子弹,同时子弹的宽高在设置类的参数里引入self.rect = pygame.Rect(0, 0, self.settings.bullet_width,self.settings.bullet_height)#子弹的初始位置设置成了飞船的初始位置self.rect.midtop = ai_game.ship.rect.midtop# 用float储存这个位置self.y = float(self.rect.y)def update(self):"""子弹向上飞"""# 每一次子弹向上移动,y轴在不断地自减self.y -= self.settings.bullet_speed# 把最新的位置给子弹self.rect.y = self.ydef draw_bullet(self):"""画出子弹,参数是用self里面储存的参数填充的"""pygame.draw.rect(self.screen, self.color, self.rect)

设置类文件

class Settings:def __init__(self):# Screen settingsself.screen_width = 1200self.screen_height = 800self.bg_color = (230, 230, 230)# Ship settingsself.ship_speed = 1.5# 这里在设置子弹的一系列的参数,等会直接调用这个类self.bullet_speed = 1.0self.bullet_width = 3self.bullet_height = 15self.bullet_color = (60, 60, 60)#最大的子弹数为3self.bullets_allowed = 3

飞船的参数设置文件

import pygameclass Ship:def __init__(self, ai_game):self.screen = ai_game.screenself.settings = ai_game.settingsself.screen_rect = ai_game.screen.get_rect()# Load the ship image and get its rect.self.image = pygame.image.load('images/ship.bmp')self.rect = self.image.get_rect()# Start each new ship at the bottom center of the screen.self.rect.midbottom = self.screen_rect.midbottom# Store a decimal value for the ship's horizontal position.self.x = float(self.rect.x)# Movement flagsself.moving_right = Falseself.moving_left = Falsedef update(self):# Update the ship's x value, not the rect.if self.moving_right and self.rect.right < self.screen_rect.right:self.x += self.settings.ship_speedif self.moving_left and self.rect.left > 0:self.x -= self.settings.ship_speed# Update rect object from self.x.self.rect.x = self.xdef blitme(self):self.screen.blit(self.image, self.rect)

手把手讲解超详细python入门游戏项目‘打外星飞船’(四)

在经过创立屏幕、飞船移动和设置子弹,我们这里开始设置外形人的创建和移动。我们这里主要的任务是:创建一众外星人让它们充满屏幕,让他们向下和两边移动,这里继承了上面四个文件外我们还多键一个文件来管理外星人的类,也就是五个文件。这里后三个文件没有太大的变化,我们主要调整了前两个文件

主文件

import sysimport pygamefrom settings import Settings
from ship import Ship
from bullet import Bullet
from alien import Alienclass AlienInvasion:def __init__(self):pygame.init()self.settings = Settings()self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)self.settings.screen_width = self.screen.get_rect().widthself.settings.screen_height = self.screen.get_rect().heightpygame.display.set_caption("Alien Invasion")self.ship = Ship(self)self.bullets = pygame.sprite.Group()self.aliens = pygame.sprite.Group()self._creat_fleet()def run_game(self):while True:self._check_events()self.ship.update()self._update_bullets()#这里多加了外星人的运动函数self._update_aliens()self._update_screen()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)def _check_keydown_events(self, event):if event.key == pygame.K_RIGHT:self.ship.moving_right = Trueelif event.key == pygame.K_LEFT:self.ship.moving_left = Trueelif event.key == pygame.K_q:sys.exit()elif event.key == pygame.K_SPACE:self._fire_bullet()def _check_keyup_events(self, event):if event.key == pygame.K_RIGHT:self.ship.moving_right = Falseelif event.key == pygame.K_LEFT:self.ship.moving_left = Falsedef _fire_bullet(self):if len(self.bullets) < self.settings.bullets_allowed:new_bullet = Bullet(self)self.bullets.add(new_bullet)def _update_bullets(self):self.bullets.update()for bullet in self.bullets.copy():if bullet.rect.bottom <= 0:self.bullets.remove(bullet)def _update_aliens(self):"""判断外星人有没有到边,到了就调整位置"""self._check_fleet_edges()self.aliens.update()def _create_fleet(self):"""用来创建外星人"""# 计算出一行可以容纳多少外星人alien = Alien(self)alien_width, alien_height = alien.rect.sizeavailable_space_x = self.settings.screen_width - (2 * alien_width)number_aliens_x = available_space_x // (2 * alien_width)#计算出一列可以容纳多少外星人ship_height = self.ship.rect.heightavailable_space_y = (self.settings.screen_height -(3 * alien_height) - ship_height)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_numberself.aliens.add(alien)def _check_fleet_edges(self):"""这里判断外星人到底屏幕底部没有"""for alien in self.aliens.sprites():#遍历每个外星人if alien.check_edges():self._change_fleet_direction()#如果到了就退出循环breakdef _change_fleet_direction(self):"""将外星人下移加左右飘"""for alien in self.aliens.sprites():alien.rect.y += self.settings.fleet_drop_speedself.settings.fleet_direction *= -1def _update_screen(self):self.screen.fill(self.settings.bg_color)self.ship.blitme()for bullet in self.bullets.sprites():bullet.draw_bullet()self.aliens.draw(self.screen)pygame.display.flip()if __name__ == '__main__':# Make a game instance, and run the game.ai = AlienInvasion()ai.run_game()

外星人控制

import pygame
from pygame.sprite import Spriteclass Alien(Sprite):"""管理的外星人的类"""def __init__(self, ai_game):"""初始化外星人并设置他们初始位置"""super().__init__()self.screen = ai_game.screenself.settings = ai_game.settings#外星人图像并且rect属性         self.image = pygame.image.load('images/alien.bmp')self.rect = self.image.get_rect()# 外星人一开始出现在屏幕的左上角self.rect.x = self.rect.widthself.rect.y = self.rect.height# 记录下外星人的位置self.x = float(self.rect.x)def check_edges(self):#判断是否超过屏幕"""看看飞船有没有超过屏幕,如果屏幕大于右边的屏幕的数后者小于零是超越屏幕的左边"""screen_rect = self.screen.get_rect()if self.rect.right >= screen_rect.right or self.rect.left <= 0:return Truedef update(self):"""这里用乘积的办法,每次就是用所在的x坐标减去方向*1or-1"""self.x += (self.settings.alien_speed *self.settings.fleet_direction)self.rect.x = self.x

子弹管理类

import pygame
from pygame.sprite import Spriteclass Bullet(Sprite):def __init__(self, ai_game):super().__init__()self.screen = ai_game.screenself.settings = ai_game.settingsself.color = self.settings.bullet_colorself.rect = pygame.Rect(0, 0, self.settings.bullet_width,self.settings.bullet_height)self.rect.midtop = ai_game.ship.rect.midtopself.y = float(self.rect.y)def update(self):# Update the decimal position of the bullet.self.y -= self.settings.bullet_speed# Update the rect position.self.rect.y = self.ydef draw_bullet(self):pygame.draw.rect(self.screen, self.color, self.rect)

总设置参数

class Settings:"""这个类用于储存一些参数"""def __init__(self):# 屏幕参数self.screen_width = 1200self.screen_height = 800self.bg_color = (230, 230, 230)# 飞船参数self.ship_speed = 1.5# 子弹参数self.bullet_speed = 1.0self.bullet_width = 3self.bullet_height = 15self.bullet_color = (60, 60, 60)self.bullets_allowed = 3# 外星人左右移动的速度1,向下移动的速度10self.alien_speed = 1.0self.fleet_drop_speed = 10# 这里其实是在设置每次外形人飞船的位置,1为右移一位,-1为左移self.fleet_direction = 1

飞船设置

import pygameclass Ship:"""飞船参数"""def __init__(self, ai_game):self.screen = ai_game.screenself.settings = ai_game.settingsself.screen_rect = ai_game.screen.get_rect()self.image = pygame.image.load('images/ship.bmp')self.rect = self.image.get_rect()self.rect.midbottom = self.screen_rect.midbottomself.x = float(self.rect.x)self.moving_right = Falseself.moving_left = Falsedef update(self):if self.moving_right and self.rect.right < self.screen_rect.right:self.x += self.settings.ship_speedif self.moving_left and self.rect.left > 0:self.x -= self.settings.ship_speedself.rect.x = self.xdef blitme(self):self.screen.blit(self.image, self.rect)

手把手讲解超详细python入门游戏项目‘打外星飞船’(五)

这是最后一个项目了,前面我们讲了整个游戏页面的控制、飞船、子弹、外星人的创建,这里我们讨论一下子弹射杀外星人和整个游戏的结束,我们这里的文件一共有六个:主函数、飞船、外星飞船、子弹、设置参数、跟踪游戏统计信息六个文件。在这里我们要实现的任务是:子弹碰到外形飞船是让飞船消失,同时飞船碰到外星人飞船或者外星人飞船碰到屏幕低端结束游戏。

主函数

import sys
from time import sleepimport pygamefrom settings import Settings
#我们需要创建一个文件去储存游戏统计信息,这里引入主函数
from game_stats import GameStats
from ship import Ship
from bullet import Bullet
from alien import Alienclass AlienInvasion:"""控制游戏所有类和函数的类"""def __init__(self):"""初始化游戏并且调用相关的函数资源"""pygame.init()self.settings = Settings()self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)self.settings.screen_width = self.screen.get_rect().widthself.settings.screen_height = self.screen.get_rect().heightpygame.display.set_caption("Alien Invasion")#创建一个用于储存游戏并且统计信息的实例self.stats = GameStats(self)self.ship = Ship(self)self.bullets = pygame.sprite.Group()self.aliens = pygame.sprite.Group()self._create_fleet()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()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)def _check_keydown_events(self, event):"""接收键盘上左右移动等指令"""if event.key == pygame.K_RIGHT:self.ship.moving_right = Trueelif event.key == pygame.K_LEFT:self.ship.moving_left = Trueelif event.key == pygame.K_q:sys.exit()elif event.key == pygame.K_SPACE:self._fire_bullet()def _check_keyup_events(self, event):"""释放键盘指令"""if event.key == pygame.K_RIGHT:self.ship.moving_right = Falseelif event.key == pygame.K_LEFT:self.ship.moving_left = Falsedef _fire_bullet(self):"""创键一个新的子弹并把他加入子弹组"""if len(self.bullets) < self.settings.bullets_allowed:new_bullet = Bullet(self)self.bullets.add(new_bullet)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 _check_bullet_alien_collisions(self):"""响应子弹和外星人碰撞,删除碰撞的两者的函数"""# 检查是否有子弹击中外星人,有就删除子弹和外星人collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)if not self.aliens:# 删除现有的子弹并创建一群外星人self.bullets.empty()self._create_fleet()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_aliens_bottom(self):"""Check if any aliens have reached the bottom of the screen."""screen_rect = self.screen.get_rect()for alien in self.aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:# Treat this the same as if the ship got hit.self._ship_hit()breakdef _ship_hit(self):"""响应飞船被外星人撞到时候"""if self.stats.ships_left > 0:# Decrement ships_left.self.stats.ships_left -= 1# 清除所有的子弹和外星人self.aliens.empty()self.bullets.empty()# 创建新的飞船,把他放到屏幕中央开始游戏self._create_fleet()self.ship.center_ship()# 暂停一会,让玩家可以看到飞船碰撞sleep(0.5)else:self.stats.game_active = Falsedef _create_fleet(self):# 计算行列的外星人可以容纳多少个,并创建数行数列的外星人alien = Alien(self)alien_width, alien_height = alien.rect.sizeavailable_space_x = self.settings.screen_width - (2 * alien_width)number_aliens_x = available_space_x // (2 * alien_width)ship_height = self.ship.rect.heightavailable_space_y = (self.settings.screen_height -(3 * alien_height) - ship_height)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.sizealien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberself.aliens.add(alien)def _check_fleet_edges(self):"""如果有任何飞船到达边缘要及时反应"""for alien in self.aliens.sprites():if alien.check_edges():self._change_fleet_direction()breakdef _change_fleet_direction(self):"""让外星人飞船左右移动"""for alien in self.aliens.sprites():alien.rect.y += self.settings.fleet_drop_speedself.settings.fleet_direction *= -1def _update_screen(self):"""更新屏幕上的图片"""self.screen.fill(self.settings.bg_color)self.ship.blitme()for bullet in self.bullets.sprites():bullet.draw_bullet()self.aliens.draw(self.screen)pygame.display.flip()if __name__ == '__main__':# Make a game instance, and run the game.ai = AlienInvasion()ai.run_game()

外星人文件

import pygame
from pygame.sprite import Spriteclass Alien(Sprite):"""外星人移动管里类"""def __init__(self, ai_game):"""初始化外星人并把放置他们的位置"""super().__init__()self.screen = ai_game.screenself.settings = ai_game.settings#下载图片self.image = pygame.image.load('images/alien.bmp')self.rect = self.image.get_rect()# 每次在左上角开始飞船self.rect.x = self.rect.widthself.rect.y = self.rect.height# 储存飞船的位置.self.x = float(self.rect.x)def check_edges(self):"""返回flag如果飞船到达边缘"""screen_rect = self.screen.get_rect()if self.rect.right >= screen_rect.right or self.rect.left <= 0:return Truedef update(self):"""向左或者向右移动飞船"""self.x += (self.settings.alien_speed *self.settings.fleet_direction)self.rect.x = self.x

子弹文件

import pygame
from pygame.sprite import Spriteclass Bullet(Sprite):"""管理子弹的类"""def __init__(self, ai_game):"""在飞船的位置创建一个子弹"""super().__init__()self.screen = ai_game.screenself.settings = ai_game.settingsself.color = self.settings.bullet_color# 现在原点创建一个矩形然后移动到飞船头部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):"""子弹超过屏幕后移除子弹"""# Update the decimal position of the bullet.self.y -= self.settings.bullet_speed# Update the rect position.self.rect.y = self.ydef draw_bullet(self):"""在屏幕上画出子弹"""pygame.draw.rect(self.screen, self.color, self.rect)

参数设置类文件

class Settings:"""设置一系列参数"""def __init__(self):"""初始化游戏的参数"""# 屏幕的大小self.screen_width = 1200self.screen_height = 800self.bg_color = (230, 230, 230)# 飞船的速度等参数self.ship_speed = 1.5self.ship_limit = 3# 子弹的设置self.bullet_speed = 1.5self.bullet_width = 3self.bullet_height = 15self.bullet_color = (60, 60, 60)self.bullets_allowed = 3# 外星人飞船的设置self.alien_speed = 1.0self.fleet_drop_speed = 10# fleet_direction of 1 represents right; -1 represents left.self.fleet_direction = 1

飞船文件

import pygameclass Ship:"""管理飞船的类"""def __init__(self, ai_game):"""初始化飞船并且调动他的位置."""self.screen = ai_game.screenself.settings = ai_game.settingsself.screen_rect = ai_game.screen.get_rect()# 调用飞船图片并且储存他的位置self.image = pygame.image.load('images/ship.bmp')self.rect = self.image.get_rect()# 每个飞船都在屏幕的中央出现self.rect.midbottom = self.screen_rect.midbottomself.x = float(self.rect.x)# 移动flagself.moving_right = Falseself.moving_left = Falsedef update(self):"""移动飞船根据flag"""# Update the ship's x value, not the rect.if self.moving_right and self.rect.right < self.screen_rect.right:self.x += self.settings.ship_speedif self.moving_left and self.rect.left > 0:self.x -= self.settings.ship_speed# 储存飞船目前的位置self.rect.x = self.xdef blitme(self):"""在目前位置画出飞船"""self.screen.blit(self.image, self.rect)def center_ship(self):"""把飞船放在屏幕中央"""self.rect.midbottom = self.screen_rect.midbottomself.x = float(self.rect.x)

跟踪游戏统计文件

class GameStats:"""跟踪游戏统计信息"""def __init__(self, ai_game):"""初始化游戏信息"""self.settings = ai_game.settingsself.reset_stats()#游戏启动处于活动状态self.game_active = Truedef reset_stats(self):"""初始化在游戏运行期间可能变化的统计信息"""self.ships_left = self.settings.ship_limit

这个是最后的配置的外星人和飞船图片
请添加图片描述
请添加图片描述

这篇关于PYTHON入门级游戏开发:宇宙飞船游戏两万字详析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/542234

相关文章

Python 字符串占位

在Python中,可以使用字符串的格式化方法来实现字符串的占位。常见的方法有百分号操作符 % 以及 str.format() 方法 百分号操作符 % name = "张三"age = 20message = "我叫%s,今年%d岁。" % (name, age)print(message) # 我叫张三,今年20岁。 str.format() 方法 name = "张三"age

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

一道经典Python程序样例带你飞速掌握Python的字典和列表

Python中的列表(list)和字典(dict)是两种常用的数据结构,它们在数据组织和存储方面有很大的不同。 列表(List) 列表是Python中的一种有序集合,可以随时添加和删除其中的元素。列表中的元素可以是任何数据类型,包括数字、字符串、其他列表等。列表使用方括号[]表示,元素之间用逗号,分隔。 定义和使用 # 定义一个列表 fruits = ['apple', 'banana

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa

python实现最简单循环神经网络(RNNs)

Recurrent Neural Networks(RNNs) 的模型: 上图中红色部分是输入向量。文本、单词、数据都是输入,在网络里都以向量的形式进行表示。 绿色部分是隐藏向量。是加工处理过程。 蓝色部分是输出向量。 python代码表示如下: rnn = RNN()y = rnn.step(x) # x为输入向量,y为输出向量 RNNs神经网络由神经元组成, python

python 喷泉码

因为要完成毕业设计,毕业设计做的是数据分发与传输的东西。在网络中数据容易丢失,所以我用fountain code做所发送数据包的数据恢复。fountain code属于有限域编码的一部分,有很广泛的应用。 我们日常生活中使用的二维码,就用到foutain code做数据恢复。你遮住二维码的四分之一,用手机的相机也照样能识别。你遮住的四分之一就相当于丢失的数据包。 为了实现并理解foutain

python 点滴学

1 python 里面tuple是无法改变的 tuple = (1,),计算tuple里面只有一个元素,也要加上逗号 2  1 毕业论文改 2 leetcode第一题做出来

高仿精仿愤怒的小鸟android版游戏源码

这是一款很完美的高仿精仿愤怒的小鸟android版游戏源码,大家可以研究一下吧、 为了报复偷走鸟蛋的肥猪们,鸟儿以自己的身体为武器,仿佛炮弹一样去攻击肥猪们的堡垒。游戏是十分卡通的2D画面,看着愤怒的红色小鸟,奋不顾身的往绿色的肥猪的堡垒砸去,那种奇妙的感觉还真是令人感到很欢乐。而游戏的配乐同样充满了欢乐的感觉,轻松的节奏,欢快的风格。 源码下载

Python爬虫-贝壳新房

前言 本文是该专栏的第32篇,后面会持续分享python爬虫干货知识,记得关注。 本文以某房网为例,如下图所示,采集对应城市的新房房源数据。具体实现思路和详细逻辑,笔者将在正文结合完整代码进行详细介绍。接下来,跟着笔者直接往下看正文详细内容。(附带完整代码) 正文 地址:aHR0cHM6Ly93aC5mYW5nLmtlLmNvbS9sb3VwYW4v 目标:采集对应城市的

python 在pycharm下能导入外面的模块,到terminal下就不能导入

项目结构如下,在ic2ctw.py 中导入util,在pycharm下不报错,但是到terminal下运行报错  File "deal_data/ic2ctw.py", line 3, in <module>     import util 解决方案: 暂时方案:在终端下:export PYTHONPATH=/Users/fujingling/PycharmProjects/PSENe