canvas 制作2048

本文介绍了2048游戏的玩法,包括数字向同一方向移动并合成的规则。通过JavaScript实现游戏的功能,如绘制场景、随机生成数字、更新视图以及监听键盘事件来控制游戏。此外,文章还展示了数据更新的关键步骤,如去0、求和和去0的处理过程。
摘要由CSDN通过智能技术生成

效果展示

对UI不满意可以自行调整,这里只是说一下游戏的逻辑,具体的API调用不做过多展示。
在这里插入图片描述

玩法分析

2048 的玩法非常简单,通过键盘的按下,所有的数字都向着同一个方向移动,如果出现两个相同的数字,就将这两个数字合成,如果所有的各自都被占满,并且无法合成的时候,视为游戏失败。

功能实现

场景

需要一个背景和16个格子,使用绘制矩形的API和一个双重循环就可以实现。

function drawMap() {
  ctx.beginPath();
  ctx.fillStyle = '#bbada0'
  ctx.fillRect(200,0,600,600);

  for(let i = 0; i < 4; i++){
    for(let k = 0; k < 4; k++){
      ctx.beginPath();
      ctx.fillStyle = 'rgba(238, 228, 218, 0.35)';
      ctx.fillRect(i * 150 + 210, k*150+10,130,130);
    }
  }
}

数字生成

我们随机生成一个数字2 或者 4 ,并且需要随机一个没有数字的位置。

在这之前我们需要准备几个变量

  • number: 用来存储新生成的数字
  • map: 一个二维数组,用来储存格子中的数字,如果是0则视为空

使用Math.random()生成随机数,并且利用循环反复生成位置,知道生成的位置为空,将数字填入map数组的对应位置。

function createNumber(closebtn) {
  let number = Math.random() > 0.5 ? 2 : 4;
  let x, y; 
  let gameover = true;
  for(let i = 0; i < 4; i++){
    for(let j = 0; j < 4; j++){
      if(numberlist[i][j] == 0){
        gameover = false;
        break;
      }
    }
  }
  // 这里是对游戏结束的判断
  if(gameover) {
    alert('gameover!');
    init();
    return;
  }
  while(1) {
    x = Math.floor(Math.random() * 4);
    y = Math.floor(Math.random() * 4);
    if(numberlist[x][y] == 0) break;
  }
  numberlist[x][y] = number;
}

更新视图

之前我们定义的一个数组map,用来储存格子中的数据,之后我们只需要根据这个map中的数据去更新我们的画布,就可以实现数字的渲染,之后的合成,也只需要对map这个数组进行更新,然后再根据数组中的数据去渲染视图。

代码中也包含了2048的配色方案,对颜色不敏感的直接用这套方案就好

function drawNumber() {
  for(let i = 0; i < 4; i++){
    for(let j = 0; j < 4; j++){
      let color = '';
      switch(numberlist[i][j]) {
        case 0: continue; break;
        case 2: color = '#EEE4DA'; break;
        case 4: color = '#ECE0C8'; break;
        case 8: color = '#f2b179'; break;
        case 16: color = '#f59563'; break;
        case 32: color = '#f67c5f'; break;
        case 64: color = '#f65e3b'; break;
        case 128: color = '#edcf72'; break;
        case 256: color = '#edcc61'; break;
        case 512: color = '#edc850'; break;
        case 1024: color = '#edc53f'; break;
        case 2048: color = '#edc22e'; break;
      }
      ctx.beginPath();
      ctx.fillStyle = color;
      ctx.fillRect(j * 150 + 210, i*150+10, 130, 130);
      ctx.fillStyle = 'black';
      ctx.fillText(numberlist[i][j], j * 150 + 75 + 200, i * 150+75, 130);
    }
  }
}

事件监听

为对应的按键绑定事件:

document.addEventListener('keydown', (e) => {
    switch(e.key) {
      case 'w': case 'ArrowUp':
      	// 这个函数用来更新数据,下一步会见到
        uploadNumberList('top');
        break;
      case 'a': case 'ArrowLeft': 
        uploadNumberList('left');
        break;
      case 's': case 'ArrowDown': 
        uploadNumberList('bottom');
        break;
      case 'd': case 'ArrowRight': 
        uploadNumberList('right');
        break;
      default: break;
    }

数据更新

数据的更新,我们用向左来做例子,一共分为3步:

  1. 去0
  2. 合成
  3. 去0

下面是实现的代码:
整体的思路下面的代码中写有注释

// 4行, 向左
      for(let i = 0; i < 4; i++){
        // 每一行执行去0,加和,去0三项
        // 建一个新数组拷贝非0元素
        const arr = numberlist[i];
        const newArr = [0,0,0,0];
        let cnt = 0;
        for(let j = 0; j < 4; j++){
          if(arr[j] != 0) {
            newArr[cnt] = arr[j];
            cnt++;
          }
        }
        // 求和
        for(let j = 0; j < 3; j++){
          if(newArr[j] == newArr[j+1] && newArr[j] != 0){
            newArr[j] = newArr[j] * 2;
            newArr[j+1] = 0;
          }
        }
        // 去0
        const newArr2 = [0,0,0,0];
        cnt = 0;
        for(let j = 0; j < 4; j++){
          if(newArr[j] != 0) {
            newArr2[cnt] = newArr[j];
            cnt++;
          }
        }
       // 经过上面的三步这一行已经处理完成,将新的处理完成的数组替换原有的
        numberlist[i] = newArr2;
      }

数据更新之后,不要忘记重新渲染下视图。

结束

到这里游戏就制作好了,像这种小游戏我觉得采用面向过程的方式更加合适
在这里插入图片描述
自己先玩上一把

另外像是 去0 和 求和 的过程完全可以封装成一个函数减少代码冗余。

Canvas在HTML5中是一个用于绘制图形的强大工具,如果你想制作一个简单的印章效果,可以利用它的绘图API。以下是一般的步骤: 1. 创建`<canvas>`元素:首先,在HTML中添加一个`<canvas>`标签,并给它设置合适的宽度和高度。 ```html <canvas id="stamp-canvas" width="100" height="100"></canvas> ``` 2. 获取画布上下文:通过JavaScript获取到这个canvas元素的2D渲染上下文,这是操作canvas的主要入口。 ```javascript const canvas = document.getElementById('stamp-canvas'); const ctx = canvas.getContext('2d'); ``` 3. 绘制矩形或自定义形状:作为印章的基本形状,你可以绘制一个圆形、椭圆或自定义形状。例如,创建一个圆形印章: ```javascript ctx.beginPath(); ctx.arc(50, 50, 40, 0, Math.PI * 2); ``` 4. 设置颜色和填充样式:选择印章的颜色,比如红色,并将其填充到路径中。 ```javascript ctx.fillStyle = 'red'; ctx.fill(); ``` 5. 添加文字或图像:如果印章需要包含文本或图案,可以在绘制之前先准备好图片,然后将其转换为DataURL并绘制。 ```javascript const imgDataUrl = ...; // 图片URL let img = new Image(); img.src = imgDataUrl; img.onload = function() { ctx.drawImage(img, 0, 0, 50, 50); }; ``` 6. 完成印章:最后,如果你希望印章有透明度,可以设置不透明度(alpha),然后应用到画布上。 ```javascript ctx.globalAlpha = 0.5; ``` 完成以上步骤后,你就得到了一个基本的canvas印章效果。你可以根据需要调整参数,如印章的位置、大小、颜色等,以满足个性化需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值