python打飞机小程序
- 游戏框架的搭建
- 安装框架包pygame
- 搜索图片资源
- plist文件相关
- 编写相应代码
- 思路
- 检测键盘
- 代码
- 思路
- 飞机显示及移动
- 关于飞机显示的努力
- ps里的gif
- png
- 思路
- 飞机类定义
- 飞机类显示
- 关于飞机显示的努力
- 可以攻击的飞机
- 思路
- 子弹类定义
- 全部子弹显示及移动
- tips列表删除相关
- 思路
- 显示敌机及移动
- 思路
- 定义敌机类
- 敌机的移动
- 思路
- 敌机子弹显示及自动攻击
- 思路
- 定义敌机子弹类
- 全部子弹显示及移动
- 自动攻击
- 思路
- 抽取基类
- 一些小心得
- 类内的变量
- 呵呵
- 一些小心得
游戏框架的搭建
安装框架包pygame
pip install pygame
搜索图片资源
教程里是有的,可我觉得太单调了
本来想搜索雷霆战机的,不太好找,便下载的全民飞机大战的素材包,但是发现这个素材包和教程里的不太一样,教程里的都是一个一个的,素材包里有很多一堆图片挤在一个图片里的,估计还需要额外学习。
plist文件相关
本来在网上找到一个可以直接根据plist文件分割大图的py,但是我执行下来一直报错,经过我不断的搜索,最后发现可能是由于我下载的plist是加密的,所以。。。(mmp)
编写相应代码
#coding=utf-8
import pygameif __name__ == "__main__":#1. 创建一个窗口,用来显示内容screen = pygame.display.set_mode((480,890),0,32)#2. 创建一个和窗口大小打图片,用来充当背景bgImageFile = "./fjdz/img_bg_logo.jpg"background = pygame.image.load(bgImageFile).convert()#3. 把背景图片放到窗口中while True:screen.blit(background,(0,0))pygame.display.update()
很尴尬的是在while True之后发现弹出来的窗口关不掉了,教程中是在vi模式编写,直接Ctrl + c 关掉了,我是在Sublime中写了,Ctrl + c不行,上网搜索杀死进程的方法使用xkill命令关掉了
图太长了好蛋疼,怎么才能显示全呢
大概只显示了三分之二的长度,也不能拉动边框
思路
学习一下如何定义一个背景屏幕,以及如何显示一个图片。
检测键盘
代码
#coding=utf-8
import pygame
from pygame.locals import *if __name__ == "__main__":#1. 创建一个窗口,用来显示内容screen = pygame.display.set_mode((512,768),0,32)#2. 创建一个和窗口大小打图片,用来充当背景bgImageFile = "./fjdz/img_bg_logo.jpg"background = pygame.image.load(bgImageFile).convert()#3. 把背景图片放到窗口中while True:screen.blit(background,(0,0))for event in pygame.event.get():if event.type == QUIT:print "exit"exit()elif event.type == KEYDOWN:if event.key == K_a or event.key == K_LEFT:print "left"elif event.key == K_d or event.key == K_RIGHT:print "right"elif event.key == K_w or event.key == K_UP:print "up"elif event.key == K_s or event.key == K_DOWN:print "down"elif event.key == K_SPACE:print "space"pygame.display.update()
思路
学习一下如何检测键盘
飞机显示及移动
由于plist的原因,卡了许久,默默去下ps,心塞。
只能先显示个飞机大阵了
(不只是飞机大阵,还有黑背景,只能先用教程里的图了)
只有教程里的gif没有黑背景,尴尬。。。
关于飞机显示的努力
一直不想用教程里的图,便想办法自己从大图里面扣
ps里的.gif
幸好大图里的图都非常好扣,但是移动到程序里的图一直有黑底,很烦,网上教程说应该存gif格式的,这样才能透明,可是在ps里没找到gif格式。然后上网搜索才知道应该选择那个存为web格式的才有gif格式。
存储完成后,到程序中显示,虽然周围确实是透明了,但是为什么图片内一些偏白的地方也透明了???
我还以为我抠图扣错了,又试了几遍,还是不行
(╯‵□′)╯︵┴─┴
png
但是我在抠图的时候发现其实大图里的背景也应该是透明的,因为我在抠图过程中发现这些图并没有背景,所以我觉得应该png格式也是可以保存透明背景的,经过搜索,证实了我的想法,那就用png格式的喽
结果经过ps处理后的png文件根本无法在ubuntu中打开,可能是由于我在存储中没有选择压缩?或者是交错?
经过搜索,网上提供的另外一种奇怪的方法解决了我的一部分问题。
那就是 把扩展名删掉。但是不幸的是拿到系统里的图片还是不知道为什么挂了
但是,待在共享文件夹里的文件还是好的
但是调用共享文件夹里的文件依然在程序中显示为黑底,由此,我推断:
一定是这个轮子不够圆!!!
当然我也不想自己去造个轮子,或者找一个更圆的轮子,因为我还可以老老实实的用教程里的图片(我屈服了QAQ)
另外,我发现,去掉后缀之后即使再加上后缀也不影响显示了,我本来是想截个无法打开的png图的,但是加上后缀后依然可以打开,而且就是把它删掉再扔进来一个新的依然可以显示,这算什么?开窍了吗?
思路
飞机类定义
- 创建一个飞机类
各种属性
本身的图片相关,如图片路径,图片尺寸
#获取图片及相关信息 self.imageName = "./feiji/hero.gif" #100x124 self.img = Image.open(self.imageName) self.imgWidth = self.img.width self.imgHeight = self.img.height
用于显示图片的屏幕相关,背景屏幕是谁,背景屏幕的尺寸(由于我将屏幕也定义了一个类,所以只传一个参数)
#获取背景屏幕 self.bScreen = bgScreen
以及初始显示位置。x,y坐标,具体数值由背景屏幕尺寸及图片尺寸决定
#设置飞机默认位置 self.x = bgScreen.x/2 - self.imgWidth/2 self.y = bgScreen.y - self.imgHeight
其它,待添加
各种方法
显示飞机,根据如何显示一个图片,显示在默认位置
#显示飞机 def display(self):self.bScreen.screen.blit(self.heroimage,(self.x,self.y))
移动飞机,根据如何显示一个图片,根据指令调整图片位置,同时设定边界,禁止移动飞机移出边界,边界数值由背景屏幕尺寸及图片尺寸决定。
#向左 def movLeft(self):if self.x > (0 - self.imgWidth/2):self.x -=10else:self.x = 0 - self.imgWidth/2
其它,待添加
飞机类显示
- 创建一个实例并应用
- 将显示飞机方法放到屏幕显示中
- 将移动飞机的方法与按键命令相结合
可以攻击的飞机
即显示我方子弹及我方子弹移动
思路
子弹类定义
- 定义一个子弹类
- 各种属性
- 本身的图片相关,如图片路径,图片尺寸
- 用于显示图片的屏幕相关,背景屏幕是谁,背景屏幕的尺寸
- 以及初始显示位置。x,y坐标,具体数值由背景屏幕尺寸,图片尺寸及飞机位置决定(所以在定义时需要传入飞机参数或只传入相关参数)
- 其它,待添加
- 各种方法
- 显示子弹,根据如何显示一个图片,显示于默认位置
- 移动子弹,根据如何显示一个图片,由于目前子弹只需要竖直移动(修改y值),所以一个函数足以。
- 其它,待添加
全部子弹显示及移动
由于子弹一般不会只有一颗,所以需要将全部子弹生成一个列表并显示。列表存放在哪呢?存放在发射子弹的飞机中不错(飞机炸了怎么办…子弹清完再清除飞机?还是将子弹放于飞机类中?)
- 在飞机类中定义全部子弹的显示方法,将列表中的子弹一一显示出来
- 在显示的时候对每一个子弹修改y值,即可完成移动
- 设定边界,在子弹出界后移除(即从列表中删除)
tips:列表删除相关
for bul in self.bullet:if bul.y > 0:self.bullet.remove(bul)
这种删除列表中的方法是错误的,当要删除的两个变量相邻时便会出错。
例:
原因嘛~
#方法一
nb = []
for bul in self.bullet:if bul.y < 0:nb.append(bul)
for bul in nb:self.bullet.remove(bul)#方法一
nb = []
for bul in self.bullet:if bul.y > 0:nb.append(bul)
self.bullet = nb
教程中给的是方法一,自己写的方法二,不清楚会有什么后果(数据地址改变?)。
显示敌机及移动
思路
定义敌机类
图片路径,初始位置x,y与普通飞机类不同,其余属性及方法通用
敌机的移动
敌机的移由代码控制,需要编写相关代码
定义一个自动移动的方法。
显然需要随机数,即random模块。
相关代码:
def autoMove(self):#如果上次的随机移动指令是否结束if self.amc <= 0:#若已结束,重新生成移动模式amm,移动次数amcself.amm = random.randint(1,3)self.amc = random.randint(5,20)else:#若未结束,移动次数减一self.amc -=1#是否移动到边缘if self.x <= 0 :#若移动到左边缘,剩余次数强制右移self.amm = 3elif self.x + self.imgWidth >= self.bScreen.x :#若移动到右边缘,剩余次数强制左移self.amm = 2#移动模式相关if self.amm == 1:#向前移,无论移动次数多少强制归0self.movDown()self.amc = 0elif self.amm == 2:#左移self.movLeft()elif self.amm == 3:#右移self.movRight()
看上去有些蠢,但是感觉也不太好化简了。
敌机子弹显示及自动攻击
思路
定义敌机子弹类
与我方子弹类基本相同,除了调用的图片路径不同。
全部子弹显示及移动
显示也差不多,移动只要改下y变动的方向即可,删除也是
自动攻击
应该在敌机类中定义一个函数,生成一个随机数,满足一定条件即调用shoot函数。(我把自动攻击和子弹显示写在一起了)
def autoShoot(self):nb = []n = random.randint(1,1000)if n < 100 :self.shoot()for bul in self.bullet:bul.display()bul.move(0,3)if bul.y > 0:nb.append(bul)self.bullet = nb
抽取基类
可以看到有许多代码都是重复的,将基类抽取出来,化简代码
一些小心得
类内的变量
在整合基类的过程中,发现在子类的初始化中,其实不用把参数一层层传到父类,父类的__init__
也是能调用到对应的变量的(只要定义了)
而self.imageName 这个参数由于在初始化过程中还需要调用,如果在子类没有定义会导致出错(虽然正常来讲不会出现未定义的情况)。便想写一个函数使它在未定义的时候进行定义一个参数。
最初想判断self.imageName == None,报错,说不存在self.imageName 这个东西,想了想,是啊,未定义呢
后来想试试缺省参数。结果由于def xxx后面忘了加冒号导致一直报错,后来发现了以后,测试一下好像也不行
上网搜索方法
1. 调用hasattr方法
2. 使用dir方法
3. 使用locals().has_key(‘var’)方法
4. 以及捕捉异常方法
由于之前并未怎么接触过捕捉异常的写法(只是学习了),导致并不喜欢捕捉异常的方法,但是其它方法都在报错,想了想,应该是在调用self.imageName时就直接报错了,无法进行判断,最后
class BaseImage(object):"""docstring for BaseImage"""def __init__(self, bgScreen):try:self.imageName = self.imageNameexcept AttributeError as e:#error: has not attributeself.imageName = "./feiji/bomb-2.gif"
呵呵
很奇怪我将一个函数display从父类(Plane)放入更深的基类(BaseImage)时heroPlane.display()便查找不到display函数了
(HeroPlane—>Plane—>BaseImage)
我把display函数粘贴在(BaseImage)中时,多缩进了一行,呵呵呵呵呵呵呵
子弹最后抽抽抽,凑成一个类了
教程到这就结束了。。。有空(猴年马月)再往下写吧
#coding=utf-8
import pygame
from pygame.locals import *
from PIL import Image
import time
import randomclass Screen(object):"""定义一个背景屏幕"""def __init__(self,x,y):#背景屏幕的尺寸self.x = xself.y = y#生成背景屏幕self.screen = pygame.display.set_mode((self.x,self.y),0,32)#静态方法:获取键盘打值@staticmethoddef getKey():for event in pygame.event.get():if event.type == QUIT:print "exit"exit()elif event.type == KEYDOWN:if event.key == K_a or event.key == K_LEFT:print "left"heroPlane.movLeft()elif event.key == K_d or event.key == K_RIGHT:print "right"heroPlane.movRight()elif event.key == K_w or event.key == K_UP:print "up"heroPlane.movUp()elif event.key == K_s or event.key == K_DOWN:print "down"heroPlane.movDown()elif event.key == K_SPACE:print "space"heroPlane.shoot()class BaseImage(object):"""在背景屏幕打印一个图片打基础"""def __init__(self, bgScreenn):#判断是否有图片文件打路径传入try:self.imageName = self.imageNameexcept AttributeError as e:#error: has not attributeself.imageName = "./feiji/bomb-2.gif"#打开图像文件,不想检测错误了self.img = Image.open(self.imageName)#获取图像的尺寸self.imgWidth = self.img.width self.imgHeight = self.img.height #s设置要显示内容打窗口self.bScreen = bgScreennself.imageScreen = pygame.image.load(self.imageName).convert()#显示图片def display(self):self.bScreen.screen.blit(self.imageScreen,(self.x,self.y))#向左def movLeft(self, speed = 10):if self.x > (speed - 10 - self.imgWidth/2):self.x -= speedelse:self.x = speed - 10 - self.imgWidth/2#向右def movRight(self, speed = 10):if self.x < (self.bScreen.x - speed - self.imgWidth/2 ):self.x += speedelse:self.x = self.bScreen.x - speed - self.imgWidth/2#向上def movUp(self, speed = 10):if self.y > speed:self.y -= speedelse:self.y = 0#向下def movDown(self, speed = 10):if self.y < (self.bScreen.y - self.imgHeight - speed):self.y += speedelse:self.y = self.bScreen.y - self.imgHeightclass Plane(BaseImage):"""一个基础飞机类"""def __init__(self, bgScreen):super(Plane,self).__init__(bgScreen)#根据类型,设置飞机默认位置if self.planeType == "Hero" :self.x = bgScreen.x/2 - self.imgWidth/2self.y = bgScreen.y - self.imgHeightelif self.planeType == "Enemy" :self.x = 0self.y = 0#全部子弹self.bullet = []#射击def shoot(self):if self.planeType == "Hero": newBullet = Bullet(self.x+self.imgWidth/2-10,self.y,self.bScreen,self.planeType)elif self.planeType == "Enemy":newBullet = Bullet(self.x+self.imgWidth/2-10,self.y+self.imgHeight,self.bScreen,self.planeType)self.bullet.append(newBullet)#展示全部子弹def bulletDisplay(self,direction = "up", speed = 1):nb = []for bul in self.bullet:bul.display()bul.move(direction)if bul.y > 0 or bul.y < self.bgScreen.y:nb.append(bul)self.bullet = nb class HeroPlane(Plane):"""基础英雄飞机类,可以视为工厂"""def __init__(self,bgScreen):#图片路径self.imageName = "./feiji/hero.gif" #100x124#self.imageName = "/mnt/share/Hero-1" #100x124#self.imageName = "./fjdz/Hero-1.gif" #100x124#飞机类型self.planeType = "Hero"super(HeroPlane,self).__init__(bgScreen)class EnemyPlane(Plane):"""基础敌方飞机,可以视为工厂"""def __init__(self,bgScreen):#图片路径self.imageName = "./feiji/enemy-1.gif" #100x124#飞机类型self.planeType = "Enemy"super(EnemyPlane,self).__init__(bgScreen)#用于自动移动的移动次数及移动模式self.auMoNumofCycles = 0self.auMoType = 0#自动射击def autoShoot(self):n = random.randint(1,1000)if n < 100 :self.shoot()#自动移动def autoMove(self):#如果上次的随机移动指令是否结束if self.auMoNumofCycles <= 0:#若已结束,重新生成移动模式,移动次数self.auMoType = random.randint(1,3)self.auMoNumofCycles = random.randint(5,20)else:#若未结束,移动次数减一self.auMoNumofCycles -=1#判断是否移动到边缘if self.x <= 0 :#若移动到左边缘,剩余次数强制右移self.auMoType = 3elif self.x + self.imgWidth >= self.bScreen.x :#若移动到右边缘,剩余次数强制左移self.auMoType = 2#移动模式相关if self.auMoType == 1:#向前移,无论移动次数多少强制归0self.movDown()self.auMoNumofCycles = 0elif self.auMoType == 2:#左移self.movLeft()elif self.auMoType == 3:#友移self.movRight()#显示子弹(敌方)def bulletDisplay(self):super(EnemyPlane, self).bulletDisplay("down")class Bullet(BaseImage):"""基础子弹类,可视为工厂"""def __init__(self,x,y,bgScreen, type):#生成子弹位置self.x = xself.y = y#根据类别选择子弹图片if type == "Hero": self.imageName = "./feiji/bullet-3.gif"elif type == "Enemy":self.imageName = "./feiji/bullet-1.gif"super(Bullet,self).__init__(bgScreen)#子弹的移动def move(self,direction,speed=1):if direction == "up":self.y -=speedelif direction == "down":self.y +=speedif __name__ == "__main__":#1. 创建一个窗口,用来显示内容bgScreen = Screen(512,700)#2. 创建一个和窗口大小打图片,用来充当背景#bgImageFile = "./fjdz/img_bg_logo.jpg"bgImageFile = "./fjdz/img_bg_level_1.jpg"background = pygame.image.load(bgImageFile).convert()#3.创建一个飞机对象heroPlane = HeroPlane(bgScreen)#4.创建一个敌方飞机enemyPlane = EnemyPlane(bgScreen)#5. 把全部图片放到窗口中while True:#背景图片bgScreen.screen.blit(background,(0,0))#我方飞机展示heroPlane.display()#我方子弹展示heroPlane.bulletDisplay();#敌方飞机展示enemyPlane.display()#敌方飞机自动移动enemyPlane.autoMove()#敌方飞机自动攻击enemyPlane.autoShoot()#敌方飞机子弹展示enemyPlane.bulletDisplay()#获取键值及相应操作Screen.getKey() #刷新显示 pygame.display.update()#延迟time.sleep(0.05)
python打飞机小程序相关推荐
- 用python 玩微信小程序“跳一跳”
12月28日,微信上线了小游戏「跳一跳」,瞬间成了全民游戏,如何牢牢占据排行榜的第一位呢?用Python帮助你,Python真的无所不能. 作为技术出身的我们,是不是想用技术改变排名呢? 注意:本文适 ...
- python小程序源代码-整理了适合新手的20个Python练手小程序
100个Python练手小程序,学习python的很好的资料,覆盖了python中的每一部分,可以边学习边练习,更容易掌握python. 本文附带基础视频教程:私信回复[基础]就可以获取的 [程序1] ...
- python开发微信小程序-微信小程序开发:python+sanic 实现小程序登录注册
开发微信小程序时,接入小程序的授权登录可以快速实现用户注册登录的步骤,是快速建立用户体系的重要一步.这篇文章将介绍 python + sanic + 微信小程序实现用户快速注册登录全栈方案. 微信小程 ...
- python开发微信小程序-Python 开发者的微信小程序开发实践
导读 在知乎上,有人提问"如何使用 Python 开发微信小程序". 其实微信小程序作为一个前端的机制,Python 并不能插上边.只不过可以作为后端接口为微信小程序提供数据服务而 ...
- python程序实例电话本-利用Python电话本小程序!这波操作你给几分?
原标题:利用Python电话本小程序!这波操作你给几分? 最近比较忙,只能抽空的写写文章,其实我也是一个上班族,python完全是个人想学然后希望以后对工作有所帮助,2019年了,祝大家新年快乐. 2 ...
- python小程序-【Python精华】100个Python练手小程序
100个Python练手小程序,学习python的很好的资料,覆盖了python中的每一部分,可以边学习边练习,更容易掌握python. [程序1] 题目:有1.2.3.4个数字,能组成多少个互不相同 ...
- python基础代码事例-Python简单基础小程序的实例代码
1 九九乘法表 for i in range(9):#从0循环到8 i += 1#等价于 i = i+1 for j in range(i):#从0循环到i j += 1 print(j,'*',i, ...
- python程序实例教程基础-Python简单基础小程序的实例代码
1 九九乘法表 for i in range(9):#从0循环到8 i += 1#等价于 i = i+1 for j in range(i):#从0循环到i j += 1 print(j,'*',i, ...
- python小程序-整理了适合新手的20个Python练手小程序
即刻关注公众号,发现世界的美好 100个Python练手小程序,学习python的很好的资料,覆盖了python中的每一部分,可以边学习边练习,更容易掌握python. [程序1] 题目:有1.2.3 ...
- 如何制作python检查小软件_如何用Python制作整蛊小程序
原标题:如何用Python制作整蛊小程序 下面的整蛊程序,千万不要发代码,否则就实现不了你整蛊的目的了.完成后一定要打包成一个exe程序,再发给朋友使用 . 1. 使用 pip install pyi ...
最新文章
- 20、30、40岁年轻人,2020年的建议 转载
- 转:微软未公开的几个过程介绍及用法
- Jsoup V的幕后秘密:优化的技巧和窍门
- Nature Milestones | 近20年人类癌症研究领域14项里程碑式进展!
- docker 启动时指定需要绑定的网卡_Docker容器网络-基础篇
- 如何用EasyRecovery找回删除的文档(附注册机下载地址)
- 拓端tecdat|R、Python、Open Refine采集pdf数据,清理数据和格式化数据
- 电力猫服务器无响应,电力猫怕什么?TP-Link电力线适配器实测
- ******实战案例解析
- 域管理电脑自动锁屏html,简单两步让windows实现关闭屏幕时自动锁定电脑
- java的list和map区别,list和map的区别是什么
- 通过写《费用明细表》发现写sql的乐趣
- 【转】华为手机logcat不出日志解决方案
- 开源分布式配置组件conf使用教程
- Appsec在RSA 2013上
- UVM—virtual sequencer and virtual sequence详解
- 海胆状金纳米颗粒,粒径:150-200nm|银包金纳米颗粒 粒径:5-200nm|碳包金纳米颗粒 粒径:可定制
- django项目内部的views层判断手机访问还是电脑访问
- 统计假设测验------(四)方差分析(F测验、多重比较原理与方法)
- 4.2nbsp;反身理论与均衡价格论
热门文章
- latex数学符号加粗_latex的安装与数学公式的书写
- linux确定字符行,linux小计,统计文件中包含指定字符串的行数
- iOS:主流启动优化方案浅析
- 619. Biggest Single Number
- 最少钱币数-1-贪心算法(错,或者叫有问题)-CCF-CSP练习题(50)
- 前端开发 - JQuery - 下
- global.asax、global.asax.compiled、PrecompiledApp.config三者关系
- [转]Spring 注解总结
- Linux修改用户名(主机名)
- 用opencv进行图像处理-利用傅里叶变换进行图像的高通滤波和锐化