• 游戏框架的搭建

    • 安装框架包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图的,但是加上后缀后依然可以打开,而且就是把它删掉再扔进来一个新的依然可以显示,这算什么?开窍了吗?

思路

飞机类定义

  1. 创建一个飞机类
  2. 各种属性

    1. 本身的图片相关,如图片路径,图片尺寸

      #获取图片及相关信息
      self.imageName = "./feiji/hero.gif" #100x124
      self.img = Image.open(self.imageName)
      self.imgWidth = self.img.width
      self.imgHeight = self.img.height
      
    2. 用于显示图片的屏幕相关,背景屏幕是谁,背景屏幕的尺寸(由于我将屏幕也定义了一个类,所以只传一个参数)

      #获取背景屏幕
      self.bScreen = bgScreen
      
    3. 以及初始显示位置。x,y坐标,具体数值由背景屏幕尺寸及图片尺寸决定

      #设置飞机默认位置
      self.x = bgScreen.x/2 - self.imgWidth/2
      self.y = bgScreen.y - self.imgHeight
      
    4. 其它,待添加

  3. 各种方法

    1. 显示飞机,根据如何显示一个图片,显示在默认位置

      #显示飞机
      def display(self):self.bScreen.screen.blit(self.heroimage,(self.x,self.y))
      
    2. 移动飞机,根据如何显示一个图片,根据指令调整图片位置,同时设定边界,禁止移动飞机移出边界,边界数值由背景屏幕尺寸及图片尺寸决定。

      #向左
      def movLeft(self):if self.x > (0 - self.imgWidth/2):self.x -=10else:self.x = 0 - self.imgWidth/2
      
    3. 其它,待添加

飞机类显示

  1. 创建一个实例并应用

    1. 将显示飞机方法放到屏幕显示中
    2. 将移动飞机的方法与按键命令相结合

可以攻击的飞机

即显示我方子弹及我方子弹移动

思路

子弹类定义

  1. 定义一个子弹类
  2. 各种属性
    1. 本身的图片相关,如图片路径,图片尺寸
    2. 用于显示图片的屏幕相关,背景屏幕是谁,背景屏幕的尺寸
    3. 以及初始显示位置。x,y坐标,具体数值由背景屏幕尺寸,图片尺寸及飞机位置决定(所以在定义时需要传入飞机参数或只传入相关参数)
    4. 其它,待添加
  3. 各种方法
    1. 显示子弹,根据如何显示一个图片,显示于默认位置
    2. 移动子弹,根据如何显示一个图片,由于目前子弹只需要竖直移动(修改y值),所以一个函数足以。
    3. 其它,待添加

全部子弹显示及移动

