Форум программистов, компьютерный форум, киберфорум
JavaScript
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
2 / 2 / 0
Регистрация: 26.01.2016
Сообщений: 80

Морской Бой

15.02.2017, 11:55. Показов 3236. Ответов 33
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задали задачу по Javascript. Написать скрипт программы "Морской Бой", только не тот морской бой который с полями, а был в СССР такой автомат игровой. Т.е. корабли плывут от одного конца экрана к другому, при нажатии на кнопку выпускается торпеда, при попадании в корабль, корабль разворачивается. Подскажите пожалуйста реализацию. ЗАпутался
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.02.2017, 11:55
Ответы с готовыми решениями:

Морской бой
var sea = , , , , ]; // Оригинальный массив, хранящий положение кораблей. ...

необходимо сделать дополнения к игре морской бой!
это код игры морской бой надо подсчитать очки у игрока и у соперника если корабль уничтожен то за это 5 очков за первое попадание в...

Создать небольшую игрушку "Морской бой"
Создать небольшую игрушку.Внизу окна неподвижно стоит пушка,в верхней половине экрана проплывает корабль.по щелчку мыши из пушки...

33
супермизантроп
Эксперт JS
3941 / 2979 / 692
Регистрация: 18.04.2012
Сообщений: 8,629
15.02.2017, 16:50
1. а как бы "перископ" нужен?
насколько помню, в том советском автомате на экране была имитация вида в перископ, на линзе которого была нанесена "топографические оси с делениями" (не знаю, как это в военной оптике правильно называется) -- перископ легко делается средствами HTML+CSS
2. и корабли двигались караванами поочередно: сначала слева направо", а затем "справа налево" -- это я к тому, что нужны будут по два "зеркальных изображения каждого из кораблей

3. и след от "торпеды" имитировался удлиняющейся красной пунктирной линией на "поверхности "моря" -- это можно реализовать посредством JS

4. для начала ищите в сети изображения "поверхности моря и неба над горизонтом", красивую картинку "взрыва" и "корабли"

5. геометрия игры и параметры скрипта будут зависеть от желаемых линейных размеров кораблей
0
2 / 2 / 0
Регистрация: 26.01.2016
Сообщений: 80
15.02.2017, 16:59  [ТС]
kalabuni, да нет, конечно же не нужен перископ и в графике не нужно все это. Вот только пункт 3 из вашего списка.
0
Эксперт JS
2463 / 1769 / 625
Регистрация: 11.07.2016
Сообщений: 4,067
15.02.2017, 17:11
kalabuni хотел сказать, что вы недостаточно подробно описали задачу.
А ещё задачка-то не на 5 минут. Вряд ли кто-то будет её делать целиком за вас. Публикуйте свои наработки и задавайте конкретные вопросы, на которые мы сможем дать конкретный ответ. Посты в стиле "вот задача - напишите реализацию" размещаются в другом разделе.
0
15.02.2017, 18:08

Не по теме:

как-то ещё будучи студентами плыли на теплоходе на остров Валаам и автомат "Морской бой", стоявший в коридоре, каким-то образом "переклинило" -- можно было играть и без 15-ти копеек... играли полночи... на "сэкономленные" деньги накупили в баре разливного пива (плюс у нас с собой было кое-что покрепче)... в общем, и упились, и уигрались :)

0
9948 / 2948 / 497
Регистрация: 05.10.2013
Сообщений: 8,019
Записей в блоге: 242
15.02.2017, 23:57
Цитата Сообщение от Adamsyork Посмотреть сообщение
да нет, конечно же не нужен перископ и в графике не нужно все это. Вот только пункт 3 из вашего списка.
Перед тем как приступать к написанию кода, нужно сначала простыми словами объяснить, что должно получиться в конечном итоге. А лучше показать рисунками. "Морской бой, как в автомате" ни о чём не говорит, потому что для меня проще реализовать это в каком-нибудь браузерном 3D движке типа Unity, PlayCanvas, Babylon.js и т.д. Или вообще делать без каких-либо движков на чистом WebGL. И то нужно делать ясное описание, потому что автомат и компьютер это разные вещи. А то что вы представляете может быть очень отдалённо напоминает ту игру.

А в вашем случае может быть достаточно чтобы перед пользователем появлялось 2D поле голубого цвета (вид сверху). Внизу вытянутый прямоугольник чёрного цвета - это пушка корабля. Сверху медленно двигается квадратик - это вражеский корабль. Пушка передвигается с помощью клавиш стрелок, а выстрел с помощью клика мышки. Все игровые объекты изображаются в виде прямоугольников.

