-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathball_mod.js
151 lines (136 loc) · 4.62 KB
/
ball_mod.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
var ballMod = (function () {
var bm = {};
var gridEl = function (x, y) {
return document.getElementsByClassName('col_' + y + '_' + x)[0];
};
function toRadians (angle) {
return angle * (Math.PI / 180);
}
function range(start, end, step) {
start = +start || 0;
step = typeof step == 'number' ? step : (+step || 1);
if (end === null) {
end = start;
start = 0;
}
// use `Array(length)` so engines like Chakra and V8 avoid slower modes
// http://youtu.be/XAqIpGU8ZZk#t=17m25s
var index = -1,
length = Math.max(0, Math.ceil((end - start) / (step || 1))),
result = Array(length);
while (++index < length) {
result[index] = start;
start += step;
}
return result;
}
// Ball instance constructor
bm.ball = function (config) {
config = config || {};
this.x = config.x || 0;
this.y = config.y || 0;
this.speed = config.speed || 1; // in "pixels"
this.direction = config.direction || 0; // in degrees
this.element = function () {
return gridEl(this.x, this.y);
};
this.element().click();
this.color = this.element().style.backgroundColor;
this.delay = config.delay || 150;
};
bm.ball.prototype.move = function (coords) {
var prevColor = this.element().style.backgroundColor;
if(this.element().style.backgroundColor) {
this.element().click();
}
this.x = coords.x;
this.y = coords.y;
var self = this;
if(!this.element().style.backgroundColor && this.element().style.backgroundColor !== this.color) {
window.setTimeout(function () {
self.element().click();
}, this.delay);
}
};
// Engine that drives the ball
bm.ballEngine = function (ballInstance) {
this.ball = ballInstance;
var self = this;
this.interval = window.setInterval(function () {
self.next();
}, this.ball.delay*2);
};
bm.ballEngine.prototype.next = function (ballInstance) {
var self = this;
var nextCoord = {
x: function (x, direction) {
x = typeof x !== 'undefined' ? x : self.ball.x;
direction = typeof direction !== 'undefined' ? direction : self.ball.direction;
return x + Math.round(Math.cos(toRadians(direction)) * self.ball.speed);
},
y: function (y, direction) {
y = typeof y !== 'undefined' ? y : self.ball.y;
direction = typeof direction !== 'undefined' ? direction : self.ball.direction;
return y + Math.round(Math.sin(toRadians(direction)) * self.ball.speed);
}
};
var collide = function (x, y) {
var likelyEl = gridEl(x, y);
if(typeof likelyEl === 'undefined') {
return true;
} else {
return likelyEl.style.backgroundColor !== '' && likelyEl.style.backgroundColor !== self.ball.element().style.backgroundColor;
}
};
var checkDirection = function (direction) {
return collide(nextCoord.x(self.ball.x, direction), nextCoord.y(self.ball.y, direction));
};
var collisionTests = range(0, 360, 45);
var newDirection = function () {
self.ball.direction %= 360;
if(self.ball.direction % 90 === 0) {
if(checkDirection(self.ball.direction)) {
return 180 - self.ball.direction;
} else {
return self.ball.direction;
}
} else {
if(self.ball.direction % 45 === 0){
var cti = collisionTests.map(function (direction) {
return checkDirection(direction);
});
var directionIndex = collisionTests.indexOf(self.ball.direction);
var dHi = directionIndex + 1 < collisionTests.length ? directionIndex + 1 : 0;
var dLo = directionIndex - 1;
var reflect = cti[directionIndex] && (!cti[dHi] && !cti[dLo]);
if(reflect || (cti[dHi] && cti[dLo])) {
return 180 + self.ball.direction;
} else {
if(cti[dHi] || cti[dLo]) {
var vertical = 360 - self.ball.direction;
var horizontal = self.ball.direction > 180 ? 540 - self.ball.direction : 180 - self.ball.direction;
var tests = {
"2": vertical,
"6": vertical,
"0": horizontal,
"4": horizontal
};
var wall = cti[dHi] ? dHi : dLo;
return tests[wall];
} else {
return self.ball.direction;
}
}
} else {
return self.ball.direction;
}
}
};
this.ball.direction = newDirection();
this.ball.move({ y: nextCoord.y(), x: nextCoord.x() });
};
bm.init = function (config) {
var e = new bm.ballEngine(new bm.ball(config));
};
return bm;
}());