1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  2. Information ausblenden

cocos2d sprite.position.x ergibt (null), aber warum?

Dieses Thema im Forum "iOS-Developer" wurde erstellt von nilsTGMD, 27.12.09.

  1. nilsTGMD

    nilsTGMD Braeburn

    Dabei seit:
    27.10.07
    Beiträge:
    47
    Moin,
    ich bin neu in obj-c und versuche gerade ein kleines Spiel mit Hilfe von cocos2d zu schreiben. Dabei möchte ich überprüfen ob zwei Objekte(Sprites) sich zu einem bestimmten Zeitpunkt auf der gleichen X-Position befinden.

    Nun lässt sich aber die Position der Sprite player nicht abfragen, mit NSLog(@"%d", player.position.x) erhalte ich immer nur (null) in der Konsole. Was mache ich da falsch? Bei den Sprites blockX funktioniert das so wie gewollt und erwartet. Die Positionsabfrage passiert in der collide-Methode, welche am Ende der Bewegung der Blöcke aufgerufen wird.

    GameScene.h
    Code:
    #import <UIKIt/UIKit.h>
    #import "cocos2d.h"
    #import "chipmunk.h"
    
    @interface GameScene : Scene { }
    @end
    
    
    @interface GameLayer : Layer {
        Sprite * block1;
        Sprite * block2;
        Sprite * block3;
        Sprite * player;
        
        cpSpace* space;
        
        UIButton *leftBtn;
        UIButton *rightBtn;
        
        float speed;
        int freePosition;
        int score;
    }
    -(void) arangeSprites;
    -(void) moveBlocks;
    -(void) collide;
    
    -(void) showMenu:(id) sender;
    -(void)resumeOption:(id)sender;
    -(void)restartOption:(id)sender;
    -(void)quitOption:(id)sender;
    
    -(void) setPlayer;
    -(void) setLayer:(Class) classLayer;
    -(void) backCallback:(id) sender;
    -(void) nextCallback:(id) sender;
    -(void) restartCallback:(id) sender;
    
    
    @end
    
    GameScene.m
    Code:
    #import "GameScene.h"
    #include <unistd.h>
    
    
    #pragma mark -
    
    @implementation GameScene
    
    -(id) init {
        self = [super init];
        if( self != nil ) {
            [self addChild: [GameLayer node] z:1];
        }
        return self;
    }
    
    @end
    
    #pragma mark -
    
    static int sceneIndex=-1;
    static NSString *transitions[] = {
        @"PlayerLayer01", @"PlayerLayer02", @"PlayerLayer03", @"PlayerLayer04"};
    
    Class nextAction() {
        sceneIndex++;
        if(sceneIndex >= sizeof(transitions))
            sceneIndex = sceneIndex % (sizeof(transitions)/sizeof(transitions[0]));
        NSString *r = transitions[sceneIndex];
        Class c = NSClassFromString(r);
        return c;
    }
    
    Class backAction() {
        sceneIndex--;
        if(sceneIndex < 0)
            sceneIndex = sizeof(transitions)/sizeof(transitions[0])-1;
        NSString *r = transitions[sceneIndex];
        Class c = NSClassFromString(r);
        return c;
    }
    
    Class restartAction() {
        if(sceneIndex < 0 || sceneIndex >= sizeof(transitions))
            return nil;
        NSString *r = transitions[sceneIndex];
        Class c = NSClassFromString(r);
        return c;
    }
    
    
    #pragma mark -
    
    @implementation GameLayer
    
    // Layer initialisieren
    -(id) init {
        self = [super init];
        
        if(self != nil) {
            Sprite *bg = [[Sprite spriteWithFile:@"background.png"] retain];
            bg.position = cpv(160,240);
            [self addChild: bg];    
            
            // Member setzen
            speed = 5.0;
            score = -1;
            
            //alle Sprites in 80x80 sonst passt das alle nicht
            block1 = [[Sprite spriteWithFile:@"vlc.png"] retain];
            block2 = [[Sprite spriteWithFile:@"vlc.png"] retain];
            block3 = [[Sprite spriteWithFile:@"vlc.png"] retain];
            [self addChild:block1 z:2];
            [self addChild:block2 z:2];
            [self addChild:block3 z:2];
            [self arangeSprites];
            
            player = [[Sprite spriteWithFile:@"car.png"] retain];
            [self addChild:player z:1];
            [self setPlayer];
            
            MenuItemImage *item1 = [MenuItemImage itemFromNormalImage:@"button.png" selectedImage:@"button_pressed.png" target:self selector:@selector(backCallback:)];
            MenuItemImage *item2 = [MenuItemImage itemFromNormalImage:@"button.png" selectedImage:@"button_pressed.png" target:self selector:@selector(nextCallback:)];
            MenuItemImage *item3 = [MenuItemImage itemFromNormalImage:@"menu.png" selectedImage:@"menu.png" target:self selector:@selector(showMenu:)];
            Menu *menu = [Menu menuWithItems:item1, item2, item3, nil];
            menu.position = CGPointZero;
            
            item1.position = ccp(320/2-80, 480/2-25);
            item2.position = ccp(320/2+80, 480/2-25);
            item3.position = ccp(305, 465);
            
            
            [self addChild:menu z:3];
        }
        return self;
    }
    
    
    //
    // Diese Methode setzt die Sprites in zufälliger Reihenfolge
    // und ruft die Methode zum bewegen auf.
    //
    -(void) arangeSprites{
        score = score++;
        NSLog(@"Score: %d", score);
        
        CGSize size = [[Director sharedDirector] winSize];
        int randomNumber = (arc4random() % 4);
        
        //Bloecke ausrichten
        if(randomNumber == 0){
            [block1 setPosition:ccp(120, size.height-40)];
            [block2 setPosition:ccp(200, size.height-40)];
            [block3 setPosition:ccp(280, size.height-40)];
            freePosition = 0;
        }
        if(randomNumber == 1){
            [block1 setPosition:ccp(40, size.height-40)];
            [block2 setPosition:ccp(200, size.height-40)];
            [block3 setPosition:ccp(280, size.height-40)];
            freePosition = 1;
        }
        if(randomNumber == 2){
            [block1 setPosition:ccp(40, size.height-40)];
            [block2 setPosition:ccp(120, size.height-40)];
            [block3 setPosition:ccp(280, size.height-40)];
            freePosition = 2;
        }
        if(randomNumber == 3){
            [block1 setPosition:ccp(40, size.height-40)];
            [block2 setPosition:ccp(120, size.height-40)];
            [block3 setPosition:ccp(200, size.height-40)];
            freePosition = 3;
        }
        [self moveBlocks];
    }
    
    // Spieler init
    -(void) setPlayer{
        CGSize size = [[Director sharedDirector] winSize];
        [player setPosition:ccp(size.width/4-40, size.height-400)];
    }
    
    // zeigt das Pausen-Menu
    -(void)showMenu:(id)sender{
        [[Director sharedDirector] pause];
    }
    
    -(void)resumeOption:(id)sender{
        [[Director sharedDirector] resume];
    }
    
    -(void)restartOption:(id)sender{
        
    }
    
    -(void)quitOption:(id)sender{
        
    }
    
    // Bloecke bewegen und Geschwindigkeit steigern
    -(void)moveBlocks{
        CGSize size = [[Director sharedDirector] winSize];
        id moveBlock1 = [MoveTo actionWithDuration:speed position:ccp(block1.position.x, size.height-400)];    
        [block1 runAction:[Sequence actions:moveBlock1, nil, nil, nil]];
        
        id moveBlock2 = [MoveTo actionWithDuration:speed position:ccp(block2.position.x, size.height-400)];    
        [block2 runAction:[Sequence actions:moveBlock2, nil, nil, nil]];
        
        id moveBlock3 = [MoveTo actionWithDuration:speed position:ccp(block3.position.x, size.height-400)];    
        [block3 runAction:[Sequence actions:moveBlock3, [CallFunc actionWithTarget:self selector:@selector(collide)],
                           [CallFunc actionWithTarget:self selector:@selector(arangeSprites)], nil]];
        
            
        // Geschwindigkeit steigern
        if(speed >= 1.5){
            speed = speed - 0.2;
        }
    }
    
    // Ueberprueft auf Kollision und reagiert entsprechend.
    -(void) collide{
        if(player.position.x < freePosition*80+40 < player.position.x){
            NSLog(@"Kollision!!");
        }
        NSLog(@"%s", [player position].x);
    }
    
    -(void) dealloc{
        [block1 release];
        [block2 release];
        [block3 release];
        [player release];
        [super dealloc];
    }
    
    -(void) setLayer: (Class) classLayer{
        if(classLayer==nil)
            return;
        Scene *scene = [Scene node];
        [scene addChild:[classLayer node]];
        [[Director sharedDirector] replaceScene:scene];
    }
    
    -(void) restartCallback: (id)sender{
        [self setLayer: restartAction()];
    }
    
    // nach Rechts fahren
    -(void) nextCallback:(id)sender{
        if(player.position.x+80 <= 320){
            CGSize size = [[Director sharedDirector] winSize];
            id actionTo = [MoveTo actionWithDuration:0.1 position:ccp(player.position.x+80, size.height-400)];    
            id rotateRight = [RotateTo actionWithDuration:0.1 angle:20];
            id rotateBack = [RotateTo actionWithDuration:0.1 angle:0];
            [player runAction:[Sequence actions:rotateRight, actionTo, rotateBack, nil]];
        }
    }
    
    // nach Links fahren
    -(void) backCallback:(id)sender{
        if(player.position.x-80 >= 0){
            CGSize size = [[Director sharedDirector] winSize];
            id actionTo = [MoveTo actionWithDuration:0.1 position:ccp(player.position.x-80, size.height-400)];    
            id rotateLeft = [RotateTo actionWithDuration:0.1 angle:-20];
            id rotateBack = [RotateTo actionWithDuration:0.1 angle:0];
            [player runAction:[Sequence actions:rotateLeft, actionTo, rotateBack, nil]];
        }
    }
    
    @end
    
    Ich weiß, dass es noch nicht der beste Stil ist, aber steh echt noch am obj-c Anfang und bin sonst nur Java gewöhnt.

    Würde mich über eure Hilfe freuen, danke!
     
  2. Poljpocket

    Poljpocket Salvatico di Campascio

    Dabei seit:
    07.01.07
    Beiträge:
    432
    Hallo, schau dir mal folgende Definitionen an:

    Wenn du im cocos2d-Projekt Sprite.h öffnest, siehst du, dass CocosNode eine Superklasse von Sprite ist. Dort nachgeschaut stellt sich heraus, dass diese als Position eine CGPoint ausgibt.

    CGPoint:
    Code:
    struct CGPoint {
       CGFloat x;
       CGFloat y;
    };
    typedef struct CGPoint CGPoint;
    
    CGFloat ist in 32bit ein float, in 64bit ein double.

    Somit ist klar, dass die Abfrage

    Code:
    NSLog(@"%d", player.position.x);
    (null) als Ausgabe ergibt, weil du ohne casting einen float (wird wohl beim iPhone 32bit sein!) als integer ausgibst und das ist noch nie gut gegangen, also ändere das %d in %f und es funktioniert.

    Eine zweite Möglichkeit ist das schon angesprochene casting. Ändere die Zeile in:

    Code:
    NSLog(@"%d", (int)player.position.x);
    Auch das sollte funktionieren.

    Gruss ppocket
     
  3. nilsTGMD

    nilsTGMD Braeburn

    Dabei seit:
    27.10.07
    Beiträge:
    47
    Ach Mist, bin Java-verwöhnt :)

    Jetzt funktionierts, Danke!!
     

Diese Seite empfehlen