python面向对象编程实例:飞机大战 您所在的位置:网站首页 python做简单的飞机大战 python面向对象编程实例:飞机大战

python面向对象编程实例:飞机大战

2024-06-23 14:29| 来源: 网络整理| 查看: 265

说明:此则博客只是自己学习python编程的学习记录,其中完成的程序设计只是飞机大战的小小小demo,只为自己熟悉python语言和pygame,所以程序并不完善,只当练手和记录,当然可基于次程序进行后续的完善开发。最后感谢一下hm的python教程。至于程序中的图片素材,如果大家有需要可在本文下方留言,可私发。

开头 祭出程序开发文档:

#01. 使用pygame创建图形窗口 #1.1 游戏的初始化和退出 # 方法:           说明: #   pygame.init()   导入并初始化所有pygame模块 #   pygame.quit()   卸载所有pygame模块,在游戏结束之前调用 #1.2 理解游戏中的坐标系 # ·坐标系: #      1. 原点在左上角(0,0) #      2. x轴水平方法向右,逐渐增加 #      3. y轴垂直方向向下,逐渐增加 # ·在游戏中,所有的可见元素都是以矩形区域来描述位置的 #      1.要描述一个矩形区域有四个元素:(x, y) (width, heigth) # ·pygame专门提供了一个类pygame.Rect用于描述矩形区域 #      Rect(x, y, width, heigth) -> Rect #1.3 创建游戏的主窗口 # ·pygame专门提供了一个模块pygame.display用于创建,管理游戏窗口 #     方法:                         说明: #       pygame.display.set_mode()     初始化游戏显示窗口 #       pygame.display.update()       刷新屏幕内容显示,稍后使用 #     使用: #       set_mode(resolution=(0,0), flags=0, depth=0) -> Surface # ·参数 #     1.resolution指定屏幕的宽和高,默认创建的窗口大小和屏幕大小一致 #     2.flags参数指定屏幕的附加选项,例如是否全屏等等,默认不需要传递 #     3.depth参数表示颜色的位数,默认自动匹配 # ·注意 #     必须使用变量记录set_mode方法的返回结果!因为:后续所有的图像绘制都基于这个返回结果 #02. 理解图像并实现图像绘制 # ·在屏幕上看到某一个图像的内容,需要三个步骤: #     1.使用pygame.image.load()加载图像的数据 #     2.使用游戏屏幕对象,调用blit方法将图像绘制到指定的位置 #     3.调用pygame.display.update()方法更新整个屏幕的显示 #03. 理解游戏循环和游戏时钟 #3.1 游戏中的动画实现原理 #    一秒60帧的高质量视频 #3.2 游戏循环 #    1.设置刷新帧率 #    2.检测用户交互 #    3.更新所有的图像位置 #    4.更新屏幕显示 #3.3 游戏时钟 # ·pygame专门提供了一个类pygame.time.Clock可以非常方便的设置屏幕绘制速度--刷新帧率 # ·使用时钟步骤: #            1.在游戏初始化创建一个时钟对象 #            2.在游戏循环中让时钟对象调用tick(帧率)方法 # ·tick方法会根据上次被调用的时间,自动设置游戏循环中的延时 #3.4 英雄的简单动画实现 # ·提示: #      1.每一次调用update()方法之前,需要把所有的游戏图像都重新绘制一遍 #      2.而且应该最先重新绘制背景图像 #3.5 在游戏循环中监听事件 # ·事件 event #       ·就是游戏启动后,用户针对游戏所做的操作 #       ·例如:点击关闭按钮,点击鼠标,按下键盘 # ·监听 #       ·在游戏循环中,判断用户具体的操作(只有捕获到用户具体的操作,才能有针对性的做出相应) # ·实现 #       ·pygame中通过pygame.event.get()可以获得用户当前所做动作的事件列表 #04. 理解精灵和精灵组 #4.1 精灵和精灵组 # ·为了简化开发步骤,pygame提供了两个类 #       1.pygame.sprite.Sprite -- 存储图像数据image和位置rect的对象 #       2.pygame.sprite.Group # ·精灵 #       image    记录图像数据 #       rect     记录在屏幕上的位置 #       update(*args): 更新精灵位置 #       kill():        从所有组中删除 # ·精灵组 #       __init__(self, *精灵): #       add(*sprites):    向组中增加精灵 #       sprites():        返回所有精灵列表 #       upadte(*args):    让组中所有精灵调用update方法 #       draw(Surface):    将组中所有精灵的image,绘制到Surface的rect位置 #4.2 派生精灵子类 # ·定义如下GameSprite继承自pygame.sprite.Sprite # ·GameSprite #       image       精灵图像,使用image_name加载 #       rect        精灵大小,默认使用图像大小 #       speed       精灵移动速度,默认为1 #       __init————(self, image_name, speed=1): #       update(self):       每次更新屏幕时在游戏循环内调用,让精灵的self.rect.y += self.speed # ·注意 #       ·在重写初始化方法时,一定要先super()一下父类的__int__方法 #       ·进而保证父类中实现的__init__代码能够被正常执行 # ·提示 #       ·image的get_rect()方法,可以返回pygame.Rect(0, 0, 图像宽, 图像高)的对象 #4.3 使用游戏精灵和精灵组创建敌机 # ·精灵 #       ·封装image,rect,speed #       ·提供update()方法,根据游戏需求,更新位置rect # ·精灵组 #       ·包含多个精灵组 #       ·update方法,让精灵组中的所有精灵调用update方法更新位置 #       ·draw(screen)方法,在screen上绘制精灵组中的所有精灵 # 游戏框架搭建 #01. 明确主程序职责 # ·游戏主程序主要负责: #       1.游戏的初始化 #       2.游戏循环 # ·设计PlaneGame类 #       screen #       clock #       精灵或精灵组 # -------------------------- #       __init__(self): #       __create_sprites(self): #       start_game(self): #       __event_handle(self): #       __check_collide(self): #       __update_sprites(self): #       __game_over(): #02. 实现飞机大战主游戏类 # ·plane_main #       1.封装主游戏类 #       2.创建游戏对象 #       3.启动游戏 # ·plane_sprites #       1.封装游戏中所有需要使用的精灵类 #       2.提供游戏的相关工具 # ·常量 #       常量的命名应该所有字母都使用大写,单词和单词之间使用下划线连接 # 背景图像 #01. 背景交替滚动的思路确定 #02. 设计背景类 # ·由GameSprite继承而来 #       Background #           __init__(self, is_alt): #           update(self): # ·初始化方法 #       1.直接指定背景图片 #       2.is_alt判断是否是另一张图 # ·update()方法 #       ·判断是否移动出屏幕,如果是,将图像设置到屏幕的正上方,从而实现交替滚动 # 敌机出场 #01. 使用定时器添加敌机 # ·定时器 #       pygame.time.set_timer(eventid, milliseconds) -> None #       ·set_timer可以创建一个事件 # ·定时器事件的监听 #       通过pygame.event.get()可以获得当前时刻所有的时间列表 #       遍历判断event.type是否等于eventid #1.1 定义并监听创建敌机的定时器事件 # ·步骤 #       1.定义定时器常量 -- eventid #       2.在初始化方法中,调用set_timer方法设置定时器时间 #       3.在游戏循环中,监听定时器事件 #02. 设计敌机类 # ·Enemy(GameSprite) #       __init__(self): #       update(self): # ·初始化方法 #       ·指定敌机图片 #       ·随机敌机的初始位置和初始速度 # ·重写update方法 #       ·判断是否飞出屏幕,如果是,从精灵组删除 #2.1 创建敌机 # ·在__create_sprites中创建敌机精灵组 # ·在__event_handler中创建敌机,并且添加到精灵组 # ·在__update_sprites中调用update和draw #2.2 随机敌机位置和速度 # ·import random #2.3 移出屏幕销毁敌机 # ·从敌机组删除 # 英雄登场 #01. 设计英雄和子弹类 # ·Hero -- 英雄 #   ·初始化方法 #       ·指定英雄图片 #       ·初始速度 = 0 -- 英雄默认静止不动 #       ·定义bullets子弹精灵组保存子弹精灵 #   ·重写update()方法 #       ·英雄需要水平移动 #       ·并且需要保证不能移出屏幕 #   ·增加bullets属性,记录所有子弹精灵 #   ·增加fire方法,用于发射子弹 #--------------------------------- #   Hero(GameSprite) #       bulltes #       __init__(self): #       update(self): #       fire(self): #--------------------------------- #   Bullet(GameSprite) #       __init__(self): #       update(self): #--------------------------------- #02. 绘制英雄 #03. 移动英雄位置(键盘按键的捕获) # ·方式一(单次按键) #       if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT: # ·方式二(支持连按) #       keys_pressed = pygame.key.get_pressed() #       if keys_pressed[pygame.K_RIGHT]: #           print("向右移动...") #04. 发射子弹 #4.1 添加发射子弹事件 # ·使用定时器完成子弹事件 #4.2 定义子弹类 # ·Bullet -- 子弹 #   ·初始化方法 #       ·指定子弹图片 #       ·初始速度 = -2 -- 子弹需要向上飞行 #   ·重写update方法 #       ·判断是否飞出屏幕,如果是,从精灵组删除 #4.3 发射子弹 # ·步骤 #       1.在hero的初始化方法中创建子弹精灵组属性 #       2.修改plane_main.pyde __update_sprites方法,让子弹精灵组调用update和draw方法 #       3.实现fire方法 #           ·创建子弹精灵 #           ·设置初始位置 -- 在英雄的正上方 #           ·将子弹添加到精灵组 #碰撞检测 #01. 碰撞检测方法 #----------------------------------------------------------------------- # ·pygame.sprite.groupcollide() #       ·两个精灵组中的所有精灵的碰撞检测 #       groupcollide(group1, group2, dokill1, dokill2, collided = None) -> Sprite_dict #       ·如果将dokill设置为True,则发生碰撞的精灵将被自动移除 #       ·collided参数是用于计算碰撞的回调函数 #           ·如果没有指定,则每一个精灵必须有一个rect属性 #----------------------------------------------------------------------- # ·pygame.sprite.spritecollide() #       ·判断某个精灵和指定精灵组中的精灵的碰撞 #       spritecollide(sprite, group, dokill, collided = None) -> Sprite_list #-----------------------------------------------------------------------

然后祭出两个py文件:

文件1. plane_sprites.py

作用: 完成精灵类的编写

#plane_sprites.py import random import pygame # 屏幕大小的常量 SCREEN_RECT = pygame.Rect(0, 0, 480, 852) # 刷新的帧率 FRAME_PER_SEC = 60 # 创建敌机的定时器常量 CREATE_ENEMY_EVENT = pygame.USEREVENT # 英雄发射子弹事件 HERO_FIRE_EVENT = pygame.USEREVENT + 1 class GameSprite(pygame.sprite.Sprite): """飞机大战游戏精灵""" def __init__(self, image_name, speed=1): # 调用父类的初始化方法 super(GameSprite, self).__init__() # 定义对象的属性 self.image = pygame.image.load(image_name) self.rect = self.image.get_rect() self.speed = speed def update(self): # 在屏幕的垂直方向上移动 self.rect.y += self.speed class Background(GameSprite): """游戏背景精灵""" def __init__(self, is_alt=False): # 1. 调用父类方法实现精灵的创建(image,rect,speed) super().__init__(r".\Image\background.png") # 2. 判断是否是交替图像,如果是,需要设置初始位置 if is_alt: self.rect.y = -SCREEN_RECT.height def update(self): #1. 调用父类的方法实现 super().update() #2. 判断是否移动出屏幕,如果移动出,将图像设置到屏幕的上方 if self.rect.y >= SCREEN_RECT.height: self.rect.y = -self.rect.height class Enemy(GameSprite): """敌机精灵""" def __init__(self): #1. 调用父类方法,创建敌机精灵,同时指定敌机图片 super().__init__(r".\Image\small_enemy.png") #2. 指定敌机的初始随机速度 1 ~ 3 self.speed = random.randint(1, 3) #3. 指定敌机的初始随机位置 self.rect.x = random.randint(0, SCREEN_RECT.width - self.rect.width) #self.rect.y = -self.rect.height self.rect.bottom = 0 def update(self): #1. 调用父类方法,保持垂直方向的飞行 super().update() #2. 判断是否飞出屏幕,如果是,需要从精灵组删除敌机 if self.rect.y >= SCREEN_RECT.height: #print("飞出屏幕,需要从精灵组删除") self.kill() def __del__(self): #print("敌机挂了 %s" % self.rect) pass class Hero(GameSprite): """英雄精灵""" def __init__(self): #1. 调用父类方法,设置image和speed super().__init__(r".\Image\hero1.png", 0) #2. 设置英雄的初始位置 self.rect.centerx = SCREEN_RECT.centerx self.rect.bottom = SCREEN_RECT.bottom - 120 #3. 创建子弹的精灵组 self.bullets = pygame.sprite.Group() def update(self): # 用速度和英雄的x进行叠加 self.rect.x += self.speed # 控制英雄不能离开屏幕 if self.rect.x < 0: self.rect.x = 0 if self.rect.right > SCREEN_RECT.right: self.rect.right = SCREEN_RECT.right def fire(self): # 英雄发射子弹 print("突突突...") # 一次发射三颗子弹 for i in (0, 1, 2): #1. 创建子弹精灵 bullet = Bullet() #2. 设置精灵的位置 bullet.rect.bottom = self.rect.y - 20 * i bullet.rect.centerx = self.rect.centerx #3. 将精灵添加到精灵组 self.bullets.add(bullet) class Bullet(GameSprite): """子弹精灵""" def __init__(self): # 调用父类方法,设置子弹图片,设置初始速度 super().__init__(r".\Image\normal_bullet.png", -2) def update(self): # 调用父类方法,让子弹沿垂直方向飞行 super().update() # 判断子弹是否飞出屏幕 if self.rect.bottom < 0: self.kill() def __del__(self): print("子弹被销毁...")

