用python实战飞机大战
Pygame是一组专门编写游戏的python模块,具有高度的可移植性。下面将介绍Pygame中提供的方法,实现一个简单的飞机大战小demo,扫描下方二维码关注我的公众号中回复“飞机大战”,即可获取demo的代码地址、本demo素材(彩色图片素材、微信经典黑白素材、音效)
本文主要内容
- 通过例子示范窗口绘制及其所需函数简要说明
- 图片移动、通过用户事件移动图片及所需函数简要说明
- 碰撞检测及所需函数简要说明
- 音频加载及所需函数简要说明
- 成果展示
环境
- python3.6+
- windows/linux
模块安装
pip install pygame
游戏窗口建立及所需函数简要说明
import os
import time
import pygame# 屏幕宽度
SCREEN_WIDTH = 500
# 屏幕高度
SCREEN_HEIGHT = 250
# 图片绝对路径
IMG_PATH = os.path.join(os.getcwd(), "img")def main():# 初始化显示模块pygame.display.init()# 创建窗口screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))# 设置窗口标题pygame.display.set_caption("python小demo 飞机大战")# 设置窗口iconpygame.display.set_icon(pygame.image.load(os.path.join(IMG_PATH, "icon.jpg")))# 加载背景图片background = pygame.image.load(os.path.join(IMG_PATH, "test_bj.png"))while True:# 将背景图片绘制到窗口上screen.blit(background, (0, 0))# 更新屏幕上内容pygame.display.update()time.sleep(0.02)if __name__ == "__main__":main()
查看下效果:
x、y是我手动绘制的,让大家可以更加直观的看到窗口坐标轴情况
所需函数简要说明
- pygame.display pygame用来控制屏幕和窗口
display.init() -> None
# 该函数只做初始化显示模块,且不返回任何东西
# 如果在使用display其他方法未初始化,会自动调用display.set_mode(size=(0, 0), flags=0, depth=0, display=0, vsync=0) -> Surface
# 该函数会创建并返回一个Surface的窗口对象
# 参数:
# size=(0, 0) 设置窗口大小,第一个是屏幕宽度,第二个是窗口高度
# flags 控制您想要的显示类型,例如是否全屏,可选参数:
# pygame.FULLSCREEN:创建一个全屏
# pygame.DOUBLEBUF:双缓冲模式,推荐和HWSURFACE或OPENGL一起使用
# pygame.HWSURFACE:硬件加速,只有在 FULLSCREEN 下可以使用
# pygame.OPENGL:创建一个 OPENGL 渲染的显示
# pygame.RESIZABLE:创建一个可调整尺寸的窗口
# pygame.NOFRAME:创建一个没有边框和控制按钮的窗口
# 可以使用按位或选择多个参数,如:
# flags = pygame.OPENGL | pygame.FULLSCREEN
# depth 参数表示颜色位数,不建议传递,默认会选择最佳的颜色深度
# display 窗口索引,默认0
# vsync 传入1时,可以获得垂直同步显示,只有同时设置了pygame.OPENGL、
# pygame.FULLSCREEN才能传值display.set_caption(title, icontitle=None) -> None
# 设置窗口标题
# 参数:
# title 窗口的标题
# icontitle 部分系统支持最小窗口时切换标题栏display.set_icon(Surface) -> None
# 设置窗口LOGO
# 参数:
# Surface 可以传入任何Surface对象作为图标,但大多数系统要求大小是32*32display.update(rectangle=None) -> None
display.update(rectangle_list) -> None
# 更新屏幕内容显示,如果设置了pygame.OPENGL情况下调用,会触发异常
# 参数:
# rectangle 一个矩形区域
# rectangle_list 多个矩形区域
# 如果传入None或者空列表,就会更新整个窗口
- pygame.image pygame用于传输图像模块
image.load(filename) -> Surface
# 加载图像,返回一个Surface对象,pygame支持常见PNG、JPG、GIF等格式图片
#参数:
# filename 图片路径,兼容运行环境,路径建议通过os.path.join()获取
- pygame.Surface pygame用于表示图片的模块
Surface.blit(source, dest, area=None, special_flags=0) -> Rect
# 将图像绘制到另外一个图像上,返回值是一个Rect对象,表示在screen上绘制的矩形区域
# 参数:
# source 矩形图像的Surface实例对象
# dest 是坐标对象,绘制在屏幕的坐标
# area 表示从scorce的area区域取出绘制的到Surface对象上
# 结合上面例子
# background = pygame.image.load(os.path.join(IMG_PATH, "test_bj.png"))
# screen.blit(background, (0, 0))
# 就是将background图片绘制到screen屏幕的0, 0坐标处Surface.get_rect(**kwargs) -> Rect
# 获取Surface的矩形区域,该矩形区域始终从坐标0, 0开始,宽度和高度与图片大小相同
# 返回一个rect对象,rect对象记录着Surface的属性信息,如:
# rect.x Surface对象x轴坐标
# rect.y Surface对象y轴坐标
# rect.width Surface对象的宽度
# rect.height Surface对象的高度
图片移动、通过用户事件移动图片
上面代码已经能够建立游戏窗口和加载背景图,现在创建英雄,通过改变坐标实现移动
import os
import time
import pygame# 屏幕宽度
SCREEN_WIDTH = 500
# 屏幕高度
SCREEN_HEIGHT = 250
# 图片绝对路径
IMG_PATH = os.path.join(os.getcwd(), "img")class HeroPlane(object):def __init__(self):super(HeroPlane, self).__init__()self.image = pygame.image.load(os.path.join(IMG_PATH, "hero_show_1.png"))self.rect = self.image.get_rect()self.rect.x = 0 # 飞机x轴位置self.rect.y = int(SCREEN_HEIGHT - self.rect.height) / 2 # 飞机y轴位置self.is_running = Trueself.bullet_list = pygame.sprite.Group()self.last_time = time.time()def move_level(self, level):# 防止飞机移出屏幕外, 增加判断add_level = self.rect.x + levelif 0 <= add_level <= SCREEN_WIDTH - self.rect.width:self.rect.x = add_levelelif add_level < 0:self.rect.x = 0elif add_level > SCREEN_WIDTH - self.rect.width:self.rect.x = SCREEN_WIDTH - self.rect.widthdef move_vertical(self, vertical):add_vertical = self.rect.y + verticalif 0 <= add_vertical <= SCREEN_HEIGHT - self.rect.height:self.rect.y = add_verticalelif add_vertical < 0:self.rect.y = 0elif add_vertical > SCREEN_HEIGHT - self.rect.height:self.rect.y = SCREEN_HEIGHT - self.rect.heightdef main():pygame.display.init()# 初始化显示模块# pygame.display.init()# 创建窗口screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))# 设置窗口标题pygame.display.set_caption("python小demo 飞机大战")# 设置窗口iconpygame.display.set_icon(pygame.image.load(os.path.join(IMG_PATH, "icon.jpg")))# 加载背景图片background = pygame.image.load(os.path.join(IMG_PATH, "test_bj.png"))# 初始化英雄类hero = HeroPlane()def update_hero():hero.move_level(2)screen.blit(hero.image, (hero.rect.x, hero.rect.y))while True:# 将背景图片绘制到窗口上screen.blit(background, (0, 0))# 更新英雄在屏幕上的位置update_hero()# 更新屏幕上内容pygame.display.update()time.sleep(0.02)if __name__ == "__main__":main()
执行效果如下:
上面加载英雄并且实现英雄移动,其实就是不断改变图片在屏幕中的绘制位置。主函数的time.sleep也可以替换成pygame.time.Clock.tick方法,但本例子中,效果偏差不远,就没有使用pygame.time提供的时间模块
上面代码虽然能够实现英雄的移动,但是无法根据玩家操作控制英雄的移动,这时候我们就需要提供特定的键盘或者鼠标事件控制英雄移动,下面示例按住鼠标实现飞机移动
import os
import sys
import time
import pygame# 屏幕宽度
SCREEN_WIDTH = 500
# 屏幕高度
SCREEN_HEIGHT = 250
# 图片绝对路径
IMG_PATH = os.path.join(os.getcwd(), "img")
# 鼠标按键标识
MOUSE_MOVE = Falseclass HeroPlane(object):def __init__(self):super(HeroPlane, self).__init__()self.image = pygame.image.load(os.path.join(IMG_PATH, "hero_show_1.png"))self.rect = self.image.get_rect()self.rect.x = 0 # 飞机x轴位置self.rect.y = int(SCREEN_HEIGHT - self.rect.height) / 2 # 飞机y轴位置self.is_running = Trueself.bullet_list = pygame.sprite.Group()self.last_time = time.time()def move_level(self, level):# 防止飞机移出屏幕外, 增加判断if 0 <= level <= SCREEN_WIDTH - self.rect.width:self.rect.x = levelelif level < 0:self.rect.x = 0elif level > SCREEN_WIDTH - self.rect.width:self.rect.x = SCREEN_WIDTH - self.rect.widthdef move_vertical(self, vertical):if 0 <= vertical <= SCREEN_HEIGHT - self.rect.height:self.rect.y = verticalelif vertical < 0:self.rect.y = 0elif vertical > SCREEN_HEIGHT - self.rect.height:self.rect.y = SCREEN_HEIGHT - self.rect.heightdef main():pygame.init()# 初始化显示模块pygame.display.init()# 创建窗口screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))# 设置窗口标题pygame.display.set_caption("python小demo 飞机大战")# 设置窗口iconpygame.display.set_icon(pygame.image.load(os.path.join(IMG_PATH, "icon.jpg")))# 加载背景图片background = pygame.image.load(os.path.join(IMG_PATH, "test_bj.png"))# 初始化英雄类hero = HeroPlane()def event_check():"""事件检测,这边做了一个简单的示例return:"""global MOUSE_MOVEfor event in pygame.event.get():if event.type == pygame.QUIT:# 接收到退出事件后退出程序pygame.quit()sys.exit()elif event.type == pygame.MOUSEBUTTONDOWN:MOUSE_MOVE = Trueelif event.type == pygame.MOUSEBUTTONUP:MOUSE_MOVE = Falseif MOUSE_MOVE:x, y = pygame.mouse.get_pos()hero.move_level(x)hero.move_vertical(y)def update_hero():screen.blit(hero.image, (hero.rect.x, hero.rect.y))while True:# 事件检测event_check()# 将背景图片绘制到窗口上screen.blit(background, (0, 0))# 更新英雄在屏幕上的位置update_hero()# 更新屏幕上内容pygame.display.update()time.sleep(0.02)if __name__ == "__main__":main()
执行效果如下:
所需函数简要说明
- pygame.event用于监听玩家事件,如按下键盘、点击鼠标等
event.get(eventtype=None) -> Eventlist
event.get(eventtype=None, pump=True) -> Eventlist
# 获取事件队列
# 参数:
# eventtype 可以传入你想要监听到的事件列表,如果不传,会把所有用户触发的事件返回
# 如上面示例中只监听了三个事件,也可以:
# pygame.event.get([pygame.QUIT, pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP])
# 但如果设置了指定类型事件,其他事件将不会被获取,存在了事件队列中中,有可能导致事件队列被堆满
# pump 默认为False,如果设置为True,event.pump()将会被调用
# 返回事件列表
# 常见事件类型:
# 事件 产生途径 参数
# QUIT 用户按下关闭按钮 none
# KEYDOWN 键盘被按下 unicode, key, mod
# KEYUP 键盘被放开 key, mod
# MOUSEMOTION 鼠标移动 pos, rel, buttons
# MOUSEBUTTONDOWN 鼠标按下 pos, button
# MOUSEBUTTONUP 鼠标放开 pos, button
# USEREVENT 用户自定义事件 code
# 上面列举了常见的事件,更多事件和方法可以点击上面文档链接查阅文档
- pygame.key用于处理键盘的模块,当键盘按下或者释放时,pygame.event.get()就能获取pygame.KEYDOWN或pygame.KEYUP事件,这两个事件都有key和mod属性:key代表键盘上每个整数ID;mod代表事件发生时修饰建位掩码。
上述例子中,如果想通过长按键盘⬅、⬆、⬇、➡控制英雄,可将事件处理函数修改为:
def event_check():"""事件检测,这边做了一个简单的示例return:"""# 设置KEYDOWN标志位,0代表键盘已释放,1、2、3、4分别代表⬅、⬆、⬇、➡global KEYDOWNfor event in pygame.event.get():if event.type == pygame.QUIT:# 接收到退出事件后退出程序pygame.quit()sys.exit()elif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:KEYDOWN = 1elif event.key == pygame.K_UP:KEYDOWN = 2elif event.key == pygame.K_DOWN:KEYDOWN = 3elif event.key == pygame.K_RIGHT:KEYDOWN = 4elif event.type == pygame.KEYUP:KEYDOWN = 0if KEYDOWN:if KEYDOWN == 1:hero.move_level(hero.rect.x - 5)elif KEYDOWN == 2:hero.move_vertical(hero.rect.y - 5)elif KEYDOWN == 3:hero.move_vertical(hero.rect.y + 5)else:hero.move_level(hero.rect.x + 5)
下面列举常见的键盘常量(更多键盘常量可点击上方链接查阅文档):
KeyASCII | 描述 |
---|---|
K_BACKSPACE | 退格键(Backspace) |
K_TAB | 制表键(Tab) |
K_CLEAR | 清除键(Clear) |
K_RETURN | 回车键(Enter) |
K_ESCAPE | 退出键(Escape) |
K_DELETE | 删除键(delete) |
K_0 - K_9 | 0 - 9 |
K_a - K_z | a - z |
K_KP0 - K_KP9 | 0 - 9(小键盘) |
K_UP | 向上箭头(up arrow) |
K_DOWN | 向下箭头(down arrow) |
K_RIGHT | 向右箭头(right arrow) |
K_LEFT | 向左箭头(left arrow) |
碰撞检测及所需函数简要说明
上面代码中,已经实现创建英雄,并且能通过事件去控制英雄的移动,下面我们可以按照创建英雄的方法,创建一个敌机,并通过让英雄与敌机碰撞发生爆炸
import os
import sys
import time
import pygame# 屏幕宽度
SCREEN_WIDTH = 500
# 屏幕高度
SCREEN_HEIGHT = 250
# 图片绝对路径
IMG_PATH = os.path.join(os.getcwd(), "img")
# 鼠标按键标识
MOUSE_MOVE = False
# 键盘长按标识位
KEYDOWN = 0class HeroPlane(object):def __init__(self):super(HeroPlane, self).__init__()self.image = pygame.image.load(os.path.join(IMG_PATH, "hero_show_1.png"))self.rect = self.image.get_rect()self.rect.x = 0 # 飞机x轴位置self.rect.y = int(SCREEN_HEIGHT - self.rect.height) / 2 # 飞机y轴位置self.is_running = Truedef move_level(self, level):# 防止飞机移出屏幕外, 增加判断if 0 <= level <= SCREEN_WIDTH - self.rect.width:self.rect.x = levelelif level < 0:self.rect.x = 0elif level > SCREEN_WIDTH - self.rect.width:self.rect.x = SCREEN_WIDTH - self.rect.widthdef move_vertical(self, vertical):if 0 <= vertical <= SCREEN_HEIGHT - self.rect.height:self.rect.y = verticalelif vertical < 0:self.rect.y = 0elif vertical > SCREEN_HEIGHT - self.rect.height:self.rect.y = SCREEN_HEIGHT - self.rect.heightclass EnemyPlane(pygame.sprite.Sprite):def __init__(self):super(EnemyPlane, self).__init__()self.image = pygame.image.load(os.path.join(IMG_PATH, "mp_show_3.png"))self.rect = self.image.get_rect()self.rect = self.image.get_rect()self.rect.x = int(SCREEN_WIDTH - self.rect.width) # 飞机x轴位置self.rect.y = int(SCREEN_HEIGHT - self.rect.height) / 2 # 飞机y轴位置self.is_running = Truedef main():pygame.init()# 初始化显示模块pygame.display.init()# 创建窗口screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))# 设置窗口标题pygame.display.set_caption("python小demo 飞机大战")# 设置窗口iconpygame.display.set_icon(pygame.image.load(os.path.join(IMG_PATH, "icon.jpg")))# 加载背景图片background = pygame.image.load(os.path.join(IMG_PATH, "test_bj.png"))# 初始化英雄hero = HeroPlane()# 初始化敌机enemy = EnemyPlane()def event_check():"""事件检测,这边做了一个简单的示例return:"""global MOUSE_MOVEfor event in pygame.event.get():if event.type == pygame.QUIT:# 接收到退出事件后退出程序pygame.quit()sys.exit()elif event.type == pygame.MOUSEBUTTONDOWN:MOUSE_MOVE = Trueelif event.type == pygame.MOUSEBUTTONUP:MOUSE_MOVE = Falseif MOUSE_MOVE:x, y = pygame.mouse.get_pos()hero.move_level(x)hero.move_vertical(y)# def event_check():# """# 事件检测,这边做了一个简单的示例# return:# """# # 设置KEYDOWN标志位,0代表键盘已释放,1、2、3、4分别代表⬅、⬆、⬇、➡# global KEYDOWN## for event in pygame.event.get():# if event.type == pygame.QUIT:# # 接收到退出事件后退出程序# pygame.quit()# sys.exit()# elif event.type == pygame.KEYDOWN:# if event.key == pygame.K_LEFT:# KEYDOWN = 1# elif event.key == pygame.K_UP:# KEYDOWN = 2# elif event.key == pygame.K_DOWN:# KEYDOWN = 3# elif event.key == pygame.K_RIGHT:# KEYDOWN = 4# elif event.type == pygame.KEYUP:# KEYDOWN = 0## if KEYDOWN:# if KEYDOWN == 1:# hero.move_level(hero.rect.x - 5)# elif KEYDOWN == 2:# hero.move_vertical(hero.rect.y - 5)# elif KEYDOWN == 3:# hero.move_vertical(hero.rect.y + 5)# else:# hero.move_level(hero.rect.x + 5)def update_hero():screen.blit(hero.image, (hero.rect.x, hero.rect.y))def update_enemy():screen.blit(enemy.image, (enemy.rect.x, enemy.rect.y))def check_crash():is_crash = pygame.sprite.collide_rect(hero, enemy)if is_crash:# 先展示飞机爆炸,然后在屏幕中间写下game over提示screen.blit(pygame.image.load(os.path.join(IMG_PATH, "ex_2.png")), (hero.rect.x, hero.rect.y))screen.blit(pygame.image.load(os.path.join(IMG_PATH, "ex_2.png")), (enemy.rect.x, enemy.rect.y))game_over = pygame.font.Font(None, 100)game_over = game_over.render("game over", True, (220, 20, 60))screen.blit(game_over, [int(SCREEN_WIDTH / 2 - game_over.get_width() / 2), int(SCREEN_HEIGHT / 2)])while True:# 事件检测event_check()# 将背景图片绘制到窗口上screen.blit(background, (0, 0))# 更新英雄在屏幕上的位置update_hero()# 更新敌机在屏幕上位置update_enemy()# 碰撞检测check_crash()# 更新屏幕上内容pygame.display.update()time.sleep(0.02)if __name__ == "__main__":main()
执行效果如下:
所需函数简要说明
- pygame.sprite 基本游戏对象类,上面例子中,我们英雄跟敌机都继承了pygame.sprite.Sprite,这是方便我们省略了造轮子的步骤,比如碰撞检测。
sprite.collide_rect(left, right) -> bool
# 检测两个继承了pygame.sprite.Sprite且具有矩形区域属性的对象是否发生了碰撞
# 该方法会根据对象的rect属性判断是否发生了碰撞
# 参数:
# left 第一个对象,如hero
# right 第二个对象,如hero
# 返回bool值, 真为发生碰撞,假为没有碰撞# 该示例中,只有一架敌机和一架英雄,但如果需要英雄与多架敌机发生碰撞
# 或者英雄发出的子弹是否击中了敌机,这就产生了一对多、多对多的检测
# 这种情况可以使用sprite.Group来完成该方法sprite.Group() -> Group
# 用于保存和管理多个 Sprite 对象的容器类
# 返回一个组对象
sprite.Group.add(*sprites) -> None
# 增加一个sprites到该组中sprite.spritecollide(sprite, group, dokill, collided = None) -> Sprite_list
# 查找一个sprite是否与sprite.Group()中的sprite发生碰撞
# 用于一对多的碰撞检测
# 参数:
# sprite 单个sprite对象
# group 一个包含多个sprite对象的组对象
# dokill bool值,如果为真,发生碰撞时,将碰撞的sprite对象从组中移除
# collided 是一个判断碰撞的函数,参数为两个sprite对象,并且需要返回bool值,如果你的
# sprite对象也有像例子中设置了rect属性,可以不传
# 返回所有和sprite发生碰撞的对象,如果没有,返回空Sprite_listsprite.groupcollide(group1, group2, dokill1, dokill2, collided = None) -> Sprite_dict
# 查找两组中所有碰撞的Sprite对象
# 用于实现多对多碰撞检测
# 参数:
# group1 第一个sprite对象的组对象
# group2 第二个sprite对象的组对象
# dokill1 bool值,如果为真,发生碰撞时,将碰撞的sprite对象从第一个组中移除
# dokill2 bool值,如果为真,发生碰撞时,将碰撞的sprite对象从第二个组中移除
# collided 是一个判断碰撞的函数,参数为两个sprite对象,并且需要返回bool值,如果你的
# sprite对象也有像例子中设置了rect属性,可以不传
# 返回一个Sprite_dict对象,类似于:
# {<group1 Sprite(in 1 groups)>: [<group2 Sprite(in 1 groups)>]}
# key 是group1 碰撞列表, value是group2碰撞列表# 上面列举了本例需要的函数,更多使用方法可以点击上面文档链接查阅文档
- pygame.font 用于加载和渲染字体
font.Font(filename, size) -> Font
font.Font(object, size) -> Font
# 从给定的文件名或者python的文件对象加载新字体
# 参数:
# filename 文件路径字符串,如os.path.join('fonts', 'ziti.ttf')
# object python文件对象
# 如果第一个参数传None,会使用默认字体
# size 整数类型,字体大小
# 返回一个Font对象font.Font.render(text, antialias, color, background=None) -> Surface
# 创建一个新的 Surface,其上呈现了指定的文本,该方法只能写一行文字,不呈现换行,空字符串会引发异常
# 参数:
# text 要展示的文本
# antialias bool值,如果为真,字符将有平滑的边缘
# color 字体颜色 RGB值
# background 用于文本背景颜色,如果没有传递,背景色是透明色# 上面列举了本例需要的函数,更多使用方法可以点击上面文档链接查阅文档
音频加载及所需函数简要说明
import os
import sys
import time
import pygame# 屏幕宽度
SCREEN_WIDTH = 500
# 屏幕高度
SCREEN_HEIGHT = 250
# 图片绝对路径
IMG_PATH = os.path.join(os.getcwd(), "img")
# 鼠标按键标识
MOUSE_MOVE = False
# 键盘长按标识位
KEYDOWN = 0
# 背景音乐路径
MUSIC_PATH = os.path.join(os.getcwd(), "sound")class HeroPlane(pygame.sprite.Sprite):def __init__(self):super(HeroPlane, self).__init__()self.image = pygame.image.load(os.path.join(IMG_PATH, "hero_show_1.png"))self.rect = self.image.get_rect()self.rect.x = 0 # 飞机x轴位置self.rect.y = int(SCREEN_HEIGHT - self.rect.height) / 2 # 飞机y轴位置self.is_running = Truedef move_level(self, level):# 防止飞机移出屏幕外, 增加判断if 0 <= level <= SCREEN_WIDTH - self.rect.width:self.rect.x = levelelif level < 0:self.rect.x = 0elif level > SCREEN_WIDTH - self.rect.width:self.rect.x = SCREEN_WIDTH - self.rect.widthdef move_vertical(self, vertical):if 0 <= vertical <= SCREEN_HEIGHT - self.rect.height:self.rect.y = verticalelif vertical < 0:self.rect.y = 0elif vertical > SCREEN_HEIGHT - self.rect.height:self.rect.y = SCREEN_HEIGHT - self.rect.heightclass EnemyPlane(pygame.sprite.Sprite):def __init__(self):super(EnemyPlane, self).__init__()self.image = pygame.image.load(os.path.join(IMG_PATH, "mp_show_3.png"))self.rect = self.image.get_rect()self.rect = self.image.get_rect()self.rect.x = int(SCREEN_WIDTH - self.rect.width) # 飞机x轴位置self.rect.y = int(SCREEN_HEIGHT - self.rect.height) / 2 # 飞机y轴位置self.is_running = Truedef main():pygame.init()# 初始化显示模块pygame.display.init()# 创建窗口screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))# 设置窗口标题pygame.display.set_caption("python小demo 飞机大战")# 设置窗口iconpygame.display.set_icon(pygame.image.load(os.path.join(IMG_PATH, "icon.jpg")))# 加载背景图片background = pygame.image.load(os.path.join(IMG_PATH, "test_bj.png"))# 初始化英雄hero = HeroPlane()# 初始化敌机enemy = EnemyPlane()# 加载背景音乐并播放pygame.mixer.init()pygame.mixer.music.load(os.path.join(MUSIC_PATH, "game_music.ogg"))pygame.mixer.music.play(loops=-1)def event_check():"""事件检测,这边做了一个简单的示例return:"""global MOUSE_MOVEfor event in pygame.event.get():if event.type == pygame.QUIT:# 接收到退出事件后退出程序pygame.quit()sys.exit()elif event.type == pygame.MOUSEBUTTONDOWN:MOUSE_MOVE = Trueelif event.type == pygame.MOUSEBUTTONUP:MOUSE_MOVE = Falseif MOUSE_MOVE:x, y = pygame.mouse.get_pos()hero.move_level(x)hero.move_vertical(y)# def event_check():# """# 事件检测,这边做了一个简单的示例# return:# """# # 设置KEYDOWN标志位,0代表键盘已释放,1、2、3、4分别代表⬅、⬆、⬇、➡# global KEYDOWN## for event in pygame.event.get():# if event.type == pygame.QUIT:# # 接收到退出事件后退出程序# pygame.quit()# sys.exit()# elif event.type == pygame.KEYDOWN:# if event.key == pygame.K_LEFT:# KEYDOWN = 1# elif event.key == pygame.K_UP:# KEYDOWN = 2# elif event.key == pygame.K_DOWN:# KEYDOWN = 3# elif event.key == pygame.K_RIGHT:# KEYDOWN = 4# elif event.type == pygame.KEYUP:# KEYDOWN = 0## if KEYDOWN:# if KEYDOWN == 1:# hero.move_level(hero.rect.x - 5)# elif KEYDOWN == 2:# hero.move_vertical(hero.rect.y - 5)# elif KEYDOWN == 3:# hero.move_vertical(hero.rect.y + 5)# else:# hero.move_level(hero.rect.x + 5)def update_hero():screen.blit(hero.image, (hero.rect.x, hero.rect.y))def update_enemy():screen.blit(enemy.image, (enemy.rect.x, enemy.rect.y))def check_crash():is_crash = pygame.sprite.collide_rect(hero, enemy)if is_crash:# 先展示飞机爆炸,然后在屏幕中间写下game over提示screen.blit(pygame.image.load(os.path.join(IMG_PATH, "ex_2.png")), (hero.rect.x, hero.rect.y))screen.blit(pygame.image.load(os.path.join(IMG_PATH, "ex_2.png")), (enemy.rect.x, enemy.rect.y))pygame.mixer.Sound(os.path.join(MUSIC_PATH, "enemy1_down.wav")).play()game_over = pygame.font.Font(None, 100)game_over = game_over.render("game over", True, (220, 20, 60))screen.blit(game_over, [int(SCREEN_WIDTH / 2 - game_over.get_width() / 2), int(SCREEN_HEIGHT / 2)])while True:# 事件检测event_check()# 将背景图片绘制到窗口上screen.blit(background, (0, 0))# 更新英雄在屏幕上的位置update_hero()# 更新敌机在屏幕上位置update_enemy()# 碰撞检测check_crash()# 更新屏幕上内容pygame.display.update()time.sleep(0.02)if __name__ == "__main__":main()
由于博客视频条件限制,这儿就不放效果了,感兴趣的朋友可以拉下我的代码体验下
所需函数简要说明
- pygame.mixer 用于加载和播放音频
mixer.init(frequency=44100,size=-16,channels=2,buffer=512,devicename=None,allowedchanges=AUDIO_ALLOW_FREQUENCY_CHANGE | AUDIO_ALLOW_CHANNELS_CHANGE
) -> None
# 初始化mixer模块以进行声音加载和播放。可以重写默认参数以提供特定的音频混合
# 参数:
# frequency pygame 2.0.0+时,范围44100-22050
# size 表示每个音频样本使用了多少位。如果是负值,则使用带符号的样本值,无效值会触发异常,2.0.0后可以是32
# channels 指定使用单声道还是立体音,1为单声道,2为立体音, 2.0.0后可以是4或者6
# buffer 控制声音混合器mixer中使用的内部样本数,默认值应适用于大多数情况
# allowedchanges 当allowedchanges=0,将在运行时转换示例以匹配硬件支持的内容,allowedchanges也支持:
# AUDIO_ALLOW_FREQUENCY_CHANGE
# AUDIO_ALLOW_FORMAT_CHANGE
# AUDIO_ALLOW_CHANNELS_CHANGE
# AUDIO_ALLOW_ANY_CHANGEmixer.music.load(filename) -> None
mixer.music.load(object) -> None
# 将加载音乐文件/或者音乐文件对象并准备播放,如果音乐已经播放,调用则会停止mixer.music.play(loops=0, start=0.0, fade_ms = 0) -> None
# 播放已经加载的音乐流,如果已经在播放时调用,则会重新播放
# 参数:
# loops 可选整数参数,表示重复播放次数,设置为-1表示无限重复
# start 可选浮点数,表示开始播放音乐时间的位置,起始位置决定于音乐格式
# fade_ms 可选整数参数,大于0时,在给定的fade_ms内逐渐加大音量pygame.mixer.Sound(filename) -> Sound
pygame.mixer.Sound(buffer) -> Sound
# 从文件或者缓冲区创建一个新的文件对象
pygame.mixer.Sound.play(loops=0, maxtime=0, fade_ms=0) -> Channel
# 开始在可用的频道上播放声音,播放时可能在必要时切断正在播放的声音
# 在本例中,调用该方法产生爆炸音效并不会影响背景音乐的播放
# 参数:
# loops 可选整数参数,表示重复播放次数,设置为-1表示无限重复
# maxtime 大于零时,在给定的maxtime停止播放(毫秒)
# fade_ms 可选整数参数,大于0时,在给定的fade_ms内逐渐加大音量
# 返回所选的通道对象# 上面列举了本例需要的函数,更多使用方法可以点击上面文档链接查阅文档
python小demo 飞机大战完整例子
在上面,大致示范了使用pygame写一个飞机大战所需模块及函数,本人也写了一个示例,包括本推文中所使用的代码都提交至github,在公众号中回复“飞机大战”即可获取源码地址,及图片素材、音频素材,下面看下我例子图片:
用python实战飞机大战相关推荐
- python项目实战—飞机大战
项目实战-飞机大战 创建游戏主窗口 pygame专门提供了一个模块Pygame.display用于创建.管理游戏窗口 方法 说明 pygame.display.set_mode() 初始化游戏显示窗口 ...
- python写飞机大战游戏_python实现飞机大战游戏
飞机大战(Python)代码分为两个python文件,工具类和主类,需要安装pygame模块,能完美运行(网上好多不完整的,调试得心累.实现出来,成就感还是满满的),如图所示: 完整代码如下: 1.工 ...
- 小甲鱼python游戏代码_【小甲鱼】零基础学习python pygame 飞机大战可执行源代码...
[实例简介] [小甲鱼]零基础学习python pygame 飞机大战可执行源代码,觉得挺有意思,故此分享. [实例截图] [核心代码] 飞机大战 └── 飞机大战 ├── bullet.py ├── ...
- python的飞机大战
python的飞机大战的完整代码 alien.py import pygame from pygame.sprite import Sprite class Alien(Sprite):"& ...
- python实现飞机大战游戏
python实现飞机大战小游戏(含源码+视频资源) 导语: 正文: 1.开发工具 2.环境搭建 3.效果如下 Step1:定义精灵类 Step2:实现游戏主循环 Step3:制作简易的游戏开始和结束界 ...
- python制作飞机大战游戏准备工作相关知识点
python制作飞机大战游戏准备工作相关知识点 1.初始化背景 `import pygame` : 导入pygame模块 `pygame.init()` : 导入并初始化所有 `pygame` 模块, ...
- 用python做飞机大战打到不同部位扣分不同_python制作飞机大战需要哪些python术语...
怎么样用Python写飞机大战游戏 为什么写出来一直都是未响应,哪里写错了吗?就算小编们没能走到最后,小编也不会心存遗憾,你有你的苦辣酸甜,小编有小编的喜怒哀乐,如果小编们不曾相遇,就没有那些美好记忆 ...
- Python实现飞机大战-第二部分(附源码、素材、超详细教程)
飞机大战第二部分 1.前言 2.飞机射击 2.1.添加子弹的相关设置 2.2.创建文件bullet.py 2.3.修改game_functions.py 2.4.修改mian.py 2.5.射击效果 ...
- python版飞机大战
python版飞机大战 用python几百行代码搞定飞机大站游戏. 我们利用pygame包进行飞机大战的游戏开发,所以大家首先得安装好pygame包,本游戏一共封装了8个类,大家可以在GitHub上下 ...
最新文章
- DevExpress WinFormsSuite 本地化(Simplified Chinese OR Traditional Chinese)
- Object C为UILabel添加点击事件
- HPU暑期第五次积分赛 - G-迷宫(BFS+最短路径)
- 【视频】vue组件之$emit父子组件间值的传递
- Mybatis源码解析之Mybatis初始化过程
- python模拟浏览器下载文件_模拟浏览器下载文件?
- TYUT-A专题题解(一)
- 梅特勒托利多xk3124电子秤说明书_托利多电子秤设置说明书1
- “win+PrtSc”图片没有保存到图片文件夹中的问题
- 02-Spring的核心API
- OpenNLP入门实验
- 上海拍照攻略,让你的朋友圈与众不同
- JAVA-IDEA开发10个小手段
- cvs数据格式 gps_运动手表GPS轨迹文件导出方法
- Pymoo:优化算法的性能指标(Performance Indicators)
- 9. 【gRPC系列学习】连接失败处理:backoff协议
- Excel拆分字符判断是否有汉字
- c语言程序设计五子棋棋盘怎么画,五子棋的棋盘画不出来,求助!!
- 一年中的第几天 哔哩哔哩2020校园招聘笔试题讲解
- 计算机专业课题 结题报告,《有效技能研究与实践》课题结题报告
热门文章
- Linux跑齿轮命令,Linux 游戏作弊工具:GameConqueror 0.09
- apache2.4虚拟主机配置
- PJBLog的CSS模板图
- 嵌入式软件工程师面试题(七)
- Symantec AntiVirus企业版联机客户机端卸载密码(转)
- 爆强笑话,笑不翻你才怪我吐血!!!
- [我所知道的BIOS]-[Chipset Config] 5
- 树莓派突然无法连接/搜索WIFI
- 《深入解析Windows操作系统》笔记第1章
- Sakai Project(1)--源码部署安装