用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中的socket模块使用代理实例
May 29 Python
详解Python中映射类型(字典)操作符的概念和使用
Aug 19 Python
基于python实现微信模板消息
Dec 21 Python
利用Python实现颜色色值转换的小工具
Oct 27 Python
Python实现视频下载功能
Mar 14 Python
pycharm配置pyqt5-tools开发环境的方法步骤
Feb 11 Python
python异步实现定时任务和周期任务的方法
Jun 29 Python
Django 使用easy_thumbnails压缩上传的图片方法
Jul 26 Python
pycharm修改文件的默认打开方式的步骤
Jul 29 Python
python实现人工智能Ai抠图功能
Sep 05 Python
浅谈Django2.0 加xadmin踩的坑
Nov 15 Python
matplotlib绘制鼠标的十字光标的实现(内置方式)
Jan 06 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
生成静态页面的php函数,php爱好者站推荐
2007/03/19 PHP
给初学者的30条PHP最佳实践(荒野无灯)
2011/08/02 PHP
使用gd库实现php服务端图片裁剪和生成缩略图功能分享
2013/12/25 PHP
ThinkPHP模板之变量输出、自定义函数与判断语句用法
2014/11/01 PHP
php实现按指定大小等比缩放生成上传图片缩略图的方法
2014/12/15 PHP
php操作MongoDB类实例
2015/06/17 PHP
php实现姓名根据首字母排序的类与方法(实例代码)
2018/05/16 PHP
CodeIgniter框架钩子机制实现方法【hooks类】
2018/08/21 PHP
jQuery随便控制任意div隐藏的方法
2013/06/28 Javascript
详解JavaScript正则表达式之RegExp对象
2015/12/13 Javascript
详解Javascript中prototype属性(推荐)
2016/09/03 Javascript
微信小程序 LOL 英雄介绍开发实例
2016/09/30 Javascript
vue.js学习笔记:如何加载本地json文件
2017/01/17 Javascript
JS一个简单的注册页面实例
2017/09/05 Javascript
jQuery实现动态控制页面元素的方法分析
2017/12/20 jQuery
微信小程序onLaunch异步,首页onLoad先执行?
2018/09/20 Javascript
浅谈KOA2 Restful方式路由初探
2019/03/14 Javascript
Vue 2.0 中依赖注入 provide/inject组合实战
2019/06/20 Javascript
Python安装lz4-0.10.1遇到的坑
2018/05/20 Python
Python实现直播推流效果
2019/11/26 Python
Python中顺序表原理与实现方法详解
2019/12/03 Python
python 解决cv2绘制中文乱码问题
2019/12/23 Python
JetBrains PyCharm(Community版本)的下载、安装和初步使用图文教程详解
2020/03/19 Python
Python如何解除一个装饰器
2020/08/07 Python
PyTorch中Tensor的数据类型和运算的使用
2020/09/03 Python
canvas探照灯效果的示例代码
2018/11/30 HTML / CSS
如何强制垃圾回收
2015/10/06 面试题
大一新生军训时的自我评价分享
2013/12/05 职场文书
农村党员学习党的群众路线教育实践活动心得体会
2014/11/04 职场文书
环卫个人总结
2015/03/03 职场文书
黑白记忆观后感
2015/06/18 职场文书
事业单位工作人员岗前培训心得体会
2016/01/08 职场文书
.Net Core导入千万级数据至Mysql的步骤
2021/05/24 MySQL
Redis可视化客户端小结
2021/06/10 Redis
JS的深浅复制详细
2021/10/16 Javascript
SQL SERVER存储过程用法详解
2022/02/24 SQL Server