summaryrefslogtreecommitdiff
path: root/client/src/akkamon/render/model/RemotePlayerSprite.ts
blob: aae911f99526f0e958039e07fdf5ec1d6dea1349 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import Phaser from 'phaser';
import { AkkamonWorldScene } from '../../scenes/AkkamonWorldScene';
import { PlayerSprite } from '../model/PlayerSprite';
import { GridPhysics } from '../engine/GridPhysics';
import { Direction } from '../Direction';

import { Queue } from '../../DataWrappers';

type RemotePlayerSpriteConfig = {
    scene: Phaser.Scene,
    tilePos: Phaser.Math.Vector2,
    texture: Phaser.Textures.Texture | string,
    frame?: string,
    moveQueue: Queue<Direction>
}

export class RemotePlayerSprite extends PlayerSprite  {

    private lastTilePos?: Phaser.Math.Vector2;
    private moveQueue: Queue<Direction> = new Queue();

    private movementDirection: Direction = Direction.NONE;

    private speedPixelsPerSecond: number = AkkamonWorldScene.TILE_SIZE * 4;

    private tileSizePixelsWalked: number = 0;

    constructor(config: RemotePlayerSpriteConfig) {
        super(config);
    }

    push(moveQueue: Array<Direction>): void {
        for (var direction of moveQueue) {
            if (direction !== Direction.NONE) {
                this.moveQueue.push(direction);
            }
        }
        // console.log(this.moveQueue);
    }

    updatePixelPosition(delta: number): void {
        const pixelsToWalkThisUpdate = this.getPixelsToWalk(delta);

        if (!this.willCrossTileBorderThisUpdate(pixelsToWalkThisUpdate)) {
            this.move(pixelsToWalkThisUpdate);
        } else if (this.shouldContinueMoving()) {
            this.move(pixelsToWalkThisUpdate);
        } else {
            this.move(AkkamonWorldScene.TILE_SIZE - this.tileSizePixelsWalked);
            this.stopMoving();
        }
    }

    shouldContinueMoving(): boolean {
        if (this.moveQueue.peek() == this.movementDirection) {
            console.log("continueing to move.");
            this.moveQueue.pop();
            return true;
        }
        return false;
    }

    willCrossTileBorderThisUpdate(pixelsToWalkThisUpdate: number): boolean {
        return (this.tileSizePixelsWalked + pixelsToWalkThisUpdate) >= AkkamonWorldScene.TILE_SIZE;
    }

    move(pixelsToMove: number): void {
        this.tileSizePixelsWalked += pixelsToMove;
        this.tileSizePixelsWalked %= AkkamonWorldScene.TILE_SIZE;

        const directionVec = GridPhysics.movementDirectionVectors[this.movementDirection]!.clone();

        const moveVec = directionVec.multiply(
            new Phaser.Math.Vector2(pixelsToMove)
        );

        const newPosition = this.getPosition().add(moveVec);
        this.newPosition(newPosition);
    }

    getPixelsToWalk(delta: number): number {
        const deltaInSeconds = delta / 1000;
        return this.speedPixelsPerSecond * deltaInSeconds;
    }

    hasMovesLeft(): boolean {
        return !this.moveQueue.isEmpty();
    }

    isMoving(): boolean {
        return this.movementDirection !== Direction.NONE;
    }

    startMoving(): void {
        if (!this.moveQueue.isEmpty()) {
            this.movementDirection = this.moveQueue.pop()!;
            this.startAnimation(this.movementDirection);
            // console.log("remote player now walking in direction: " + this.movementDirection);
        } else {
            // console.log("moveQueue empty!");
        }
    }

    stopMoving(): void {
        this.stopAnimation(this.movementDirection);
        this.movementDirection = Direction.NONE;
    }
}