用 JavaScript 实现简单拼图游戏

作者 : 开心源码 本文共4084个字,预计阅读时间需要11分钟 发布时间: 2022-05-12 共70人阅读


本篇主要讲解,如何利用原生的 JavaScript

来实现一个简单的拼图小游戏。

线上体验地址:拼图

一、游戏的基础逻辑

想用一门语言来开发游戏,必需先理解如何使用这门语言来实现少量基础逻辑,比方图像的绘制、交互的解决、定时器等。

1、图形绘制

图形绘制是一切的基础,这里使用 JavaScriptcanvas 上进行绘制。即先在 html 中创立 canvas 元素,而后在 JavaScript 中,通过 id 拿到这个元素,并且通过 canvas 拿到对应的上下文环境 context ,为后续的绘图做好准备。

<canvas id="background" width="450px" height="450px"></canvas>
var background = document.getElementById("background");var context = background.getContext('2d');

通过 contextdrawImage 方法可以绘制图片,这里进行了相应的封装:

注:这里要等图片加载完毕后再进行绘制,即在 onload 中去调用 drawImage 方法,否则会绘制失败。

var drawImageItem = function(index, position) {    var img = new Image();    img.src = './image/dog_0' + String(index+1) + '.jpg';    img.onload = () => {        var rect = rectForPosition(position);        context.drawImage(img, rect[0], rect[1], rect[2], rect[3]);    }}

在绘制图片之后,我们还需要去动态刷新视图,否则 canvas 就只是一张静态的图片。假如是简单的图形刷新,只要在原来的位置重新绘制,进行覆盖就可。但有时候我们只要要将原来已存在的图形清理掉,而不需要绘制新图案。比方在拼图游戏中,将一个方块移动到另一个位置后,需要清空原来的位置。

通过 contextclearRect 方法可以达到清理的目的。以下是清理 canvas 的某个区域的代码:

var originRect = rectForPosition(origin);context.clearRect(originRect[0], originRect[1], originRect[2], originRect[3]);

2、事件解决

有了图形的绘制后,我们还需要解决玩家的输入事件,而后根据输入事件,来决定什么时候刷新视图。输入事件可以分为 3 种:在手机上有触屏事件;在 PC 上,有鼠标和键盘事件。

JavaScript 中对触屏和鼠标点击的监听是一样的,都是通过 canvasonclick 事件进行回调,具体如下:

// 屏幕点击background.onclick = function(e) {};

我们可以通过 e.offsetXe.offsetY 来获取触控点在 canvas 中的位置。

注: canvas 的坐标原点在左上角,即左上角的坐标是 (0, 0)

键盘的按键点击则是通过 documentonkeyuponkeydown 等事件进行回调。 onkeyup 是指按键的抬起事件, onkeydown 是指按键的按下事件。我们可以通过 keyCode 知道当前具体是哪一个按键,而后根据不同的按键去解决不同的逻辑,如下:

if (event.keyCode == '37') {  // 左    // do something} else if (event.keyCode == '38') { // 上    // do something} else if (event.keyCode == '39') { // 右    // do something} else if (event.keyCode == '40') { // 下    // do something}

3、定时器

有时候,除了在玩家输入的时候需要去刷新视图,还需要每隔一段时间定时去刷新视图。比方在一个贪吃蛇游戏中,就需要每隔一段时间就去刷新蛇的位置。

这个时候我们就需要一个定时器,让它每隔一段时间去执行一段刷新视图的代码。我们通过 setInterval 方法来实现定时器功能:

setInterval("run()", 100);

上面这段代码表示每隔 100 毫秒,去执行一次 run 方法。

二、拼图的基础逻辑

有了游戏的基础逻辑,下面来看一下如何实现拼图的逻辑。

1、生成随机序列

由于不是任意序列都可以通过平移的方式来复原,所以我们不能简单地生成一个随机序列。比方 1、0、2、3、4、5、6、7、8 这个序列,无论怎样平移,都不可能复原。

这里采取的做法是:预先设置了 4 个可复原的序列,先从这 4 个序列中随机选取一个,而后再对序列进行模拟平移若干步骤。以此来尽可能地保证初始序列的多样性,也保证了序列的可复原性。具体代码如下:

var setupRandomPosition = function() {    var list1 = [4, 3, 2, 8, 0, 7, 5, 6, 1];    var list2 = [2, 0, 5, 6, 8, 7, 3, 1, 4];    var list3 = [3, 7, 2, 4, 1, 6, 8, 0, 5];    var list4 = [3, 2, 4, 1, 7, 6, 5, 0, 8];    var lists = [list1, list2, list3, list4];    imageIndexForPosition = lists[parseInt(Math.random() * 4)];    // 获取空位位置    var emptyPosition = 0;    for (var i = imageIndexForPosition.length - 1; i >= 0; i--) {        if (imageIndexForPosition[i] == lastIndex()) {            emptyPosition = i;            break;        }    }    background.emptyPosition = emptyPosition;    // 随机移动次数    var times = 10;    while (times--) {        // 获取随机数,决定空位哪个位置进行移动        var direction = parseInt(Math.random() * 4);        var target = -1;        if (direction == 0) {            target = topOfPosition(emptyPosition);  // 上        } else if (direction == 1) {            target = leftOfPosition(emptyPosition);  // 左         } else if (direction == 2) {            target = rightOfPosition(emptyPosition);  // 右        } else if (direction == 3) {            target = bottomOfPosition(emptyPosition);  // 下        }        if (target < 0 || target > lastIndex()) {  // 位置不合法,继续下一次循环            continue;        }        var result = moveImageIfCanAtPosition(target);        if (result >= 0) { // 假如移动成功,升级空位的位置            emptyPosition = target;        }    }}

2、判断能否可以移动方块

在保存顺序的时候,是用 0~8 这 9 个数字来保存,而空白的方块是数字 8 的位置。所以判断可以移动的唯一条件是,目标位置的值能否为 8。代码如下:

var isPositionEmpty = function(position) {    if (position < 0 || position > lastIndex()) {        return false;    }     if (imageIndexForPosition[position] == lastIndex()) {        return true;    } else {        return false;    }}

上面 lastIndex() 的值为 8。

3、实现方块移动

方块移动的实现很简单,先将旧位置的图形清理,而后在新的位置绘制。

var refreshImagePositions = function(origin, target) {    var originRect = rectForPosition(origin);    context.clearRect(originRect[0], originRect[1], originRect[2], originRect[3]);    drawImageItem(imageIndexForPosition[target], target);}

4、检查能否完成

检查图案能否已经复原,只要要对数组进行一次遍历,看能否有序就可。

var checkIfFinish = function() {    for (var index = 0; index < imageIndexForPosition.length; index++) {        if (index != imageIndexForPosition[index]) {            return false;        }    }    return true;}

5、交互事件屏蔽

当图案复原之后,我们不希望玩家还能通过键盘或者鼠标来移动方块,这个时候就需要对交互事件进行屏蔽。

只要要一个标志位即可以达到这个目的:

// 屏幕点击background.onclick = function(e) {    if (isFinish) {        return;    }    // do something};// 键盘按钮事件document.onkeyup = function(event) {    if (isFinish) {        return;    }    // do something}

当图案复原之后,标志位 isFinish 会被置为 true ,而后在屏幕点击和键盘按钮响应事件的开始处增加判断,假如已经结束,则不继续走方块移动的逻辑。

本次给大家推荐一个免费的学习群,里面概括移动应用网站开发,css,html,webpack,vue node angular以及面试资源等。
对web开发技术感兴趣的同学,欢迎加入Q群:943129070,不论你是小白还是大牛我都欢迎,还有大牛整理的一套高效率学习路线和教程与您免费分享,同时每天升级视频资料。
最后,祝大家早日学有所成,拿到满意offer,快速升职加薪,走上人生巅峰。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 用 JavaScript 实现简单拼图游戏

发表回复