Frage

EINRICHTUNG:
Ich arbeite an einem 2-D-Kachel-basiertes Spiel (Vogelperspektive) für das iPhone. Die App liest in einem Kachel-d (.tbx) tilemap Datei von Fliesen mit einer ‚blockiert‘ Eigenschaft entweder wahr oder falsch darzustellen, ob der Held durch die Fliese bewegen kann. I iterieren jede Kachel in der Karte und erzeugen ein 2-dimensionales Array C darstellt Kachel Zeilen und Spalten die blockierten Eigenschaft (true / false) jede Platte zu halten. Als ich den Helden auf der ganzen Linie zu bewegen, überprüfe ich die Position des Helden mit dem Array zu sehen, ob die Fliese er bewegt auf blockiert ist oder nicht. Wenn blockiert, wird der Held der Position, die durch so viel umgekehrt, wie es voran wurde.

PROB:
Das Problem ist, wenn ein Held auf einem blockierten Kachel getreten ist, kann er nicht davon losfahren. Tile Positionen korrekt sind in dem Sinne, dass Fliesen blockiert erkannt werden, wo sie sein sollte, aber Held ist dennoch fest. Held geht ‚Pixel‘ und nicht ‚durch Fliese‘. Das ist alles. Nur die linke Sache Code zu erhalten: (Held ist 28 Pixel um 36 Pixel groß)

//Code from GameScreen.m





-(void)generateCollisionMap
{




for(int layer=0; layer < 2; layer++) {
            for(int yy=0; yy < _screenTilesHeight; yy++) {

                NSLog(@"Row %i", yy);

                for(int xx=0; xx < _screenTilesWide; xx++) {
                    int _globalTileID = [[[tileMap layers] objectAtIndex:layer] getGlobalTileIDAtX:xx y:yy];
                    NSString *_value = [tileMap getTilePropertyForGlobalTileID:_globalTileID key:@"blocked" defaultValue:@"false"];
                    if([_value isEqualToString:@"true"]) {

                        _blocked[xx][yy] = YES;
                        NSLog(@"Cell %i = YES", xx);

                    }else{

                        if(_blocked[xx][yy] == YES){
                        NSLog(@"Leaving Cell %i as = YES", xx);
                            //Leave As Is

                        }else{

                         _blocked[xx][yy] = NO;
                        NSLog(@"Cell %i = NO", xx);

                        }

                    }
                }
            }
            }
}





//Code from Hero.m


-(void)moveHero
{

            // Up

            if(moveDirection == 1 && !doesNeedShiftWorld) {
                heroY += _playerSpeed;
                [self checkBlocked:1];
                _currentAnimation = _upAnimation;
                _moving = YES;
            }

            // Down
            if(moveDirection == 2 && !doesNeedShiftWorld) {
                heroY -= _playerSpeed;
                [self checkBlocked:2];
                _currentAnimation = _downAnimation;
                _moving = YES;
            }

            // Left
            if(moveDirection == 3 && !doesNeedShiftWorld) {
                heroX -= _playerSpeed;
                [self checkBlocked:3];
                _currentAnimation = _leftAnimation;
                _moving = YES;
            }

            // Right
            if(moveDirection == 4 && !doesNeedShiftWorld) {
                heroX += _playerSpeed;
                [self checkBlocked:4];
               _currentAnimation = _rightAnimation;
                _moving = YES;
            }



}   



//  ... 


