如何使用cocos2d来制作一个塔防游戏:第二部分
教程截图:
欢迎来到《如何使用cocos2d制作一个塔防游戏》的第二部分--今天,我们将添加代码来放置炮塔。哈哈,放置炮塔,很hgih吧!如果你还没有读过(译)如何使用cocos2d来制作一个塔防游戏:第一部分,你可能要先看看再继续。
好吧,你从上个教程可能学到了,那个还不是完整真实的游戏--我们需要使之更真实。但是,我们并不需要一个复杂的A*算法,或者DFS/BFS(深度优先和广度优先),或者Best-first算法来查找路径。实际上,我们根本不需要基于tile的地图。但是,为了遵循KISS原则(keep it 易做图,stupid),我们还是采用tild map的做法。
所以,让我们来看看如何放置炮塔,以及炮塔是怎么工作的----请原谅我的烂枪法。
这里有本教程的完整源代码。
炮塔放置的方式就是,玩家从Game HUD 中点选中一个塔,然后拖动到某个可以放置的位置,然后松手就ok了。塔也有自己的攻击范围,用一个带阴影的圆表示。这个圆会在你点选中Hud中的炮塔的时候显示出来,放置好炮塔之后就消失了,表明不可以再移动了,除非把它卖掉!现在,有意思的部分来了----如果用户把塔拖到沙漠地带,我们就在那个位置显示一个”机关炮“。如果拖到其他地方(比如creep行走的路上面),我们就让它不可以放置,如果松手,塔就会回到hud里面。
你可以看到,好多地方都有沙子,一个塔可以放置在一个给定的tile上面。我们实现的方式就是两个函数---”tileCoordForPosition“和”addTower“方法。 “tileCoordForPosition” 是一种快速定位给定point是哪个tile的坐标点,而“addTower”函数就是实际放置炮塔的方法。具体实现如下:
- (CGPoint) tileCoordForPosition:(CGPoint) position{ int x = position.x / self.tileMap.tileSize.width; int y = ((self.tileMap.mapSize.height * self.tileMap.tileSize.height) - position.y) / self.tileMap.tileSize.height; return ccp(x,y);}-(void)addTower: (CGPoint)pos { DataModel *m = [DataModel getModel]; Tower *target = nil; CGPoint towerLoc = [self tileCoordForPosition: pos]; int tileGid = [self.background tileGIDAt:towerLoc]; NSDictionary *props = [self.tileMap propertiesForGID:tileGid]; NSString *type = [props valueForKey:@"buildable"]; NSLog(@"Buildable: %@", type); if([type isEqualToString: @"1"]) { target = [MachineGunTower tower]; target.position = ccp((towerLoc.x * 32) + 16, self.tileMap.contentSize.height - (towerLoc.y * 32) - 16); [self addChild:target z:1]; target.tag = 1; [m._towers addObject:target]; } else { NSLog(@"Tile Not Buildable"); }} 你可能看到“addTower”方法在我们用户想让他放置在某个位置的时候被调用了---然后我们使用“tileCoordPosition”方法来得到tile位置,并且使用这个位置来得到tile本身。然后查找tile的属性是不是“buildable”的。如果属性值==1,那么就可以放置。相应的,我们就创建一个tower,然后计算一下放置的位置,然后把塔加到层里去。如果属性“buidable”==null或者0的话,那么就什么也不做,只输出一句话。
由于我们刚刚提到了tower类,所以,它的实现非常重要,让我们来看一看:
#import "cocos2d.h"#import "DataModel.h"@inte易做图ce Tower : CCSprite { int _range; CCSprite * selSpriteRange;}@property (nonatomic, assign) int range;@end@inte易做图ce MachineGunTower : Tower {}+ (id)tower;- (void)towerLogic:(ccTime)dt;@end
这是一个非常基础的类---我们定义了炮塔可以攻击的范围,同时还有选中一个炮塔并移动它的时候,会出现的一个虚拟的射程范围精灵。你可能也注意到了,我们还定义了一个MachineGunTower类,它从Tower派生过来的。因为,每一种tower都有一些特殊的属性,所以我们定义不同的类来使得事情变得更加简单,并且更容易管理。基本上,所有的tower都有一些共同的特点,比如射程是多少,杀伤力是多少等。
接下来,看它的实现:
#import "Tower.h"@implementation Tower@synthesize range = _range;@end@implementation MachineGunTower+ (id)tower { MachineGunTower *tower = nil; if ((tower = [[[super alloc] initWithFile:@"MachineGunTurret.png"] autorelease])) { tower.range = 200; [tower schedule:@selector(towerLogic:) interval:0.2]; } return tower;}-(id) init{ if ((self=[super init]) ) { //[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES]; } return self;}-(void)towerLogic:(ccTime)dt {}@end
这里也没太多好说的---只是一个基类,我们甚至不需要实现init方法。因为,我们将在下一个教程中添加一些代码,这里暂时空白,不过并没有关系。我们加载炮塔的图片,同时设置射程,并且创建了一个towerLogic调度器,时间间隔是0.2秒。这样,塔就可以坐在那儿了,但是,这个towerLogic方法还是空的,不过下个教程中,我们将添加一些代码!
现在,你看到了tower的代码,接下来一件比较重要的事,就是向你展示如何实现游戏的hud--它里面包含了可以被选中的tower,而且可以把它们拖到游戏layer中去。这时,我们有两个层被加到场景中去了,下面是gameHud的代码:
#import "cocos2d.h"@inte易做图ce GameHUD : CCLayer { CCSprite * background; CCSprite * selSpriteRange; CCSprite * selSprite; NSMutableArray * movableSprites;}+ (GameHUD *)sharedHUD;@end 这里,我们定义了层的背景图片,selSprite是tower图片的一个拷贝,可以选中它,并在屏幕上拖动。而selSpriteRange是一个射程图片,当我们选中一个塔在屏幕上移动的时候,在塔的周围会有一个圆形的阴影,代表了塔的射程。最后,我们定义了movableSprites数组,它是gameLayer中可以供玩家选取的所有的炮塔图片的集合。
让我们看看gameHud的具体实现吧:
-(id) init{ if ((self=[super init]) ) { CGSize winSize = [CCDirector sharedDirector].winSize; // Draw the background of the game HUD [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGB565]; background = [CCSprite spriteWithFile:@"hud.png"]; background.anchorPoint = ccp(0,0); [self addChild:background]; [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_Default]; // Load the images of the towers well have and draw them to the game HUD layer movableSprites = [[NSMutableArray alloc] init]; NSArray *images = [NSArray arrayWithObjects:@"MachineGunTurret.png", @"MachineGunTurret.png", @"MachineGunTurret.png", @"MachineGunTurret.png", nil]; for(int i = 0; i < images.count; ++i) { NSString *image = [images objectAtIndex:i]; CCSprite *sprite = [CCSprite spriteWithFile:image]; float offsetFraction = ((float)(i+1))/(images.count+1); sprite.position = ccp(winSize.width*offsetFraction, 35); [self addChild:sprite]; [movableSprites addObject:sprite]; } [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES]; } return self;}
我希望代
补充:综合编程 , 其他综合 ,