1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  2. Unsere jährliche Weihnachts-Banner-Aktion hat begonnen! Wir freuen uns auf viele, viele kreative Vorschläge.
    Mehr dazu könnt Ihr hier nachlesen: Weihnachtsbanner 2016

    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