按昨天的说法,今天将开始做一个简单的游戏了。

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

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

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

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

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

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

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

  1. # -*- coding: utf8 -*-
  2.  
  3. background_image_filename = 'background.png'
  4. mouse_image_filename = 'hero.png'
  5. #指定图像文件名称
  6.  
  7. import pygame #导入pygame库
  8. from sys import exit #向sys模块借一个exit函数用来退出程序
  9.  
  10. pygame.init() #初始化pygame,为使用硬件做准备
  11. screen = pygame.display.set_mode((480, 650), 0, 32)
  12. #创建了一个窗口
  13. pygame.display.set_caption("PlaneFight!")
  14. #设置窗口标题
  15.  
  16. background = pygame.image.load(background_image_filename).convert()
  17. mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()
  18. #加载并转换图像
  19. while True:
  20. #游戏主循环
  21.  
  22. for event in pygame.event.get():
  23. if event.type == pygame.QUIT:
  24. #接收到退出事件后退出程序
  25. pygame.quit()
  26. exit()
  27.  
  28. screen.blit(background, (0,0))
  29. #将背景图画上去
  30.  
  31. x, y = pygame.mouse.get_pos()
  32. #获得鼠标位置
  33. x-= mouse_cursor.get_width() / 2
  34. y-= mouse_cursor.get_height() / 2
  35. #计算光标的左上角位置
  36. screen.blit(mouse_cursor, (x, y))
  37. #把光标画上去
  38.  
  39. pygame.display.update()
  40. #刷新一下画面

显示结果就会如下:

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

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

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


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

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

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

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

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

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

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

  1. # -*- coding: utf8 -*-
  2.  
  3. background_image_filename = 'background.png'
  4. mouse_image_filename = 'hero.png'
  5. bullet_image_filename = 'bullet.png'
  6. #指定图像文件名称
  7.  
  8. import pygame #导入pygame库
  9. from sys import exit #向sys模块借一个exit函数用来退出程序
  10.  
  11. pygame.init() #初始化pygame,为使用硬件做准备
  12. screen = pygame.display.set_mode((480, 650), 0, 32)
  13. #创建了一个窗口
  14. pygame.display.set_caption("PlaneFight!")
  15. #设置窗口标题
  16. pygame.mouse.set_visible(False)
  17.  
  18. background = pygame.image.load(background_image_filename).convert()
  19. mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()
  20. bullet = pygame.image.load(bullet_image_filename).convert_alpha()
  21. #加载并转换图像
  22.  
  23. bullet_x, bullet_y = 0, -100 #初始化子弹坐标
  24. while True:
  25. #游戏主循环
  26.  
  27. for event in pygame.event.get():
  28. if event.type == pygame.QUIT:
  29. #接收到退出事件后退出程序
  30. pygame.quit()
  31. exit()
  32.  
  33. screen.blit(background, (0,0))
  34. #将背景图画上去
  35. x, y = pygame.mouse.get_pos()
  36. #获得鼠标位置
  37. if bullet_y < -1 : #移动子弹
  38. bullet_x, bullet_y = x, y
  39. else:
  40. bullet_y -= 1
  41.  
  42. x-= mouse_cursor.get_width() / 2
  43. y-= mouse_cursor.get_height() / 2
  44. #计算光标的左上角位置
  45.  
  46. screen.blit(bullet, (bullet_x, bullet_y))
  47. screen.blit(mouse_cursor, (x, y))
  48. #把光标画上去
  49.  
  50. pygame.display.update()
  51. #刷新一下画面

