I have a gamepad with a direction pad and 2 buttons. All of them are digital (not analog).
I have a procedure for handling their events:
-(void)gamepadTick:(float)delta
{
...
if ([gamepad.B active]) {
[ship shoot];
}
...
}
And I call it via a command:
[self schedule:@selector(gamepadTick:) interval:1.0 / 60];
[ship shoot] calls shoot function from Weapon class:
-(void)shoot
{
Bullet *bullet = [Bullet bulletWithTexture:bulletTexture];
Ship *ship = [Ship sharedShip];
bullet.position = [ship getWeaponPosition];
[[[CCDirector sharedDirector] runningScene] addChild:bullet];
CGSize winSize = [[CCDirector sharedDirector] winSize];
int realX = ship.position.x;
int realY = winSize.height + bullet.contentSize.height / 2;
CGPoint realDest = ccp(realX, realY);
int offRealX = realX - bullet.position.x;
int offRealY = realY - bullet.position.y;
float length = sqrtf((offRealX*offRealX) + (offRealY*offRealY));
float velocity = 480/1; // 480pixels/1sec
float realMoveDuration = length / velocity;
[bullet runAction:[CCSequence actions:[CCMoveTo actionWithDuration:realMoveDuration position:realDest],
[CCCallFuncN actionWithTarget:self selector:@selector(bulletMoveFinished:)], nil]];
}
-(void)bulletMoveFinished:(id)sender
{
CCSprite *sprite = (CCSprite *)sender;
[[[CCDirector sharedDirector] runningScene] removeChild:sprite cleanup:YES];
}
The problem is the weapon shoots too much of bullets. Is it possible to reduce their amount without writing using of timers and functions which are separate for each button and direction pad?
-(void) update:(ccTime)delta {
totalTime += delta;
if (fireButton.active && totalTime > nextShotTime) {
nextShotTime = totalTime + 0.5f;
GameScene* game = [GameScene sharedGameScene];
[game shootBulletFromShip:[game defaultShip]];
}
// Allow faster shooting by quickly tapping the fire button if (fireButton.active == NO)
{
nextShotTime = 0;
}
}
it is an original code from "learn cocos2d game development" book by Steffen Itterheim. But I can improve this code a little.
Updated
It is harder to understand my code than the original one but it has a correct structure. It means the following: - global timer belongs to a scene; - ship can shoot via weapon; - weapon can shoot with bullets and delay between bullets belong to this weapon (not the scene as in the original example)
Scene class contains totalTime variable, a ship object and the following method to handle timer updating:
-(void)update:(ccTime)delta
{
totalTime += delta;
if (!fireButton.active) {
ship.weapon.nextShotTime = 0;
} else if (totalTime > ship.weapon.nextShotTime) {
[ship.weapon updateNextShotTime:totalTime];
[ship shoot];
}
}
Ship class contains a weapon object and a shoot method (this method is not actual for this question).
Weapon class contains nextShotTime variable and the following method:
-(void)updateNextShotTime:(ccTime)currentTime
{
nextShotTime = currentTime + 0.05f;
}