pygame实现打飞机小游戏
目录
- 效果预览
- 项目结构
- 游戏对屏幕的适配
- 游戏屏幕的绘制与飞机创建
- 飞机的移动
- 子弹与敌机类
- 敌机的爆炸
- 游戏小彩蛋
- 完整代码
- 项目获取
效果预览
最近上实训课,写了这么一个简单的小玩意。运行效果如下:(这个是有音效的,不过这个展示不了因为这里只能上传GIF)
项目结构
游戏对屏幕的适配
由于我使用的是笔记本所以对于屏幕来说是进行了缩放的,例如,我的笔记本缩放了125%
但是问题在于我们的pygame和其他的一些库例如selenium其实是按照100%显示的像素来算的。所以这个时候我们需要进行一个换算。
这个也好算: 当前显示像素比 = 100%显示像素比 X 缩放比
我们只需要换算一下就好了。这里我定义了一个类,来实现我们的需求,自动检测我们的电脑的屏幕缩放比,之后换算。
from win32 import win32api, win32gui, win32print
from win32.lib import win32confrom win32.win32api import GetSystemMetricsclass ChangeRealSize(object):'''该类主要对屏幕进行像素适配,按照缩放比对像素进行换算为100%显示示例:RealSize = ChangeRealSize()x=RealSize.getreal_xy(500)此时就可以换算为当前屏幕的像素'''def get_real_resolution(self):"""获取真实的分辨率"""hDC = win32gui.GetDC(0)w = win32print.GetDeviceCaps(hDC, win32con.DESKTOPHORZRES)h = win32print.GetDeviceCaps(hDC, win32con.DESKTOPVERTRES)return w, hdef get_screen_size(self):"""获取缩放后的分辨率"""w = GetSystemMetrics (0)h = GetSystemMetrics (1)return w, hdef getreal_xy(self,x):'''返回按照100%来算的真实的像素值'''real_resolution = self.get_real_resolution()screen_size = self.get_screen_size()screen_scale_rate = round(real_resolution[0] / screen_size[0], 2)try:x = x/screen_scale_rateexcept:#对笔记本进行适配,一般而言在100%比的机器上x不会出错x=1.25return int(x)
游戏屏幕的绘制与飞机创建
屏幕绘制直接使用pygame.display.set_mode()的bitl()绘制方法,进行绘制。当然这里的背景是会动的。所以使用到了一个精灵的派生类。
import pygame,random
from ChangeRealSize import ChangeRealSize
GetReal = ChangeRealSize()class GameSprite(pygame.sprite.Sprite):def __init__(self,image_path,speed=1):super().__init__()self.image = pygame.image.load(image_path)self.rect = self.image.get_rect()self.speed = speeddef update(self):self.rect.y+=self.speedclass Background(GameSprite):def __init__(self, image_path="./Plane_Img/background1.png",flag=False):super().__init__(image_path)if flag:self.rect.y = -self.rect.heightdef update(self):self.rect.y+=1if self.rect.y >= self.rect.height:self.rect.y = -self.rect.height
实现的具体方法如下:
飞机类的实现
这个我是自己定义的所以的话,没有办法直接使用那个自带的碰撞检测,我还定义了一个碰撞检测方法。
飞机的移动
这个和游戏类的事件检测配合。
具体思路是用pygame.event.get()进行事件检测。之后检测到按下某一个按键,例如向前移动是,就会设置向前移动的信号,那么这个时候飞机就会一直往前走。当松开后,那么设置信号为假,那么飞机就会停下来。由于飞机会一直在循环里面检测有没有按下那个向前,所以当你长按往前时,飞机会一直往前,直到你松开。
子弹与敌机类
这个子弹和敌机都是精灵派生类的子类。所以的话就一起说一下。
重点要说的时子弹类的碰撞检测,和敌机的碰撞检测。这里主要说一下子弹类,因为这个和敌机类似。只是有些细节不一样。
class Bullet(GameSprite):def __init__(self,P_rect,is_hero=False,bullet_image = "./Plane_Img/bullet-3.gif",hero_rect=None):self.hero_rect = hero_rectself.bullet_image = bullet_imageself.speed = 4self.is_hero = is_heroself.P_rect = P_rectself.screen_height = GetReal.getreal_xy(800)self.screen_width = GetReal.getreal_xy(500)self.actarct_plan = Falseself.actract_hero=[]super().__init__(self.bullet_image,self.speed)self.rect.x = self.P_rect.x+((self.P_rect.width-self.rect.width)/2)self.rect.y = self.P_rect.ydef enemy_bullet(self):#可以在这里计算飞机被击中了多少次#被击中减少5点if not self.is_hero:bullet_x = self.rect.x + int(self.rect.width / 2)bullet_y = self.rect.y + int(self.rect.height / 2)hero_plane_x = self.hero_rect.x + int(self.hero_rect.width / 2)hero_plane_y = self.hero_rect.y + int(self.hero_rect.height / 2)subtract_y = abs(int(bullet_y - hero_plane_y))subtract_x = abs(int(bullet_x - hero_plane_x))if subtract_y <= int((self.rect.height + self.hero_rect.height) / 2) and \subtract_x <= int((self.rect.width + self.hero_rect.height) / 2):self.actract_hero.append(1)return Truedef update(self):if self.enemy_bullet():#直接在这里计算数字一次减少5global HERO_PLANE_HPHERO_PLANE_HP-=5# print(HERO_PLANE_HP)self.kill()if self.is_hero:self.rect.y-=self.speedelse:super().update()if self.rect.bottom >=self.screen_height-3 :self.kill()
子弹的话分两种,一个是飞机子弹,一个是敌机子弹,敌机的自带检测碰撞。一方面是方便分数统计(敌机击中飞机几次)了另一方面也是因为飞机是自定义的没有办法用pygame的事件检测(自带的)
敌机的爆炸
这个其实又和飞机的爆炸类似。
主要是检测有没有撞到飞机,之后通过切换图片就好了。当然这个时候我是开了线程的。不然会很快闪过去,换了和没换一样你看不到效果。
切换图片的函数,切换完毕,删除这个敌机类减少内存消耗
游戏小彩蛋
这个其实就是一个自己的后面
具体作用就是修改自己的飞机的HP值为99万
当然这个小游戏还没有做完,无敌也有点无聊,玩久了的话。
def CheatEngine():global HERO_PLANE_HPprint("HP is %d" % HERO_PLANE_HP)while 1:key = input("maybe you can input something:")if key=='break':print("enjoy your game please Bye~")returnelif key=="Huterox is best":HERO_PLANE_HP=999999print("Now your HP is %d!!!"%HERO_PLANE_HP)return
完整代码
import pygame,random
from ChangeRealSize import ChangeRealSize
GetReal = ChangeRealSize()class GameSprite(pygame.sprite.Sprite):def __init__(self,image_path,speed=1):super().__init__()self.image = pygame.image.load(image_path)self.rect = self.image.get_rect()self.speed = speeddef update(self):self.rect.y+=self.speedclass Background(GameSprite):def __init__(self, image_path="./Plane_Img/background1.png",flag=False):super().__init__(image_path)if flag:self.rect.y = -self.rect.heightdef update(self):self.rect.y+=1if self.rect.y >= self.rect.height:self.rect.y = -self.rect.height
········································································································
import pygame,random,time,threading,os
from ChangeRealSize import ChangeRealSize
from GameSprite import GameSprite,BackgroundGetReal = ChangeRealSize()GREATE_ENMEY_EVENT = pygame.USEREVENT#只能出现一次
HERO_FIRE_BULLTE = pygame.USEREVENT+1 #第二个事件
HERO_PLANE_HP = 300def CheatEngine():global HERO_PLANE_HPprint("HP is %d" % HERO_PLANE_HP)while 1:key = input("maybe you can input something:")if key=='break':print("enjoy your game please Bye~")returnelif key=="Huterox is best":HERO_PLANE_HP=999999print("Now your HP is %d!!!"%HERO_PLANE_HP)returnclass Base():'''飞机的初始化样式,位置'''def __init__(self,x,y,width,height,path):self.x = GetReal.getreal_xy(x)self.y = GetReal.getreal_xy(y)self.width = GetReal.getreal_xy(width)self.height = GetReal.getreal_xy(height)self.image = pygame.image.load(path)self.rect = pygame.Rect(self.x,self.y,self.height,self.width)class Planer(Base):def __init__(self,x,y,width,height,path,screen):Base.__init__(self,x,y,width,height,path)self.Killed = Falseself.screen = screenself.GoStrange=Falseself.TurnLeft = Falseself.TurnRight =Falseself.GoBack = Falseself.Fire_flag = Falseself.Boom_path="./Plane_Img/hero_blowup_n{}.png"self.bullet_group=pygame.sprite.Group()pygame.time.set_timer(HERO_FIRE_BULLTE,250)self.Plane_need_Killed=[]#由于会重复执行只能去用列表的数量来判断def Move(self):if self.Killed:self.rect=pygame.Rect(0,0,0,0)returnif self.GoStrange:if self.rect.bottom <= 300:self.show()returnelse:self.rect.y -= 3self.show()if self.TurnLeft:if self.rect.x<=3:self.show()returnelse:self.rect.x-=2self.show()if self.TurnRight:if self.rect.x>=Game.screen_x-self.rect.width-3:self.show()returnelse:self.rect.x+=2self.show()if self.GoBack:if self.rect.bottom>=Game.screen_y-30:self.show()returnelse:self.rect.y +=2self.show()self.show()def Get_bullet(self):#子弹加载if self.Killed:returnif self.Fire_flag:MusicPlay().PlayPlanSound()bullet = Bullet(self.rect,True)self.bullet_group.add(bullet)def Fire(self):#子弹发射if self.Killed:returnself.bullet_group.update()self.bullet_group.draw(self.screen)def Goal(self):passdef show(self):if self.Killed:returnGame.screen.blit(self.image,self.rect)# pygame.display.update()def __plane_Boom(self):if self.Killed:returnfor i in range(1, 5):self.image_path = self.Boom_path.format(i)self.image = pygame.image.load(self.image_path)time.sleep(0.3)time.sleep(1)self.Killed =Truedef Plane_Live(self):if self.Killed:returnglobal HERO_PLANE_HPif HERO_PLANE_HP<=0:HERO_PLANE_HP =0self.Plane_need_Killed.append(1)if len(self.Plane_need_Killed)==1:t = threading.Thread(target=self.__plane_Boom)t.start()#音乐播放类
class MusicPlay():def __init__(self):self.bgmusic = pygame.mixer.musicdef PlayBg(self):self.bgmusic.load("./music/PlaneWarsBackgroundMusic.mp3")self.bgmusic.set_volume(0.3)self.bgmusic.play(-1)def StarBg(self):self.bgmusic.stop()def PlayPlanSound(self):self.PlayPlaneMusic = pygame.mixer.Sound("./music/hero_fire.wav")self.PlayPlaneMusic.set_volume(0.2)self.PlayPlaneMusic.play()def StopPlayPlanSound(self):pass#子弹类
class Bullet(GameSprite):def __init__(self,P_rect,is_hero=False,bullet_image = "./Plane_Img/bullet-3.gif",hero_rect=None):self.hero_rect = hero_rectself.bullet_image = bullet_imageself.speed = 4self.is_hero = is_heroself.P_rect = P_rectself.screen_height = GetReal.getreal_xy(800)self.screen_width = GetReal.getreal_xy(500)self.actarct_plan = Falseself.actract_hero=[]super().__init__(self.bullet_image,self.speed)self.rect.x = self.P_rect.x+((self.P_rect.width-self.rect.width)/2)self.rect.y = self.P_rect.ydef enemy_bullet(self):#可以在这里计算飞机被击中了多少次#被击中减少5点if not self.is_hero:bullet_x = self.rect.x + int(self.rect.width / 2)bullet_y = self.rect.y + int(self.rect.height / 2)hero_plane_x = self.hero_rect.x + int(self.hero_rect.width / 2)hero_plane_y = self.hero_rect.y + int(self.hero_rect.height / 2)subtract_y = abs(int(bullet_y - hero_plane_y))subtract_x = abs(int(bullet_x - hero_plane_x))if subtract_y <= int((self.rect.height + self.hero_rect.height) / 2) and \subtract_x <= int((self.rect.width + self.hero_rect.height) / 2):self.actract_hero.append(1)return Truedef update(self):if self.enemy_bullet():#直接在这里计算数字一次减少5global HERO_PLANE_HPHERO_PLANE_HP-=5# print(HERO_PLANE_HP)self.kill()if self.is_hero:self.rect.y-=self.speedelse:super().update()if self.rect.bottom >=self.screen_height-3 :self.kill()#敌机类
class Enemy(GameSprite):def __init__(self,hero_plane,screen,image_path="./Plane_Img/enemy0.png"):self.speed = random.randint(1,3)self.image_path =image_pathself.screen = screenself.hero_plane = hero_planeself.hero_bullet = self.hero_plane.bullet_groupself.fire_interval = False#通过这个和另一个计时线程配合来实现子弹的间断发射self.collied_with_plan = []super().__init__(self.image_path,self.speed)self.screen_height = GetReal.getreal_xy(800)self.screen_width = GetReal.getreal_xy(500)self.Turn_L_Flag = Trueself.Boom_path = "./Plane_Img/enemy0_down{}.png"self.rect.y = GetReal.getreal_xy(self.rect.top-self.rect.bottom)self.rect.x = random.randint(0, self.screen_width - self.rect.width)self.bullet_group = pygame.sprite.Group()def __Boom(self):#这里还可以对以后飞机击落敌机的数量计数#敌机应该检测自己有没有和飞机的子弹相撞flag_killed_by_bullet = pygame.sprite.spritecollide(self,self.hero_bullet,True)if flag_killed_by_bullet or self.__IS_collied_with_plan():#被用户撞了HP值减少20global HERO_PLANE_HPif len(self.collied_with_plan)==1:HERO_PLANE_HP -=20t = threading.Thread(target=self.Boom_ing)t.start()passdef Boom_ing(self):for i in range(1, 5):self.image_path = self.Boom_path.format(i)self.image = pygame.image.load(self.image_path)time.sleep(0.2)self.kill()def __IS_collied_with_plan(self):#碰撞检查是否与用户飞机碰撞center_enemy_x = self.rect.x +int(self.rect.width/2)center_enemy_y = self.rect.y +int(self.rect.height/2)center_plane_x = self.hero_plane.rect.x+int(self.hero_plane.rect.width/2)center_plane_y = self.hero_plane.rect.y+int(self.hero_plane.rect.height/2)subtract_y = abs(int(center_enemy_y-center_plane_y))subtract_x = abs(int(center_enemy_x-center_plane_x))if subtract_y <= int((self.rect.height+self.hero_plane.rect.height)/2) and\subtract_x <= int((self.rect.width+self.hero_plane.rect.height)/2):self.collied_with_plan.append(1)return Truedef __Bullet_building(self):if self.rect.y% 50 ==0:buttle = Bullet(self.rect,bullet_image="./Plane_Img/bullet-1.gif",hero_rect=self.hero_plane.rect)self.bullet_group.add(buttle)def __Shut(self):self.bullet_group.update()self.bullet_group.draw(self.screen)def update(self):super().update()#定义敌机的出现self.__Boom()#监听是否碰撞和子弹被射击self.__Bullet_building()self.__Shut()if self.rect.top >= self.screen_height + 3:#//越界判断# self.rect.y = -20self.kill()if self.Turn_L_Flag:self.rect.x += random.randint(1,2)if self.rect.right >= self.screen_width - 3:self.Turn_L_Flag = Falseelse:self.rect.x -= random.randint(2, 3)if self.rect.left <= 3:self.Turn_L_Flag = Trueclass PlayGame(object):def __init__(self):pygame.init()self.screen_x, self.screen_y = GetReal.getreal_xy(500), GetReal.getreal_xy(800)self.screen = pygame.display.set_mode((self.screen_x, self.screen_y))self.Flush_Clcok = pygame.time.Clock()pygame.display.set_caption('英雄无敌!!!')self.enemy_group = pygame.sprite.Group()self.hero_palne = Planer(200, 500, 100, 125, "./Plane_Img/hero1.png", self.screen)pygame.time.set_timer(GREATE_ENMEY_EVENT,1000)#绑定常量事件def __game_over(self):global HERO_PLANE_HPif self.hero_palne.Killed:while True:bye = pygame.image.load("./Plane_Img/gameover_.png")self.screen.blit(bye,(0,0))pygame.display.update()for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()os._exit(0)def __Listening_keyboard(self,hero_palne):'''键盘按键事件侦听''''''hero_palne部分是侦听用户飞机的其余的是其他的事件侦听'''for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()os._exit(0)elif event.type == pygame.KEYDOWN:#检测键盘按下if event.key == pygame.K_w or event.key == pygame.K_UP:hero_palne.GoStrange = Trueif event.key == pygame.K_a or event.key == pygame.K_LEFT:hero_palne.TurnLeft = Trueif event.key == pygame.K_d or event.key == pygame.K_RIGHT:hero_palne.TurnRight = Trueif event.key == pygame.K_s or event.key == pygame.K_DOWN:hero_palne.GoBack = Trueif event.key == pygame.K_SPACE:hero_palne.Fire_flag= Trueif event.type == HERO_FIRE_BULLTE:hero_palne.Get_bullet()elif event.type == pygame.KEYUP:# 检测键盘松开if event.key == pygame.K_w or event.key == pygame.K_UP:hero_palne.GoStrange = Falseelif event.key == pygame.K_a or event.key == pygame.K_LEFT:hero_palne.TurnLeft = Falseelif event.key == pygame.K_d or event.key == pygame.K_RIGHT:hero_palne.TurnRight = Falseelif event.key == pygame.K_s or event.key == pygame.K_DOWN:hero_palne.GoBack = Falseif event.key == pygame.K_SPACE:hero_palne.Fire_flag = False#敌机出现侦听elif event.type == GREATE_ENMEY_EVENT:self.__Enemy_init()def __doc__(self):passdef __BackGround_init(self):bg1 = Background()bg2 = Background(flag=True)self.back_ground = pygame.sprite.Group(bg1,bg2)def __ShowBackGround(self):self.back_ground.update()self.back_ground.draw(self.screen)def __Enemy_init(self):#临时的东西enemy = Enemy(self.hero_palne,self.screen)self.enemy_group.add(enemy)def __Show_enemy(self):if self.enemy_group:self.enemy_group.update()self.enemy_group.draw(self.screen)def __Check_planecollied_enemy(self):passdef star_game(self):PlayerMusic = MusicPlay()PlayerMusic.PlayBg()hero_palne = Planer(200, 500, 100, 125, "./Plane_Img/hero1.png", self.screen)self.__BackGround_init()#加载背景self.__Enemy_init()#加载敌机while 1:self.__ShowBackGround()self.__Show_enemy()self.__Listening_keyboard(self.hero_palne )self.hero_palne.Move()self.hero_palne.Fire()self.hero_palne.Plane_Live()self.__game_over()pygame.display.update() # 敲黑板这个方法最好只出现一次,就在你的游戏主循环里面实现self.Flush_Clcok.tick(60)if __name__ == '__main__':t = threading.Thread(target=CheatEngine)t.start()Game = PlayGame()Game.star_game()
项目获取
(不会玩git的痛苦!!!)
链接:https://pan.baidu.com/s/1Fm2BA3QXW08xkuVMfvDt1A
提取码:6666
pygame实现打飞机小游戏相关推荐
- Pygame:编写一个小游戏
大学最后的考试终于结束了,迎来了暑假和大四的漫长的"自由"假期.当然要自己好好"玩玩"了. 我最近在学习Python,本意是在机器学习深度学习上使用Python ...
- 基于pygame实现的飞机大战游戏
目录 1.引言 1.1 背景 1.2 意义 1.3 功能 2.系统结构 2.1 整体框架 2.2 精灵与精灵组 2.3 功能介绍 2.3.1 玩家飞机 2.3.2 敌机类型和关卡设定 2.3.3 敌机 ...
- Python编写微信打飞机小游戏(三)
如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢. Python编写微信打飞机小游戏(一) Python编写微信打飞机小游戏(二) Python编写微信打飞机小游戏(三 ...
- Python编写微信打飞机小游戏(八)
如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢. Python编写微信打飞机小游戏(一) Python编写微信打飞机小游戏(二) Python编写微信打飞机小游戏(三 ...
- Python编写微信打飞机小游戏(十一)
如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢. Python编写微信打飞机小游戏(一) Python编写微信打飞机小游戏(二) Python编写微信打飞机小游戏(三 ...
- 可以帮我做一个python的3D飞机小游戏吗
当然可以!我很乐意帮助你做一个 Python 的 3D 飞机小游戏. 如果你是 Python 初学者,我建议你先了解一些 Python 的基础知识,包括变量.数据类型.流程控制语句.函数等.这些知识都 ...
- Python编写微信打飞机小游戏(七)
如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢. Python编写微信打飞机小游戏(一) Python编写微信打飞机小游戏(二) Python编写微信打飞机小游戏(三 ...
- Python编写微信打飞机小游戏(十)
如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢. Python编写微信打飞机小游戏(一) Python编写微信打飞机小游戏(二) Python编写微信打飞机小游戏(三 ...
- Python编写微信打飞机小游戏(五)
如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢. Python编写微信打飞机小游戏(一) Python编写微信打飞机小游戏(二) Python编写微信打飞机小游戏(三 ...
- Python编写微信打飞机小游戏(十二)
如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢. Python编写微信打飞机小游戏(一) Python编写微信打飞机小游戏(二) Python编写微信打飞机小游戏(三 ...
最新文章
- python中读取文件过程中seek()函数的使用
- LNMP环境搭建(centos6.9+mysql5.7+php7.1+nginx1.10)
- 特征选择和特征生成问题初探
- Asp.Net Identity 深度解析 之 注册登录的扩展
- MINA与JMX集成(翻译)
- ImportError: cannot import name cbook
- 跟着太白老师学python 09day 初识函数
- BeagleBone Black 板第三课:Debian7.5系统安装和远程控制BBB板
- 使用md5对文件去重
- Elasticsearch 带中文分词的全文检索(分页+高亮返回)
- 献给七夕|微生物和您的爱情生活
- TypeError: xx takes 1 positional argument but 4 were given
- ubuntu 9.04/9.10 下代码阅读工具 kscope 的安装
- dbca 命令行静默方式创建Oracle RAC
- Facebook北京大学2015年宣讲会小记【Facebook Technical Talk】
- 关于lego-loam的总结(一)
- The Buffer Bomb
- C语言实例:输出八进制,十进制,十六进制,指定位数整数,带符号整数,科学计数法表示的整数
- 连续信号积分 matlab程序,连续信号的微积分与卷积.ppt
- Remix连接本地项目(Solidity)
热门文章
- python蒙特卡洛模拟return_蒙特卡罗方法入门
- 端午节谋定顺应自然-农业大健康·万祥军:根植古代农耕文化
- java毕业生设计二手物品交易系统计算机源码+系统+mysql+调试部署+lw
- 相机镜头等效焦距和实际焦距换算
- 解决问题multiply defined
- redis1.2.6 sds.c
- mysql中一些字节如何计算_在MySQL中将字节值计算为兆字节(MB)?
- vue学习日记(流水账
- c++中类的private的static变量实现类对象的数据共享
- 第二人生的源码分析(二十)显示人物名称