summaryrefslogtreecommitdiff
path: root/client/src/RemotePlayerSprite.ts
blob: 6103d09019d2eb878ad2ed7acc3db9b0f29c69bb (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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import Phaser from 'phaser';
import AkkamonStartScene from './scene';
import { PlayerSprite } from './sprite';
import { GridPhysics } from './GridPhysics';
import { Direction } from './Direction';

export class Queue<T> {
    private _data = new Array();

    constructor(data?: Array<T>) {
        if (data !== undefined) {
            this._data = data;
        }
    }

    push(element: T): void {
        this._data.push(element);
    }

    pushArray(arr: T[]): void {
        for (var element of arr) {
            this._data.push(element);
        }
    }

    pop(): T | undefined {
        return this._data.shift();
    }

    isEmpty(): boolean {
        return this._data.length == 0;
    }

    peek() {
        return this._data[0];
    }
}

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 = AkkamonStartScene.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(AkkamonStartScene.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) >= AkkamonStartScene.TILE_SIZE;
    }

    move(pixelsToMove: number): void {
        this.tileSizePixelsWalked += pixelsToMove;
        this.tileSizePixelsWalked %= AkkamonStartScene.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;
    }
}