0

そのため、キャラクターのヘルスが 100 未満の場合 (テスト目的)、シーンを停止してゲーム オーバー シーンに移行するように設定しました。

if (playerDataManager.playerHealth < 100) {
   [[CCDirector sharedDirector]  replaceScene:[CCTransitionFade transitionWithDuration:3 scene: [GameLogic scene]]];
}

ただし、プレイヤーのヘルスが 100 を下回ると、新しいシーンに移動しますが、FPS は 60 から 5 に劇的に低下します。

のリストを取得すると、OpenGL error 0x0503 in -[EAGLView swapBuffers]そのように約 40 秒間フリーズしたままになり、その後 FPS がフリーズして 60 に戻り、次のリストを取得します。2012-07-13 10:37:50.234 Tilegame[93513:10a03] cocos2d: removeChildByTag: child not found!

その後、通常どおりアプリを続行し、メイン メニューに戻って新しいゲームを開始し、エラーを再現します。

#import "HelloWorldLayer.h"
#import "Menu.h"
#import "SimpleAudioEngine.h"
#import "LogCabinMap.h"
#import "LogShedMap.h"
#import "SaveData.h"
#import "pauseM.h"
#import "Player.h"
#import "GameLogic.h"

CCSprite *player;
CGPoint newPos;
int joyDegrees;

// HelloWorldLayer implementation
@implementation HelloWorldLayer

@synthesize tileMap = _tileMap;
@synthesize background = _background;
@synthesize buildings = _buildings;
@synthesize meta = _meta;
@synthesize player = _player;
@synthesize foreground = _foreground;
@synthesize numCollected = _numCollected;
@synthesize hud = _hud;


-(void) animateEnemy:(CCSprite*)enemy {
    //speed of the enemy
    ccTime actualDuration = .2;
    id actionMove;
    int distanceFromPlayer = ccpDistance(player.position, enemy.position);

    if (distanceFromPlayer < 200) { //Check whether enemy can "see" Ninja before moving towards him.
        //rotate to face the player
        CGPoint diff = ccpSub(player.position,enemy.position);
        float angleRadians = atanf((float)diff.y / (float)diff.x);
        float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
        float cocosAngle = -1 * angleDegrees;
        if (diff.x < 0) {
            cocosAngle += 180;
    }
        enemy.rotation = cocosAngle;

    actionMove = [CCMoveBy actionWithDuration:actualDuration
                                                   position:ccpMult(ccpNormalize(ccpSub(player.position,enemy.position)),10)];

} else {
            actionMove = [CCMoveBy actionWithDuration:actualDuration
                                     position:ccpMult(ccpNormalize(ccpSub(player.position,enemy.position)),0)];
}

id actionMoveDone = [CCCallFuncN actionWithTarget:self
                                         selector:@selector(enemyMoveFinished:)];
[enemy runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
}

// callback. starts another iteration of enemy movement.
- (void) enemyMoveFinished:(id)sender {
     CCSprite *enemy = (CCSprite *)sender;

    [self animateEnemy: enemy];
}



-(void)addEnemyAtX:(int)x y:(int)y {
    CCSprite *enemy = [CCSprite spriteWithFile:@"enemy1.png"];
    enemy.position = ccp(x, y);
    [self addChild:enemy];
    [self animateEnemy:enemy];
}

-(void)setViewpointCenter:(CGPoint) position {

    CGSize winSize = [[CCDirector sharedDirector] winSize];

    int x = MAX(position.x, winSize.width / 2);
    int y = MAX(position.y, winSize.height / 2);
    x = MIN(x, (_tileMap.mapSize.width * _tileMap.tileSize.width) 
        - winSize.width / 2);
    y = MIN(y, (_tileMap.mapSize.height * _tileMap.tileSize.height) 
        - winSize.height/2);
    CGPoint actualPosition = ccp(x, y);

    CGPoint centerOfView = ccp(winSize.width/2, winSize.height/2);
    CGPoint viewPoint = ccpSub(centerOfView, actualPosition);
    self.position = viewPoint;

}

-(id) init
{
    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.tileMap = [CCTMXTiledMap tiledMapWithTMXFile:@"TileMap.tmx"];
        self.background = [_tileMap layerNamed:@"Background"];
        self.foreground = [_tileMap layerNamed:@"Foreground"];
        self.buildings = [_tileMap layerNamed:@"Buildings"];
        self.meta = [_tileMap layerNamed:@"Meta"];
        _meta.visible = NO;

        CCTMXObjectGroup *objects = [_tileMap objectGroupNamed:@"Objects"];
        NSAssert(objects != nil, @"'Objects' object group not found");
        //NSMutableDictionary * padPoints = [objects objectNamed:@"pad"];
        NSMutableDictionary * padPoints;
        SaveData * SaveDataManager = [SaveData sharedSaveDataManager];

        for (int i = 0; i < 20; i ++) {
            for (padPoints in [objects objects]) {
                if ([[SaveDataManager.padArray objectAtIndex: i] intValue] == 1 ){
                    if ([[padPoints valueForKey:@"pad"] intValue] == i){
                        int x = [[padPoints valueForKey:@"x"] intValue];
                        int y = [[padPoints valueForKey:@"y"] intValue];
                        self.player = [CCSprite spriteWithFile:@"man.png"];
                        _player.position = ccp(x+16,y+16);
                        //[self addChild:_player];
                }
            }
        }
    }
    // iterate through objects, finding all enemy spawn points
    // create an enemy for each one
    NSMutableDictionary * spawnPoints;
    for (spawnPoints in [objects objects]) {
        if ([[spawnPoints valueForKey:@"Enemy"] intValue] == 2){
            int x = [[spawnPoints valueForKey:@"x"] intValue];
            int y = [[spawnPoints valueForKey:@"y"] intValue];
            [self addEnemyAtX:x+=16 y:y+=64];

        }
    }


    player = [CCSprite spriteWithFile:@"man.png"];

    player.position= _player.position;
    [_tileMap addChild:player z: 0];

   // [self addChild:player z:10];

    [self setViewpointCenter:player.position];
    [self addChild:_tileMap z:-1];
    [self scheduleUpdate];
    }
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)setPlayerPosition:(CGPoint)position {
    Player * playerDataManager = [Player playerSaveDataManager];
    CGPoint tileCoord = [self tileCoordForPosition:position];
    int tileGid = [_meta tileGIDAt:tileCoord];
    int x = player.position.x;
    int y = player.position.y;
    if (tileGid) {
        NSDictionary *properties = [_tileMap propertiesForGID:tileGid];
        if (properties) {
            NSString *collision = [properties valueForKey:@"Collidable"];
            if (collision && [collision compare:@"True"] == NSOrderedSame) {
                //[[SimpleAudioEngine sharedEngine] playEffect:@"hit.caf"];
                if (joyDegrees > 45 && joyDegrees < 135){

                    player.position = ccp(x,y-1);
                }
                if (joyDegrees > 135 && joyDegrees < 225){

                    player.position = ccp(x+1,y);
                }
                if (joyDegrees > 225 && joyDegrees < 315){

                    player.position = ccp(x,y+1);
                }
                if ((joyDegrees > 315 && joyDegrees < 360) || (joyDegrees > -1 && joyDegrees < 45)){
                                       player.position = ccp(x-1,y);
                }
                return;
            }
            NSString *collectable = [properties valueForKey:@"Collectable"];
            if (collectable && [collectable compare:@"True"] == NSOrderedSame) {
                [[SimpleAudioEngine sharedEngine] playEffect:@"pickup.caf"];
                [_meta removeTileAt:tileCoord];
                [_foreground removeTileAt:tileCoord];
                self.numCollected += 1;
                [_hud numCollectedChanged:_numCollected];
                playerDataManager.playerHealth -= 10;
            }
            NSString *Gate = [properties valueForKey:@"Gate"];
            if (Gate && [Gate compare:@"1"] == NSOrderedSame) {
                SaveData * SaveDataManager = [SaveData sharedSaveDataManager];
                //[SaveDataManager.padArray removeAllObjects];
                for (int i = 0; i < 20; i ++) {
                    [SaveDataManager.padArray replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:0]];
                }
                [SaveDataManager.padArray replaceObjectAtIndex:1 withObject:[NSNumber numberWithInt:1]];  
                //[[CCDirector sharedDirector] replaceScene:[LogCabinMap scene]];
                [[CCDirector sharedDirector] pushScene:[LogCabinMap scene]];
            }
            if (Gate && [Gate compare:@"2"] == NSOrderedSame) {
                SaveData * SaveDataManager = [SaveData sharedSaveDataManager];
                //[SaveDataManager.padArray removeAllObjects];
                for (int i = 0; i < 20; i ++) {
                    [SaveDataManager.padArray replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:0]];
                }
                [SaveDataManager.padArray replaceObjectAtIndex:1 withObject:[NSNumber numberWithInt:1]];
                //[[CCDirector sharedDirector] replaceScene:[LogShedMap scene]];
                [[CCDirector sharedDirector] pushScene:[LogShedMap scene]];
            }


        }
    }

    //[[SimpleAudioEngine sharedEngine] playEffect:@"move.caf"];
    player.position = position;
   }

-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
     return YES;

}


-(void) update:(ccTime)deltaTime {
    [self setPlayerPosition:newPos];
    [self setViewpointCenter:player.position];
}



// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
    // in case you have something to dealloc, do it in this method
    // in this particular example nothing needs to be released.
    // cocos2d will automatically release all the children (Label)
    self.tileMap = nil;
    self.background = nil;
    self.foreground = nil;
    self.buildings = nil;
    self.meta =nil;
    self.player = nil;
    player = nil;
    self.hud = nil;
    // don't forget to call "super dealloc"
    [super dealloc];
}
@end


@implementation HelloWorldHud
@synthesize background;
@synthesize background2;
@synthesize health;
@synthesize baseScaleFactor;

+(CCScene *) scene
{
    // 'scene' is an autorelease object.
    CCScene *scene = [CCScene node];

    // 'layer' is an autorelease object.
    HelloWorldHud *layer = [HelloWorldHud node];

    // add layer as a child to scene

    [scene addChild: layer z:2];
    HelloWorldLayer *hud = [HelloWorldLayer node];    
    [scene addChild: hud z:1];

    //layer.hud = hud;
    // return the scene
    return scene;
}

-(void)initJoystick {                         
    SneakyJoystickSkinnedBase *joystickBase = [[[SneakyJoystickSkinnedBase alloc] init]     autorelease];        
    joystickBase.backgroundSprite = [CCSprite spriteWithFile:@"JoyB.png"];                     
    joystickBase.thumbSprite = [CCSprite spriteWithFile:@"JoyS.png"]; 
    joystickBase.joystick = [[SneakyJoystick alloc] initWithRect: CGRectMake(0, 0, 128, 128)]; 
    joystickBase.position = ccp(55, 55);
    [self addChild:joystickBase];
    leftJoystick = [[joystickBase.joystick retain] autorelease];  
}

-(void) update:(ccTime)deltaTime { 
    Player *playerDataManager = [Player playerSaveDataManager];
    CGPoint scaledVelocity = ccpMult(leftJoystick.velocity, 100); 
    CGPoint newPosition = ccp(player.position.x + scaledVelocity.x * deltaTime, player.position.y + scaledVelocity.y * deltaTime); 

    if (leftJoystick.velocity.x == 0 && leftJoystick.velocity.y == 0 ){
        if (!playerDataManager.standStill) {
            [player stopAllActions];
            playerDataManager.walkUp = FALSE;
            playerDataManager.walkDown = FALSE;
            playerDataManager.walkRight = FALSE;
            playerDataManager.walkLeft = FALSE;
            playerDataManager.standStill = TRUE;
            [player runAction:playerDataManager.standAction];
        } 
    }
    if (leftJoystick.degrees > 45 && leftJoystick.degrees < 135){
        if (!playerDataManager.walkUp) {
            [player stopAllActions];
            playerDataManager.walkUp = TRUE;
            playerDataManager.walkDown = FALSE;
            playerDataManager.walkRight = FALSE;
            playerDataManager.walkLeft = FALSE;
            playerDataManager.standStill = FALSE;
            [player runAction:playerDataManager.walkUpAction];
        } 
    }
    if (leftJoystick.degrees > 135 && leftJoystick.degrees < 225){
        if (!playerDataManager.walkLeft) {
            [player stopAllActions];
            playerDataManager.walkUp = FALSE;
            playerDataManager.walkDown = FALSE;
            playerDataManager.walkRight = FALSE;
            playerDataManager.walkLeft = TRUE;
            playerDataManager.standStill = FALSE;
            [player runAction:playerDataManager.walkLeftAction];
        } 
    }
    if (leftJoystick.degrees > 225 && leftJoystick.degrees < 315){
        if (!playerDataManager.walkDown) {
            [player stopAllActions];
            playerDataManager.walkUp = FALSE;
            playerDataManager.walkDown = TRUE;
            playerDataManager.walkRight = FALSE;
            playerDataManager.walkLeft = FALSE;
            playerDataManager.standStill = FALSE;
            [player runAction:playerDataManager.walkDownAction];
        } 
    }
    if (((leftJoystick.degrees > 315 && leftJoystick.degrees < 360) &&     (leftJoystick.velocity.x != 0 && leftJoystick.velocity.y != 0 )) || ((leftJoystick.degrees > -1 && leftJoystick.degrees < 45) && (leftJoystick.velocity.x != 0 && leftJoystick.velocity.y != 0 ))){
        if (!playerDataManager.walkRight) {
            [player stopAllActions];
            playerDataManager.walkUp = FALSE;
            playerDataManager.walkDown = FALSE;
            playerDataManager.walkRight = TRUE;
            playerDataManager.walkLeft = FALSE;
            playerDataManager.standStill = FALSE;
            [player runAction:playerDataManager.walkRightAction];
        } 
    }

    float scaleFactor = playerDataManager.playerHealth/baseScaleFactor; 
    health.scaleX = playerDataManager.playerHealth/1;
    newPos = newPosition;
    joyDegrees = leftJoystick.degrees;
    if (playerDataManager.playerHealth < 100) {
       [[CCDirector sharedDirector]  replaceScene:[CCTransitionFade transitionWithDuration:3 scene: [GameLogic scene]]];
        [[CCDirector sharedDirector]  replaceScene: [GameLogic scene]];
    }
}



-(void) scroll:(ccTime)dt 
{
    //move 30*dt px vertically
    if (background.position.y<background2.position.y){
        background.position = ccp(background.contentSize.width/2, background.position.y - 225*dt);
        background2.position = ccp(background2.contentSize.width/2,     background.position.y+background.contentSize.height);
    }else{
        background2.position = ccp(background2.contentSize.width/2, background2.position.y- 225*dt);
        background.position = ccp(background.contentSize.width/2, background2.position.y+background2.contentSize.height);

    }

    //reset offscreen position
    if (background.position.y <-background.contentSize.height/2)
    {
        background.position =     ccp(background.contentSize.height/2,background2.position.y+background2.contentSize.height);
    }else if (background2.position.y < -background2.contentSize.height/2)
    {
        background2.position = ccp(background2.contentSize.height/2,     background.position.y+background.contentSize.height);
    }
}


-(id) init
{
    if ((self = [super init])) {
        CGSize size = [CCDirector sharedDirector].winSize;


        background = [CCSprite spriteWithFile:@"rain.png"];
        background2 = [CCSprite spriteWithFile:@"rain.png"];

        [background.texture setAliasTexParameters];
        [background2.texture setAliasTexParameters];

        //position background sprites
        background.position =     ccp(background.contentSize.height/2,background.contentSize.width/2);
        background2.position = ccp(size.width,0);

        //schedule to move background sprites
        //[self schedule:@selector(scroll:)];

        //adding them to the main layer

        //[self addChild:background z:-1];
        //[self addChild:background2 z:-1];

        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"GUI.plist"]; 
        CCSpriteBatchNode *GUISpriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"GUI.png"];
        [self addChild:GUISpriteSheet];

        CCSprite * healthBar = [CCSprite spriteWithSpriteFrameName:@"bar.png"];
        CCSprite * cap = [CCSprite spriteWithSpriteFrameName:@"cap.png"];
        CCSprite * endCap = [CCSprite spriteWithSpriteFrameName:@"endcap.png"];
        health = [CCSprite spriteWithSpriteFrameName:@"red.png"];
        healthBar.anchorPoint = ccp(0,1);
        health.anchorPoint = ccp(0,1);
        cap.anchorPoint = ccp(0,1);
        endCap.anchorPoint = ccp(0,1);
        healthBar.position = ccp(1 , size.height);
        healthBar.scaleX = 25;
        cap.position = ccp(0 , size.height);
        int width = [healthBar boundingBox].size.width;
        endCap.position = ccp(width , size.height);
        health.position = ccp(1, size.height-2);
        baseScaleFactor = width;
        health.scaleX = baseScaleFactor;
        [self addChild:healthBar];
        [self addChild:cap];
        [self addChild:endCap];
        [self addChild:health];
        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];

        CCMenuItemFont * pause = [CCMenuItemFont itemFromString:@"Pause" target:self selector:@selector(pause:)];       
        CCMenu *menu = [CCMenu menuWithItems: pause, nil];
        pause.position = ccp(206,142);
        [self addChild:menu];

        CCSprite *pix = [CCSprite spriteWithFile:@"pix.png"];
        pix.position = ccp(size.width/2, size.height/2);
        //pix.scale = 50000;
    [self addChild:pix z:1];
        //[pix runAction:[CCTintTo actionWithDuration:10 red:255 green:0 blue:0]];
        //[pix runAction:[CCScaleTo actionWithDuration:15 scale:500]];

        pix.color = ccc3(255, 255, 255); 
        [self scheduleUpdate];



        [self initJoystick];

    }
    return self;
}


