用pycharm写一个打飞机的游戏
首先要pycharm中安装pygame,
源代码
mport sys # 导入系统模块
import random # 导入随机数
import pygame # 导入pygame模块
import pygame.locals # 导入pygame本地策略
APP_ICON = “res/app.ico” # 设计图片常量
IMG_BACKGROUND = “res/img_bg_level_1.jpg” # 设计图片常量
设置敌机图片库常量元组
IMG_ENEMYS = (“res/img-plane_1.png”,“res/img-plane_2.png”,“res/img-plane_3.png”,“res/img-plane_4.png”,“res/img-plane_5.png”,“res/img-plane_6.png”,“res/img-plane_7.png”)
IMG_PLAYER = “res/hero2.png” # 设置玩家飞机图片
IMG_BULLET = “res/bullet_13.png” # 设置子弹图片
创建所有显示的图形父类Model
class Model:
window = None # 主窗体对象,用于模型访问使用
构造方法
def init(self, img_path, x, y):
self.img = pygame.image.load(img_path) # 背景图片
self.x = x # 窗体中放置的x坐标
self.y = y # 窗体中放置的y坐标
将模型加入窗体的方法抽取到父类
def display(self):
self.window.blit(self.img, (self.x, self.y)) # 填充图片到窗体中
@staticmethod # 碰撞操作与模型对象无关,属于模型相关操作,定义为静态方法
def is_hit(rect1,rect2): # 定义双方是否碰撞的静态方法
return pygame.Rect.colliderect(rect1, rect2) # 返回两个矩形是否相交,即是否碰撞
背景类
class Background(Model):
定义背景移动的方法
def move(self):
加入判断
if self.y <= Game.WINDOW_HEIGHT: # 更新高度的引用 # 如果没有超出屏幕就正常移动
self.y += 1 # 纵坐标自增1
else: # 如果超出屏幕,恢复图片位置为原始位置
self.y = 0 # 纵坐标 = 0
覆盖父类display方法,做辅助背景贴图
def display(self):
self.window.blit(self.img, (self.x, self.y)) # 原始背景贴图,推荐使用super().display()
self.window.blit(self.img, (self.x, self.y - Game.WINDOW_HEIGHT)) # 更新高度的引用 # 辅助背景即将原始背景图片展示第二遍,坐标位置与第一遍展示上下拼接吻合
玩家类
class PlayerPlane(Model):
覆盖init方法
def init(self,img_path, x, y):
super().init(img_path, x, y) # 调用父类构造方法
self.bullets = [] # 定义子弹列表为空,默认没有子弹
覆盖display方法
def display(self,enemys): # 在显示飞机和子弹的同时,传入敌机列表,判断子弹是否与敌机相撞,添加enemys形参
super().display() # 调用父类方法
remove_bullets = [] # 定义被删除的子弹列表
for bullet in self.bullets: # 循环子弹
优化子弹存储队列,超出屏幕移出子弹
if bullet.y < -29 : # 如果子弹位置超出屏幕
remove_bullets.append(bullet) # 将要删除的子弹加入列表
else: # 如果子弹位置未超出屏幕范围
rect_bullet = pygame.locals.Rect(bullet.x, bullet.y, 20, 29) # 创建子弹矩形对象,传入x,y,width,height
for enemy in enemys: # 对未超出屏幕显示范围的子弹与所有敌机进行碰撞检测
rect_enemy = pygame.locals.Rect(enemy.x,enemy.y,100,68) # 创建敌机矩形对象,传入x,y,width,height
调用碰撞检测方法,传入当前子弹对象,传入敌机对象,判断是否碰撞
if Model.is_hit(rect_bullet,rect_enemy) : # 如果碰撞
enemy.is_hited = True # 击中敌机即设置当前敌机为被击中状态
enemy.bomb.is_show = True # 设置爆破效果状态开启
enemy.bomb.x = enemy.x # 设置爆破效果开启位置x坐标
enemy.bomb.y = enemy.y # 设置爆破效果开启位置y坐标
remove_bullets.append(bullet) # 将产生碰撞的子弹加入删除列表
sound = pygame.mixer.Sound(“res/bomb.wav”) # 添加混音音效文件
sound.play() # 播放爆破效果音
break # 当前子弹击中了一架敌机,终止对剩余敌机的碰撞检测,终止敌机循环
for bullet in remove_bullets: # 循环删除子弹列表
self.bullets.remove(bullet) # 从原始子弹列表中删除要删除的子弹
敌机类
class EnemyPlane(Model):
覆盖init方法
def init(self):
img = IMG_ENEMYS[random.randint(0,len(IMG_ENEMYS)-1)] # 设置图片路径随机从元组中获取
x = random.randint(0, Game.WINDOW_WIDTH - 100) # 设置x坐标随机生成 横向位置 0 到 屏幕宽度 - 飞机宽度(100)
y = random.randint(-Game.WINDOW_HEIGHT, -68) # 设置y坐标随机生成 纵向位置 -屏幕高度 到 -飞机高度
super().init(img,x,y) # 调用父类构造方法
self.is_hited = False # 添加敌机被击中的状态
self.bomb = Bomb() # 为敌机添加绑定的爆破效果对象
定义敌机移动的方法
def move(self):
控制敌机到达底部后,返回顶部
if self.y < Game.WINDOW_HEIGHT and not self.is_hited : # 添加敌机被击中的状态判定 # 敌机未超出屏幕
self.y += 4 # 控制敌机移动速度
else: # 敌机超出屏幕
self.img = pygame.image.load(IMG_ENEMYS[random.randint(0, len(IMG_ENEMYS) - 1)]) # 修改敌机到达底部后返回的图片随机生成,同初始化策略
self.x = random.randint(0, Game.WINDOW_WIDTH - 100) # 修改敌机到达底部后返回顶部的策略,x随机生成,同初始化策略
self.y = random.randint(-Game.WINDOW_HEIGHT, -68) # 修改敌机到达底部后返回顶部的策略,y随机生成,同初始化策略
self.is_hited = False # 重置敌机是否被击中状态为未被击中,False
子弹类
class Bullet(Model):
定义子弹移动的方法
def move(self):
self.y -= 12 # 控制子弹移动速度
爆炸效果类
class Bomb(Model): # 创建爆炸效果类
def init(self): # 定义单独的初始化方法
self.x = None # 定义爆炸显示的横坐标x
self.y = None # 定义爆炸显示的纵坐标y
self.imgs = [ pygame.image.load(“res/bomb-”+str(i)+".png") for i in range(1,7)] # 加载爆炸效果使用的所有图片列表
self.is_show = False # 定义是否开启爆破效果属性
self.times = 0 # 定义爆破图片展示控制变量
设置测试类入口操作
if name == “main”:
Game().run()import sys # 导入系统模块
import random # 导入随机数
import pygame # 导入pygame模块
import pygame.locals # 导入pygame本地策略
APP_ICON = “res/app.ico” # 设计图片常量
IMG_BACKGROUND = “res/img_bg_level_1.jpg” # 设计图片常量
设置敌机图片库常量元组
IMG_ENEMYS = (“res/img-plane_1.png”,“res/img-plane_2.png”,“res/img-plane_3.png”,“res/img-plane_4.png”,“res/img-plane_5.png”,“res/img-plane_6.png”,“res/img-plane_7.png”)
IMG_PLAYER = “res/hero2.png” # 设置玩家飞机图片
IMG_BULLET = “res/bullet_13.png” # 设置子弹图片
创建所有显示的图形父类Model
class Model:
window = None # 主窗体对象,用于模型访问使用
构造方法
def init(self, img_path, x, y):
self.img = pygame.image.load(img_path) # 背景图片
self.x = x # 窗体中放置的x坐标
self.y = y # 窗体中放置的y坐标
将模型加入窗体的方法抽取到父类
def display(self):
self.window.blit(self.img, (self.x, self.y)) # 填充图片到窗体中
@staticmethod # 碰撞操作与模型对象无关,属于模型相关操作,定义为静态方法
def is_hit(rect1,rect2): # 定义双方是否碰撞的静态方法
return pygame.Rect.colliderect(rect1, rect2) # 返回两个矩形是否相交,即是否碰撞
背景类
class Background(Model):
定义背景移动的方法
def move(self):
加入判断
if self.y <= Game.WINDOW_HEIGHT: # 更新高度的引用 # 如果没有超出屏幕就正常移动
self.y += 1 # 纵坐标自增1
else: # 如果超出屏幕,恢复图片位置为原始位置
self.y = 0 # 纵坐标 = 0
覆盖父类display方法,做辅助背景贴图
def display(self):
self.window.blit(self.img, (self.x, self.y)) # 原始背景贴图,推荐使用super().display()
self.window.blit(self.img, (self.x, self.y - Game.WINDOW_HEIGHT)) # 更新高度的引用 # 辅助背景即将原始背景图片展示第二遍,坐标位置与第一遍展示上下拼接吻合
class Game:
WINDOW_WIDTH = 512 # 定义窗体宽度常量
WINDOW_HEIGHT = 768 # 定义窗体高度常量
设置测试类入口操作
if name == “main”:
Game().run()
最后运行,图片如下
posted on 2021-12-26 11:45 20212420谭伟志 阅读(912) 评论(0) 编辑 收藏 举报