forked from noops-challenge/mazebot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoverlay-renderer.js
118 lines (97 loc) · 4.26 KB
/
overlay-renderer.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
// Render the overlay:
// - the avatar
// - the goal
// this is continuously animating and is called many times per second
function OverlayRenderer(
overlayContext,
coordinates
) {
return {
updateOverlay: function (avatarPosition, avatarDirection, endingPosition, frame) {
CanvasUtils.resetCanvas(overlayContext, "rgba(0,0,0,0)");
// goal first, so the avatar "floats" above if adjacent
drawGoal(avatarPosition, endingPosition, frame);
drawAvatar(avatarPosition, avatarDirection, frame);
}
};
function drawGoal(currentPosition, endingPosition, time) {
var position = coordinates.canvasPosition(endingPosition);
if (position.offscreen) {
// goal is offscreen - render a directional pointer to the goal
var avatarScreenPosition = coordinates.canvasPosition(currentPosition);
// figure out the direction
var direction = angle(currentPosition, endingPosition);
var distance = Math.abs(currentPosition[0] - endingPosition[0]) + Math.abs(currentPosition[1] - endingPosition[1]);
// make it farther away from the avatar the farther from goal
var distanceModifier = (Math.min(40, distance - 20) / 100);
var radius = position.size * (0.85 + distanceModifier);
// could vary this too...
var lineWidth = 3;
// cycle the colors based on current time
var frame = Math.floor((time / 150) % Styles.goalDirection.length);
// draw the arcs
for (var i = 0; i < Styles.goalDirection.length; i++) {
var magnitude = 0.08 * (i + 0.5);
var style = Styles.goalDirection[(frame + i) % Styles.goalDirection.length]
CanvasUtils.drawArc(overlayContext, avatarScreenPosition.center, radius * (1 - (i * 0.05)), direction - magnitude, direction + magnitude, lineWidth, style)
}
}
else {
// hrender a target
// how big?
if (position.size < 30) factor = factor * 1.2;
if (position.size < 15) factor = factor * 1.2;
// pulse the size over time
var factor = Math.abs(time % 2000 - 1000) / 4000;
var scale = 0.4 + factor;
var basis = scale * position.size;
CanvasUtils.drawFilledCircle(overlayContext, position.center, basis * 1.2, position.size / 10, "black", "yellow");
if (coordinates.cellSize() > 12) {
CanvasUtils.drawFilledCircle(overlayContext, position.center, basis, position.size / 9, "black", "yellow");
}
CanvasUtils.drawFilledCircle(overlayContext, position.center, basis * 0.8, position.size / 8, "red", "white");
if (coordinates.cellSize() > 12) {
CanvasUtils.drawFilledCircle(overlayContext, position.center, basis * 0.6, position.size / 8, "red", "yellow");
}
CanvasUtils.drawFilledCircle(overlayContext, position.center, basis * 0.4, position.size / 8, "red", "white");
CanvasUtils.drawFilledCircle(overlayContext, position.center, basis * 0.2, position.size / 8, "black", "red");
}
}
function angle(from, to) {
var dy = to[1] - from[1];
var dx = to[0] - from[0];
return Math.atan2(dy, dx);
}
// Draw the arrow that represensts the avatar
function drawAvatar(avatarPosition, avatarDirection, time) {
var cell = coordinates.canvasPosition(avatarPosition);
var scale = 0.8 - (0.0003 * Math.abs(time % 1000 - 500));
// size for the display, kinda
if (cell.size < 20) scale += 0.4;
if (cell.size < 10) scale += 0.4;
var c = cell.scale(scale);
var width = Math.floor(cell.size / 15);
// point the arrow
if (avatarDirection === 'W') {
drawArrow(overlayContext, c.w, c.ne, c.se, width);
}
else if (avatarDirection === 'E') {
drawArrow(overlayContext, c.e, c.nw, c.sw, width);
}
else if (avatarDirection === 'S') {
drawArrow(overlayContext, c.s, c.ne, c.nw, width);
}
else {
drawArrow(overlayContext, c.n, c.se, c.sw, width);
}
}
function drawArrow(overlayContext, tip, c1, c2, width) {
//shadow
CanvasUtils.drawPath(overlayContext, 2, 'black', shadowOffset(width, [c1, c2, tip, c1]), { fill: 'black' });
// arrow
CanvasUtils.drawPath(overlayContext, width, '#00E8F6', [c1, c2, tip, c1], { fill: 'yellow' });
}
function shadowOffset(width, points) {
return points.map(function(p) { return [p[0] + width * 1.5, p[1] + width * 1.5] });
}
}