可以得到这样的效果:

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


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

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

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

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

  1. clock = pygame.time.Clock()
  2. time_passed = clock.tick()
  3. time_passed = clock.tick(50)

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

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

  1. # -*- coding: utf8 -*-
  2.  
  3. background_image_filename = 'background.png'
  4. mouse_image_filename = 'hero.png'
  5. bullet_image_filename = 'bullet.png'
  6. #指定图像文件名称
  7.  
  8. import pygame #导入pygame库
  9. from sys import exit #向sys模块借一个exit函数用来退出程序
  10.  
  11. pygame.init() #初始化pygame,为使用硬件做准备
  12. screen = pygame.display.set_mode((480, 650), 0, 32)
  13. #创建了一个窗口
  14. pygame.display.set_caption("PlaneFight!")
  15. #设置窗口标题
  16. pygame.mouse.set_visible(False)
  17.  
  18. background = pygame.image.load(background_image_filename).convert()
  19. mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()
  20. bullet = pygame.image.load(bullet_image_filename).convert_alpha()
  21. #加载并转换图像
  22.  
  23. bullet_x, bullet_y = 0, -100 #初始化子弹坐标
  24. bullet_speed = 600 #初始化子弹速度
  25. clock = pygame.time.Clock()
  26. while True:
  27. #游戏主循环
  28.  
  29. for event in pygame.event.get():
  30. if event.type == pygame.QUIT:
  31. #接收到退出事件后退出程序
  32. pygame.quit()
  33. exit()
  34. time_passed = clock.tick(100)
  35. time_passed_second = time_passed/1000.0
  36. screen.blit(background, (0,0))
  37. #将背景图画上去
  38. x, y = pygame.mouse.get_pos()
  39. #获得鼠标位置
  40. if bullet_y < -1 : #移动子弹
  41. bullet_x, bullet_y = x, y
  42. else:
  43. bullet_y -= time_passed_second * bullet_speed
  44.  
  45. x-= mouse_cursor.get_width() / 2
  46. y-= mouse_cursor.get_height() / 2
  47. #计算光标的左上角位置
  48.  
  49. screen.blit(bullet, (bullet_x, bullet_y))
  50. screen.blit(mouse_cursor, (x, y))
  51. #把光标画上去
  52.  
  53. pygame.display.update()
  54. #刷新一下画面

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

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

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

2015/11/4用Python写游戏,pygame入门(4):获取鼠标的位置及运动的更多相关文章

  1. 2015/11/6用Python写游戏,pygame入门(6):控制大量的对象

    昨天我们已经实现了这个游戏的三个基本类. 但是现在它还是没办法做成一个适合玩的游戏,毕竟只有一架敌机的游戏是很乏味的.所以,我们需要好多子弹,也需要好多敌机. 所以,我们要创建list,这个list存 ...

  2. 2015/11/1用Python写游戏,pygame入门(1):pygame的安装

    这两天学习数据结构和算法,有时感觉并不如直接做项目来的有趣.刚刚学完python的基本使用,现在刚好趁热打铁做个小项目. 由于本人一直很想制作一款游戏,就想使用Python制作一个基础的游戏.搜了一下 ...

  3. 2015/11/5用Python写游戏,pygame入门(5):面向对象的游戏设计

    昨天的内容里有了运动的子弹,虽然我们只添加了一个子弹,但你可以看到我们需要记录子弹的x,y坐标,每次要更新它的坐标.如果我们想要有多颗子弹,就需要存储多个坐标.那时候处理起来就不显得那么简单,也许我们 ...

  4. 2015/11/2用Python写游戏,pygame入门(2):游戏中的事件和显示

    pygame是一个比较大的库,以我这点弱小的实力是没办法详解的.所以我只讲我懂得那些部分,其他部分由大家慢慢查找了解. ------------------------------- 我用pygame ...

  5. 2015/11/9用Python写游戏,pygame入门(8):按钮和游戏结束

    昨天没有更新内容,今天相对多写一些. 因为我们已经基本完成游戏框架,但是游戏结束后,并不知道怎样比较好开始.我本来本着懒的原则,想结束后显示一个黑屏,然后你重新点一下鼠标就重新开始.但是那样实在太不像 ...

  6. 2015/11/3用Python写游戏,pygame入门(3):字体模块、事件显示和错误处理

    游戏里面一般是肯定会出现文字显示的,即使是俄罗斯方块也应该显示分数.那么我们应该怎样来显示文字呢,今天一起学习一下pygame的font模块. 使用字体模块 pygame可以直接调用系统字体,也可以调 ...

  7. 2015/11/7用Python写游戏,pygame入门(7):碰撞检测

    我们已经完成了飞机大战的大部分东西,但是游戏还是没有办法正式开玩,因为子弹并不能打掉飞机.只有完成了这一个工作,游戏才算基本成型. 今天的内容就非常简单了,就是做到这个碰撞检测,以及控制好子弹和飞机的 ...

  8. python小游戏-pygame模块

    一.tkinter模块的GUI 基本上使用tkinter来开发GUI应用需要以下5个步骤: 导入tkinter模块中我们需要的东西. 创建一个顶层窗口对象并用它来承载整个GUI应用. 在顶层窗口对象上 ...

  9. 大一C语言学习笔记(11)---编程篇--写一个程序,可以获取从键盘上输入的的三个数,并能够判断是否可以以这三个数字作为边长来构成一个三角形,如果可以的话,输出此三角形的周长及面积,要求 0 bug;

    考核内容: 写一个程序,可以获取从键盘上输入的的三个数,并能够判断是否可以以这三个数字作为边长来构成一个三角形,如果可以的话,输出此三角形的周长及面积: 答案: #include<stdio.h ...

