用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动


Posted in Python onNovember 05, 2015

目标是拷贝微信的飞机大战,当然拷贝完以后大家就具备自己添加不同内容的能力了。

首先是要拿到一些图片素材,熟悉使用图像处理软件和绘画的人可以自己制作,并没有这项技能的同学只能和我一样从网上下载相应的素材了。

用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动

网上可以找到相应的这样的图片,注意,所有的元件图片要是png类型的图片,那样可以有透明的背景,否则会有白色的边框露出来。

找到素材以后我们就要开始搭建我们的飞机大战了。

微信上的飞机大战是由手指控制的,在电脑上,我们就先用鼠标代替了。

按照之前我们在天空上移动云的那个程序,我们可以知道该怎么做。

无非是将背景和前景换一下。代码如下:

# -*- coding: utf8 -*-
background_image_filename = 'background.png'
mouse_image_filename = 'hero.png'
#指定图像文件名称
import pygame #导入pygame库
from sys import exit #向sys模块借一个exit函数用来退出程序
pygame.init() #初始化pygame,为使用硬件做准备
screen = pygame.display.set_mode((480, 650), 0, 32)
#创建了一个窗口
pygame.display.set_caption("PlaneFight!")
#设置窗口标题
background = pygame.image.load(background_image_filename).convert()
mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()
#加载并转换图像
while True:
#游戏主循环
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      #接收到退出事件后退出程序
      pygame.quit()
      exit()
  screen.blit(background, (0,0))
  #将背景图画上去
  x, y = pygame.mouse.get_pos()
  #获得鼠标位置
  x-= mouse_cursor.get_width() / 2
  y-= mouse_cursor.get_height() / 2
  #计算光标的左上角位置
  screen.blit(mouse_cursor, (x, y))
  #把光标画上去
  pygame.display.update()
  #刷新一下画面

显示结果就会如下:

用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动

上次没有说明鼠标图片跟随鼠标位置的具体说法,这里说明一下,用pygame.mouse.get_pos()可以得到一个鼠标的当前坐标位置的元组,将这个值赋值给x, y ,之后可以用它方便调用,但是如果我们直接用这个量,图片将会出现在鼠标的右下角,这是图片的坐标系决定的。如果我们想让它鼠标在图片中心,必须让鼠标坐标和图片中心对齐。对于任何一个Surface对象,可以用get_width(), get_height()和gei_size()对象,来获得它的尺寸,这样我们就可以将鼠标中点和图像尺寸对齐。

当然,美中不足的是鼠标本身出现在了游戏上,可能看起来不是那么和谐,可以通过pygame.mouse.set_visible(False)来设置鼠标的可见性。把这一句加入程序就可以隐藏鼠标。

好的,我们完成了一个部分,飞机可以显示在了屏幕上并能自由移动,但是,这个移动是完全由我们移动的,那些自己移动的飞机和子弹又是怎么做到移动的呢?

我们现在知道游戏的动画本质是由一张张图的变化而来的,子弹的运动也是这样,我们需要它每一幅图比上一幅图都向前多移动一点,这样就可以实现子弹的移动。

我们用总结一下子弹的特点:

1、子弹从飞机前端射出,发射的坐标应该是鼠标所在的位置。

2、每一帧子弹都向前多移动一些。

3、子弹飞出屏幕底部时,不再处理该子弹。(这里我用一个技巧,让子弹重新回到鼠标所在的位置)

4、为了使子弹从飞机下面飞出去,我们需要先绘制子弹,再在上面绘制飞机。

子弹有这样三个特点,根据这三个特点,可以写出它的代码:

# -*- coding: utf8 -*-
background_image_filename = 'background.png'
mouse_image_filename = 'hero.png'
bullet_image_filename = 'bullet.png'
#指定图像文件名称
import pygame #导入pygame库
from sys import exit #向sys模块借一个exit函数用来退出程序
pygame.init() #初始化pygame,为使用硬件做准备
screen = pygame.display.set_mode((480, 650), 0, 32)
#创建了一个窗口
pygame.display.set_caption("PlaneFight!")
#设置窗口标题
pygame.mouse.set_visible(False)
background = pygame.image.load(background_image_filename).convert()
mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()
bullet = pygame.image.load(bullet_image_filename).convert_alpha()
#加载并转换图像
bullet_x, bullet_y = 0, -100 #初始化子弹坐标
while True:
#游戏主循环
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      #接收到退出事件后退出程序
      pygame.quit()
      exit()
  screen.blit(background, (0,0))
  #将背景图画上去
  x, y = pygame.mouse.get_pos()
  #获得鼠标位置
  if bullet_y < -1 : #移动子弹
    bullet_x, bullet_y = x, y
  else:
    bullet_y -= 1
  x-= mouse_cursor.get_width() / 2
  y-= mouse_cursor.get_height() / 2
  #计算光标的左上角位置
  screen.blit(bullet, (bullet_x, bullet_y))
  screen.blit(mouse_cursor, (x, y))
  #把光标画上去
  pygame.display.update()
  #刷新一下画面

可以得到这样的效果:

用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动

子弹会从飞机打出,到屏幕顶端时就会重置。

上面的代码似乎是解决了子弹运动的问题,如此而来,敌机的运动也显得非常的简单。暂时不讲具体显示敌机的代码,让大家思考。

可其实有一个很容易发现的问题,那就是每一台机器的处理速度不一样,虽然每次循环时都让坐标自减一,实际上,还是有很大的差别的,处理速度快的机器可能一秒钟处理一千次循环,而处理慢的机器可能才30次循环,两台机器看到的动画帧率完全不同,子弹速度也完全不同,这应该怎么处理呢?

还好pygame早就帮我们做好了这一点,我们只需要这么去做就可以让所有的机子都有同样的速度。

pygame.time模块给我们提供了一个Clock()对象,让我们轻易做到控制帧率:

clock = pygame.time.Clock()
time_passed = clock.tick()
time_passed = clock.tick(50)

第一行初始化了一个Cloc对象,第二行返回了一个从上一次到现在调用的时间(毫秒计的单位),第三行就是控制帧率的好办法了。在每一次循环过程中加上它,在clock.tick()里加入参数,代表了你设定的最大帧率,你的画面的最大帧率就是你写的值,当然,有的时候动画过于复杂,它可能没办法到达这个帧率,那时我们需要别的优化方式。那么怎么保证控制的匀速呢?

将上面的代码再一次变化:

# -*- coding: utf8 -*-
background_image_filename = 'background.png'
mouse_image_filename = 'hero.png'
bullet_image_filename = 'bullet.png'
#指定图像文件名称
import pygame #导入pygame库
from sys import exit #向sys模块借一个exit函数用来退出程序
pygame.init() #初始化pygame,为使用硬件做准备
screen = pygame.display.set_mode((480, 650), 0, 32)
#创建了一个窗口
pygame.display.set_caption("PlaneFight!")
#设置窗口标题
pygame.mouse.set_visible(False)
background = pygame.image.load(background_image_filename).convert()
mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()
bullet = pygame.image.load(bullet_image_filename).convert_alpha()
#加载并转换图像
bullet_x, bullet_y = 0, -100 #初始化子弹坐标
bullet_speed = 600 #初始化子弹速度
clock = pygame.time.Clock()
while True:
#游戏主循环
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      #接收到退出事件后退出程序
      pygame.quit()
      exit()
  time_passed = clock.tick(100)
  time_passed_second = time_passed/1000.0
  screen.blit(background, (0,0))
  #将背景图画上去
  x, y = pygame.mouse.get_pos()
  #获得鼠标位置
  if bullet_y < -1 : #移动子弹
    bullet_x, bullet_y = x, y
  else:
    bullet_y -= time_passed_second * bullet_speed
  x-= mouse_cursor.get_width() / 2
  y-= mouse_cursor.get_height() / 2
  #计算光标的左上角位置
  screen.blit(bullet, (bullet_x, bullet_y))
  screen.blit(mouse_cursor, (x, y))
  #把光标画上去
  pygame.display.update()
  #刷新一下画面

我比较懒,直接贴了全部的代码。。。