由于子弹一般不会只有一颗,所以需要将全部子弹生成一个列表并显示。列表存放在哪呢?存放在发射子弹的飞机中不错(飞机炸了怎么办…子弹清完再清除飞机?还是将子弹放于飞机类中?)

  1. 在飞机类中定义全部子弹的显示方法,将列表中的子弹一一显示出来
  2. 在显示的时候对每一个子弹修改y值,即可完成移动
  3. 设定边界,在子弹出界后移除(即从列表中删除)

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打飞机小程序相关推荐

  1. 用python 玩微信小程序“跳一跳”

    12月28日,微信上线了小游戏「跳一跳」,瞬间成了全民游戏,如何牢牢占据排行榜的第一位呢?用Python帮助你,Python真的无所不能. 作为技术出身的我们,是不是想用技术改变排名呢? 注意:本文适 ...

  2. python小程序源代码-整理了适合新手的20个Python练手小程序

    100个Python练手小程序,学习python的很好的资料,覆盖了python中的每一部分,可以边学习边练习,更容易掌握python. 本文附带基础视频教程:私信回复[基础]就可以获取的 [程序1] ...

  3. python开发微信小程序-微信小程序开发:python+sanic 实现小程序登录注册

    开发微信小程序时,接入小程序的授权登录可以快速实现用户注册登录的步骤,是快速建立用户体系的重要一步.这篇文章将介绍 python + sanic + 微信小程序实现用户快速注册登录全栈方案. 微信小程 ...

  4. python开发微信小程序-Python 开发者的微信小程序开发实践

    导读 在知乎上,有人提问"如何使用 Python 开发微信小程序". 其实微信小程序作为一个前端的机制,Python 并不能插上边.只不过可以作为后端接口为微信小程序提供数据服务而 ...

  5. python程序实例电话本-利用Python电话本小程序!这波操作你给几分?

    原标题:利用Python电话本小程序!这波操作你给几分? 最近比较忙,只能抽空的写写文章,其实我也是一个上班族,python完全是个人想学然后希望以后对工作有所帮助,2019年了,祝大家新年快乐. 2 ...

  6. python小程序-【Python精华】100个Python练手小程序

    100个Python练手小程序,学习python的很好的资料,覆盖了python中的每一部分,可以边学习边练习,更容易掌握python. [程序1] 题目:有1.2.3.4个数字,能组成多少个互不相同 ...

  7. 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, ...

  8. 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, ...

  9. python小程序-整理了适合新手的20个Python练手小程序

    即刻关注公众号,发现世界的美好 100个Python练手小程序,学习python的很好的资料,覆盖了python中的每一部分,可以边学习边练习,更容易掌握python. [程序1] 题目:有1.2.3 ...

  10. 如何制作python检查小软件_如何用Python制作整蛊小程序

    原标题:如何用Python制作整蛊小程序 下面的整蛊程序,千万不要发代码,否则就实现不了你整蛊的目的了.完成后一定要打包成一个exe程序,再发给朋友使用 . 1. 使用 pip install pyi ...

最新文章

  1. 20、30、40岁年轻人,2020年的建议 转载
  2. 转:微软未公开的几个过程介绍及用法
  3. Jsoup V的幕后秘密:优化的技巧和窍门
  4. Nature Milestones | 近20年人类癌症研究领域14项里程碑式进展!
  5. docker 启动时指定需要绑定的网卡_Docker容器网络-基础篇
  6. 如何用EasyRecovery找回删除的文档(附注册机下载地址)
  7. 拓端tecdat|R、Python、Open Refine采集pdf数据,清理数据和格式化数据
  8. 电力猫服务器无响应,电力猫怕什么?TP-Link电力线适配器实测
  9. ******实战案例解析
  10. 域管理电脑自动锁屏html,简单两步让windows实现关闭屏幕时自动锁定电脑
  11. java的list和map区别,list和map的区别是什么
  12. 通过写《费用明细表》发现写sql的乐趣
  13. 【转】华为手机logcat不出日志解决方案
  14. 开源分布式配置组件conf使用教程
  15. Appsec在RSA 2013上
  16. UVM—virtual sequencer and virtual sequence详解
  17. 海胆状金纳米颗粒,粒径:150-200nm|银包金纳米颗粒 粒径:5-200nm|碳包金纳米颗粒 粒径:可定制
  18. django项目内部的views层判断手机访问还是电脑访问
  19. 统计假设测验------(四)方差分析(F测验、多重比较原理与方法)
  20. 4.2nbsp;反身理论与均衡价格论

热门文章

  1. latex数学符号加粗_latex的安装与数学公式的书写
  2. linux确定字符行,linux小计,统计文件中包含指定字符串的行数
  3. iOS:主流启动优化方案浅析
  4. 619. Biggest Single Number
  5. 最少钱币数-1-贪心算法(错,或者叫有问题)-CCF-CSP练习题(50)
  6. 前端开发 - JQuery - 下
  7. global.asax、global.asax.compiled、PrecompiledApp.config三者关系
  8. [转]Spring 注解总结
  9. Linux修改用户名(主机名)
  10. 用opencv进行图像处理-利用傅里叶变换进行图像的高通滤波和锐化