sysadmin-vlg.ru

Простая игра на HTML5 Canvas – часть 4

2017-08-10 12:18:37 TrefAS

Часть 4а. РИСУЕМ ПЛАТФОРМЫ

Есть два типа платформ. Наш персонаж может прыгать по обычной (оранжевой) и зеленой (батут), который дает дополнительное ускорение и гипер-ультра-высокий прыжок. Всегда есть семь платформ на экране (я попробовал другое количество, от 4 до 10 и только 7 прекрасно работает с размером экрана заявленным в начале). Давайте создадим класс платформ (функции платформы будут наследовать).
var Platform = function(x, y, type){
//функция принимает позицию и тип платформы
var that=this;
that.firstColor = '#FF8C00';that.secondColor = '#EEEE00';that.onCollide = function(){player.fallStop();};//если тип платформы отличен от 1, то просто устанавливаем нужный цвет и вызываем функцию
//fallStop() определенную в прошлой части урока
if (type === 1) {//, но если тип равен '1', устанавливаем другие цвета и ускорение взлета jumpSpeed равным 50.
//после этого метод checkJump()примет '50' вместо '17' предусмотренных по умолчанию.
that.firstColor = '#AADD00';that.secondColor = '#698B22';that.onCollide = function(){
player.fallStop();player.jumpSpeed = 50;};}
that.x = ~~x;that.y = y;that.type = type;
return that;
};
Теперь необходимо создать функцию, которая будет генерировать все платформы и складывать их в platforms[] массив, который мы определим в ближайшее время. После этого нарисуем платформы на экране.
var nrOfPlatforms = 7,
platforms = [],platformWidth = 70,platformHeight = 20;//глобальные (пока) переменные не очень подходят для хранения размеров платформ, но
//в нашем случае они необходимы для вычисления столкновений, поэтому размещены здесь
//а не в свойствах класса платформ
var generatePlatforms = function(){var position = 0, type;//'position' это Y координата платформы на экране и вначале она равно нулю
for (var i = 0; i < nrOfPlatforms; i++) {type = ~~(Math.random()*5);
if (type == 0) type = 1;else type = 0;//Обычных платформ будет примерно в пять раз больше, чем батутов
platforms[i] = new Platform(Math.random()*(width-platformWidth),position,type);//случайно выбранная позиция по Xif (position < height - platformHeight)
position += ~~(height / nrOfPlatforms);}//и Y интервал
}();
//эта функция будет вызвана только один раз, перед стартом игры
Добавляем метод Draw () объекту платформы:
var Platform = function(x, y, type){(...)that.draw = function(){ctx.fillStyle = 'rgba(255, 255, 255, 1)';//Это важно заменить прозрачность в rgba на 1 (непрозрачно), потому что Google Chrome помнит
//предыдущее значение, которое мы устанавливали, рисуя облака (круги) на заднем фоне, в
//Firefox и Safari этого не происходит
 var gradient = ctx.createRadialGradient(that.x + (platformWidth/2), that.y + (platformHeight/2), 5, that.x + (platformWidth/2), that.y + (platformHeight/2), 45);
gradient.addColorStop(0, that.firstColor);gradient.addColorStop(1, that.secondColor);ctx.fillStyle = gradient;ctx.fillRect(that.x, that.y, platformWidth, platformHeight);//заполняем прямоугольную платформу градиентной заливкой
};
return that;
};
Платформы должна быть нарисованы на каждом кадре, так что обновление GameLoop () является обязательным.
var GameLoop = function(){(...)platforms.forEach(function(platform){platform.draw();
});
(...)
};

Часть 4б. СТОЛКНОВЕНИЯ 

Чудненько, но нет взаимодействия между ангелом и платформами. Одна маленькая функция исправит ситуацию. Позвольте мне представить checkCollision ():
var checkCollision = function(){platforms.forEach(function(e, ind){//проверяем каждую платформуif ((player.isFalling) &&
//только когда персонаж падает(player.X < e.x + platformWidth) &&
(player.X + player.width > e.x) &&
(player.Y + player.height > e.y) &&
(player.Y + player.height < e.y + platformHeight)//и находится прямо над платформой) {e.onCollide();}})}
Еще одно обновление основного цикла (подходящий момент, чтобы закомментировать функцию MoveCircles (), если платформы стоят на месте, почему фон движется? будет больше смысла, когда мы будем осуществлять прокрутку платформ и фона одновременно). Так GameLoop () функция должна выглядеть в настоящее время:
var GameLoop = function(){clear();//MoveCircles(5);DrawCircles();
if (player.isJumping) player.checkJump();if (player.isFalling) player.checkFall();
platforms.forEach(function(platform){platform.draw();});
checkCollision();
player.draw();gLoop = setTimeout(GameLoop, 1000 / 50);}
Результат этой части урока можно посмотреть по адресу: http://jsbin.com/igeta3/, а скачать исходники тут: http://guthub.com/michalbe/Simple-game-with-HTML5-Canvas. Думаю следующая часть будет последней, но кто знает;)
Копирайты.
Автор: Михал Будзинский https://twitter.com/#!/@michalbe

Автор перевода: Андрей Семенов https://twitter.com/#!/a_semenov79