ПОКОДИЛ
понемногу возвращаюсь в мукер, например в субботу кодил около пяти часов! это рекорд - из-за личных обстоятельств более 5 месяцев не мукерил больше часов двух в неделю. дополнительный стимул - теперь программирую на большом 34-дюймовой мониторе
пока переключился на создание на канвасе простеньких игр с нуля - наконец-то к этому готов. опять же подобные игры затем легко вставить в мейкер как мини-игры. когда разбираешься в устройстве подобных игрулек, то наконец-то начинаешь видеть картину в целом. об это картине и попробую рассказать, а начну с самого базового
ГАЛАГА с нуля
начать решил с галаги - не особо сложная и при этом от нее легко оттолкнуться к другим играм. в ней у меня три класса - два вспомогательных и основа - Script
class Helper {}
class Images{}
class Script{}
1. Вспомогательный класс Helper
Здесь вспомогательные функции,которые по сути никак не относятся, к логике игры. Пока она одна:
Рандом в интервале двух чисел.
random(min, max) {
return Math.floor(Math.random()*(max-min+1))+min;
}
Подробнее:
Math.random()- функция, которая возвращается рандомное число от 0 до 1.
Умножаем ее на интервал минимального и максимального числа: Math.random()*(max-min)
Оно обычно с кучей знаков после запятой, поэтому округляем через Math.floor(): Math.floor(Math.random()*(max-min))
Так как Math.floor() округляет "вниз", то к интервалу прибавляем единичку: Math.floor(Math.random()*(max-min+1))
Прибавляем минимальное число, так как мы нашли рандом в интервале между минимумо и максимумом: Math.floor(Math.random()*(max-min+1))+min
class Helper {
random(min, max) {
return Math.floor(Math.random()*(max-min+1))+min;
}
}
class Images{}
class Script{}
2. Вспомогательный класс Images
Картинки, используемые в игре. Чтоб не было зависимостей и не приходилось качать картинки и вставлять их в папку своей игры чтоб пощупать плагин, они сделаны через "base 64 To Img", т.е. каждая картинка записана кодом. Плюс это помогает оптимизировать память.
Например берем картинку звездолета в формате ПНГ, вставляем в этот
сайт и получаем здоровенный код.
Cоздаем объект Image: let img= new Image()
А тот здоровенный код указываем в свойство src: img.src = "data:image/png;base64,здоровенный код в кавычках";
Итого:
spaceship() {
var img = new Image();
img.src = "data:image/png;base64,здоровенный код в кавычках";
return img;
}
То же самое для спрайтов врагов:
enemy() {
var img = new Image();
img.src = "data:image/png;base64,здоровенный код в кавычках";
return img;
}
куча одинакового кода поэтому создаем фукцию:
base64ToImg(value) {
var img = new Image();
img.src = value;
return img;
}
а наши функции звездолета и врагов просто вызывают его:
spaceship() {
return this.base64ToImg("data:image/png;base64,здоровенный код в кавычках")
}
Затем добавляем картинки для повер-апов, титульного экрана, экрана гейм-овера, спрайт врагов
Итого:
class Helper {
random(min, max) {
return Math.floor(Math.random()*(max-min+1))+min;
}
}
class Images{
base64ToImg(value) {
var img = new Image();
img.src = value;
return img;
}
spaceship() {
return this.base64ToImg("data:image/png;base64,здоровенный код в кавычках")
}
powerup() {
return this.base64ToImg("data:image/png;base64,здоровенный код в кавычках")
}
title() {
return this.base64ToImg("data:image/png;base64,здоровенный код в кавычках")
}
gameover() {
return this.base64ToImg("data:image/png;base64,здоровенный код в кавычках")
}
enemy() {
return this.base64ToImg("data:image/png;base64,здоровенный код в кавычках")
}
}
class Script{}
3. Основной класс Script
Здесь происходит вся логика игры, плюс хранятся данные.
В первую очередь заполняем конструктор класса, в котором находится запоминаемая игрой информация:
class Script {
constructor() {}
}
1) создание объекта "канвас" - HTML элемента, использующийся для рисования графики.
this.canvas = document.querySelector("#canvas");
this.context = canvas.getContext("2d");
2) Вызов класса "Хэлпер"
this.helper = new Helper();
3) Вызов класса "Имаджес"
this.images = new Images();
4) Массив с клавишами клаиватуры. Пока это стрелки для управления звездолетом и пробел для выстрелов:
this.keyArray = [
32, // 'Space bar'
37, // 'Left' key
39, // 'Right' key
38, // 'Up' key
40 // 'Down' key
];
5) Объект с нажатыми кнопками:
this.keyState = {};
6) Объект с объектами игры:
this.data
7) В нем у нас находятся переменные-переключатели, говорящие программе стартовала игра или же гейм овер:
start: false,
end: false,
8) Размеры экрана игры:
canvas: { width: 360, height: 680 },
9) размеры титульника, его координаты (x,y), картинка, которую мы берем из класса "имаджес"
title: {
width: 175,
height: 55,
x: 92,
y: 100,
image: this.images.title()
},
10) То же самое для гейм овера
gameover: {
width: 273,
height: 33,
x: 43,
y: 100,
image: this.images.gameover()
},
11) Звездолет: спрайт, ширина, высота, коорднаты х и у, направление выстрелов, текущая и максимальная скорость, жизни, очки и наконец объект "снарядов " fire.
В объекте снарядов также есть шрина, длина, цвет, напарвление, текущая и амксимальная скорость, максимальное чисто выпущенных снарядов и наконец массив со список всех выпущенных снарядов
spaceship: {
image: this.images.spaceship(),
width: 45,
height: 65,
x: 0,
y: 0,
direct: 'front',
moveSpeed: 4,
maxSpeed: 10,
life: 3,
score: 0б,
fire: {
width: 5,
height: 15,
color: 'white',
direct: 'front',
moveSpeed: 4,
maxSpeed: 10,
maxSpawn: 2,
spawn: [],
},
},
12) Враги, у которых есть имя спрайта, ширина, высота, цвет, скорость, жизни, тип, массив со списком всех врагов на экране
enemy: {
image: this.images.enemy(),
width: 31,
height: 31,
color: 'white',
moveSpeed: 3,
life: 1,
type: 'default',
spawn: [],
}
ИТОГО:
Пока наш код такой. По сути это просто база данных с кратинками, база данных с объектами игры и функция рандома. Все конечно не предусмотришь, поэтому скорее всего эта база будет дополняться или наоборот какие-то ее элементы будут убраны.
class Helper {
random(min, max) {
return Math.floor(Math.random()*(max-min+1))+min;
}
}
class Images{
base64ToImg(value) {
var img = new Image();
img.src = value;
return img;
}
spaceship() {
return this.base64ToImg("data:image/png;base64,здоровенный код в кавычках")
}
powerup() {
return this.base64ToImg("data:image/png;base64,здоровенный код в кавычках")
}
title() {
return this.base64ToImg("data:image/png;base64,здоровенный код в кавычках")
}
gameover() {
return this.base64ToImg("data:image/png;base64,здоровенный код в кавычках")
}
enemy() {
return this.base64ToImg("data:image/png;base64,здоровенный код в кавычках")
}
}
class Script{
constructor() {
this.canvas = document.querySelector("#canvas");
this.context = canvas.getContext("2d");
this.helper = new Helper();
this.images = new Images();
this.keyArray = [
32, // 'Space bar'
37, // 'Left' key
39, // 'Right' key
38, // 'Up' key
40 // 'Down' key
];
this.keyState = {};
this.data = {
start: false,
end: false,
canvas: { width: 360, height: 680 },
title: {
width: 175,
height: 55,
x: 92,
y: 100,
image: this.images.title()
},
gameover: {
width: 273,
height: 33,
x: 43,
y: 100,
image: this.images.gameover()
},
spaceship: {
image: this.images.spaceship(),
width: 45,
height: 65,
x: 0,
y: 0,
direct: 'front',
fire: {
width: 5,
height: 15,
color: 'white',
direct: 'front',
spawn: [],
moveSpeed: 4,
maxSpeed: 10,
maxSpawn: 2
},
moveSpeed: 4,
maxSpeed: 10,
life: 3,
score: 0
},
enemy: {
image: this.images.enemy(),
width: 31,
height: 31,
color: 'white',
spawn: [],
moveSpeed: 3,
summonTime: 50,
timer: 0,
life: 1,
type: 'default'
}
}
}
}
Пока все.
ДАЛЕЕ
В следующем уроке мы:
- нарисуем наш экран игры и корабль, создав для этого функцию "рендер"
- научимся обновлять экран игры
- научимся упарвлять этим нашим звездолет