Вот я набросал в Paint'e, как будет выглядеть игра в конце. Так же опишите, как в вашем представлении должна выглядеть игра.
Миниатюры
Морской Бой  
1
9948 / 2948 / 497
Регистрация: 05.10.2013
Сообщений: 8,019
Записей в блоге: 242
16.02.2017, 00:37
Игровые объекты можно рисовать на элементе <canvas>, как показано ниже. Показать, как перемещать пушку клавишами клавиатуры?
PHP/HTML
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
<!DOCTYPE html>
<html>
<head>
    <title>Морской бой</title>
    <meta charset="utf-8" />
</head>
<body>
    <canvas width="400" height="400" id="ctx"></canvas>
 
    <script>
        var ctx = document.getElementById("ctx").getContext("2d");
 
        // Закрашиваем поле голубым цветом - это будет море
        ctx.fillStyle = "#ccfff9";
        ctx.fillRect(0, 0, 400, 400);
 
        // Рисуем врага тёмно-синим цветом
        ctx.fillStyle = "#475fff";
        ctx.fillRect(90, 50, 30, 20);
 
        // Рисуем торпеду чёрным цветом
        ctx.fillStyle = "#000000";
        ctx.fillRect(100, 200, 10, 20);
 
        // Рисуем игрока (пушку) чёрным цветом
        ctx.fillRect(100, 370, 10, 30);
    </script>
</body>
</html>
Миниатюры
Морской Бой  
1
2 / 2 / 0
Регистрация: 26.01.2016
Сообщений: 80
16.02.2017, 17:13  [ТС]
8Observer8, буду признателен))

Добавлено через 26 минут
8Observer8, ну вот как раз так и должна выглядеть, как вы нарисовали. Понятие игрового автомата я использовал, чтобы кто помнит таков имел представление про саму суть игры. А так да, то, что вы набросали в пейнте это то, что нужно. Понятное дело, здесь не идет речь о 3D абсолютно.
0
9948 / 2948 / 497
Регистрация: 05.10.2013
Сообщений: 8,019
Записей в блоге: 242
16.02.2017, 18:24
Давайте вместе попробуем. Одному скучно. Предлагаю программировать на https://jsfiddle.net/

Я создал там проект: https://jsfiddle.net/8Observer8/u8gy0sda/

PHP/HTML
1
<canvas width="300" height="300" id="ctx"></canvas>
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 var ctx = document.getElementById("ctx").getContext("2d");
 
        // Закрашиваем поле голубым цветом - это будет море
        ctx.fillStyle = "#ccfff9";
        ctx.fillRect(0, 0, 300, 300);
 
        // Рисуем врага тёмно-синим цветом
        ctx.fillStyle = "#475fff";
        ctx.fillRect(90, 50, 30, 20);
 
        // Рисуем торпеду чёрным цветом
        ctx.fillStyle = "#000000";
        ctx.fillRect(100, 200, 10, 20);
 
        // Рисуем игрока (пушку) чёрным цветом
        ctx.fillRect(100, 270, 10, 30);
Вы измените что-нибудь, например, цвет: врага, торпеды и игрока. А чтобы проще было подобрать цвета нагуглите: colour picker. Когда цвета измените, то нажмите кнопку Run, потом нажмите кнопку Update и пришлите сюда новую ссылку (не забудьте продублировать код на форуме) Поправилам форума, когда даёшь ссылку на jsfiddle нужно дублировать код на форуме.

Возьмём за основу код из этого тутора, где делают Pong на чистом JavaScript и Canvas2D API: 2D игра на чистом JavaScript Особенно анимацию движения и определение столкновений.
1
2 / 2 / 0
Регистрация: 26.01.2016
Сообщений: 80
17.02.2017, 11:51  [ТС]
8Observer8, поменял цвет врага, при изменении цвета торпеды, такой же цвет приобретает и пушка, почему-то. Понял почему) Добавил отдельно цвет пушки.

