您的位置:首页 > 移动开发 > Cocos引擎

用cocos2d 2.1制作一个过河小游戏(3): 船与河岸Sprite设计

2014-04-16 16:08 351 查看
好,我又来了......

这次来讲下船BoatSprite和河岸BankSprite的设计。在这个过河游戏中,我们有两个河岸:左岸与右岸。每个岸上都能站人。游戏开始的时候3个牧师和3个魔鬼都是站在右岸上,他们的目标是要全部都到左岸上去。河边有条船,船上最多可以坐两人,而且至少要有一个人船才能开过去。具体的信息就是这些。

在我们的设计中,船是BoatSprite,河岸是BankSprite。

下面来讲讲我的思路吧。接着上一篇讲述,我们知道,船也是应该有一个Side属性来标识其目前是在河的哪一边。河岸也应该有Side属性,不过这个是它的确定属性,一旦设定后就不需要改变了。接着,每次游戏中我们都需要判断每边PriestSprite和DevilSprite的个数,好决定玩家是胜利了还是挂了,所以船和河岸都应该记录下此时船上/岸上PriestSprite和DevilSprite的个数。

接下来有个问题其实困扰了我一段时间:我们在BoatSprite和BankSprite中是否需要设置一个NSMutableArray来存放当前存在于船上/河岸上的Person呢?一开始我是比较倾向于都设置这样一个Array的,当人物从船上跳到岸上时,船上相应的Person就被remove掉,然后岸上的Array中加入这一Person。这个想法是非常自然而然的。但是后面转念一想:其实在岸上保留这样的一个Person的队列到底有没有什么实际作用呢?从上一遍我们知道,我们操作人物都是通过触屏的,当触屏事件发生时,触摸到PersonSprite会首先响应到该事件并委托给游戏逻辑BaseLayer来处理。无论人是从船上跳到岸上还是从岸上跳到船上,我的BaseLayer都可以处理,和河岸其实并没有半毛钱关系。河岸要做的,就是更改当前岸上人物的数目而已。故两个int属性表示两种人的数量,足矣。同理,船上也并不需要这样的一个队列。

是的,从这个角度看船确实也不需要Array了。但是真的是这样吗?岸上不需要Person的Array是因为每次对Person的操作都是独立的,由BaseLayer完成的,和之前岸上已有的人物的个数和种类都没有关系(因为我们已经通过PersonSprite的number属性规定好了每个人在岸上都有固定的站位),但是船上就不是了。船上可以坐两个人,但是当船上已经坐着一个人的时候,另一个人想上船,他必须知道那个已经在船上的人坐在船的前面位置还是后面位置,不然两个人可能就会重叠在一起了。所以说,人物上船的动作是和当前船上已有人的属性是有关的。

那么如何解决这个问题?一种直观的做法就是给船添加两个BOOL属性,分别记录前座和后座有没有人。每个人上来的时候都先查看前座的情况,再决定是坐前座还是后座。当然了前面首先需要判断船是否已经满人了。另一种做法就是增加一个PersonList来记录已经上来的人。前面的方法相对好一点,因为后面的方法会将上船的精灵retain一次,下船再释放掉,增加了一点点系统消耗。不过目前我还是用的第二种。即我在BoatSprite中加入了PersonList属性。

接下来上代码:

1. BoatSprite

BoatSprite.h

#import "CCSprite.h"
#import "PersonSprite.h"

@interface BoatSprite : CCSprite

@property (strong,nonatomic) NSMutableArray *personList;

@property (assign,nonatomic) int priestNumber; //record the number of priests on the boat
@property (assign,nonatomic) int devilNumber; //record the number of devils on the boat

@property (assign,nonatomic) Side boatSide; //record the side the boat currently on

+(id)initBoatWithFile:(NSString *)file;

@end

BoatSprite.m
#import "BoatSprite.h"

@implementation BoatSprite

+(id)initBoatWithFile:(NSString *)file
{
BoatSprite *temp = [BoatSprite spriteWithFile:file];
PublicArg *arg = [PublicArg sharedArg];

temp.scale = 0.5f;
temp.personList = [[NSMutableArray alloc]initWithCapacity:2];
temp.priestNumber = 0;
temp.devilNumber = 0;
temp.boatSide = Right;
temp.position = arg.boatRightPoint;

return temp;
}
@end

2. BankSprite

BankSprite.h

#import "CCSprite.h"
#import "PersonSprite.h"

@interface BankSprite : CCSprite

@property (assign,nonatomic) int priestNumber; //record the number of priests on the bank
@property (assign,nonatomic) int devilNumber; //record the number of devils on the bank

@property (assign,nonatomic) Side bankSide; //record the side of the bank

-(id) initWithSide:(Side)side;

@end

BankSprite.m

#import "BankSprite.h"

@implementation BankSprite

-(id) initWithSide:(Side)side
{
if( (self=[super init]) ) {
self.bankSide = side;

if (side == Right)
{
_priestNumber = 3;
_devilNumber = 3;
}
else
{
_priestNumber = 0;
_devilNumber = 0;
}
}
return self;
}

@end

这次的部分还是比较简单的。下一次就到大BOSS-----BaseLayer游戏逻辑的设计了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: