我正在尝试从Tiled地图编辑器tmx文件制作一些移动的图块。 我在他们自己的层中有移动的瓷砖,我只是想让它们向上移动,然后当它们达到某个y时,向下移动等等。
我一直在寻找一个明确的方法来完成这个,但我的努力没有成功。
我尝试使用一些方法here。
我对cocos2d开发一般都是新手,所以我对此有所了解。非常感谢您的宝贵时间。如果您有任何问题,请询问! :) 此外,如果它有帮助,我试图移动的瓷砖是大T形。
最终更新:
(删除了更多不相关的代码,以便将来任何人都可以轻松找到我的解决方案(完整的答案如下),你可以在上面的链接中找到我的图层迭代方法。)
好的,所以我终于让它接近我想要的......我不认为这是最理想的做法,但这就是我所拥有的。
注意:为了让它适合你,你必须让你的应用程序退出调试模式,否则它会滞后/让玩家掉到地上(至少它对我来说......)。
我有一个更新功能,每帧调用某些功能。 (检查碰撞,移动平台等)。
该更新函数调用我的移动平台函数..
像这样:[self movePlatforms:0.1];
这是我的movePlatforms函数..
-(void)movePlatforms: (ccTime) dt{
if(goingDown){
moveCount++;
}else{
moveCount--;
}
CGSize s = [movingTiles layerSize];
for( int x=0; x<s.width;x++) {
for( int y=0; y< s.height; y++ ) {
CCSprite *tile = [movingTiles tileAt:ccp(x,y)];
if(goingDown){
CGPoint newPosition = ccp(tile.position.x, tile.position.y - 1);
tile.position = newPosition;
if(moveCount >= 100){
goingDown = false;
}
}else{
CGPoint newPosition = ccp(tile.position.x, tile.position.y + 1);
tile.position = newPosition;
if(moveCount <= 0){
goingDown = true;
}
}
}
}
}
基本上,我创建了一个int moveCount和一个BOOL goDown来跟踪我的movePlatform函数被调用了多少次。所以100次通话后,它会切换方向。
(这对我来说很好,你可能还需要像碰撞检测器这样的其他东西,如果是这样的话就使用它。)
if (CGRectIntersectsRect([someSprite boundingBox], [someSprite boundingBox])) {
//Do something
}
希望这对未来的某个人有用,我知道这对我来说非常头疼,它可能甚至没有正确完成或有更好的方法来做到这一点,但如果这有助于你,那就是真棒!
答案 0 :(得分:2)
创建和删除切片会影响您的性能。 而不是它,尝试移动瓷砖改变他们的位置:
CCSprite *tile = [movingTiles tileAt:ccp(92,platformY)];
[movingTiles removeTileAt:ccp(92,platformY)];
CGPoint newTilePosition = tile.position;
if (goingDown){
newTilePosition.y ++;
if(newTilePosition.y >= 20){
goingDown = false;
}
}else{
newTilePosition.y --;
if(newTilePosition.y <= 10){
goingDown = true;
}
}
tile.position = newTilePosition;
答案 1 :(得分:1)
这是我的移动瓷砖如何工作的一步一步的步骤,这只与移动的瓷砖有关,而不是别的。
注意:你需要将它作为一个版本(而不是调试版)来运行,以便让所有内容顺利运行,而不是让你的角色掉在地上。
在界面中我创建了这些变量:
@interface HelloWorldLayer(){
CCTMXTiledMap *map;
BOOL goingDown;
int moveCount;
}
CCTMXTiledMap是我的地图的实例。 BOOL和int是我用来跟踪移动磁贴的两个变量。
-(id) init {
if( (self=[super init]) ) {
// add our map
map = [[CCTMXTiledMap alloc] initWithTMXFile:@"level1-1.tmx"];
map.position = ccp(0,0);
[self addChild:map];
//add our moving platforms layer
movingTiles = [map layerNamed:@"moving_platforms"];
//set the variables I use to keep track of the moving platforms
goingDown = true;
moveCount = 0;
//schedule my update method
[self schedule:@selector(update:)];
}
return self;
}
在init方法之后,我创建了我的移动平台方法:
-(void)movePlatforms: (ccTime) dt{
if(goingDown){
moveCount++;
}else{
moveCount--;
}
CGSize s = [movingTiles layerSize];
for( int x=0; x<s.width;x++) {
for( int y=0; y< s.height; y++ ) {
CCSprite *tile = [movingTiles tileAt:ccp(x,y)];
if(goingDown){
CGPoint newPosition = ccp(tile.position.x, tile.position.y - 1);
tile.position = newPosition;
if(moveCount >= 100){
goingDown = false;
}
}else{
CGPoint newPosition = ccp(tile.position.x, tile.position.y + 1);
tile.position = newPosition;
if(moveCount <= 0){
goingDown = true;
}
}
}
}
}
所以这就是魔术发生的地方,我使用了here得到的方法,而绅士Mauricio Tollin告诉我,我可以更新一个瓦片位置,而不是销毁并重新创建它们。
因此,我遍历移动平台层中的每个磁贴,并告诉他们每次调用时都会关闭1,直到moveCount&gt; = 100,然后它说goDown现在为false,并且它会切换方向。从那里它来回,数到100,然后再回来。
如果你想让它移动更长时间,只需增加100到200或任何你想要的。 (或者您可以使用检查来检测碰撞,当它与指定的精灵发生碰撞时,您可以将其更改。如果这更符合您的要求,请使用此方法。)
if (CGRectIntersectsRect([someSprite boundingBox], [someSprite boundingBox])) {
//Do something
}
毕竟,我创建了更新方法:
-(void)update:(ccTime)dt{
[self movePlatforms:0.1];
}
在init方法中,它调度每帧调用的update方法,然后update方法将运行movePlatforms方法(或需要经常检查的任何其他函数,例如危险检测等)。
您还可以通过更改传递给movePlatforms的时间来使平台移动得更慢,或者您可以在init方法中安排更慢的更新间隔。
我希望将来可以帮助某人,我只是想通过更深入的过程来创建这个答案,因为我的问题帖子在我学习的时候真的没有组织和大量编辑。