Я давно не использовал холст, поэтому снова познакомился с холстом, написав небольшую игру «Тетрис». Если у вас есть определенная основа холста, реализовать его несложно.
Подробное объяснение принципаГлядя на окончательный интерфейс игры, мы видим, что необходимо реализовать следующие ключевые функции:
Вся панель представляет собой систему координат, в которой верхний левый угол (0,0) является началом координат, верхний правый угол (12,0), нижний левый угол (0,20) и нижний правый угол (12,20). ). Можно определить координатное положение каждой точки. Независимо от того, заполнен ли квадрат, мы можем рассматривать каждый квадрат как элемент массива: 0 означает отсутствие, 1 означает, что он заполнен. Панель 12*20 использует два слоя массивов, то есть реализовано 20 массивов длиной 12.
var карты = [[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,1,0 ,1,0], ...];
Код для рисования панели можно реализовать с помощью самого простого API холста.
//Сетка for(var i=0;i<12;i++){ for(var j=0;j<20;j++){ ctx.fillRect(i*40,j*40,40,40); strokeRect(i*40,j*40,40,40); if(this.maps[j][i]==1){//Квадрат заполнен содержимым ctx.save(); ctx.lineWidth=4; ctx.fillStyle='hsla(200,100%,50%,.5)'; ctx.strokeStyle='hsla(200,100%,50%,.9)'; ctx.fillRect(i*40, j*40,40,40); ctx.strokeRect(i*40+2,j*40+2,38,38); ctx.restore(); } } } //Граница ctx.lineWidth=4; ctx.strokeStyle='hsla(0,100%,0); %,.3)'; ctx.moveTo(0,0); ctx.lineTo(0,20*40); ctx.lineTo(12*40,20*40); ctx.lineTo(12*40,0); ctx.stroke();Реализация блоков
В игре используются следующие 7 изображений.
В сочетании с представленной выше системой координат массив [x1, y1, x2, y2, x3, y3, x4, y4] представляет собой представление данных координат четырех точек на приведенном выше графике. Координаты семи графиков: следующее:
вар Арр = [[4,0,4,1,5,1,6,1],[4,1,5,1,6,1,6,0],[4,0,5,0,5,1, 6,1],[4,1,5,0, 5,1,6,0],[5,0,4,1,5,1,6,1],[4,0,5,0,6,0,7,0],[5,0, 6,0,5,1,6,1]];
Чтобы переместить блок, просто пройдите по всему массиву и добавьте вектор смещения. Это очень просто.
class Shape {constructor(m){ this.m = Object.assign([],m); } move(x,y){ // Смещение var m = this.m, l = m.length; |0; для (var i=0;i<l;i=i+2){m[i]+=x; m[i+1]+=y; верните это }
Вращение блоков Помимо перемещения влево-вправо и вверх-вниз, блоки в «Тетрисе» еще и вращаются, верно? Немного подумав, вы поймете, что это всего лишь матричное преобразование, то есть каждый раз фигура поворачивается на 90 градусов вокруг центральной точки. Я использую третью точку массива в качестве центральной точки графического преобразования. Конечно, эта обработка не идеальна.
class Shape { Transform(){//Преобразование двумерной матрицы var m =this.m, l = m.length, c = Math.ceil(l/2), x = m[c], y = m[c+ 1], cos = Math.cos(Math.PI/180 * 90), sin = Math.sin(Math.PI/180 * 90); for (var i=0;i<l;i=i+2); { if(i == c) продолжить; var mx = m[i]- x, my = m[i+1] - y, nx = mx*cos - my*sin, ny = my*cos + mx*sin; м[я]=х+nx; м[я+1]=y+ny } вернуть это;граничные условия
В основном это включает в себя следующие три аспекта
Пересечь массив (1) Когда координата y любой точки равна 19, это означает, что она достигла дна; (2) Получить информацию о положении координаты y+1 на картах. Если она равна 1, это означает. он был заполнен. В обоих случаях, когда период движущегося блока заканчивается, просто заполняем координаты блока в массив, соответствующий картам.
Если координата y+1 заполнена и текущая координата меньше 1, то есть она уже находится вверху интерфейса, то игра окончена.
var isEnd = false,isOver=false,x,y;for(var i=0,sl=that.shape.m.length;i<sl;i=i+2){ x=that.shape.m[i ]; y=that.shape.m[i+1]; if(y >= 19){ // Внизу isEnd = true;break; } if(that.maps[y+1][x]== 1 ){ // Позиция y+1 заполнена isEnd = true; if(y <= 1){isOver=true;} // Игра окончена }}
В конце цикла перемещения блока проверяется, заполнен ли каждый слой, и обработка после заполнения квадрата. Если все элементы определенного массива равны 1, это означает, что сетка заполнена. Затем удалите массив и в то же время поместите массив с каждым элементом 0 в заголовок списка.
checkPoint() { var that = this,maps = that.maps; for(var i=0,l=maps.length;i<l;i++){ if(Math.min.apply(null,maps[i]) == 1){// Указывает, что слой заполнен that.maps.splice(i,1); that.score+=10; Увеличьте оценку that.maps.unshift([0,0,0,0,0,0,0,0,0,0,0,0]);Привязка событий
Главное — связать событие нажатия клавиши. Следует отметить, что события сдвига влево и вправо включают определение границы.
bindEvent(){ var that = this; document.addEventListener('keydown',function(e){ switch(e.keyCode){ case 13: //введите cancelAnimationFrame(that.timer); that.init().update( ); случай 80: //p that.pause = !that.pause; случай 40: //down that.d = 0.5; //левая переменная = false, карты = that.maps, shape = that.shape, m = shape.m for(var i=0,l=m.length;i<l;i=i+2){ if(m[i]<=0 || maps[m[i+1]][m[i]-1] == 1){ over = true;break } } if(!over) shape.move( -1,0); 39: //правая переменная over = false, shape = that.shape,maps = that.maps, m = shape.m; for(var i=0,l=m.length;i<l;i=i+2 ){ if(m[i]>=11 || maps[m[i+1]][m[i]+1] == 1){ over = true;break; } } if(!over) shape. двигаться (1,0); перерыв; случай 32: //space that.shape.transform(); перерыв } },false);}Подвести итог
Здесь реализованы самые основные функции тетриса, а такие функциональные моменты, как уровни, не реализованы. В то же время в демо все еще есть несовершенства, которые необходимо исправить.
Выше приведено все содержание этой статьи. Я надеюсь, что она будет полезна для изучения всеми. Я также надеюсь, что все поддержат сеть VeVb Wulin.