HTML5
1
<canvas width="300" height="300" id="ctx"></canvas>
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
       var ctx = document.getElementById("ctx").getContext("2d");
 
        // Закрашиваем поле голубым цветом - это будет море
        ctx.fillStyle = "#ccfff9";
        ctx.fillRect(0, 0, 300, 300);
 
        // Рисуем врага тёмно-синим цветом
        ctx.fillStyle = "#0d1f96";
        ctx.fillRect(90, 50, 30, 20);
 
        // Рисуем торпеду чёрным цветом
        ctx.fillStyle = "#bc0d0d";
        ctx.fillRect(100, 200, 10, 20);
 
        // Рисуем игрока (пушку) чёрным цветом
        ctx.fillStyle = "#000311";
        ctx.fillRect(100, 270, 10, 30);
Вот ссылка https://jsfiddle.net/u8gy0sda/5/
0
9948 / 2948 / 497
Регистрация: 05.10.2013
Сообщений: 8,019
Записей в блоге: 242
17.02.2017, 17:23
С английским у вас как? Давайте рассмотрим цикл рисования (drawing loop)

Как там написано по ссылке drawing loop будем двигать врага слева направо, а потом сделаем движение торпеды вверх.

JavaScript
1
2
3
4
function draw() {
    // drawing code
}
setInterval(draw, 10);
Функция setInterval автоматически вызывает функцию draw() каждые 10 миллисекунд. В секунде 1000 миллисекунд. Это значит, что функция draw() будет вызываться 1000/10 = 100 раз в секунду. То есть 100 FPS (Frame Per Second)

Анимация движения заключается в том, что (1) мы рисуем прямоугольник (врага), (2) через 10 милисекунд стираем его, (3) изменяем координаты (на чуть-чуть - на 1-2 пикселя) и (4) снова рисуем. Через 10 милисекунд опять: стираем, меняем координаты, рисуем.

Я сделал в точности, как в туторе: Move the ball

Враг двигается слева направо: https://jsfiddle.net/8Observer8/u8gy0sda/8/

По аналогии сделайте, чтобы торпеда двигалась вверх. Нужно будет создать вверху две переменные: torpedoY и torpedoSpeed, как я делал с врагом.

PHP/HTML
1
<canvas width="300" height="300" id="ctx"></canvas>
JavaScript
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
var enemyX = 90;
var enemySpeed = 1;
 
//var ctx = document.getElementById("ctx").getContext("2d");
var canvas = document.getElementById("ctx");
var ctx = canvas.getContext("2d");
 
// Закрашиваем поле голубым цветом - это будет море
ctx.fillStyle = "#ccfff9";
ctx.fillRect(0, 0, 300, 300);
 