- (void) checkBlocked:(int)checkDirection
{

    float xx = (heroX+160.0f+_tileWidth) / _tileWidth;
    float yy = 11-((heroY+300.0f+_tileHeight) / _tileHeight); 


    switch (checkDirection) {

        case 1:

            yy -= 1;

            if([_scene isBlocked:xx y:yy] ||
               [_scene isBlocked:(heroX+160.0f) y:yy]) {
                NSLog(@"Scene Blocked at %i, %i!", (int)xx, (int)yy);
                heroY -= _playerSpeed;

            }else{

                NSLog(@"Clear at %i, %i!", (int)xx, (int)yy);

            }

            break;

        case 2:


            if([_scene isBlocked:xx y:yy] ||
               [_scene isBlocked:xx y:(heroY+300.0f)] ||
               [_scene isBlocked:(heroX+160.0f) y:(heroY+300.0f)]) {
                NSLog(@"Scene Blocked at %i, %i!", (int)xx, (int)yy);
                heroY += _playerSpeed;

            }else{

                NSLog(@"Clear at %i, %i!", (int)xx, (int)yy);

            }


            break;

        case 3:

            xx += 1;

            if([_scene isBlocked:xx y:yy] ||
               [_scene isBlocked:(heroX+160.0f) y:yy] || 
               [_scene isBlocked:(heroX+160.0f) y:(heroY+300.0f)]) {
                NSLog(@"Scene Blocked at %i, %i!", (int)xx, (int)yy);
                heroX += _playerSpeed;

            }else{

                NSLog(@"Clear at %i, %i!", (int)xx, (int)yy);

            }


            break;

        case 4:


            if([_scene isBlocked:xx y:yy] || 
               [_scene isBlocked:xx y:(heroY+300.0f)]) {
                NSLog(@"Scene Blocked at %i, %i!", (int)xx, (int)yy);
                heroX -= _playerSpeed;

            }else{

                NSLog(@"Clear at %i, %i!", (int)xx, (int)yy);

            }


            break;

    }

}
War es hilfreich?

Lösung

Ihr Problem ist, dass Sie den Spieler in Bewegung sind, und zu überprüfen, ob der Raum, den er bewegt blockiert wird. Stattdessen möchten Sie die Position, um herauszufinden, dass er zu bewegen geht zu wollen, zu sehen, ob es blockiert ist, und auch dann nur ihn bewegen, wenn sie nicht blockiert wird. Außerdem können Sie immer in einer Klausel in dem seinen aktuellen Raum auszuschließen. das heißt, solange Ihr Charakter ist nicht Rasterabstände zu ändern, kann er immer bewegen, aber sobald er Gitter ist über Räume zu ändern, sollten Sie überprüfen, um zu sehen, ob er mit etwas kollidiert.

Hier ist der Code unter:

if(moveDirection == 1 && !doesNeedShiftWorld) {
    heroY += _playerSpeed;
    [self checkBlocked:1];
    _currentAnimation = _upAnimation;
    _moving = YES;
}

Es sollte wie folgt sein:

if(moveDirection == 1 && !doesNeedShiftWorld)
{
    //Figure out if the player is changing grid spaces.
    BOOL isChangingSpaces = ((int)((heroY + _playerSpeed) / myGridSizeVariable) != (int)(heroY / myGridSizeVariable));

    //The player should be able to move either if he isn't
    //changing grid spaces or if his destination space is free.
    if ( !isChangingSpaces || (spaceIsOpenAtX:heroX andY:heroY+_playerSpeed) )
    {
        heroY += _playerSpeed;
        _currentAnimation = _upAnimation;
        _moving = YES;
    }
}

Und Sie sollten wirklich versuchen, Ihren Code zu machen viel mehr objektorientiert. An dieser Stelle scheint es völlig prozeduralen zu sein und alle Variablen sind globale Variablen, die definitiv kein guter Weg zu gehen. „CheckBlocked“ sollte wie folgt umgeschrieben werden „: andY: spaceIsOpenAtX“, denn dann können Sie eine beliebige X setzen und Y-Koordinate, dass Sie wollen, um zu sehen, ob diese Position blockiert wird. Wie Sie es jetzt getan haben, Ihr Code zu abstrakt ist (vorbei um ganze Zahlen ohne Angabe von dem, was sie bedeutet andere als Ihre tatsächlichen if-Anweisung überprüft) und es nicht für jede Situation angewandt werden kann, was auch immer abgesehen von dem einmaligen Gebrauch Sie gibt es.

Wirklich, Sie player.speed und player.animation haben sollten und [Labyrinth spaceIsOpen] usw. Sie Objective-C verwenden, nicht nur C. Und selbst wenn Sie C verwenden würden, würde es eine bessere Idee zu tun, es in einem OO-Weg.

Andere Tipps

Ich denke, das Problem ist, dass man den Spieler bewegen auf die blockierte Fliesen und er bleibt stecken lassen.

Ich würde überprüfen, um zu sehen, ob die Richtung der Spieler, bevor blockiert bewegen die Spieler dort zu bewegen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top