文件2. plane_main.py

作用: 主程序(构建起程序框架)

#plane_main.py import pygame from plane_sprites import * class PlaneGame(object): """飞机大战主游戏""" def __init__(self): print("游戏初始化") #1. 创建游戏窗口 self.screen = pygame.display.set_mode(SCREEN_RECT.size) #2. 创建游戏的时钟 self.clock = pygame.time.Clock() #3. 调用私有方法,精灵和精灵组的创建 self.__create_sprites() #4. 设置定时器事件 -- 创建敌机 1s pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000) #5. 设置发射子弹事件 pygame.time.set_timer(HERO_FIRE_EVENT, 500) def __create_sprites(self): # 创建背景精灵和精灵组 bg1 = Background(False) bg2 = Background(True) self.back_group = pygame.sprite.Group(bg1, bg2) # 创建敌机的精灵组 self.enemy_group = pygame.sprite.Group() # 创建英雄的精和精灵组 self.hero = Hero() self.hero_group = pygame.sprite.Group(self.hero) def start_game(self): print("游戏开始...") while True: #1. 设置刷新帧率 self.clock.tick(FRAME_PER_SEC) #2. 事件监听 self.__event_handler() #3. 碰撞检测 self.__check_collide() #4. 更新/绘制精灵组 self.__update_sprites() #5. 更新显示 pygame.display.update() def __event_handler(self): for event in pygame.event.get(): # 判断是否退出游戏 if event.type == pygame.QUIT: PlaneGame.__game_over() elif event.type == CREATE_ENEMY_EVENT: #print("敌机出场...") # 创建敌机精灵 enemy = Enemy() # 将敌机精灵添加到敌机精灵组 self.enemy_group.add(enemy) elif event.type == HERO_FIRE_EVENT: self.hero.fire() #elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT: # print("向右移动...") # 使用键盘提供的方法获取键盘按键 - 按键元组 keys_pressed = pygame.key.get_pressed() # 判断元组中对应的按键索引值 if keys_pressed[pygame.K_RIGHT]: print("向右移动...") self.hero.speed = 2 elif keys_pressed[pygame.K_LEFT]: print("向左移动...") self.hero.speed = -2 else: self.hero.speed = 0 def __check_collide(self): #1. 子弹摧毁敌机 pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True) #2. 敌机撞毁英雄 enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True) # 判断列表enemies是否有内容 if len(enemies) > 0: #让英雄牺牲 self.hero.kill() #结束游戏 PlaneGame.__game_over() def __update_sprites(self): self.back_group.update() self.back_group.draw(self.screen) self.enemy_group.update() self.enemy_group.draw(self.screen) self.hero_group.update() self.hero_group.draw(self.screen) self.hero.bullets.update() self.hero.bullets.draw(self.screen) @staticmethod def __game_over(): print("游戏结束") pygame.quit() exit() if __name__ == '__main__': # 创建游戏对象 game = PlaneGame() # 启动游戏 game.start_game()

小小小demo编程实现效果:



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有