function draw()
{
    // Очищаем канву
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    // Рисуем врага тёмно-синим цветом
    ctx.fillStyle = "#0d1f96";
    ctx.fillRect(enemyX, 50, 30, 20);
    enemyX += enemySpeed;
 
    // Рисуем торпеду красным цветом
    ctx.fillStyle = "#bc0d0d";
    ctx.fillRect(100, 200, 10, 20);
 
    // Рисуем игрока (пушку) чёрным цветом
    ctx.fillStyle = "#000311";
    ctx.fillRect(100, 270, 10, 30);
}
setInterval(draw, 10);
1
2 / 2 / 0
Регистрация: 26.01.2016
Сообщений: 80
17.02.2017, 17:34  [ТС]
8Observer8 увы не особо с английским в плане чтения((

HTML5
1
<canvas width="300" height="300" id="ctx"></canvas>
JavaScript
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
var enemyX = 90;
var enemySpeed = 1;
var torpedoY = 90;
var torpedoSpeed = 1;
 
//var ctx = document.getElementById("ctx").getContext("2d");
var canvas = document.getElementById("ctx");
var ctx = canvas.getContext("2d");
 
// Закрашиваем поле голубым цветом - это будет море
ctx.fillStyle = "#ccfff9";
ctx.fillRect(0, 0, 300, 300);
 
function draw()
{
    // Очищаем канву
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    // Рисуем врага тёмно-синим цветом
    ctx.fillStyle = "#0d1f96";
    ctx.fillRect(enemyX, 50, 30, 20);
    enemyX += enemySpeed;  
    torpedoY += torpedoSpeed;
 
    // Рисуем торпеду красным цветом
    ctx.fillStyle = "#bc0d0d";
    ctx.fillRect(100, 200, 10, 20);
 
    // Рисуем игрока (пушку) чёрным цветом
    ctx.fillStyle = "#000311";
    ctx.fillRect(100, 270, 10, 30);
}
setInterval(draw, 10);
https://jsfiddle.net/u8gy0sda/10/
0
Superposition
 Аватар для Padimanskas
950 / 615 / 256
Регистрация: 27.10.2013
Сообщений: 2,083
17.02.2017, 17:52
тоже делаю этот тир)

HTML5
1
<canvas width="300" height="300"></canvas>
JavaScript
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
152
153
154
155
156
157
158
159
160
161
162
163
let ctx = document.querySelector('canvas').getContext('2d');
 
class Cannon {
  constructor(x, y, ctx, global, bullets, bullet) {
    this.x = x;
    this.y = y;
    this.bullets = bullets;
    this.bullet = bullet;
    this.ctx = ctx;
    this.global = global;
    this.moveLeft = false;
    this.moveRight = false;
 
    global.addEventListener('keydown', this.keyDown.bind(this));
    global.addEventListener('keyup', this.keyUp.bind(this));
  }
 
  render() {
    this.ctx.fillStyle = "#000311";
    this.ctx.fillRect(this.x, this.y, 10, 30);
  }
 
  move() {
    let Bullet = this.bullet;
 
    if (this.moveRight) this.x--;
    if (this.moveLeft) this.x++;
    if (this.canShoot && !this.bullets.length) {
      this.bullets.push(new Bullet(this.x, this.y, this.ctx, this.global));
      this.canShoot = false;
    }
    if(this.x < 0) this.x++;
    if(this.x > 290) this.x--;
  }
 
  keyDown(e){
    switch(e.which){
      case 37: this.moveRight = true; break;
      case 39: this.moveLeft = true; break;
            case 32: this.canShoot = true; break;
    }
    
  }
  
  keyUp(e){
      switch(e.which){
      case 37: this.moveRight = false; break;
      case 39: this.moveLeft = false; break;
      case 32: this.canShoot = false; break;
    }
  }
 
}
 
class Bullet {
  constructor(x, y, ctx, global, ships) {
    this.x = x;
    this.y = y;
    this.ctx = ctx;
    this.global = global;
    this.delete = false;
    this.ships = ships;
  }
 
  render() {
    this.ctx.fillStyle = "#bc0d0d";
    this.ctx.fillRect(this.x, this.y, 10, 20);
  }
 
  move() {
    this.y--;
    if (this.y < 0) this.delete = true;
  }
 
}
 
 
class Bullets {
    constructor(bullets = []){
    this.bullets = bullets;
  }
  
  render() {
    this.bullets.forEach((bullet, id, bullets) => {
      if (bullet.delete) bullets.splice(id, 1);
      bullet.render();
      bullet.move();
    });
  }
  getBullets(){
    return this.bullets;
  }
}
 
class Ship {
  constructor(x, y, ctx, global) {
    this.x = x;
    this.y = y;
    this.ctx = ctx;
    this.global = global;
    this.delete = false;
    this.moveRight = true;
    this.moveLeft = false;
  }
  render() {
        ctx.fillStyle = "#0d1f96";
        ctx.fillRect(this.x, this.y, 30, 20);
  }
 
  move() {
    if(this.moveRight) this.x++;
    if(this.moveLeft) this.x--;
    if (this.y < 0 || this.y > 300) this.delete = true;
  }
}
 
class Ships {
    constructor(ships, bullets){
        this.ships = ships;
    this.bullets = bullets;
  }
   
}
 
class CollRecognizer {
 
  constructor(ships, bullets) {
    this.ships = ships;
    this.bullets = bullets;
  }
  
  recognision(){
      this.bullets.forEach((bullet, id, bullets) => {
      if (bullet.delete) bullets.splice(id, 1);
      bullet.render();
      bullet.move();
    });
    
    switch(obj.name){
        case 'rightBorder': this.rightBorderColl = true; break;
      case 'leftBorder': this.leftBorderColl = true; break;
    }
  }
}
 
 
 
 
let bullets = new Bullets();
let cannon = new Cannon(100, 270, ctx, document, bullets.getBullets(), Bullet);
let ship = new Ship(50, 50, ctx, document);
 
function gameLoop() {
  ctx.fillStyle = "#ccfff9";
  ctx.fillRect(0, 0, 300, 300);
  ship.render();
 // ship.move();
  cannon.render();
  cannon.move();
    bullets.render();
  requestAnimationFrame(gameLoop);
}
requestAnimationFrame(gameLoop);
https://jsfiddle.net/u8gy0sda/11/
1
9948 / 2948 / 497
Регистрация: 05.10.2013
Сообщений: 8,019
Записей в блоге: 242
17.02.2017, 17:52
Adamsyork, у вас торпеда не двигается. Подумайте, почему?
1
2 / 2 / 0
Регистрация: 26.01.2016
Сообщений: 80
17.02.2017, 22:31  [ТС]
8Observer8, не двигается наверно потому, что мы не назначили ей точку старта
0
9948 / 2948 / 497
Регистрация: 05.10.2013
Сообщений: 8,019
Записей в блоге: 242
18.02.2017, 00:16
Значит, вы не поняли, как двигается враг. Функция draw() вызывается каждые 10 миллисекунд, потому что её вызывает setInterval(draw, 10); вот так:

JavaScript
1
2
3
4
5
function draw()
{
    // ...
}
setInterval(draw, 10);
Внутри функции draw() мы сначала очищаем холст:
JavaScript
1
2
// Очищаем канву
    ctx.clearRect(0, 0, canvas.width, canvas.height);
Выставляем цвет и рисуем врага:
JavaScript
1
2
    ctx.fillStyle = "#0d1f96";
    ctx.fillRect(enemyX, 50, 30, 20);
Заметьте, что X координата - это переменная enemyX. Она инициализированна в самом верху кода:
JavaScript
1
var enemyX = 90;
Далее, мы увеличиваем enemyX для следующей перерисовки:
JavaScript
1
enemyX += enemySpeed;
А теперь сравните код для отрисовки врага и торпеды. Как сделать, чтобы торпеда двигалась вверх?

JavaScript
1
ctx.fillRect(x, y, widht, height);
JavaScript
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
var enemyX = 90;
var enemySpeed = 1;
var torpedoY = 90;
var torpedoSpeed = 1;
 
//var ctx = document.getElementById("ctx").getContext("2d");
var canvas = document.getElementById("ctx");
var ctx = canvas.getContext("2d");
 
// Закрашиваем поле голубым цветом - это будет море
ctx.fillStyle = "#ccfff9";
ctx.fillRect(0, 0, 300, 300);
 
function draw()
{
    // Очищаем канву
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    // Рисуем врага тёмно-синим цветом
    ctx.fillStyle = "#0d1f96";
    ctx.fillRect(enemyX, 50, 30, 20);
    enemyX += enemySpeed;  
 
    // Рисуем торпеду красным цветом
    ctx.fillStyle = "#bc0d0d";
    ctx.fillRect(100, 200, 10, 20);
    torpedoY += torpedoSpeed;
 
    // Рисуем игрока (пушку) чёрным цветом
    ctx.fillStyle = "#000311";
    ctx.fillRect(100, 270, 10, 30);
}
setInterval(draw, 10);
1
Superposition
 Аватар для Padimanskas
950 / 615 / 256
Регистрация: 27.10.2013
Сообщений: 2,083
18.02.2017, 02:42
готово)

