500行代码,教你用python写个微信飞机大战
这几天在重温微信小游戏的飞机大战,玩着玩着就在思考人生了,这飞机大战怎么就可以做的那么好,操作简单,简单上手。
帮助蹲厕族、YP族、饭圈女孩在无聊之余可以有一样东西让他们振作起来!让他们的左手 / 右手有节奏有韵律的朝着同一个方向来回移动起来!
这是史诗级的发明,是浓墨重彩的一笔,是……
在一阵抽搐后,我结束了游戏,瞬时觉得一切都索然无味,正在我进入贤者模式时,突然想到,如果我可以让更多人已不同的方式体会到这种美轮美奂的感觉岂不美哉?
所以我打开电脑,创建了一个 plan_game.py
……
先看效果图
操作环境
- 操作系统:windows10
- python版本:python 3.7
- 代码编辑器:pycharm 2018.2
- 使用模块:os,sys,random,pygame
因为实现代码使用到了一个pygame的第三方模块,没有的先 pip install
一下,这里顺便提供一个比较好的pygame的教程.
https://eyehere.net/2011/python-pygame-novice-professional-index/
具体实现
- 首先我们先指定素材文件的文件目录.方便我们后面的使用。这些素材已经全部上传至公众号Python专栏,后台回复:飞机大战,即可获得。
import os
# 得到当前文件夹下面的material_images目录的路径
source_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'material_images')
- 实现一个Game类,用来完成这个游戏的主要逻辑。
import pygame
class Game():
def __init__(self, background_image_path, size=(480, 700), title='飞机大战', font_name='方正舒体', font_size=30, speed=2000):
'''
:param background_image_path: 背景图片的路径地址
:param size: 游戏窗口的大小
:param title: 游戏窗口的标题
:param font_name: 指定字体
:param font_size: 指定字体大小
:param speed: 背景图滚动整个窗口一次所用时间,单位为ms
'''
self.size = size
self.screen = pygame.display.set_mode(size)
self.title = title
self.background_image_path = background_image_path
self.background = pygame.image.load(self.background_image_path).convert()
# 设置字体对象,得到系统中自带的字体
self.font = pygame.font.SysFont(font_name, font_size)
# 得到Clock对象,我们可以使用它来获取距离上次绘制图像的时间
self.clock = pygame.time.Clock()
# 背景图初始位置
self.height = 0
# 使用窗口的高度处于滚动的时间,就能得到每ms滚动的距离
self.every_ms_move_distance = self.size[1] / speed # 2秒
# 分数
self.score = 0
# 存放所有的敌机
self.enemies = []
def show_score(self):
'''
显示分数, 在窗口的的最上方距离上边距10px, 左右居中
'''
pass
def set_time_passed(self):
# 控制画 的帧, 越大越快
# 得到上一次绘制图像到到现在的时间, ms
self.time_passed = self.clock.tick()
def draw_background(self):
'''
绘制背景图片,一直向下滚动,营造飞机一直往上面飞的感觉
'''
# 每次移动的距离 = 每ms移动的距离 * 上次到现在的时间(ms)
pass
def create_enemy(self, image_path=os.path.join(source_dir,'enemy1.png'), enemy_number=5):
'''
创建敌机
:param image_path: 敌机的图片地址
:param enemy_number: 最多有几个敌机在屏幕上
'''
pass
def draw_enemies(self, time_passed, screen):
'''
绘制敌机到屏幕上,清理跑出窗口的敌机,
:param time_passed: 上次绘制导向现在经过的时间
:param screen: 绘制的窗口对象
'''
pass
def bullet_and_enemy_crash_detection(self, bullets):
'''
检测子弹是否击中敌机
:param bullets: 飞机的所有子弹
'''
pass
def plan_and_enemy_crash_detection(self, plan, allow_crash_size=None):
'''
检测敌机与飞机是否相撞
:param plan: 飞机对象
:param allow_crash_size: 允许飞机碰撞的大小,只有左右有效
'''
pass
def draw_plan(self, plan, time_passed):
'''
绘制飞机
:param plan: 飞机对象
:param time_passed: 距离上次绘制的时间
:return:
'''
pass
def game_over(self):
'''
游戏结束
'''
while True:
# 绘制背景图
pass
def run(self):
'''
游戏入口函数,开始函数,主体函数
:return:
'''
# 设置游戏窗口的大小
pygame.display.set_caption(self.title)
# 初始化一个飞机对象
plan = Plan()
while True:
# 如果飞机自毁完成, 游戏结束, 调用game_over函数
pass
# 检测监听事件
pass
# 检测上下左右的移动案件.
# w,a,s,d 和 上,下,左,右键都可以
# 然后执行plan.update函数,改变飞机的位置
pass
# 子弹和敌机的碰撞检测
self.bullet_and_enemy_crash_detection(plan.bullets)
# 飞机与敌机的碰撞检测
self.plan_and_enemy_crash_detection(plan)
# 设置属性time_passed的值, 距离上次的时间,方便后面使用
self.set_time_passed()
# 绘制背景图片
self.draw_background()
# 显示分数
self.show_score()
# 生成敌机
self.create_enemy()
# 绘制敌机
self.draw_enemies(time_passed=self.time_passed, screen=self.screen)
# 绘制飞机
self.draw_plan(plan=plan, time_passed=self.time_passed)
# 绘制子弹
plan.draw_bullets(time_passed=self.time_passed, screen=self.screen)
# 显示我们的图像
pygame.display.update()
这里说以下怎样查看自己的系统中有哪些自带的字体.
pygame.font.get_fonts(),这个函数就能够得到系统中所有的自带字体文件。不过,当我们游戏中有中文的时候,我们也得选择支持中文的字体,否则的话是显示不出中文的。
- 实现DestroyAnimationMixin类,这个类主要是用来显示飞机或敌机的自毁动画
# 显示飞机自毁动画的Mixin类, 可用于飞机和敌机的自毁动画显示
class DestroyAnimationMixin():
def show_destroy_animation(self, time_passed, destroy_time=200):
'''
显示自毁动画
动画其实就是几张图片切换的比较快,我们的眼睛识别不出来,所以认为他是动态的,也就是动画
:param time_passed: 距离上次绘制图像到现在的时间,单位ms
:param destroy_time: 自毁动画总共显示时间,单位ms
'''
# 因为我们的自毁图片有四张,需要依次显示,首先动画的效果
# self.destroy_image_position 表示第几章自毁图片,从零开始
# 如果大于等于4了,说明自毁动画显示完成,设置self.destroyed变量为True, 方便别处调用
if self.destroy_image_position >= 4:
self.destroyed = True
return
# 依次加载自毁图片
if self.time_passed >= destroy_time / 4:
self.image = pygame.image.load(os.path.join(source_dir, self.destroy_images[self.destroy_image_position])).convert_alpha()
self.destroy_image_position += 1
self.time_passed = 0
else:
self.time_passed += time_passed
- 实现飞机类,完成飞机的主要操作。飞机的操作包括:飞机位置、飞机子弹、发射子弹等。
# 飞机类,继承DestroyAnimationMixin, 方便使用显示自毁动画的函数
class Plan(DestroyAnimationMixin):
def __init__(self, image_path=os.path.join(source_dir,'plan.png'), background_size=(480, 700)):
'''
:param image_path: 飞机图片地址
:param background_size: 游戏窗口大小
'''
self.background_size = background_size
self.image = pygame.image.load(image_path).convert_alpha()
self.image_size = self.image.get_size()
self.position = [(background_size[0]-self.image_size[0]) / 2, 500]
# 飞机每次移动的距离
self.every_time_move_distance = 0.5
# 飞机的子弹
self.bullets = []
# destroy association attributes, 自毁相关属性
# 开始自毁
self.start_destroy = False
# 自毁结束
self.destroyed = False
# 自毁图片
self.destroy_images = ['me_destroy_1.png', 'me_destroy_2.png', 'me_destroy_3.png', 'me_destroy_4.png']
# 自毁图片位置
self.destroy_image_position = 0
# 距离上次绘制图像到现在的时间
self.time_passed = 0
def update(self, direction):
'''
更新飞机位置
:param direction: 飞机移动方向
'''
pass
def shut(self, image_path=os.path.join(source_dir,'bullet.png')):
'''
飞机发射子弹
:param image_path: 子弹图片
'''
pass
def draw_bullets(self, time_passed, screen):
'''
绘制飞机的所有子弹
:param time_passed: 距离上次绘制图像到现在的时间
:param screen: 绘制到哪一个窗口中
'''
pass
- 实现敌机类,完成敌机的主要操作。主要是用来更新位置。
# 敌机类,继承DestroyAnimationMixin, 方便使用显示自毁动画的函数
class Enemy(DestroyAnimationMixin):
def __init__(self, image_path=os.path.join(source_dir, 'enemy1.png'), speed=2000, background_size=(480, 700)):
'''
:param image_path: 敌机图片地址
:param speed: 敌机移动整个窗口需要的时间,单位ms,也就是速度
:param background_size: 游戏窗口的尺寸
'''
self.image = pygame.image.load(image_path).convert_alpha()
self.speed = background_size[1] / speed
self.background_size = background_size
self.position = [random.randint(0, background_size[0]-self.image.get_size()[0]), -self.image.get_size()[1]]
# 开始自毁
self.start_destroy = False
# 自毁完成
self.destroyed = False
# 自毁图片路径
self.destroy_images = ['enemy1_down1.png', 'enemy1_down2.png', 'enemy1_down3.png', 'enemy1_down3.png']
# 距离上次绘制图像到现在的时间
self.time_passed = 0
# 自毁图片在self.destroy_images的位置
self.destroy_image_position = 0
def update(self, time_passed):
'''
更新敌机的位置
:param time_passed: 距离上次绘制图像到现在的时间
:return:
'''
pass
- 实现子弹类,完成子弹的主要操作
# 飞机子弹类
class Bullet():
def __init__(self, image_path=os.path.join(source_dir,'bullet.png'), background_size=(480, 700), plan=None, speed=1000):
'''
:param image_path: 子弹的图片地址
:param background_size: 游戏窗口大小
:param plan: 飞机对象
:param speed: 子弹飞行速度
'''
self.image = pygame.image.load(image_path).convert_alpha()
self.background_size = background_size
self.speed = background_size[1] / speed
# 子弹是否击中敌机
self.destroyed = False
self.position = self._get_position(plan)
def _get_position(self, plan):
'''
根据plan得到子弹发出位置
:param plan: 飞机对象
'''
bullet_size = self.image.get_size()
plan_width = plan.image_size[0]
x = (plan_width-bullet_size[0]) / 2
return [plan.position[0] + x, plan.position[1]]
def update(self, time_passed):
'''
改变子弹位置
:param time_passed: 距离上次绘制图像到现在的时间
'''
# 如果子弹超出屏幕或者击中敌机,就设置self.position[1]为-100,在plan.draw的时候就移除它
if self.position[1] + self.image.get_size()[1] <= 0 or self.destroyed:
self.position[1] = -100
return
# 改变的距离 = 时间 * 速率
self.position[1] -= time_passed * self.speed
这样,我们就把所有的操作都实现完了,接下来只需要使用 Game().run(),就可以运行我们的游戏了。
关注公众号:Python专栏,后台回复:飞机大战,即可获得完整代码及素材包。
500行代码,教你用python写个微信飞机大战的更多相关文章
- 20行代码教你用python给证件照换底色
1.图片来源 该图片来源于百度图片,如果侵权,请联系我删除!图片仅用于知识交流.本文只是为了告诉大家:python其实有很多黑科技(牛逼的库),我们既可以用python处理工作中的一些事儿,同时我们也 ...
- iOS开发——实用技术OC篇&8行代码教你搞定导航控制器全屏滑动返回效果
8行代码教你搞定导航控制器全屏滑动返回效果 前言 如果自定了导航控制器的自控制器的leftBarButtonItem,可能会引发边缘滑动pop效果的失灵,是由于 self.interactivePop ...
- 10分钟教你用Python玩转微信之抓取好友个性签名制作词云
01 前言+展示 各位小伙伴我又来啦.今天带大家玩点好玩的东西,用Python抓取我们的微信好友个性签名,然后制作词云.怎样,有趣吧~好了,下面开始干活.我知道你们还是想先看看效果的. 后台登录: 词 ...
- 10分钟教你用Python玩转微信之好友性别比例统计分析
01 前言+效果展示 想必,微信对于大家来说,是再熟悉不过的了.那么,大家想不想探索一下微信上的各种奥秘呢?今天,我们一起来简单分析一下微信上的好友性别比例吧~废话不多说,开始干活. 结果如下: 02 ...
- Python之游戏开发-飞机大战
Python之游戏开发-飞机大战 想要代码文件,可以加我微信:nickchen121 #!/usr/bin/env python # coding: utf-8 import pygame impor ...
- [500lines]500行代码写web server
项目地址:https://github.com/aosabook/500lines/tree/master/web-server.作者是来自Mozilla的Greg Wilson.项目是用py2写成. ...
- 手把手教你用1行代码实现人脸识别 --Python Face_recognition
环境要求: Ubuntu17.10 Python 2.7.14 环境搭建: 1. 安装 Ubuntu17.10 > 安装步骤在这里 2. 安装 Python2.7.14 (Ubuntu17.10 ...
- 一步一步手写GIS开源项目-(1)500行代码实现基础GIS展示功能
1.开篇 大学毕业工作已经两年了,上学那会就很想研读一份开源GIS的源码,苦于自己知识和理解有限,而市面上也没有什么由浅入深讲解开源gis原理的书籍,大多都是开源项目简介以及项目的简单应用.对于初级程 ...
- 教你用python写:HDU刷题神器
声明:本文以学习为目的,请不要影响他人正常判题 HDU刷题神器,早已被前辈们做出来了,不过没有见过用python写的.大一的时候见识了学长写这个,当时还是一脸懵逼,只知道这玩意儿好屌-.时隔一年,决定 ...
随机推荐
- 深入浅出TypeScript(5)- 在React项目中使用TypeScript
前言 在第二小节中,我们讨论了利用TypeScript创建Web项目的实现,在本下节,我们讨论一下如何结合React创建一个具备TypeScript类型的应用项目. 准备 Webpack配置在第二小节 ...
- SpringMVC 视图解析器 InternalResourceViewResolver
我们在使用SpringMVC的时候,想必都知道,为了安全性考虑,我们的JSP文件都会放在WEB-INF下, 但是我们在外部是不可以直接访问/WEB-INF/目录下的资源对吧, 只能通过内部服务器进行转 ...
- redis在windows下安装设置密码及主从数据库
redis在windows下安装设置密码及主从数据库 1.安装 下载解压后,如图所示: 2.配置. 打开redis.windows.conf文件,在此处设置端口和ip: 这里设置持久化: 在这里设置密 ...
- Intellij IDEA使用restclient测试
Intellij IDEA内置了restclient来帮忙我们测试我们的后台代码,让我们可以脱离第三方工具测试,也更不需要我们编写前端代码,直接让我们能想网站发送get,post,put,delet ...
- PB级数据实现秒级查询ES的安装
什么是ES?ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java语言开发的, ...
- Android开发:为什么我们从来不去感谢开源项目维护者?
今天我想谈一谈,为什么我们很少去感谢开源项目维护者: 一.这样的项目我也可以做啊 “蛤?这项目对我来说也太简单了吧.” “我一周之内就能做一个更好的版本出来.” 确实,很多人都可以在 Hackatho ...
- 使用Hypothesis生成测试数据
Hypothesis是Python的一个高级测试库.它允许编写测试用例时参数化,然后生成使测试失败的简单易懂的测试数据.可以用更少的工作在代码中发现更多的bug. 安装 pip install hyp ...
- Day 23 系统服务之救援模式
1.CentOS6与Centos 7启动流程 4.运行级别C6&C7 0 关机 1 单用户模式 (超级权限 必须面对实体硬件) 2 暂未使用 3 字符界面(黑框) 4 暂未使用 5 图形界面 ...
- FlutterGo 后端知识点提炼:midway+Typescript+mysql(sequelize)
前言 关于 FlutterGo 或许不用太多介绍了. 如果有第一次听说的小伙伴,可以移步FlutterGo官网查看下简单介绍. FlutterGo 在这次迭代中有了不少的更新,笔者在此次的更新中,负责 ...
- zipkin+elk微服务日志收集分析系统
docker安装elk日志分析系统 在win10上安装docker环境 tip:win7/8 win7.win8 系统 win7.win8 等需要利用 docker toolbox 来安装,国内可以使 ...