根据触摸位置更好的角色移动

Better character movement according to touch location

我在 3 x 3 平台(正交和 2D 精灵游戏)的中间生成了一个角色。该平台由 9 块瓷砖组成。如果触摸在他上方,角色需要向上移动,如果触摸离开他,则角色需要向左移动,依此类推。他只会上下左右移动;不是对角线。我拥有所有这些功能,但它很笨重 - 因为角色并不总是 "listen" 并且最终会朝着最接近触摸的另一个方向前进。有人可以看看并告诉我如何修复代码吗?似乎下面代码的真正问题是当玩家触摸屏幕时在四个 90 度角之一内的某处,系统不知道该做什么……或类似的事情。

//This movement method is called by 'touchesBegan' method inside an SKScene (Good ol' GameScene).
-(void)moveCharRedTo:(CGPoint)touchedLocation
{
    //If touch is to the left of the character then move character to the left by 1 tile.
    if (touchedLocation.x < _playerChar.position.x)
    {
        _charRedPointPos = [_platformLayer coordForPoint:_playerChar.position];
        _charRedRight = CGPointMake(_charRedPointPos.x - 1, _charRedPointPos.y);

        if ([_platformLayer isValidTileCoord:_charRedRight] && ![self tileAtCoord:_charRedRight hasAnyProps:(noGoCategory)])
        {
            _charRedRight = [_platformLayer pointForCoord:_charRedRight];
            [_playerChar runAction:[SKAction moveTo:_charRedRight duration:0.0]];
        }
    }
    //Move right.
    if (touchedLocation.x > _playerChar.position.x)
    {
        _charRedPointPos = [_platformLayer coordForPoint:_playerChar.position];
        _charRedRight = CGPointMake(_charRedPointPos.x + 1, _charRedPointPos.y);

        if ([_platformLayer isValidTileCoord:_charRedRight] && ![self tileAtCoord:_charRedRight hasAnyProps:(blueTileCategory)])
        {
            _charRedRight = [_platformLayer pointForCoord:_charRedRight];
            [_playerChar runAction:[SKAction moveTo:_charRedRight duration:0.0]];
        }
    }

    //Move down.
    if (touchedLocation.y < _playerChar.position.y)
    {
        _charRedPointPos = [_platformLayer coordForPoint:_playerChar.position];
        _charRedDown = CGPointMake(_charRedPointPos.x, _charRedPointPos.y + 1);

        if ([_platformLayer isValidTileCoord:_charRedDown] && ![self tileAtCoord:_charRedDown hasAnyProps:(noGoCategory)])
        {
            _charRedDown = [_platformLayer pointForCoord:_charRedDown];
            [_playerChar runAction:[SKAction moveTo:_charRedDown duration:0.0]];
        }
    }
    //Move up.
    if (touchedLocation.y > _playerChar.position.y) //else
    {
        _charRedPointPos = [_platformLayer coordForPoint:_playerChar.position];
        _charRedUp = CGPointMake(_charRedPointPos.x, _charRedPointPos.y - 1);

        if ([_platformLayer isValidTileCoord:_charRedUp] && ![self tileAtCoord:_charRedUp hasAnyProps:(noGoCategory)])
        {
            _charRedUp = [_platformLayer pointForCoord:_charRedUp];
            [_playerChar runAction:[SKAction moveTo:_charRedUp duration:0.0]];
        }
        //NSLog(@"Was on (%f,%f)", _charRedPointPos.x, _charRedPointPos.y);
    }

    [_playerChar movementAnimation]; //Little animation method for every time the character moves.
}

你的问题是你只需要选择一个移动方向。找出移动的方式,如下所示。

NS_ENUM(unsigned short, MovementDirection)
{
    Left = 0,
    Right = 1,
    Top = 2,
    Bottom = 3
}

-(MovementDirection)movementDirectionBetweenCurrentPoint:(CGPoint)currentPoint newPoint:(CGPoint)newPoint
{
    double dx = newPoint.x - currentPoint.x;
    double dy = newPoint.y - currentPoint.y;

    if(dx > dy)
        return (dx > 0) Right : Left;
    else
        return (dy > 0) Top : Bottom;
}
-(void)moveCharRedTo:(CGPoint)touchedLocation
{
    MovementDirection direction = [self movementDirectionBetweenCurrentPoint:_playerChar.position newPoint:touchedLocation];
    //If touch is to the left of the character then move character to the left by 1 tile.
    if (direction == Left)
    {
        _charRedPointPos = [_platformLayer coordForPoint:_playerChar.position];
        _charRedRight = CGPointMake(_charRedPointPos.x - 1, _charRedPointPos.y);

        if ([_platformLayer isValidTileCoord:_charRedRight] && ![self tileAtCoord:_charRedRight hasAnyProps:(noGoCategory)])
        {
            _charRedRight = [_platformLayer pointForCoord:_charRedRight];
            [_playerChar runAction:[SKAction moveTo:_charRedRight duration:0.0]];
        }
    }
    //Move right.
    else if (direction == Right)
    {
        _charRedPointPos = [_platformLayer coordForPoint:_playerChar.position];
        _charRedRight = CGPointMake(_charRedPointPos.x + 1, _charRedPointPos.y);

        if ([_platformLayer isValidTileCoord:_charRedRight] && ![self tileAtCoord:_charRedRight hasAnyProps:(blueTileCategory)])
        {
            _charRedRight = [_platformLayer pointForCoord:_charRedRight];
            [_playerChar runAction:[SKAction moveTo:_charRedRight duration:0.0]];
        }
    }

    //Move down.
    else if (direction == Bottom)
    {
        _charRedPointPos = [_platformLayer coordForPoint:_playerChar.position];
        _charRedDown = CGPointMake(_charRedPointPos.x, _charRedPointPos.y + 1);

        if ([_platformLayer isValidTileCoord:_charRedDown] && ![self tileAtCoord:_charRedDown hasAnyProps:(noGoCategory)])
        {
            _charRedDown = [_platformLayer pointForCoord:_charRedDown];
            [_playerChar runAction:[SKAction moveTo:_charRedDown duration:0.0]];
        }
    }
    //Move up.
    else if (direction == Top) //else
    {
        _charRedPointPos = [_platformLayer coordForPoint:_playerChar.position];
        _charRedUp = CGPointMake(_charRedPointPos.x, _charRedPointPos.y - 1);

        if ([_platformLayer isValidTileCoord:_charRedUp] && ![self tileAtCoord:_charRedUp hasAnyProps:(noGoCategory)])
        {
            _charRedUp = [_platformLayer pointForCoord:_charRedUp];
            [_playerChar runAction:[SKAction moveTo:_charRedUp duration:0.0]];
        }
        //NSLog(@"Was on (%f,%f)", _charRedPointPos.x, _charRedPointPos.y);
    }

    [_playerChar movementAnimation]; //Little animation method for every time the character moves.
}