HTML5
1
<canvas width="300" height="300"></canvas>
JavaScript
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
let ctx = document.querySelector('canvas').getContext('2d');
 
class Cannon {
  constructor(x, y, ctx, global, bullets, bullet) {
    this.x = x;
    this.y = y;
    this.bullets = bullets;
    this.bullet = bullet;
    this.ctx = ctx;
    this.global = global;
    this.moveLeft = false;
    this.moveRight = false;
 
    global.addEventListener('keydown', this.keyDown.bind(this));
    global.addEventListener('keyup', this.keyUp.bind(this));
  }
 
  render() {
    this.ctx.fillStyle = "#000311";
    this.ctx.fillRect(this.x, this.y, 10, 30);
  }
 
  move() {
    let Bullet = this.bullet;
 
    if (this.moveRight) this.x--;
    if (this.moveLeft) this.x++;
    if (this.canShoot && !this.bullets.length) {
      this.bullets.push(new Bullet(this.x, this.y, 10, 20, this.ctx, this.global));
      this.canShoot = false;
    }
    if (this.x < 0) this.x++;
    if (this.x > 290) this.x--;
  }
 
  keyDown(e) {
    switch (e.which) {
      case 37: this.moveRight = true; break;
      case 39: this.moveLeft = true; break;
      case 32:  this.canShoot = true; break;
    }
 
  }
 
  keyUp(e) {
    switch (e.which) {
      case 37: this.moveRight = false; break;
      case 39: this.moveLeft = false; break;
      case 32: this.canShoot = false; break;
    }
  }
 
}
 
