我对这件事情有点新鲜,编码和寻求帮助所以我不确定什么是酷的,什么不是。我已经完成了我的第一个游戏的编码,现在我正在测试它,一段时间后感觉生涩。我注意到CPU爬升到99%然后FPS下降到45左右。即使游戏闲置也会发生这种情况。
这场比赛基本上是一条龙在吃火球之前飞来飞去,在能量耗尽之前着陆。土地太快而且结束了。转向是通过加速度计。
正如我所说,我不确定这里有什么问题,所以我只是想出去发布我的主要实现文件,并希望有人发现我的很快就会被撕成碎片。如果它没有完成,请告诉我,我会把它取下来。
感谢。
#import "Gameplay.h"
#import "CCTextureCache.h"
#import <CoreMotion/CoreMotion.h>
//LEAVE ALONE - Change energy cost to affect flight time
NSInteger energyCapacity = 1000;
//LEAVE ALONE - Change energy cost to affect flight time
NSInteger energyRemaining;
//Make smaller to make flight last longer
NSInteger energyCost = 3;
//Number of fireBalls spawned
NSInteger numberOfFireBalls = 30;
NSInteger bonusBalls = 30;
//Move more towards 0 to make it more difficult to land
CGFloat maximumVerticalVelocity = (-60);
NSInteger _score;
NSInteger _totalScore;
CGFloat _energyMultiplier;
#define ARC4RANDOM_MAX 0x100000000
// Constants defining the x coord boundaries for the landing pad
static const int minimumPadX = 50;
static const int maximumPadX = 260;
@implementation Gameplay {
//game play objects
CCPhysicsNode *_physicsNode;
CCNode *_contentNode;
CCSprite *_dragon;
CCSprite *_ground;
CCSprite *_landingPad;
CCSprite *_background1;
CCSprite *_background2;
CCSprite *_background3;
CCSprite *_energyBar;
//NSMutableArray *_fireBalls;
//game over objects
CCLabelTTF *_scoreLabel;
CCLabelTTF *_showFireBallsLabel;
CCLabelTTF *_showenergyLabel;
CCLabelTTF *_showScoreLabel;
CCLabelTTF *_highscoreLabel;
CCLabelTTF *_gameResultsLabel;
CCLabelTTF *_crashNotice;
CCLabelTTF *_groundNotice;
CCButton *_retryButtonMain;
//various handlers
double _rotationImpulse;
CMMotionManager *_motionManager;
BOOL ready;
BOOL crashed;
BOOL takenOff;
float accelerX;
}
// is called when CCB file has completed loading
- (void)didLoadFromCCB {
//setup initialisations
_crashNotice.visible = NO;
_groundNotice.visible = NO;
_scoreLabel.visible = YES;
_score = 0;
energyRemaining = 1000;
ready = NO;
crashed = NO;
takenOff = NO;
_retryButtonMain.visible = NO;
//collision type declarations
_dragon.physicsBody.collisionType = @"dragon";
_ground.physicsBody.collisionType = @"ground";
_landingPad.physicsBody.collisionType = @"landingPad";
_physicsNode.collisionDelegate = self;
//_physicsNode.debugDraw = YES;
//place the landing pad randomly and place dragon on top
CGFloat random = ((double)arc4random() / ARC4RANDOM_MAX);
CGFloat range = maximumPadX - minimumPadX;
_landingPad.position = ccp((random * range)+50, _landingPad.position.y);
_dragon.physicsBody.velocity = ccp(0,0);
_dragon.position = ccp(_landingPad.position.x, 61);
//Spawn the fireBalls
for (int i = 0; i < numberOFireBalls; i++) {
[self spawnFireBall];
}
//Spawm fireBall gold
[self spawnFireBallGold];
}
- (id)init{
if (self = [super init]){
_motionManager = [[CMMotionManager alloc] init];
}return self;
}
- (void)onEnter{
[super onEnter];
mAllowTouch = YES;
// tell this scene to accept touches
self.userInteractionEnabled = true;
[_motionManager startAccelerometerUpdates];
}
- (void)onExit{
[super onExit];
[_motionManager stopAccelerometerUpdates];
}
#define filteringFactor 0.07
- (void)update:(CCTime)delta {
if (ready){
//Accelerometer handling
CMAccelerometerData *accelerometerData = _motionManager.accelerometerData;
CMAcceleration acceleration = accelerometerData.acceleration;
_rotationImpulse = acceleration.x * 20000 *delta;
//dragon rotation dampening using low pass filter
accelerX = ((acceleration.x * filteringFactor) + (accelerX * (1.0 - filteringFactor)));
_dragon.rotation = accelerX * 100;
_dragon.rotation = clampf(_dragon.rotation, -50, 50);
//or high pass
//accelerX = acceleration.x - ( (acceleration.x * filteringFactor) + (accelerX * (1.0 - filteringFactor)) );
}
if(_dragon.position.y > 67){
takenOff = YES;
}
//Sets where the camera will stop in the Y direction
CGRect worldYBoundary = CGRectMake(0, 0, _background1.contentSize.width, 2880);
[_contentNode runAction:[CCActionFollow actionWithTarget:_dragon worldBoundary:worldYBoundary]];
//Clamp the XY velocity of the dragon
float yVelocity = clampf(_dragon.physicsBody.velocity.y, -1 * MAXFLOAT, 400.f);
float xVelocity = clampf(_dragon.physicsBody.velocity.x, -500.f, 500.f);
_dragon.physicsBody.velocity = ccp(xVelocity, yVelocity);
//If the energy runs out, remove the flames
if(energyRemaining <= 0){
[_dragon setTexture:[[CCTextureCache sharedTextureCache] addImage:@"dragonNoFlames.png"]];
}
//turn values into floats for calculations
float energyRemainingFloat = (float) energyRemaining;
float energyCapacityFloat = (float) energyCapacity;
//Reflect energy remaining in the onscreen bar
_energyBar.scaleX = (energyRemainingFloat/energyCapacityFloat);
//Keep dragon on the screen
float maxX = _ground.contentSize.width - _dragon.contentSize.width/2;
float minX = _dragon.contentSize.width/2;
float maxY = self.contentSize.height - _dragon.contentSize.height/2;
if(_dragon.position.x < minX){
_dragon.position = ccp(minX, _dragon.position.y);
_dragon.physicsBody.velocity = ccp(0,_dragon.physicsBody.velocity.y);
}else if(_dragon.position.x > maxX){
_dragon.position = ccp(maxX, _dragon.position.y);
_dragon.physicsBody.velocity = ccp(0,_dragon.physicsBody.velocity.y);
}
if (_dragon.position.y > maxY) {
_dragon.position = ccp(_dragon.position.x, maxY);
_dragon.physicsBody.velocity = ccp(_dragon.physicsBody.velocity.x, 0);
}
}
//Spawn fireBalls on visible screen
-(void)spawnfireBall{
// _fireBalls = [NSMutableArray array];
CCNode *fireBall = [CCBReader load:@"fireBall"];
CGFloat randomX = ((double)arc4random() / ARC4RANDOM_MAX);
CGFloat randomY = ((double)arc4random() / ARC4RANDOM_MAX);
CGFloat rangeX = 320 - 48;
CGFloat rangeY = self.contentSize.height - 48;
fireBall.position = ccp((randomX * rangeX)+24, (randomY * rangeY)+ _ground.contentSize.height + _dragon.contentSize.height);
fireBall.physicsBody.velocity = ccp(0,0);
[_physicsNode addChild:fireBall];
// [_fireBalls addObject:fireBall];
}
-(void)spawnfireBallGold{
CCNode *fireBallGold = [CCBReader load:@"BonusBall"];
CGFloat randomX = ((double)arc4random() / ARC4RANDOM_MAX);
CGFloat randomY = ((double)arc4random() / ARC4RANDOM_MAX);
CGFloat rangeX = 320 - 48;
CGFloat rangeY = self.contentSize.height*5 - 48;
fireBallGold.position = ccp((randomX * rangeX)+24, (randomY * rangeY)+ _ground.contentSize.height + _dragon.contentSize.height);
fireBallGold.physicsBody.velocity = ccp(0,0);
[_physicsNode addChild:fireBallGold];
// [_fireBalls addObject:fireBall];
}
//On collision with fireBall, add to score, remove fireBall and spawn another
-(void)ccPhysicsCollisionPostSolve:(CCPhysicsCollisionPair *)pair dragon:(CCNode *)nodeA fireBall:(CCNode *)nodeB{
[self fireBallRemoved:nodeB];
// [self spawnfireBallGold];
[self spawnfireBall];
_score ++;
_scoreLabel.string = [NSString stringWithFormat:@"%d", _score];
}
//On collision with ground, explode and remove dragon. End game
-(void)ccPhysicsCollisionPostSolve:(CCPhysicsCollisionPair *)pair dragon:(CCNode *)nodeA ground:(CCNode *)nodeB{
[self landedBadly];
}
//Collision detection handling maximum landing velocity
-(BOOL)ccPhysicsCollisionPreSolve:(CCPhysicsCollisionPair *)pair dragon:(CCNode *)nodeA landingPad:(CCNode *)nodeB{
//if travelling too fast on landing..
if (_dragon.physicsBody.velocity.y < maximumVerticalVelocity){
[self landedBadly];
//if landed safely
}else if (ready && takenOff){
[self landedSafely];
}return TRUE;
}
-(void)ccPhysicsCollisionPostSolve:(CCPhysicsCollisionPair *)pair dragon:(CCNode *)nodeA bonus:(CCNode *)nodeB{
for (int i = 0; i < bonusBalls; i++){
[self fireBallRemoved:nodeB];
[self spawnFireBall];
}
}
-(void)landedSafely{
mAllowTouch = NO;
ready = NO;
self.userInteractionEnabled = NO;
_dragon.physicsBody.velocity = ccp(0,0);
[_dragon setTexture:[[CCTextureCache sharedTextureCache] addImage:@"dragonNoFlames.png"]];
//convert NSIntegers to floats for calculations
float energyRemainingFloat = (float) energyRemaining;
float energyCapacityFloat = (float) energyCapacity;
//calculate energy multiplier
_energyMultiplier = 1/(((energyRemainingFloat/energyCapacityFloat)*(energyRemainingFloat/energyCapacityFloat))+0.001);
int newEnergyMultiplier = (_energyMultiplier + 0.5);
_totalScore = _score * newEnergyMultiplier;
//show game won state
[[OALSimpleAudio sharedInstance] playEffect:@"win.caf"];
_retryButtonMain.visible = YES;
_scoreLabel.visible = NO;
_showFireBallsLabel.visible = YES;
_gameResultsLabel.visible = YES;
_showScoreLabel.visible = YES;
_showenergyLabel.visible = YES;
_showenergyLabel.string = [NSString stringWithFormat:@"%.i", newEnergyMultiplier];
_showFireBallsLabel.string = [NSString stringWithFormat:@"%d", _score];
_showScoreLabel.string = [NSString stringWithFormat:@"%d", _totalScore];
}
-(void)landedBadly{
mAllowTouch = NO;
ready = NO;
crashed = YES;
self.userInteractionEnabled = NO;
[[OALSimpleAudio sharedInstance] playEffect:@"explode.caf"];
CCParticleSystem *explosion = (CCParticleSystem *)[CCBReader load:@"dragonExplosion"];
explosion.autoRemoveOnFinish = YES;
explosion.position = _dragon.position;
[_dragon.parent addChild:explosion];
_retryButtonMain.visible = YES;
_crashNotice.visible = YES;
[_dragon removeFromParentAndCleanup:YES];
}
//remove fireBalls method
- (void)fireBallRemoved:(CCNode *)fireBall {
[fireBall removeFromParent];
}
// The start of an anywhere touch event
- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
//Lets the touch interface know you're ready
ready = YES;
if(mAllowTouch){
if(energyRemaining > 0){
// Change the sprite texture to have flames
[_dragon setTexture:[[CCTextureCache sharedTextureCache] addImage:@"dragonFlames.png"]];
// enable firing of dragon while finger is pressed on screen
[self schedule:@selector(keepFiring) interval:0.07];
}
}}
// The end of a screen touch
- (void)touchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
//Change the image of the dragon to remove flames
[_dragon setTexture:[[CCTextureCache sharedTextureCache] addImage:@"dragonNoFlames.png"]];
// release the screen press
[self unschedule:@selector(keepFiring)];
}
-(void)keepFiring{
if(!crashed){
if(mAllowTouch){
if(energyRemaining > 0){
energyRemaining = energyRemaining - energyCost;
//apply angular and linear impulses
[_dragon.physicsBody applyImpulse:ccp(_rotationImpulse,320.f)];
}
}
}
}
- (void)resetGame {
// reload this level
[[CCDirector sharedDirector] replaceScene: [CCBReader loadAsScene:@"Gameplay"]];
}
@end