Gravity Guy — различия между версиями
Материал из Department of Theoretical and Applied Mechanics
(→top) |
(→Игра) |
||
(не показаны 2 промежуточные версии этого же участника) | |||
Строка 6: | Строка 6: | ||
== Игра == | == Игра == | ||
− | {{#widget:Iframe | url=http://tm.spbstu.ru/htmlets/js2020/GravityGuy/GravityGuy.html | width=800 | height= | + | {{#widget:Iframe | url=http://tm.spbstu.ru/htmlets/js2020/GravityGuy/GravityGuy.html | width=800 | height=400 | border=0 }} |
+ | |||
+ | == Код программы == | ||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | '''HTML:''' <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
+ | <!DOCTYPE html> | ||
+ | <html> | ||
+ | |||
+ | <head> | ||
+ | <meta charset="UTF-8"> | ||
+ | <title>Gravity guy!</title> | ||
+ | </head> | ||
+ | |||
+ | <body> | ||
+ | |||
+ | <script src="Курсач.js"></script> | ||
+ | <canvas id="cnvs" width="760" height="363"></canvas> | ||
+ | |||
+ | </body> | ||
+ | |||
+ | </html> | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | '''JavaScript:''' <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
+ | window.addEventListener('load', main, false); | ||
+ | |||
+ | function createImage(imagePath) { | ||
+ | let img = new Image(); | ||
+ | img.src = imagePath; | ||
+ | return img; | ||
+ | } | ||
+ | |||
+ | var bgImage = createImage('bg_760.jpg'); // Фон | ||
+ | var UpImage = createImage('Up.png'); // Блок вверхний | ||
+ | var BottomImage = createImage('Bottom.png'); // Блок нижний | ||
+ | var playerImage = createImage('pl.png'); // Игрок | ||
+ | var coinImage = createImage('coin.png'); // Монетка | ||
+ | |||
+ | function main() { | ||
+ | |||
+ | function drawImage(obj) { | ||
+ | ctx.drawImage(obj.image, obj.x-obj.w/2, obj.y-obj.h/2, obj.w, obj.h); | ||
+ | } | ||
+ | |||
+ | var ctx = cnvs.getContext('2d'); | ||
+ | var w = cnvs.width; | ||
+ | var h = cnvs.height; | ||
+ | |||
+ | var defaultUp = 60; | ||
+ | var defaultBottom = 300; | ||
+ | var gap = 150; // Отступ между блоками | ||
+ | var lastBlock = false; | ||
+ | |||
+ | var dt = 0.1; | ||
+ | var score = 0; | ||
+ | |||
+ | // Создание блоков | ||
+ | function createBlockUp(x, y) { | ||
+ | return { | ||
+ | x: x, | ||
+ | y: y, | ||
+ | w: 150, | ||
+ | h: 40, | ||
+ | image: UpImage, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function createBlockBottom(x, y) { | ||
+ | return { | ||
+ | x: x, | ||
+ | y: y, | ||
+ | w: 150, | ||
+ | h: 40, | ||
+ | image: BottomImage, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | var blocksUp = [ | ||
+ | createBlockUp(90+gap, defaultUp), | ||
+ | createBlockUp(90+3*gap, defaultUp), | ||
+ | ]; | ||
+ | |||
+ | var blocksBottom = [ | ||
+ | createBlockBottom(90, defaultBottom), | ||
+ | createBlockBottom(90+2*gap, defaultBottom), | ||
+ | createBlockBottom(90+4*gap, defaultBottom), | ||
+ | ]; | ||
+ | |||
+ | |||
+ | // Создание монеток | ||
+ | function createCoin(x, y) { | ||
+ | return { | ||
+ | x: x, | ||
+ | y: y, | ||
+ | w: 30, | ||
+ | h: 30, | ||
+ | image: coinImage, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | var coins = []; | ||
+ | |||
+ | // Игрок | ||
+ | var player = { | ||
+ | x: 90, | ||
+ | y: 200, | ||
+ | grav: 30, | ||
+ | vx: 10, | ||
+ | vy: 0, | ||
+ | w: 36, | ||
+ | h: 36, | ||
+ | image: playerImage, | ||
+ | inAir: true, | ||
+ | } | ||
+ | |||
+ | |||
+ | // При нажатии на кнопку | ||
+ | document.addEventListener('keydown', (event) => { | ||
+ | const keyName = event.key; | ||
+ | if (!player.inAir) { | ||
+ | player.grav *= -1; | ||
+ | player.vy *= -10; | ||
+ | } | ||
+ | }) | ||
+ | |||
+ | |||
+ | function draw() { | ||
+ | |||
+ | // Рисует фон | ||
+ | ctx.clearRect(0,0,w,h) | ||
+ | ctx.drawImage(bgImage, 0, 0); | ||
+ | |||
+ | // Счёт монеток | ||
+ | ctx.fillStyle = '#000'; | ||
+ | ctx.font = '24px Verdana'; | ||
+ | ctx.fillText('Монеток: ' + score, w - 180, 40); | ||
+ | |||
+ | // Рисует игрока | ||
+ | drawImage(player); | ||
+ | |||
+ | // Рисует платформы и монетки | ||
+ | for (var i=0; i < blocksBottom.length; i++) { | ||
+ | drawImage(blocksBottom[i]); | ||
+ | } | ||
+ | for (var i=0; i < blocksUp.length; i++) { | ||
+ | drawImage(blocksUp[i]); | ||
+ | } | ||
+ | for (var i=0; i < coins.length; i++) { | ||
+ | drawImage(coins[i]); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | function physics() { | ||
+ | |||
+ | // Движение игрока | ||
+ | player.y += player.grav * dt; | ||
+ | player.inAir = true; | ||
+ | |||
+ | // Столкновение с платформой | ||
+ | for (var i=0; i < blocksBottom.length; i++) { | ||
+ | var block = blocksBottom[i] | ||
+ | if (player.x > block.x-block.w/2 | ||
+ | && player.x < block.x+block.w/2 | ||
+ | && player.y + player.h/2 > block.y-block.h/2 - 20) { | ||
+ | player.y = block.y - block.h/2 - 5; | ||
+ | player.vy = 1; | ||
+ | player.inAir = false; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | for (var i=0; i < blocksUp.length; i++) { | ||
+ | var block = blocksUp[i]; | ||
+ | if (player.x > block.x - block.w/2 | ||
+ | && player.x < block.x + block.w/2 | ||
+ | && player.y - player.h/2 - 10 < block.y + block.h/2 - 20) { | ||
+ | player.y = block.y + block.h/2 - 5; | ||
+ | player.vy = -1; | ||
+ | player.inAir = false; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Движение платформ и монеток | ||
+ | for (var i=0; i < blocksBottom.length; i++) { | ||
+ | blocksBottom[i].x -= player.vx * dt; | ||
+ | } | ||
+ | for (var i=0; i < blocksUp.length; i++) { | ||
+ | blocksUp[i].x -= player.vx * dt; | ||
+ | } | ||
+ | for (var i=0; i < coins.length; i++) { | ||
+ | coins[i].x -= player.vx * dt; | ||
+ | } | ||
+ | |||
+ | // Создание новых платформ с монетками | ||
+ | if (blocksBottom[blocksBottom.length-1].x < 800 - gap && !lastBlock) { | ||
+ | |||
+ | var x = 800 - Math.floor(Math.random()*50); | ||
+ | var y = Math.floor(defaultUp + Math.random()*60) | ||
+ | |||
+ | blocksUp.push(createBlockUp(x, y)) | ||
+ | coins.push(createCoin(x-40, y+25)); | ||
+ | coins.push(createCoin(x, y+25)); | ||
+ | coins.push(createCoin(x+40, y+25)); | ||
+ | |||
+ | lastBlock = true; | ||
+ | dt += 0.01; | ||
+ | } | ||
+ | |||
+ | if (blocksUp[blocksUp.length-1].x < 800 - gap && lastBlock) { | ||
+ | |||
+ | var x = 800 - Math.floor(Math.random()*20); | ||
+ | var y = Math.floor(defaultBottom - Math.random()*50) | ||
+ | |||
+ | blocksBottom.push(createBlockBottom(x, y)) | ||
+ | coins.push(createCoin(x-40, y-25)); | ||
+ | coins.push(createCoin(x, y-25)); | ||
+ | coins.push(createCoin(x+40, y-25)); | ||
+ | |||
+ | lastBlock = false; | ||
+ | } | ||
+ | |||
+ | // Перезапуск игры | ||
+ | if(player.y + player.h <= 0 || player.y - player.h >= defaultBottom) { | ||
+ | location.reload(); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | function collectingCoins() { | ||
+ | // Сбор монеток | ||
+ | for (var i=0; i < coins.length; i++) { | ||
+ | |||
+ | var penny = coins[i]; | ||
+ | |||
+ | if (player.w/2 + penny.w/2 > penny.x - player.x | ||
+ | && player.h/2 + player.h/2 > player.y - penny.y | ||
+ | && player.h/2 + player.h/2 > penny.y - player.y ) { | ||
+ | coins.splice(0, 1); | ||
+ | score++; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | function control() { | ||
+ | draw(); | ||
+ | physics(); | ||
+ | collectingCoins(); | ||
+ | requestAnimationFrame(control); | ||
+ | } | ||
+ | |||
+ | control(); | ||
+ | |||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | </div> |
Текущая версия на 17:24, 30 мая 2020
Описание[править]
- Реализация компьютерной игры Gravity Guy на языке программирования JavaScript
- Автор: Павлова Екатерина
- Группа 3630103/90003
Игра[править]
Код программы[править]
HTML:
1 <!DOCTYPE html>
2 <html>
3
4 <head>
5 <meta charset="UTF-8">
6 <title>Gravity guy!</title>
7 </head>
8
9 <body>
10
11 <script src="Курсач.js"></script>
12 <canvas id="cnvs" width="760" height="363"></canvas>
13
14 </body>
15
16 </html>
JavaScript:
1 window.addEventListener('load', main, false);
2
3 function createImage(imagePath) {
4 let img = new Image();
5 img.src = imagePath;
6 return img;
7 }
8
9 var bgImage = createImage('bg_760.jpg'); // Фон
10 var UpImage = createImage('Up.png'); // Блок вверхний
11 var BottomImage = createImage('Bottom.png'); // Блок нижний
12 var playerImage = createImage('pl.png'); // Игрок
13 var coinImage = createImage('coin.png'); // Монетка
14
15 function main() {
16
17 function drawImage(obj) {
18 ctx.drawImage(obj.image, obj.x-obj.w/2, obj.y-obj.h/2, obj.w, obj.h);
19 }
20
21 var ctx = cnvs.getContext('2d');
22 var w = cnvs.width;
23 var h = cnvs.height;
24
25 var defaultUp = 60;
26 var defaultBottom = 300;
27 var gap = 150; // Отступ между блоками
28 var lastBlock = false;
29
30 var dt = 0.1;
31 var score = 0;
32
33 // Создание блоков
34 function createBlockUp(x, y) {
35 return {
36 x: x,
37 y: y,
38 w: 150,
39 h: 40,
40 image: UpImage,
41 }
42 }
43
44 function createBlockBottom(x, y) {
45 return {
46 x: x,
47 y: y,
48 w: 150,
49 h: 40,
50 image: BottomImage,
51 }
52 }
53
54 var blocksUp = [
55 createBlockUp(90+gap, defaultUp),
56 createBlockUp(90+3*gap, defaultUp),
57 ];
58
59 var blocksBottom = [
60 createBlockBottom(90, defaultBottom),
61 createBlockBottom(90+2*gap, defaultBottom),
62 createBlockBottom(90+4*gap, defaultBottom),
63 ];
64
65
66 // Создание монеток
67 function createCoin(x, y) {
68 return {
69 x: x,
70 y: y,
71 w: 30,
72 h: 30,
73 image: coinImage,
74 }
75 }
76
77 var coins = [];
78
79 // Игрок
80 var player = {
81 x: 90,
82 y: 200,
83 grav: 30,
84 vx: 10,
85 vy: 0,
86 w: 36,
87 h: 36,
88 image: playerImage,
89 inAir: true,
90 }
91
92
93 // При нажатии на кнопку
94 document.addEventListener('keydown', (event) => {
95 const keyName = event.key;
96 if (!player.inAir) {
97 player.grav *= -1;
98 player.vy *= -10;
99 }
100 })
101
102
103 function draw() {
104
105 // Рисует фон
106 ctx.clearRect(0,0,w,h)
107 ctx.drawImage(bgImage, 0, 0);
108
109 // Счёт монеток
110 ctx.fillStyle = '#000';
111 ctx.font = '24px Verdana';
112 ctx.fillText('Монеток: ' + score, w - 180, 40);
113
114 // Рисует игрока
115 drawImage(player);
116
117 // Рисует платформы и монетки
118 for (var i=0; i < blocksBottom.length; i++) {
119 drawImage(blocksBottom[i]);
120 }
121 for (var i=0; i < blocksUp.length; i++) {
122 drawImage(blocksUp[i]);
123 }
124 for (var i=0; i < coins.length; i++) {
125 drawImage(coins[i]);
126 }
127
128 }
129
130 function physics() {
131
132 // Движение игрока
133 player.y += player.grav * dt;
134 player.inAir = true;
135
136 // Столкновение с платформой
137 for (var i=0; i < blocksBottom.length; i++) {
138 var block = blocksBottom[i]
139 if (player.x > block.x-block.w/2
140 && player.x < block.x+block.w/2
141 && player.y + player.h/2 > block.y-block.h/2 - 20) {
142 player.y = block.y - block.h/2 - 5;
143 player.vy = 1;
144 player.inAir = false;
145 }
146 }
147
148 for (var i=0; i < blocksUp.length; i++) {
149 var block = blocksUp[i];
150 if (player.x > block.x - block.w/2
151 && player.x < block.x + block.w/2
152 && player.y - player.h/2 - 10 < block.y + block.h/2 - 20) {
153 player.y = block.y + block.h/2 - 5;
154 player.vy = -1;
155 player.inAir = false;
156 }
157 }
158
159 // Движение платформ и монеток
160 for (var i=0; i < blocksBottom.length; i++) {
161 blocksBottom[i].x -= player.vx * dt;
162 }
163 for (var i=0; i < blocksUp.length; i++) {
164 blocksUp[i].x -= player.vx * dt;
165 }
166 for (var i=0; i < coins.length; i++) {
167 coins[i].x -= player.vx * dt;
168 }
169
170 // Создание новых платформ с монетками
171 if (blocksBottom[blocksBottom.length-1].x < 800 - gap && !lastBlock) {
172
173 var x = 800 - Math.floor(Math.random()*50);
174 var y = Math.floor(defaultUp + Math.random()*60)
175
176 blocksUp.push(createBlockUp(x, y))
177 coins.push(createCoin(x-40, y+25));
178 coins.push(createCoin(x, y+25));
179 coins.push(createCoin(x+40, y+25));
180
181 lastBlock = true;
182 dt += 0.01;
183 }
184
185 if (blocksUp[blocksUp.length-1].x < 800 - gap && lastBlock) {
186
187 var x = 800 - Math.floor(Math.random()*20);
188 var y = Math.floor(defaultBottom - Math.random()*50)
189
190 blocksBottom.push(createBlockBottom(x, y))
191 coins.push(createCoin(x-40, y-25));
192 coins.push(createCoin(x, y-25));
193 coins.push(createCoin(x+40, y-25));
194
195 lastBlock = false;
196 }
197
198 // Перезапуск игры
199 if(player.y + player.h <= 0 || player.y - player.h >= defaultBottom) {
200 location.reload();
201 }
202
203 }
204
205 function collectingCoins() {
206 // Сбор монеток
207 for (var i=0; i < coins.length; i++) {
208
209 var penny = coins[i];
210
211 if (player.w/2 + penny.w/2 > penny.x - player.x
212 && player.h/2 + player.h/2 > player.y - penny.y
213 && player.h/2 + player.h/2 > penny.y - player.y ) {
214 coins.splice(0, 1);
215 score++;
216 }
217
218 }
219
220 }
221
222
223 function control() {
224 draw();
225 physics();
226 collectingCoins();
227 requestAnimationFrame(control);
228 }
229
230 control();
231
232 }