Лабиринт
Описание
Реализация копьютерной игры Лабринт на языке программирования JavaScript
Правила игры: 1. Перед пользователем появляется клетчатое поле, пустое окно для ввода чисел снизу и кнопка «Start» 2. Задача нарисовать лабиринт. Используя правую кнопку мыши, игрок нажимает на ребра сетки или около него, чтобы создать стенку в лабиринте. Повторное нажатие убирает, нарисованный объект. Далее игрок вводит число объектов (шаров), которое не должно превышать 25, в специальном поле, расположенным ниже лабиринта, и нажимает «Start», чтобы запустить игру. 3. После старта частицы начинают двигаться, отталкиваясь от стенок лабиринта, самого поля и от друг друга абсолютно упруго. Игра заканчивается тогда, когда первая из частиц попадает в определенную область, произвольно генерирующуюся в поле и проявляющуюся на мониторе по окончании игры. 4. После окончание на экран игрока выводится слова о его победе и время движения выигравшей частицы.
Исполнители: Бутузова Е.С., Галанина Е.В.
Группа 3630103/90003 Кафедра Теоретической механики
Визуализация
Код программы
1 var N = 600;
2 var x ;
3 var y ;
4 const eps = 7;
5 var edge_vert = [];
6 var edge_hor = [];
7 var IsBelongs_vert = false;
8 var IsBelongs_hor = false;
9 var start_pressed = false;
10 var winFlag = false;
11 var mousecoords = [];
12 var start;
13
14 window.addEventListener('load', main, false);
15 function main() {
16 var ctx = canvas_example.getContext('2d');
17 var w = canvas_example.width;
18 var h = canvas_example.height;
19
20 //рисует сетку
21 function Plot(x,y){
22 ctx.beginPath();
23 ctx.width = 2;
24 for (var i = 0; i<N; i+=50){
25 var x = i;
26 var y = 600;
27 ctx.moveTo(x,0);
28 ctx.lineTo(x,y);
29 ctx.stroke();
30 }
31 for (var j = 0; j<N; j+=50) {
32 var x = 600;
33 var y = j;
34 ctx.moveTo(0,y);
35 ctx.lineTo(x,y);
36 ctx.stroke();
37 }
38 }
39
40 function abs(x)
41 {
42 if(x < 0){
43 return -x;
44 }
45 else{
46 return x;
47 }
48 }
49 //возвращает координаты точки
50 function set_point(_x, _y) {
51 return {
52 x: _x,
53 y: _y,
54 }
55 }
56 //возвращает координаты ребра
57 function set_edge(a,b,c,d){
58 return{
59 beg: set_point(a,b),
60 end: set_point(c,d)
61 }
62 }
63 //возвращает последний элемент массива
64 function last(array)
65 {
66 if(array.length != 0)
67 {
68 return array[array.length - 1];
69 }
70 }
71 //отрисовывает ребра
72 function draw(m, color)
73 {
74 ctx.width = 1;
75 ctx.beginPath()
76 ctx.moveTo(m.beg.x, m.beg.y);
77 ctx.lineTo(m.end.x, m.end.y);
78 ctx.strokeStyle = color;
79 ctx.fillStyle = "rgba(0, 0, 200, 1)";
80 ctx.lineWidth =3 ;
81 ctx.stroke();
82 }
83
84 // only for edge_vert and edge_hor, проверяет есть ли уже такое ребро в массиве
85 function is_in(arr, x1, y1, x2, y2)
86 {
87 for(var i = 0; i < arr.length; i++)
88 {
89 if(arr[i].beg.x == x1 && arr[i].beg.y == y1
90 && arr[i].end.x == x2 && arr[i].end.y == y2)
91 {
92 return true;
93 }
94 }
95 return false;
96 }
97 //аналогично is_in, но возвращает индекс
98 function find(arr, x1, y1, x2, y2)
99 {
100 for(var i = 0; i < arr.length; i++)
101 {
102 if(arr[i].beg.x == x1 && arr[i].beg.y == y1
103 && arr[i].end.x == x2 && arr[i].end.y == y2)
104 {
105 return i;
106 }
107 }
108 return -1;
109 }
110
111 //проверка нажатия
112 function check(m) {
113 for(var i = 0; i < N; i += 50){
114 if(abs(m.x - i) < eps)
115 {
116 if( !is_in(edge_vert, i, m.y - m.y%50, i, m.y - m.y%50 + 50) )
117 {
118 edge_vert.push(set_edge(i, m.y - m.y%50, i, m.y - m.y%50 + 50));
119 IsBelongs_vert = true;
120 }
121 else
122 {
123 var ind = find(edge_vert, i, m.y - m.y%50, i, m.y - m.y%50 + 50);
124 var m = edge_vert[ind];
125 draw(m, "black");
126 edge_vert.splice(ind, 1);
127 }
128 }
129 if (abs(m.y - i) < eps)
130 {
131 if( !is_in(edge_hor, m.x - m.x%50, i, m.x - m.x%50 + 50, i) )
132 {
133 edge_hor.push(set_edge(m.x - m.x%50, i, m.x - m.x%50 + 50, i)) ;
134 IsBelongs_hor = true;
135 }
136 else
137 {
138 var ind = find(edge_hor, m.x - m.x%50, i, m.x - m.x%50 + 50, i);
139 var m = edge_hor[ind];
140 draw(m, "black");
141 edge_hor.splice(ind, 1);
142 }
143 }
144 }
145 //console.log(edge_hor);
146 //console.log(edge_vert);
147 //console.log(mousecoords);
148 }
149 //определяет координаты мышки
150 function getMouseCoords(e) {
151 var m = {};
152 var rect = canvas_example.getBoundingClientRect();
153 m.x = e.clientX - rect.left;
154 m.y = e.clientY- rect.top;
155 return m;
156 }
157
158 canvas_example.onmousedown = function(e) {
159 if(!start_pressed)
160 {
161 var m = getMouseCoords(e);
162 check(m);
163 //console.log(edge_vert);
164 //console.log(edge_hor);
165 }
166 }
167
168 //рисуем выбранные ребра
169 canvas_example.onmouseup = function(e){
170 if(!start_pressed)
171 {
172 var m;
173 if(IsBelongs_vert){
174
175 m = last(edge_vert);
176 draw(m, "red");
177 }
178 if(IsBelongs_hor){
179 m = last(edge_hor);
180 draw(m, "red");
181 }
182 IsBelongs_hor = false;
183 IsBelongs_vert = false;
184 }
185 }
186 //привязываем появление частиц к нажатию кнопки старт
187 button_start.onclick = function() {
188 if(!start_pressed)
189 {
190 var particles = new Particles_generate(edge_vert,edge_hor);
191 var dt = 1 / particles.get_fps();
192 start_pressed = true;
193 setInterval(control.bind(this, particles), 1000 * dt);
194 start = new Date().getTime();
195
196 }
197 }
198 //отрисовывает выбранные ребра лабиринта
199 function Draw_labirint () {
200 ctx.clearRect(0,0,w,h);
201 var k;
202 for(var i = 0; i< edge_vert.length; i++){
203 k = edge_vert[i];
204 ctx.beginPath()
205 ctx.moveTo(k.beg.x, k.beg.y);
206 ctx.lineTo(k.end.x, k.end.y);
207 ctx.strokeStyle="red";
208 ctx.fillStyle = "rgba(0, 0, 200, 1)";
209 ctx.lineWidth=3;
210
211 ctx.stroke();
212 }
213
214 var n;
215 for(var j = 0; j < edge_hor.length; j++){
216 n = edge_hor[j];
217 ctx.beginPath()
218 ctx.moveTo(n.beg.x,
219
220 n.beg.y);
221 ctx.lineTo(n.end.x, n.end.y);
222 ctx.strokeStyle="red";
223 ctx.fillStyle = "rgba(0, 0, 200, 1)";
224 ctx.lineWidth=3;
225 ctx.stroke();
226 }
227 }
228
229 Plot(x,y);
230 //Particle();
231
232 function control(particles) {
233 if(!particles.stopped){
234 ctx.clearRect(0, 0, w, h);
235 Draw_labirint();
236 particles.Check_standoff();
237 particles.control();
238 particles.win();
239 //setInterval(control.bind(this, particles), 1000 * dt);
240 }
241 }
242 }