随机推荐

  1. 【动态规划】POJ-3616

    一.题目 Description Bessie is such a hard-working cow. In fact, she is so focused on maximizing her pro ...

  2. SpringMVC入门学习案例笔记

    一.数据库环境用mysql,数据库建表语句如下: /* SQLyog v10.2 MySQL - 5.1.72-community : Database - mybatis ************* ...

  3. sprintf函数 %6.2f

    %6.2f6表示数据表示至少6位,后面的.2表示小数点后保留两位 比如2342.123415用这个表示的话,结果就是2342.12如果不足六位就会在前面补空格超过六位的话正常显示 代码例子:int m ...

  4. C1WPF制作OLAP Cube浏览工具

    经过前期一段时间对WPF的学习了解,相信大家对WPF有了一定的了解.今天我们一起来了解使用Component One(简称C1)的WPF控件制作CUBE浏览工具.其实这个OLAP控件官方已经有了很详细 ...

  5. Android自定义View实现仿QQ实现运动步数效果

    效果图: 1.attrs.xml中 <declare-styleable name="QQStepView"> <attr name="outerCol ...

  6. Scrum 项目准备5.0

    1.团队成员完成自己认领的任务. 2.燃尽图:理解.设计并画出本次Sprint的燃尽图的理想线.参考图6. 3.每日立会更新任务板上任务完成情况.燃尽图的实际线,分析项目进度是否在正轨.    每天的 ...

  7. From 百度知道 SQLSERVER 字符集排序规则简单说明

    https://zhidao.baidu.com/question/390314825002277485.html 学习一下, 以后说不定用得到. collate Latin1_General_CS_ ...

  8. docker weave安装

    1.升级内核到3.10.0以上,安装iproute22.安装 0.80版本:#wget -O /usr/local/bin/weave https://raw.githubusercontent.co ...

  9. [C/C++] multimap查找一个key对应的多个value

    在multimap中,同一个键关联的元素必然相邻存放.基于这个事实,就可以将某个键对应的值一一输出. 1.使用find和count函数.count函数求出某个键出现的次数,find函数返回一个迭代器, ...

  10. hdu6447 YJJ's Salesman

    这个题意和数据范围一看就是离散化之后树状数组优化DP.给的"从左下方走上去才能拿到收益"的性质其实可以当成"必须从横纵坐标严格比某个点小的地方转移过来".1A了 ...