class Bullet {
  constructor(x, y, width, height, ctx, global, ships) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.ctx = ctx;
    this.global = global;
    this.delete = false;
    this.ships = ships;
    this.velocity = 5;
  }
 
  render() {
    this.ctx.fillStyle = "#bc0d0d";
    this.ctx.fillRect(this.x, this.y, this.width, this.height);
  }
 
  move() {
    this.y-=this.velocity;
    if (this.y < 0) this.delete = true;
  }
 
}
 
 
class Bullets {
  constructor(bullets = []) {
    this.bullets = bullets;
  }
 
  render() {
    this.bullets.forEach((bullet, id, bullets) => {
      if (bullet.delete) bullets.splice(id, 1);
      bullet.render();
      bullet.move();
    });
  }
  getBullets() {
    return this.bullets;
  }
}
 
class Ship {
  constructor(x, y, width, height, ctx, global) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.ctx = ctx;
    this.global = global;
    this.delete = false;
    this.velocity = 1;
  }
  render() {
    ctx.fillStyle = "#0d1f96";
    ctx.fillRect(this.x, this.y, this.width, this.height);
  }
 
  move() {
    this.x += this.velocity;
    if (this.x < 0 || this.x > 300 - this.width) this.changeDirection();
  }
  
  changeDirection(){
    this.velocity = -this.velocity;
  }
}
 
class Ships {
  constructor(ships = []) {
    this.ships = ships;
  }
 
  render() {
    this.ships.forEach((ship, id, ships) => {
      ship.render();
      ship.move();
    });
  }
  getShips() {
    return this.ships;
  }
 
}
 
class CollDetector {
 
  constructor(bullets, ships) {
    this.ships = ships;
    this.bullets = bullets;
  }
 
  checkAABB(obj1, obj2) {
    if (obj1.x < obj2.x + obj2.width &&
      obj1.x + obj1.width > obj2.x &&
      obj1.y < obj2.y + obj2.height &&
      obj1.height + obj1.y > obj2.y) {
      return true;
    }
    return false;
  }
 
  checkCollisions() {
    this.ships.forEach((ship, shipId, ships) => {
      this.bullets.forEach((bullet, bulletId, bullets) => {
                if(this.checkAABB(ship, bullet)){
            bullet.delete = true;
          ship.changeDirection();
        }
      });
    });
  }
}
 
let bullets = new Bullets();
let ships = new Ships([new Ship(50, 50, 30, 20, ctx, document), new Ship(150, 50, 30, 20, ctx, document)]);
let cannon = new Cannon(100, 270, ctx, document, bullets.getBullets(), Bullet);
let collDetector = new CollDetector(bullets.getBullets(), ships.getShips());
 
function gameLoop() {
  ctx.fillStyle = "#ccfff9";
  ctx.fillRect(0, 0, 300, 300);
  ships.render();
  bullets.render();
  cannon.move();
  cannon.render();
  collDetector.checkCollisions();
  requestAnimationFrame(gameLoop);
}
requestAnimationFrame(gameLoop);
https://jsfiddle.net/u8gy0sda/14/
2
9948 / 2948 / 497
Регистрация: 05.10.2013
Сообщений: 8,019
Записей в блоге: 242
18.02.2017, 11:18
Adamsyork, за вами задание заставить двигаться торпеду. Найдите ошибку в этом коде:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var torpedoY = 90;
var torpedoSpeed = 1;
 
// ...
 
function draw()
{
    // Очищаем канву
    ctx.clearRect(0, 0, canvas.width, canvas.height);
 
    // ...
 
    // Рисуем торпеду красным цветом
    ctx.fillStyle = "#bc0d0d";
    ctx.fillRect(100, 200, 10, 20);
    torpedoY += torpedoSpeed;
 
    // ...
}
setInterval(draw, 10);
Следующим заданием будет заставить пушку двигаться с помощью клавиш A и D. Потом мы сделаем выстрел на пробел.

Я сделал движение пушки вправо (и упор в стенку), а вы по аналогии сделайте движение влево: https://jsfiddle.net/8Observer8/u8gy0sda/16/

PHP/HTML
1
2
3
4
5
6
7
<canvas width="300" height="300" id="ctx"></canvas>
<h3>Controls:</h3>
<ul>
    <li>Click and Play</li>
    <li>Movement: A, D</li>
    <li>Shooting: Space</li>
</ul>
JavaScript
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
var enemyX = 90; // Координата врага по X
var enemySpeed = 1; // Cкорость врага
 
