Original Post
Hi there..i have been working on a game which uses accelerometer. The map i'm using is made using Tiled and i'm having problem implementing accelerometer to move the character. I've tried it but the movement is not smooth at all and very jumpy. I'm using xcode and cocos2d to make the game. Here is my code:
[spoiler]
// Import the interfaces
#import "HelloWorldLayer.h"
#import "SimpleAudioEngine.h"
#define kFilterFactor 0.05
@implementation HelloWorldHud
-(id) init
{
if ((self = [super init])) {
CGSize winSize = [[CCDirector sharedDirector] winSize];
label = [CCLabelTTF labelWithString:@"0" dimensions:CGSizeMake(50, 20) alignment:UITextAlignmentRight fontName:@"Verdana-Bold" fontSize:18.0];
label.color = ccc3(0,0,0);
int margin = 10;
label.position = ccp(winSize.width - (label.contentSize.width/2) - margin, label.contentSize.height/2 + margin);
[self addChild:label];
totalTime = 60;
timeLabel = [CCLabelTTF labelWithString:@"60" fontName:@"Arial" fontSize:18];
timeLabel.color = ccc3(0, 0, 0);
timeLabel.position = CGPointMake(winSize.width/2, winSize.height);
timeLabel.anchorPoint = CGPointMake(0.5f, 1.0f);
[self addChild:timeLabel];
[self schedule: @selector(update:)];
}
return self;
}
- (void)numCollectedChanged:(int)numCollected {
[label setString:[NSString stringWithFormat:@"%d", numCollected]];
}
-(void)update:(ccTime)dt
{
totalTime -= dt;
currentTime = (int)totalTime;
if(totalTime > currentTime)
{
//myTime = currentTime;
[timeLabel setString:[NSString stringWithFormat:@"%02d:%02d", currentTime/60, currentTime%60]];
}
}
@end
// HelloWorldLayer implementation
@implementation HelloWorldLayer
@synthesize tileMap = _tileMap;
@synthesize background = _background;
@synthesize player = _player;
@synthesize meta = _meta;
@synthesize foreground = _foreground;
@synthesize numCollected = _numCollected;
@synthesize hud = _hud;
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];
// add layer as a child to scene
[scene addChild: layer];
layer.tag = 1;
HelloWorldHud *hud = [HelloWorldHud node];
[scene addChild:hud];
layer.hud = hud;
// return the scene
return scene;
}
// on "init" you need to initialize your instance
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init])) {
[[SimpleAudioEngine sharedEngine] preloadEffect:@"pickup.caf"];
[[SimpleAudioEngine sharedEngine] preloadEffect:@"hit.caf"];
[[SimpleAudioEngine sharedEngine] preloadEffect:@"move.caf"];
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"TileMap.caf"];
//self.isTouchEnabled = YES;
self.isAccelerometerEnabled = YES;
UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
accel.updateInterval = 1.0f/60.0f;
//load background
self.tileMap = [CCTMXTiledMap tiledMapWithTMXFile:@"TileMap.tmx"];
self.background = [_tileMap layerNamed:@"Background"];
self.foreground = [_tileMap layerNamed:@"Foreground"];
//load collidable tile
self.meta = [_tileMap layerNamed:@"Meta"];
_meta.visible = NO;
//starting point
CCTMXObjectGroup *objects = [_tileMap objectGroupNamed:@"Objects"];
NSAssert(objects !=nil, @"'Objects' object group not found");
NSMutableDictionary *spawnPoint = [objects objectNamed:@"SpawnPoint"];
NSAssert(spawnPoint !=nil, @"SpawnPoint object not found");
int x = [[spawnPoint valueForKey:@"x"] intValue];
int y = [[spawnPoint valueForKey:@"y"] intValue];
int tileSpawnWidth = _tileMap.tileSize.width;
int tileSpawnHeight = _tileMap.tileSize.height;
x = (x - (x % tileSpawnWidth)) + (tileSpawnWidth/2);
y = (y - (y % tileSpawnHeight)) + (tileSpawnHeight/2);
//load player
self.player = [CCSprite spriteWithFile:@"Player.png"];
_player.position = ccp(x, y);
_player.tag = 2;
[self addChild:_player];
id setCamera = [CCFollow actionWithTarget:_player];
[self runAction:setCamera];
[self addChild: _tileMap z:-1];
}
return self;
}
-(CGPoint) tileCoordForPosition: (CGPoint)position {
int x = position.x / _tileMap.tileSize.width;
int y = ((_tileMap.mapSize.height * _tileMap.tileSize.height) - position.y) / _tileMap.tileSize.height;
return ccp(x,y);
}
-(void) registerWithTouchDispatcher
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
return YES;
}
-(void) setPlayerPosition:(CGPoint)position
{
//Convert x, y coordinate of player into tile coordinate
CGPoint tileCoord = [self tileCoordForPosition:position];
int tileGid = [_meta tileGIDAt:tileCoord];
if(tileGid) {
NSDictionary *properties = [_tileMap propertiesForGID:tileGid];
if(properties) {
//Check if collide with wall/stone
NSString *collision = [properties valueForKey:@"Collidable"];
if(collision && [collision compare: @"True"] == NSOrderedSame) {
[[SimpleAudioEngine sharedEngine] playEffect:@"hit.caf"];
return;
}
//Check if collide with collectable item
NSString *collectable = [properties valueForKey:@"Collectable"];
if(collectable && [collectable compare:@"True"] == NSOrderedSame) {
[_meta removeTileAt:tileCoord];
[_foreground removeTileAt:tileCoord];
self.numCollected++;
[_hud numCollectedChanged:_numCollected];
[[SimpleAudioEngine sharedEngine] playEffect:@"pickup.caf"];
}
}
}
[[SimpleAudioEngine sharedEngine] playEffect:@"move.caf"];
//_player.position = position;
ccTime moveDuration = 0.3;
id playerMove = [CCMoveTo actionWithDuration:moveDuration position:position];
id cameraMove = [CCFollow actionWithTarget:_player worldBoundary:CGRectMake(0, 0, (_tileMap.mapSize.width * _tileMap.tileSize.width), (_tileMap.mapSize.height * _tileMap.tileSize.height))];
[_player runAction:playerMove];
[self runAction:cameraMove];
}
#define kPlayerSpeed 100
#define kHeroMovementAction 1
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
//UIAccelerationValue accelX, accelY;
//accelX = (acceleration.x*kFilterFactor) + (accelX*(1.0 - kFilterFactor));
//accelY = (acceleration.y*kFilterFactor) + (accelY*(1.0 - kFilterFactor));
HelloWorldLayer *layer = (HelloWorldLayer *) [[[CCDirector sharedDirector] runningScene] getChildByTag:1];
CCSprite *playerSprite = (CCSprite *) [layer getChildByTag:2];
CGPoint playerPos;
float destX, destY;
BOOL shouldMove = NO;
float currentX = playerSprite.position.x;
float currentY = playerSprite.position.y;
if(acceleration.x > 0.25)
{
destX = currentX - (acceleration.y * kPlayerSpeed);
destY = currentY + (acceleration.x * kPlayerSpeed);
shouldMove = YES;
} else
if(acceleration.x < -0.25)
{
destX = currentX - (acceleration.y * kPlayerSpeed);
destY = currentY + (acceleration.x * kPlayerSpeed);
shouldMove = YES;
} else
if(acceleration.y < -0.25)
{
destX = currentX - (acceleration.y * kPlayerSpeed);
destY = currentY + (acceleration.x * kPlayerSpeed);
shouldMove = YES;
} else
if(acceleration.y > 0.25)
{
destX = currentX - (acceleration.y * kPlayerSpeed);
destY = currentY + (acceleration.x * kPlayerSpeed);
shouldMove = YES;
} else
{
destX = currentX;
destY = currentY;
}
playerPos.x = destX;
playerPos.y = destY;
if(shouldMove)
{
CGSize wins = [[CCDirector sharedDirector] winSize];
if(destX < 30 || destX > wins.width - 30 || destY < 30 || destY > wins.height - 100)
{
[self setPlayerPosition:playerPos];
}
else
{
CCAction *action = [CCMoveTo actionWithDuration:1 position:CGPointMake(destX, destY)];
[action setTag:kHeroMovementAction];
[playerSprite runAction:action];
}
}
else
{
[playerSprite stopActionByTag:kHeroMovementAction];
}
}
@end
[/spoiler]
Hope that someone could help me solve this problem. Thank You.
[spoiler]
// Import the interfaces
#import "HelloWorldLayer.h"
#import "SimpleAudioEngine.h"
#define kFilterFactor 0.05
@implementation HelloWorldHud
-(id) init
{
if ((self = [super init])) {
CGSize winSize = [[CCDirector sharedDirector] winSize];
label = [CCLabelTTF labelWithString:@"0" dimensions:CGSizeMake(50, 20) alignment:UITextAlignmentRight fontName:@"Verdana-Bold" fontSize:18.0];
label.color = ccc3(0,0,0);
int margin = 10;
label.position = ccp(winSize.width - (label.contentSize.width/2) - margin, label.contentSize.height/2 + margin);
[self addChild:label];
totalTime = 60;
timeLabel = [CCLabelTTF labelWithString:@"60" fontName:@"Arial" fontSize:18];
timeLabel.color = ccc3(0, 0, 0);
timeLabel.position = CGPointMake(winSize.width/2, winSize.height);
timeLabel.anchorPoint = CGPointMake(0.5f, 1.0f);
[self addChild:timeLabel];
[self schedule: @selector(update:)];
}
return self;
}
- (void)numCollectedChanged:(int)numCollected {
[label setString:[NSString stringWithFormat:@"%d", numCollected]];
}
-(void)update:(ccTime)dt
{
totalTime -= dt;
currentTime = (int)totalTime;
if(totalTime > currentTime)
{
//myTime = currentTime;
[timeLabel setString:[NSString stringWithFormat:@"%02d:%02d", currentTime/60, currentTime%60]];
}
}
@end
// HelloWorldLayer implementation
@implementation HelloWorldLayer
@synthesize tileMap = _tileMap;
@synthesize background = _background;
@synthesize player = _player;
@synthesize meta = _meta;
@synthesize foreground = _foreground;
@synthesize numCollected = _numCollected;
@synthesize hud = _hud;
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];
// add layer as a child to scene
[scene addChild: layer];
layer.tag = 1;
HelloWorldHud *hud = [HelloWorldHud node];
[scene addChild:hud];
layer.hud = hud;
// return the scene
return scene;
}
// on "init" you need to initialize your instance
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init])) {
[[SimpleAudioEngine sharedEngine] preloadEffect:@"pickup.caf"];
[[SimpleAudioEngine sharedEngine] preloadEffect:@"hit.caf"];
[[SimpleAudioEngine sharedEngine] preloadEffect:@"move.caf"];
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"TileMap.caf"];
//self.isTouchEnabled = YES;
self.isAccelerometerEnabled = YES;
UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
accel.updateInterval = 1.0f/60.0f;
//load background
self.tileMap = [CCTMXTiledMap tiledMapWithTMXFile:@"TileMap.tmx"];
self.background = [_tileMap layerNamed:@"Background"];
self.foreground = [_tileMap layerNamed:@"Foreground"];
//load collidable tile
self.meta = [_tileMap layerNamed:@"Meta"];
_meta.visible = NO;
//starting point
CCTMXObjectGroup *objects = [_tileMap objectGroupNamed:@"Objects"];
NSAssert(objects !=nil, @"'Objects' object group not found");
NSMutableDictionary *spawnPoint = [objects objectNamed:@"SpawnPoint"];
NSAssert(spawnPoint !=nil, @"SpawnPoint object not found");
int x = [[spawnPoint valueForKey:@"x"] intValue];
int y = [[spawnPoint valueForKey:@"y"] intValue];
int tileSpawnWidth = _tileMap.tileSize.width;
int tileSpawnHeight = _tileMap.tileSize.height;
x = (x - (x % tileSpawnWidth)) + (tileSpawnWidth/2);
y = (y - (y % tileSpawnHeight)) + (tileSpawnHeight/2);
//load player
self.player = [CCSprite spriteWithFile:@"Player.png"];
_player.position = ccp(x, y);
_player.tag = 2;
[self addChild:_player];
id setCamera = [CCFollow actionWithTarget:_player];
[self runAction:setCamera];
[self addChild: _tileMap z:-1];
}
return self;
}
-(CGPoint) tileCoordForPosition: (CGPoint)position {
int x = position.x / _tileMap.tileSize.width;
int y = ((_tileMap.mapSize.height * _tileMap.tileSize.height) - position.y) / _tileMap.tileSize.height;
return ccp(x,y);
}
-(void) registerWithTouchDispatcher
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
return YES;
}
-(void) setPlayerPosition:(CGPoint)position
{
//Convert x, y coordinate of player into tile coordinate
CGPoint tileCoord = [self tileCoordForPosition:position];
int tileGid = [_meta tileGIDAt:tileCoord];
if(tileGid) {
NSDictionary *properties = [_tileMap propertiesForGID:tileGid];
if(properties) {
//Check if collide with wall/stone
NSString *collision = [properties valueForKey:@"Collidable"];
if(collision && [collision compare: @"True"] == NSOrderedSame) {
[[SimpleAudioEngine sharedEngine] playEffect:@"hit.caf"];
return;
}
//Check if collide with collectable item
NSString *collectable = [properties valueForKey:@"Collectable"];
if(collectable && [collectable compare:@"True"] == NSOrderedSame) {
[_meta removeTileAt:tileCoord];
[_foreground removeTileAt:tileCoord];
self.numCollected++;
[_hud numCollectedChanged:_numCollected];
[[SimpleAudioEngine sharedEngine] playEffect:@"pickup.caf"];
}
}
}
[[SimpleAudioEngine sharedEngine] playEffect:@"move.caf"];
//_player.position = position;
ccTime moveDuration = 0.3;
id playerMove = [CCMoveTo actionWithDuration:moveDuration position:position];
id cameraMove = [CCFollow actionWithTarget:_player worldBoundary:CGRectMake(0, 0, (_tileMap.mapSize.width * _tileMap.tileSize.width), (_tileMap.mapSize.height * _tileMap.tileSize.height))];
[_player runAction:playerMove];
[self runAction:cameraMove];
}
#define kPlayerSpeed 100
#define kHeroMovementAction 1
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
//UIAccelerationValue accelX, accelY;
//accelX = (acceleration.x*kFilterFactor) + (accelX*(1.0 - kFilterFactor));
//accelY = (acceleration.y*kFilterFactor) + (accelY*(1.0 - kFilterFactor));
HelloWorldLayer *layer = (HelloWorldLayer *) [[[CCDirector sharedDirector] runningScene] getChildByTag:1];
CCSprite *playerSprite = (CCSprite *) [layer getChildByTag:2];
CGPoint playerPos;
float destX, destY;
BOOL shouldMove = NO;
float currentX = playerSprite.position.x;
float currentY = playerSprite.position.y;
if(acceleration.x > 0.25)
{
destX = currentX - (acceleration.y * kPlayerSpeed);
destY = currentY + (acceleration.x * kPlayerSpeed);
shouldMove = YES;
} else
if(acceleration.x < -0.25)
{
destX = currentX - (acceleration.y * kPlayerSpeed);
destY = currentY + (acceleration.x * kPlayerSpeed);
shouldMove = YES;
} else
if(acceleration.y < -0.25)
{
destX = currentX - (acceleration.y * kPlayerSpeed);
destY = currentY + (acceleration.x * kPlayerSpeed);
shouldMove = YES;
} else
if(acceleration.y > 0.25)
{
destX = currentX - (acceleration.y * kPlayerSpeed);
destY = currentY + (acceleration.x * kPlayerSpeed);
shouldMove = YES;
} else
{
destX = currentX;
destY = currentY;
}
playerPos.x = destX;
playerPos.y = destY;
if(shouldMove)
{
CGSize wins = [[CCDirector sharedDirector] winSize];
if(destX < 30 || destX > wins.width - 30 || destY < 30 || destY > wins.height - 100)
{
[self setPlayerPosition:playerPos];
}
else
{
CCAction *action = [CCMoveTo actionWithDuration:1 position:CGPointMake(destX, destY)];
[action setTag:kHeroMovementAction];
[playerSprite runAction:action];
}
}
else
{
[playerSprite stopActionByTag:kHeroMovementAction];
}
}
@end
[/spoiler]
Hope that someone could help me solve this problem. Thank You.