设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
查看: 57849|回复: 17
打印 上一主题 下一主题

【Pygame 第5课】 游戏中的运动

[复制链接]

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

跳转到指定楼层
楼主
发表于 2013-8-27 21:36:08 |显示全部楼层 |倒序浏览
本来,在上一次pygame的教程中,我只是顺手拿了微信“打飞机”里的图来演示用鼠标控制图片位置的操作。后来觉得,这个游戏还算比较适合用来做例子,也有朋友反馈说想做这个游戏,那不如就以“打飞机”为例来说python游戏开发好了。

今天,就再进一步:既然要打飞机,那得能发射子弹才行。所以从最简单的做起,来给游戏加上“一颗”子弹。

上次的背景图和飞机图,我自己稍微处理了下,包括这一课要用到的子弹图片,都放在论坛上,需要的自行下载。

大体的思路是这样的:
  • 用之前在屏幕上绘制飞机的方法,再绘制一张很小的子弹图片。补充一下:当你需要绘制一张带透明部分的图片时,要用convert_alpha()替代之前的convert(),具体用法参见代码中。
  • 子弹被发射的位置是飞机的位置,也就是鼠标的位置。注意,要让它们的中心点对齐,而不是左上角对齐,处理方法我们已经说过。
  • 让这个子弹往上运动。还记得我在第2课《游戏的本质》里面说的吗:在游戏主循环中,要处理物理运动。所以在程序中要做的就是,每次循环里,把子弹图片的y坐标减少一个量(因为屏幕左上角的坐标是(0,0))。为了能记住子弹上一次循环中的位置,要有变量专门来记录子弹的坐标值。
  • 当子弹移动到屏幕上方外部之后(y坐标小于0),再把它的位置重置回发射的位置。这样看上去就是又一颗子弹被发射出来了,尽管我们一直是在操作同一张图片。游戏中经常会使用到诸如此类的小技巧,来欺骗你的视觉,这也是我觉得开发游戏很有意思的一个地方,好像是在变魔术。
  • 为了看起来更符合常理,你得把子弹的图片放在飞机的图片下面,这样看上去才会是从飞机上发射出去,而不是凭空冒出来的。在程序中,就是先绘制子弹,再绘制飞机,像是画油画,后画的会覆盖掉先画的。
  • 我在一开始就将子弹的位置设到屏幕上方之外,这样它就会自动被循环内的条件判断给重置位置,而不需要我再额外手动去初始化它的位置。


理清了如上的思路之后,能不能搞定代码了?如果能的话,就先别往下看,试着在程序里写写看。

以下是我的实现代码:
  1. # -*- coding: utf-8 -*-
  2. import pygame
  3. from sys import exit
  4. pygame.init()
  5. screen = pygame.display.set_mode((450, 800), 0, 32)
  6. pygame.display.set_caption("Hello, World!")
  7. background = pygame.image.load('back.jpg').convert()
  8. plane = pygame.image.load('plane.png').convert_alpha()
  9. bullet = pygame.image.load('bullet.png').convert_alpha()
  10. #加载子弹图像
  11. bullet_x = 0
  12. bullet_y = -1
  13. #初始化子弹位置
  14. while True:
  15.     for event in pygame.event.get():
  16.         if event.type == pygame.QUIT:
  17.             pygame.quit()
  18.             exit()
  19.     screen.blit(background, (0,0))
  20.     x, y = pygame.mouse.get_pos()
  21.     if bullet_y < 0:
  22.         #如果子弹位置超出了屏幕上端
  23.         bullet_x = x - bullet.get_width() / 2
  24.         bullet_y = y - bullet.get_height() / 2
  25.         #把子弹的中心位置设为鼠标坐标
  26.     else:
  27.         bullet_y -= 5
  28.         #子弹的位置往上移
  29.     screen.blit(bullet, (bullet_x, bullet_y))
  30.     #把子弹画到屏幕上
  31.     x-= plane.get_width() / 2
  32.     y-= plane.get_height() / 2
  33.     screen.blit(plane, (x, y))
  34.     pygame.display.update()
复制代码
5-2.png

5-1.png

#==== Crossin的编程教室 ====#
微信ID:crossincode
论坛:http://crossin.me
QQ群:312723402

面向零基础初学者的编程课
每天5分钟,轻松学编程




back.jpg (17.86 KB, 下载次数: 1794)

back.jpg

bullet.png (308 Bytes, 下载次数: 1946)

bullet.png

plane.png (9.18 KB, 下载次数: 1889)

plane.png

#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

沙发
发表于 2013-8-27 21:42:43 |显示全部楼层
补充一下:当你需要绘制一张带透明部分的图片时,要用convert_alpha()替代之前的convert(),具体用法参见代码中。


今天微信上推送的里面忘说了。
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

板凳
发表于 2013-8-27 23:47:44 |显示全部楼层
Myk_cc 发表于 2013-8-27 22:34
在今天内容的基础上增加一行子弹。ps:两行子弹真霸气

#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

地板
发表于 2013-8-28 20:24:16 |显示全部楼层
OrangeScript 发表于 2013-8-28 14:53
这样写可以吗?

不太对哦
你运行试试

这样每次都会把子弹坐标设在鼠标位置上,然后。。。后面逻辑有点乱
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

5#
发表于 2014-1-9 11:20:35 |显示全部楼层
浮生湮灭了美好 发表于 2013-10-19 19:01
先生我想问下 那个坐标为什么是还有子弹上移是我觉得本来应该是+的在第四象限。 ...

因为是要往左上移动,所以是-
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

6#
发表于 2015-4-15 13:53:16 |显示全部楼层
Jerome 发表于 2015-4-14 22:35
pygame.display.set_mode()
第二个参数是是否全屏,那请问第三个参数代表什么?

图片位深度
文档里似乎说这个值最好不要给,它会用系统默认的
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

7#
发表于 2015-12-26 18:24:25 |显示全部楼层
周末晒被子 发表于 2015-12-26 13:47
先生先生看我的\(^o^)/~三行子弹最霸气

举一反三
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

8#
发表于 2015-12-27 20:46:14 |显示全部楼层
周末晒被子 发表于 2015-12-27 15:32
先生,我发现我的代码子弹的往上移动的幅度,和先生的一样,同样是 y -= 5 ,但是运行后发现,先生的代 ...

不可能所有代码都一样,执行出来不一样吧。肯定有哪里不同,你分析下不一样的代码。
我猜测,大概是因为帧率不一样,我的代码帧率快,所以每帧5像素就很快了。你的代码里,可能因为某些原因导致帧率较低
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

9#
发表于 2015-12-28 16:22:05 |显示全部楼层
周末晒被子 发表于 2015-12-28 09:38
找到原因了,奇怪。

加载这两张图片的时候,我的是这样:

会的。你去搜索一下 pygame convert ,了解它的作用
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

10#
发表于 2016-2-2 11:51:24 |显示全部楼层
catherinemic 发表于 2016-2-1 14:28
加了一些限制让飞机不飞出窗外,外加从飞机中心飞出的三行子弹,做出来好有成就感呀~~ ...

#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即加入

QQ|手机版|Archiver|Crossin的编程教室 ( 苏ICP备15063769号  

GMT+8, 2024-5-2 22:17 , Processed in 0.030905 second(s), 31 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部