- (void)numCollectedChanged:(int)numCollected {
    [label setString:[NSString stringWithFormat:@"%d", numCollected]];
    // [label setString:[NSString stringWithFormat:@"%d", score]];
}

- (void) pause: (id) sender
{
    [[CCDirector sharedDirector] pushScene:[pauseM scene]];

}

- (void) dealloc
{

    self.background = nil;
    self.background2 = nil;
    self.health = nil;
    self.meta =nil;
    player = nil;

    // don't forget to call "super dealloc"
    [super dealloc];
}

@end

上は問題が発生したときに実行されている .m シーンで、下は GameLogic.m です。

#import "GameLogic.h"
#import "Player.h"
#import "Menu.h"

@implementation GameLogic

+(id) scene
{
    CCScene *scene = [CCScene node];

    GameLogic *layer = [GameLogic node];

    [scene addChild: layer];

    return scene;
}


+(id) gameLogicSaveDataManager {
    static id gameLogicSaveDataManager = nil;
    if (gameLogicSaveDataManager == nil) {
        gameLogicSaveDataManager = [[self alloc] init];
    }
    return gameLogicSaveDataManager;
}


-(id) init
{

    if( (self=[super init] )) {
        CCSprite *bg = [CCSprite spriteWithFile:@"bg.jpg"];
        bg.anchorPoint = ccp(0,0);
        id fadeIn = [CCFadeIn actionWithDuration:3];

        [self addChild:bg];
        [bg runAction: fadeIn];   

        CCLayer *menuLayer = [[[CCLayer alloc] init] autorelease];
        [self addChild:menuLayer];
        CCMenuItemImage *home = [CCMenuItemImage
                                          itemFromNormalImage:@"bg.jpg"
                                          selectedImage:@"bg.jpg"
                                          target:self
                                          selector:@selector(home:)];
        CCMenu *menu = [CCMenu menuWithItems: home, nil];
        home.position = ccp(0,0);
        [menuLayer addChild: menu];
    }
    return self;
}

- (void) home: (id) sender
{
    [[CCDirector sharedDirector] replaceScene:[Menu scene]];

}

- (void) dealloc
{
    [super dealloc];
}

@end
4

2 に答える 2

1

OpenGL エラー 0x503 はGL_STACK_OVERFLOW、opengl スタックにあまりにも多くのものをプッシュしていることを意味します。

pushSceneあなたのコードには のインスタンスがいくつかありますが、popどこにもインスタンスはありません。ポップせずに無期限にプッシュし続けることはできません。そうしないと、このエラーが発生します。

于 2012-07-13T21:44:23.070 に答える
0

シーンで現在実行されているもの、割り当てられている方法、リリースされている方法を確認する必要があります。また、新しくロードされたシーンGameLogicについても同じ情報を知る必要があります。質問を編集して、これらのデータを追加します。

于 2012-07-13T15:13:25.807 に答える