这里面,我们每次读取了经过的时间,然后根据每次经过的时间不同,乘以速度系数来得到应该变化多少位移。用这种方法调整的动画,在不同的电脑上都有相同的显示。

敌机怎么显示,看大家怎么做了。明天继续讲,关于敌机的显示和随机性。

Python 相关文章推荐
Python备份Mysql脚本
Aug 11 Python
pygame学习笔记(1):矩形、圆型画图实例
Apr 15 Python
详解Django缓存处理中Vary头部的使用
Jul 24 Python
Python实现Linux命令xxd -i功能
Mar 06 Python
python实现八大排序算法(1)
Sep 14 Python
Python图片转换成矩阵,矩阵数据转换成图片的实例
Jul 02 Python
分享Python切分字符串的一个不错方法
Dec 14 Python
Python列表常见操作详解(获取,增加,删除,修改,排序等)
Feb 18 Python
opencv resize图片为正方形尺寸的实现方法
Dec 26 Python
Python爬虫抓取论坛关键字过程解析
Oct 19 Python
python递归函数用法详解
Oct 26 Python
python中pyplot基础图标函数整理
Nov 10 Python
python实现将内容分行输出
Nov 05 #Python
Python IDE PyCharm的基本快捷键和配置简介
Nov 04 #Python
Python实现周期性抓取网页内容的方法
Nov 04 #Python
Python压缩解压缩zip文件及破解zip文件密码的方法
Nov 04 #Python
python通过文件头判断文件类型
Oct 30 #Python
python制作花瓣网美女图片爬虫
Oct 28 #Python
python制作最美应用的爬虫
Oct 28 #Python
You might like
DIY一个适配电脑声卡的动圈话筒放大器
2021/03/02 无线电
php中file_get_content 和curl以及fopen 效率分析
2014/09/19 PHP
tp5框架基于Ajax实现列表无刷新排序功能示例
2020/02/10 PHP
php+ajax实现文件切割上传功能示例
2020/03/03 PHP
javascript 二分法(数组array)
2010/04/24 Javascript
js简单实现删除记录时的提示效果
2013/12/05 Javascript
js中Math之random,round,ceil,floor的用法总结
2013/12/26 Javascript
Javascript判断文件是否存在(客户端/服务器端)
2014/09/16 Javascript
javascript消除window.close()的提示窗口
2015/05/20 Javascript
jQuery的实例及必知重要的jQuery选择器详解
2016/05/20 Javascript
form+iframe解决跨域上传文件的方法
2016/11/18 Javascript
基于Swiper实现移动端页面图片轮播效果
2017/12/28 Javascript
vue 列表页跳转详情页获取id以及详情页通过id获取数据
2019/03/27 Javascript
在react项目中使用antd的form组件,动态设置input框的值
2020/10/24 Javascript
react ant Design手动设置表单的值操作
2020/10/31 Javascript
Python程序中使用SQLAlchemy时出现乱码的解决方案
2015/04/24 Python
八大排序算法的Python实现
2021/01/28 Python
Python用模块pytz来转换时区
2016/08/19 Python
Python通过future处理并发问题
2017/10/17 Python
python和shell获取文本内容的方法
2018/06/05 Python
Python中fnmatch模块的使用详情
2018/11/30 Python
django框架使用方法详解
2019/07/18 Python
Python解析命令行读取参数之argparse模块
2019/07/26 Python
python实现两个字典合并,两个list合并
2019/12/02 Python
python re模块匹配贪婪和非贪婪模式详解
2020/02/11 Python
python绘制分布折线图的示例
2020/09/24 Python
Expedia印度:您的一站式在线旅游网站
2017/08/24 全球购物
缴纳养老保险的证明
2014/01/10 职场文书
优秀毕业生就业推荐信
2014/05/22 职场文书
优秀大学生自荐信
2014/06/09 职场文书
城市规划应届毕业生自荐信
2014/07/04 职场文书
2014年远程教育工作总结
2014/12/09 职场文书
个人先进事迹材料范文
2014/12/29 职场文书
禁毒主题班会教案
2015/08/14 职场文书
go语言使用Casbin实现角色的权限控制
2021/06/26 Golang
MySQL三种方式实现递归查询
2022/04/18 MySQL