请选择 进入手机版 | 继续访问电脑版
设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
查看: 37586|回复: 37

【Pygame 第6课】 面向对象的游戏设计

[复制链接]

174

主题

45

好友

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

发表于 2013-8-28 20:28:13 |显示全部楼层
上节课中,我们的飞机已经可以发射子弹了,尽管只有一颗。为什么我只加了一颗?试着多加几颗你就会发现,你得用好几个变量去分别记录它们的xy坐标,在主循环中判断每一颗子弹的状态。你可以用list把程序写得稍稍不那么复杂,但这还没完。别忘了你打飞机的对手--敌机还没有加入到游戏。到时候你又需要更多的变量去记录它们的坐标,去判断它们的状态,去处理敌机、子弹、玩家飞机之间的关系。想想都觉得头大。

于是乎,我之前煞费苦心讲解的面向对象就该派上用场了。我要把子弹相关的东西都封装在一起。

先看看目前子弹相关的有哪些东西:x、y坐标,一张图片,好像就这么多。然后,还有一段处理子弹运动状态的代码。来建一个Bullet类,把x、y、image作为成员变量,再提供一个叫做move的成员函数,处理子弹的运动。

#定义一个Bullet类,封装子弹相关的数据和方法
  1. class Bullet:
  2.     def __init__(self):
  3.         #初始化成员变量,x,y,image
  4.         self.x = 0
  5.         self.y = -1
  6.         self.image = pygame.image.load('bullet.png').convert_alpha()

  7.     def move(self):
  8.         #处理子弹的运动
  9.         if self.y < 0:
  10.             mouseX, mouseY = pygame.mouse.get_pos()
  11.             self.x = mouseX - self.image.get_width() / 2
  12.             self.y = mouseY - self.image.get_height() / 2
  13.         else:
  14.             self.y -= 5
复制代码
代码的内容基本和之前一样,只是改为了面向对象的写法。如果你对__init__,self这些字眼感到陌生的话,请发送数字47到50,回顾一下关于python面向对象的课程。

接下来,程序主体就可以瘦身了。在原本加载子弹图片、初始化位置的地方,直接创建一个Bullet的实例。
  1. bullet = Bullet()
复制代码
在主循环中处理子弹运动的地方,调用Bullet的move方法。
  1. bullet.move()
复制代码
绘制子弹的时候,从bullet实例中取数据。
  1. screen.blit(bullet.image, (bullet.x, bullet.y))
复制代码
就这么简单。

运行程序看看效果是否正常。相比昨天,游戏的功能没有任何进展,但在结构上清晰了许多。之后,可以放心地添加更多子弹和敌机,而不会导致代码变成一坨。


6.png


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

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

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

使用道具 举报

1

主题

0

好友

95

积分

注册会员

Rank: 2

发表于 2013-8-28 20:46:34 |显示全部楼层

回帖奖励 +1

coding中,赶上了crossin先生的更新。
回复

使用道具 举报

0

主题

0

好友

56

积分

注册会员

Rank: 2

发表于 2013-8-28 22:41:20 来自手机 |显示全部楼层

回帖奖励 +1

一步一步学习
回复

使用道具 举报

2

主题

0

好友

49

积分

新手上路

Rank: 1

发表于 2013-8-29 07:55:08 |显示全部楼层

回帖奖励 +1

def __init__(self)   
还有看别人的代码
最下面经常有if __name__ == '__main__'这样的代码
到底是什么意思
网上查了一下  没有搞明白
谢谢老师
回复

使用道具 举报

174

主题

45

好友

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

发表于 2013-8-29 16:54:29 |显示全部楼层
leo 发表于 2013-8-29 07:55
def __init__(self)   
还有看别人的代码
最下面经常有if __name__ == '__main__'这样的代码
  1. def __init__(self)  
复制代码
是一个类被实例化的时候调用的,也就是你创建一个实例时,会先运行这段代码,一般用来初始化类的成员变量。
  1. if __name__ == '__main__'
复制代码
是为了让这里面的代码在这个文件被直接执行时调用。而当这个文件被作为模块被其他程序import的时候,就不会调用这里面的代码
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

3

主题

0

好友

161

积分

注册会员

Rank: 2

发表于 2013-8-29 20:17:26 |显示全部楼层
看完留个名,差一个就赶上进度啦
回复

使用道具 举报

3

主题

0

好友

161

积分

注册会员

Rank: 2

发表于 2013-8-29 20:20:23 |显示全部楼层
不对,我好像已经跟上了==!
回复

使用道具 举报

174

主题

45

好友

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

发表于 2013-8-29 23:14:22 |显示全部楼层
Victor 发表于 2013-8-29 20:20
不对,我好像已经跟上了==!

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

使用道具 举报

0

主题

0

好友

37

积分

新手上路

Rank: 1

发表于 2013-8-30 16:17:30 |显示全部楼层
同样追上进度了
回复

使用道具 举报

0

主题

0

好友

63

积分

注册会员

Rank: 2

发表于 2013-9-11 00:55:01 |显示全部楼层
感觉可以把self.image.get_width()放到__init__里面去执行, 就不用每次move都计算一次了
回复

使用道具 举报

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

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

GMT+8, 2024-4-18 12:19 , Processed in 0.034569 second(s), 35 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部