var torpedoY = 90; // Координата торпеды по Y
var torpedoSpeed = 1; // Скорость торпеды
 
var gunX = 100; // Координата пушки по X
var gunY = 270; // Координата пушки по Y
var gunWidth = 10; // Ширина пушки
var gunHeight = 30; // Высота пушки
var gunSpeed = 1; // Скорость пушки
 
var rightPressed = false; // Нажата ли клавиша "вправо"
var leftPressed = false; // Нажата ли клавиша "влево"
 
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
 
//var ctx = document.getElementById("ctx").getContext("2d");
var canvas = document.getElementById("ctx");
var ctx = canvas.getContext("2d");
 
// Главный игровой цикл
function gameLoop()
{
    update();
    draw();
}
setInterval(gameLoop, 10);
 
function update()
{
    enemyX += enemySpeed;
    torpedoY += torpedoSpeed;
    
    // Двигаем пушку по нажатию клавиш. Обрабатываем упор в стенки
    if(rightPressed && gunX < canvas.width - gunWidth)
    {
        gunX += gunSpeed;
    }
    else if (leftPressed)
    {
    
    }
}
 
function draw()
{
    // Очищаем канву
    ctx.clearRect(0, 0, canvas.width, canvas.height);
 
    // Рисуем игровые объекты
    drawSea();
    drawEnemy();
    drawTorpedo();
    drawGun();
}
 
function drawSea()
{
    // Рисуем море голубым цветом
    ctx.fillStyle = "#ccfff9";
    ctx.fillRect(0, 0, 300, 300);
}
 
function drawEnemy()
{
    // Рисуем врага тёмно-синим цветом
    ctx.fillStyle = "#0d1f96";
    ctx.fillRect(enemyX, 50, 30, 20);
}
 
function drawTorpedo()
{
    // Рисуем торпеду красным цветом
    ctx.fillStyle = "#bc0d0d";
    ctx.fillRect(100, 200, 10, 20);
}
 
function drawGun()
{
    // Рисуем игрока (пушку) чёрным цветом
    ctx.fillStyle = "#000311";
    ctx.fillRect(gunX, gunY, gunWidth, gunHeight);
}
 
function keyDownHandler(e)
{
    if(e.keyCode == 68)
    {
        rightPressed = true;
    }
    else if(e.keyCode == 65)
    {
        leftPressed = true;
    }
}
 
function keyUpHandler(e)
{
    if(e.keyCode == 68)
    {
        rightPressed = false;
    }
    else if(e.keyCode == 65)
    {
        leftPressed = false;
    }
}

P.S. Я сделал небольшой рефакторинг кода (то есть улучшение), чтобы его читать было проще. Изменение позиций будет в функции update(), а рисование в draw(). Из функции draw() вызываются функции рисования объектов: drawEnemy(), drawTorpedo() и т.д. Главный цикл будет называться gameLoop(). Получается такая структура кода:

JavaScript
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
// Главный игровой цикл
function gameLoop()
{
    update();
    draw();
}
setInterval(gameLoop, 10);
 
function update()
{
}
 
function draw()
{
    // Очищаем канву
    ctx.clearRect(0, 0, canvas.width, canvas.height);
 
    // Рисуем игровые объекты
    drawSea();
    drawEnemy();
    drawTorpedo();
    drawGun();
}
 
function drawSea()
{
    // Рисуем море голубым цветом
    ctx.fillStyle = "#ccfff9";
    ctx.fillRect(0, 0, 300, 300);
}
 
function drawEnemy()
{
    // Рисуем врага тёмно-синим цветом
    ctx.fillStyle = "#0d1f96";
    ctx.fillRect(enemyX, 50, 30, 20);
}
 
function drawTorpedo()
{
    // Рисуем торпеду красным цветом
    ctx.fillStyle = "#bc0d0d";
    ctx.fillRect(100, 200, 10, 20);
}
 
function drawGun()
{
    // Рисуем игрока (пушку) чёрным цветом
    ctx.fillStyle = "#000311";
    ctx.fillRect(gunX, gunY, gunWidth, gunHeight);
}
1
2 / 2 / 0
Регистрация: 26.01.2016
Сообщений: 80
18.02.2017, 14:56  [ТС]
8Observer8, можно пару вопросов?
1. Я смотрю что код состоит из HTML и JavaScript. Как мне это делать в моем редакторе? Именно SublimeText? То, что мы параллельно работаем в самом проекте это прекрасно, а вот как мне совместить в редакторе два разных синтаксиса?
2. На каком форуме мне надо дублировать ссылки?
0
9948 / 2948 / 497
Регистрация: 05.10.2013
Сообщений: 8,019
Записей в блоге: 242
18.02.2017, 17:37
Цитата Сообщение от Adamsyork Посмотреть сообщение
можно пару вопросов?
Конечно, можно! Я наоборот жду, когда вы начнёте задавать вопросы.

