Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normalization of direction vector on npcs and player #286

Open
ipinzi opened this issue May 17, 2024 · 1 comment
Open

Normalization of direction vector on npcs and player #286

ipinzi opened this issue May 17, 2024 · 1 comment

Comments

@ipinzi
Copy link

ipinzi commented May 17, 2024

Firstly, love the work that is happening on this project

So I just cloned the project and took a look at the example project and there seems to be some oversight in the gameplay programming
When moving diagonally the player moves faster than moving horizontally, usually this is because the input vector is not normalized.

I dug a bit deeper into the code and found where directions are being assigned but it looks like this would only deal with 4 directional movement from what I can see...

if (input == Control.Action) {
    await player.triggerCollisionWith(RpgCommonPlayer.ACTIONS.ACTION)
}
else if (
    input == Direction.Left ||
    input == Direction.Right ||
    input == Direction.Up ||
    input == Direction.Down
) {
    player.moving = true
    moving = true
    const isMove = await player.moveByDirection(+input, deltaTimeInt || 1)
    if (isMove) {
        routesMove.push(inputData)
    }
}

So it seems like the movement for x and y axis would be additional and therefore the length of the directional vector is wrong when moving diagonally.
Anyway! The way that the direction is calculated is fine but the fact that is added together for x and y, FORGETABOUTIT you don't want to do that.

    private directionToAngle(direction: number): number {
        const angle = (direction < 2 ? +direction + 2 : direction - 2) * 90
        return toRadians(angle)
    }

    /** @internal */
    defineNextPosition(direction: number, deltaTimeInt: number): Vector2d {
        const angle = this.directionToAngle(direction)
        const computePosition = (prop: string) => {
            return this.position[prop] + this.speed * deltaTimeInt
                * (Math.round(Math[prop == 'x' ? 'cos' : 'sin'](angle) * 100) / 100)
        }
        // If it's greater than 1, round value to reduces bandwidth
        const x = this.speed < 1 ? computePosition('x') : round(computePosition('x'))
        const y = this.speed < 1 ? computePosition('y') : round(computePosition('y'))
        return new Vector2d(x, y, ~~this.position.z)
    }

What you want to do is get the player input as a vector2. If the player or npc is pressing up or wants to move up the vector2 is (0,-1) if up left its (-1,-1) if down right its (1,1) etc then you can normalize this vector with a function like this:

function normalize(vector: Vector2d): Vector2d {
    const magnitude = Math.sqrt(vector.x * vector.x + vector.y * vector.y);
    return {
        x: vector.x / magnitude,
        y: vector.y / magnitude
    };
}

That way the length of the vector will be normalized. Then you can multiply that vector by the speed and deltatime and bingo, you have correct diagonal movement consistent with the speed of horizontal movement.

@RSamaium
Copy link
Owner

Hello,

Thanks for your feedback! Your help is very useful for the corrections on RPGJS :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants