• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    如何利用pygame实现打飞机小游戏

    效果预览

    最近上实训课,写了这么一个简单的小玩意。运行效果如下:(这个是有音效的,不过这个展示不了因为这里只能上传GIF)

    项目结构

    游戏对屏幕的适配

    由于我使用的是笔记本所以对于屏幕来说是进行了缩放的,例如,我的笔记本缩放了125%

    但是问题在于我们的pygame和其他的一些库例如selenium其实是按照100%显示的像素来算的。所以这个时候我们需要进行一个换算。

    这个也好算: 当前显示像素比 = 100%显示像素比 X 缩放比

    我们只需要换算一下就好了。这里我定义了一个类,来实现我们的需求,自动检测我们的电脑的屏幕缩放比,之后换算。

    from win32 import win32api, win32gui, win32print
    from win32.lib import win32con
    
    from win32.win32api import GetSystemMetrics
    
    class 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, h
    
    
        def get_screen_size(self):
            """获取缩放后的分辨率"""
            w = GetSystemMetrics (0)
            h = GetSystemMetrics (1)
    
    
            return w, h
    
    
        def 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_rate
            except:
                #对笔记本进行适配,一般而言在100%比的机器上x不会出错
                x=1.25
            return 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 = speed
    
    
    
        def update(self):
    
    
            self.rect.y+=self.speed
    
    
    class Background(GameSprite):
    
        def __init__(self, image_path="./Plane_Img/background1.png",flag=False):
    
            super().__init__(image_path)
            if flag:
                self.rect.y = -self.rect.height
    
        def update(self):
            self.rect.y+=1
            if 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_rect
            self.bullet_image = bullet_image
            self.speed = 4
            self.is_hero = is_hero
            self.P_rect = P_rect
            self.screen_height = GetReal.getreal_xy(800)
            self.screen_width = GetReal.getreal_xy(500)
            self.actarct_plan = False
            self.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.y
    
        def 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 True
    
        def update(self):
    
            if self.enemy_bullet():
                #直接在这里计算数字一次减少5
                global HERO_PLANE_HP
                HERO_PLANE_HP-=5
                # print(HERO_PLANE_HP)
    
                self.kill()
            if self.is_hero:
                self.rect.y-=self.speed
            else:
                super().update()
            if self.rect.bottom >=self.screen_height-3 :
                self.kill()
    
    

    子弹的话分两种,一个是飞机子弹,一个是敌机子弹,敌机的自带检测碰撞。一方面是方便分数统计(敌机击中飞机几次)了另一方面也是因为飞机是自定义的没有办法用pygame的事件检测(自带的)

    敌机的爆炸

    这个其实又和飞机的爆炸类似。

    主要是检测有没有撞到飞机,之后通过切换图片就好了。当然这个时候我是开了线程的。不然会很快闪过去,换了和没换一样你看不到效果。

    切换图片的函数,切换完毕,删除这个敌机类减少内存消耗


    游戏小彩蛋

    这个其实就是一个自己的后面

    具体作用就是修改自己的飞机的HP值为99万

    当然这个小游戏还没有做完,无敌也有点无聊,玩久了的话。

    def CheatEngine():
    
        global  HERO_PLANE_HP
    
        print("HP is %d" % HERO_PLANE_HP)
    
    
        while 1:
    
            key = input("maybe you can input something:")
            if key=='break':
                print("enjoy your game please Bye~")
                return
            elif key=="Huterox is best":
                HERO_PLANE_HP=999999
    
                print("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 = speed
    
    
    
        def update(self):
    
    
            self.rect.y+=self.speed
    
    
    class Background(GameSprite):
    
        def __init__(self, image_path="./Plane_Img/background1.png",flag=False):
    
            super().__init__(image_path)
            if flag:
                self.rect.y = -self.rect.height
    
        def update(self):
            self.rect.y+=1
            if 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,Background
    
    GetReal = ChangeRealSize()
    
    GREATE_ENMEY_EVENT = pygame.USEREVENT#只能出现一次
    HERO_FIRE_BULLTE = pygame.USEREVENT+1 #第二个事件
    HERO_PLANE_HP = 300
    
    
    def CheatEngine():
    
        global  HERO_PLANE_HP
    
        print("HP is %d" % HERO_PLANE_HP)
    
    
        while 1:
    
            key = input("maybe you can input something:")
            if key=='break':
                print("enjoy your game please Bye~")
                return
            elif key=="Huterox is best":
                HERO_PLANE_HP=999999
    
                print("Now your HP is %d!!!"%HERO_PLANE_HP)
                return
    
    class 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 = False
            self.screen = screen
            self.GoStrange=False
            self.TurnLeft = False
            self.TurnRight =False
            self.GoBack = False
            self.Fire_flag = False
    
            self.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)
                return
    
            if self.GoStrange:
    
                if self.rect.bottom = 300:
                    self.show()
    
                    return
    
                else:
                    self.rect.y -= 3
                    self.show()
            if self.TurnLeft:
    
                if self.rect.x=3:
                    self.show()
                    return
                else:
                    self.rect.x-=2
                    self.show()
    
    
            if self.TurnRight:
    
                if self.rect.x>=Game.screen_x-self.rect.width-3:
                    self.show()
                    return
                else:
                    self.rect.x+=2
                    self.show()
            if self.GoBack:
                if self.rect.bottom>=Game.screen_y-30:
                    self.show()
                    return
                else:
                    self.rect.y +=2
                    self.show()
    
            self.show()
    
    
        def Get_bullet(self):
            #子弹加载
            if self.Killed:
                return
            if self.Fire_flag:
                MusicPlay().PlayPlanSound()
                bullet = Bullet(self.rect,True)
                self.bullet_group.add(bullet)
    
    
        def Fire(self):
            #子弹发射
            if self.Killed:
                return
            self.bullet_group.update()
    
            self.bullet_group.draw(self.screen)
    
    
        def Goal(self):
            pass
    
        def show(self):
            if self.Killed:
                return
            Game.screen.blit(self.image,self.rect)
    
            # pygame.display.update()
    
        def __plane_Boom(self):
            if self.Killed:
                return
            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.3)
            time.sleep(1)
            self.Killed =True
    
        def Plane_Live(self):
            if self.Killed:
                return
    
            global HERO_PLANE_HP
            if HERO_PLANE_HP=0:
                HERO_PLANE_HP =0
                self.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.music
    
        def 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_rect
            self.bullet_image = bullet_image
            self.speed = 4
            self.is_hero = is_hero
            self.P_rect = P_rect
            self.screen_height = GetReal.getreal_xy(800)
            self.screen_width = GetReal.getreal_xy(500)
            self.actarct_plan = False
            self.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.y
    
        def 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 True
    
        def update(self):
    
            if self.enemy_bullet():
                #直接在这里计算数字一次减少5
                global HERO_PLANE_HP
                HERO_PLANE_HP-=5
                # print(HERO_PLANE_HP)
    
                self.kill()
            if self.is_hero:
                self.rect.y-=self.speed
            else:
                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_path
            self.screen = screen
            self.hero_plane = hero_plane
            self.hero_bullet = self.hero_plane.bullet_group
    
            self.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 = True
            self.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值减少20
                global  HERO_PLANE_HP
                if len(self.collied_with_plan)==1:
                    HERO_PLANE_HP -=20
    
    
                t = threading.Thread(target=self.Boom_ing)
                t.start()
    
    
            pass
        def 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 True
    
    
    
    
        def __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 = -20
                self.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 = False
            else:
                self.rect.x -= random.randint(2, 3)
                if self.rect.left = 3:
                    self.Turn_L_Flag = True
    
    class 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_HP
            if 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 = True
    
                    if event.key == pygame.K_a or event.key == pygame.K_LEFT:
                        hero_palne.TurnLeft = True
    
                    if event.key == pygame.K_d or event.key == pygame.K_RIGHT:
                        hero_palne.TurnRight = True
    
                    if event.key == pygame.K_s or event.key == pygame.K_DOWN:
                        hero_palne.GoBack = True
    
                    if event.key  == pygame.K_SPACE:
                        hero_palne.Fire_flag= True
    
                if  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 = False
    
                    elif event.key == pygame.K_a or event.key == pygame.K_LEFT:
                        hero_palne.TurnLeft = False
    
                    elif event.key == pygame.K_d or event.key == pygame.K_RIGHT:
                        hero_palne.TurnRight = False
    
                    elif event.key == pygame.K_s or event.key == pygame.K_DOWN:
                        hero_palne.GoBack = False
    
                    if event.key == pygame.K_SPACE:
    
                        hero_palne.Fire_flag = False
    
            #敌机出现侦听
    
                elif event.type == GREATE_ENMEY_EVENT:
                    self.__Enemy_init()
    
        def __doc__(self):
            pass
    
    
        def __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):
    
                pass
    
        def 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的痛苦!!!)

    点击这里下载

    总结

    到此这篇关于如何利用pygame实现打飞机小游戏的文章就介绍到这了,更多相关pygame打飞机小游戏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • python pygame实现五子棋小游戏
    • 详解使用PyInstaller将Pygame库编写的小游戏程序打包为exe文件
    • 使用PyInstaller将Pygame库编写的小游戏程序打包为exe文件及出现问题解决方法
    • 使用Python第三方库pygame写个贪吃蛇小游戏
    • python运用pygame库实现双人弹球小游戏
    • python+pygame实现坦克大战小游戏的示例代码(可以自定义子弹速度)
    • 使用pygame编写Flappy bird小游戏
    • pygame库实现俄罗斯方块小游戏
    • pygame库实现移动底座弹球小游戏
    • 使用pygame实现垃圾分类小游戏功能(已获校级二等奖)
    上一篇:Python中requests做接口测试的方法
    下一篇:Python使用Kubernetes API访问集群
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    如何利用pygame实现打飞机小游戏 如何,利用,pygame,实现,打,