-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathActor.js
123 lines (108 loc) · 3.65 KB
/
Actor.js
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
class Actor extends Sprite {
/**
* Constuctor for Actor.
*/
constructor() {
super();
}
/**
* Initialises the Actor with a given position.
*
* @param {Game} game
* @param {number} width The width of the Actor.
* @param {number} height The height of the Actor.
* @param {string} content The content to add into the Actor. Optional.
* @param {boolean} shadow
*/
init(game, width, height, content, shadow) {
super.init(game, width, height, content, shadow);
// An HTML template is used for the structure of the actor.
this.appendChild(document.importNode(document.getElementById('person').content, true));
}
/**
* Tells the Actor to stop moving. If fully is not provided, and there are pending destination
* points, then the Actor will start moving to the next point. If fully is set to true then
* all pending destination points are cleared.
*
* @param {boolean} fully Whether to fully stop the Actor or not.
*/
stop(fully) {
// Clear the current destination.
this.destX = this.destZ = -1;
this.heading = null;
if (this.destFn && !fully) {
this.destFn();
this.destFn = null;
}
// To fully stop, we need to also clear the pending destinations.
if (fully) this.dests = [];
}
/**
* Tells the Actor to move to the given position on the screen.
*
* @param {number} x The X position to move to.
* @param {number} y The Y position to move to.
* @param {Function} fn The function to execute once the Actor reaches the X/Y position.
* @param {boolean} cond Doesn't movement part only if true. If false, still executes function if set.
*/
moveTo(x, z, fn, cond=true) {
if (cond) this.dests.push({ z: z, x: x, fn: fn }); else if (fn) fn()
}
/**
* Actor momentarily jumps.
*
* @param {Function} fn The function to execute once the Actor finishes the jump.
*/
jump(fn) {
this.querySelector(".actor").classList.add("jump");
setTimeout(() => {
this.querySelector(".actor").classList.remove("jump");
if (fn) fn();
}, 200);
}
/**
* Updates the Actor's position based on its current heading and destination point.
*/
update() {
// Only update the Actor if it is currently on screen.
if (this.style.display != 'none') {
// Mask out left/right/in/out but retain the current jumping directions.
let direction;
if ((this.destX != -1) && (this.destZ != -1)) {
if (this.touching({ cx: this.destX, cz: this.destZ*3, radius: -this.radius }, 20)) {
// We've reached the destination.
this.stop();
} else {
this.heading = Math.atan2(this.destZ - this.z, this.destX - this.cx);
}
} else if (this.dests.length > 0) {
// If there is a destination position waiting for ego to move to, pop it now.
let pos = this.dests.shift();
this.destZ = pos.z
this.destX = pos.x;
this.destFn = pos.fn;
}
if (this.heading !== null) {
// Convert the heading to a direction value.
if (Math.abs(this.heading) > 2.356) {
direction |= Sprite.LEFT;
} else if (Math.abs(this.heading) < 0.785) {
direction |= Sprite.RIGHT;
} else if (this.heading > 0) {
direction |= Sprite.OUT;
} else {
direction |= Sprite.IN;
}
}
// Update Ego's direction to what was calculated above.
this.setDirection(direction);
// Move Ego based on it's heading.
if (this.heading !== null) this.move();
if (this.moved) {
this.classList.add('walking');
} else {
this.classList.remove('walking');
}
}
}
}