【教女朋友 从 0 到 1 学编程系列】三、2048 前端游戏实战-课后作业补充

本文介绍了教女朋友编程系列的第三部分,聚焦2048游戏的前端实战。内容包括添加重新开始游戏按钮及逻辑,记录历史最高分,以及响应式布局的实现。提供了在线演示链接,讨论了为何要在开始游戏时移除和重新绑定键盘侦听事件,以及如何使用Localstorage保存最高分。响应式布局提示中建议使用百分比或vw/vh单位,并推荐了Xwiper库和Touch Event资源来支持手势划动。
摘要由CSDN通过智能技术生成

课后作业

  • 添加重新开始游戏的按钮及逻辑
  • 添加记录历史最高分的逻辑
  • 响应式布局的样式

在线演示: https://inscode.csdn.net/@willin/girl-3-2048

重新开始游戏按钮

首先确认一下开始函数的逻辑:

function startGame() {
  initializeGameBoard();
  addRandomTile();
  addRandomTile();
  generateGameBoard();
  document.removeEventListener('keydown', handleKeyDown, false);
  document.addEventListener('keydown', handleKeyDown, false);
}

其中 removeEventListener 移除已经有的键盘侦听事件并重新绑定。

为什么要这样做?

如果没有 removeEventListener 操作,每次开始游戏时添加键盘侦听事件,就会导致这样的一个 bug:只按了一次方向键,却重复执行了多次合并。

在 html 中添加开始按钮:

<button onclick="startGame()">重新开始</button>

然后需要修改一下初始化的任务函数,清空棋盘和得分:

function initializeGameBoard() {
  // 清空棋盘和得分
  gameBoard = [];
  score = 0;
  // 不动
  for (let i = 0; i < 4; i++) {
    gameBoard.push(new Array(4).fill(0));
  }
}

如果不清空数据,就会在原来的棋盘上直接新增。

添加记录历史最高分的逻辑

首先添加显示的 html 代码:

<div class="score">得分: <span class="game-score">0</span></div>
<div class="score">最高分: <span class="game-high-score">0</span></div>

加上最高分的部分。

然后修改渲染逻辑 generateGameBoard 函数:

function generateGameBoard() {
  // ... 上面不动
  // 判断历史最高分
  let max = parseInt(localStorage.getItem('score')) || 0;
  if(score > max) {
    max = score;
    localStorage.setItem('score',`${score}`);
  }
  const highScoreContainer = document.querySelector('.game-high-score');
  highScoreContainer.textContent = max;
}

这里的逻辑很简单,判断当前得分是否高于历史最高分,如果高于,就向 Localstorage 中存储最新的得分。

响应式布局的样式

考虑到该游戏是通过键盘操作,响应式布局意义不太大。

所以额外再留下一个作业,修改响应式布局,并且支持手势划动(左划、右划、上划、下划)来移动数字方块。

响应式布局提示

  • 响应式布局不可以用固定宽高,如: width: 400px; height: 400px; 这种,需要使用百分比或者 vwvh 之类(100vw 等于 100% 屏幕设备宽度)的单位。
  • 可以使用 min-widthmax-width 来约束最大宽度,高度同理。
  • 使用 MediaQuery 来针对不同尺寸屏幕进行个性化的样式定制。

JS Swipe(手势)

有很多第三方库,可以直接引入使用。

比如 Xwiper

如果用原生 JS (Vanilla JS 即原生 JS)实现,就需要了解一下 Touch Event:

这里,是一个简单的实现 Demo:

let pageWidth = window.innerWidth || document.body.clientWidth;
let treshold = Math.max(1,Math.floor(0.01 * (pageWidth)));
let touchstartX = 0;
let touchstartY = 0;
let touchendX = 0;
let touchendY = 0;

const limit = Math.tan(45 * 1.5 / 180 * Math.PI);
const gestureZone = document.getElementById('modalContent');

gestureZone.addEventListener('touchstart', function(event) {
    touchstartX = event.changedTouches[0].screenX;
    touchstartY = event.changedTouches[0].screenY;
}, false);

gestureZone.addEventListener('touchend', function(event) {
    touchendX = event.changedTouches[0].screenX;
    touchendY = event.changedTouches[0].screenY;
    handleGesture(event);
}, false);

function handleGesture(e) {
    let x = touchendX - touchstartX;
    let y = touchendY - touchstartY;
    let xy = Math.abs(x / y);
    let yx = Math.abs(y / x);
    if (Math.abs(x) > treshold || Math.abs(y) > treshold) {
        if (yx <= limit) {
            if (x < 0) {
                console.log("left");
            } else {
                console.log("right");
            }
        }
        if (xy <= limit) {
            if (y < 0) {
                console.log("top");
            } else {
                console.log("bottom");
            }
        }
    } else {
        console.log("tap");
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Willin 老王带你躺平养老

感谢你这么好看还这么慷慨

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值