Цитата Сообщение от Adamsyork Посмотреть сообщение
Я смотрю что код состоит из HTML и JavaScript. Как мне это делать в моем редакторе? Именно SublimeText?
Я использую Visual Studio 2015. Пробовал Brackets. Если он похож на SublimeText, то можно создать пустую папку. Запустить редактор SublimeText и в нём выбрать в меню "File" -> "Open Folder" (или там будет "Open Web Site") и выбрать пустую папку. Далее, правой кнопкой по проекту в редакторе SublimeText и выбрать "Add" -> "New File". Таким образом нужно создать два файла: index.html и main.js

Далее, вам нужно скопировать в вставить код:

index.html
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
    <title>Морской бой</title>
    <meta charset="utf-8" />
    <script src="main.js"></script>
</head>
<body>
    <canvas width="300" height="300" id="canvas2d"></canvas>
</body>
</html>
main.js
JavaScript
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
var enemyX = 90; // Координата врага по X
var enemySpeed = 1; // Cкорость врага
 
var torpedoY = 90; // Координата торпеды по Y
var torpedoSpeed = 1; // Скорость торпеды
 
var gunX = 100; // Координата пушки по X
var gunY = 270; // Координата пушки по Y
var gunWidth = 10; // Ширина пушки
var gunHeight = 30; // Высота пушки
var gunSpeed = 1; // Скорость пушки
 
var rightPressed = false; // Нажата ли клавиша "вправо"
var leftPressed = false; // Нажата ли клавиша "влево"
 
var canvas = null;
var context = null;
 
// Для запуска с сервера
window.onload = main;
 
// Для запуска из jsfiddle.net
//main();
 
function main()
{
    //var context = document.getElementById("context").getContext("2d");
    canvas = document.getElementById("canvas2d");
    context = canvas.getContext("2d");
 
    // Главный игровой цикл
    function gameLoop()
    {
        update();
        draw();
    }
    setInterval(gameLoop, 10); // Запускаем главный игровой цикл
}
 
function update()
{
    enemyX += enemySpeed;
    torpedoY += torpedoSpeed;
}
 
function draw()
{
    // Очищаем канву
    context.clearRect(0, 0, canvas.width, canvas.height);
 
    // Рисуем игровые объекты
    drawSea();
    drawEnemy();
    drawTorpedo();
    drawGun();
}
 
function drawSea()
{
    // Рисуем море голубым цветом
    context.fillStyle = "#ccfff9";
    context.fillRect(0, 0, 300, 300);
}
 
function drawEnemy()
{
    // Рисуем врага тёмно-синим цветом
    context.fillStyle = "#0d1f96";
    context.fillRect(enemyX, 50, 30, 20);
}
 
function drawTorpedo()
{
    // Рисуем торпеду красным цветом
    context.fillStyle = "#bc0d0d";
    context.fillRect(100, 200, 10, 20);
}
 
function drawGun()
{
    // Рисуем игрока (пушку) чёрным цветом
    context.fillStyle = "#000311";
    context.fillRect(gunX, gunY, gunWidth, gunHeight);
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.02.2017, 17:37
Помогаю со студенческими работами здесь

Морской бой
Здравствуйте! Начинаю изучать программирование с помощью создания игры Морской бой. Ничего не получается((( Помогите, пожалуйста, понять в...

Игра Морской бой
Нужно создать игру морской бой, в которой на одном компьютере будет играть два человека одновременно. Для того чтобы игроки не подглядывали...

Морской бой
Скажите - каким образом лучше написать морской бой (т.е. как лучше сделать форму). у меня есть несколько идей: 1)набросать 200...

морской бой
#include &lt;iostream&gt; // cin, cout #include &lt;clocale&gt; // поддержка русского языка #include &lt;conio.h&gt; // _getch() #include...

Морской бой
Удалите: выбор стратегии, делать первый ход, самостоятельную расстановку кораблей. Позиции должны указываться русскими буквами от А до...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru