利用原生的JavaScript实现简单拼图游戏
前言
本篇主要讲解,如何利用原生的 javascript
来实现一个简单的拼图小游戏。
一、游戏的基础逻辑
想用一门语言来开发游戏,必须先了解如何使用这门语言来实现一些基础逻辑,比如图像的绘制、交互的处理、定时器等。
1、图形绘制
图形绘制是一切的基础,这里使用 javascript 在 canvas 上进行绘制。即先在 html 中创建 canvas 元素,然后在 javascript 中,通过 id 拿到这个元素,并且通过 canvas 拿到对应的上下文环境 context ,为后续的绘图做好准备。
<canvas id="background" width="450px" height="450px"></canvas>
var background = document.getelementbyid("background"); var context = background.getcontext('2d');
通过 context 的 drawimage 方法可以绘制图片,这里进行了相应的封装:
注:这里要等图片加载完毕后再进行绘制,即在 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 就只是一张静态的图片。如果是简单的图形刷新,只需在原来的位置重新绘制,进行覆盖即可。但有时候我们只需要将原来已存在的图形清除掉,而不需要绘制新图案。比如在拼图游戏中,将一个方块移动到另一个位置后,需要清空原来的位置。
通过 context 的 clearrect 方法可以达到清除的目的。以下是清除 canvas 的某个区域的代码:
var originrect = rectforposition(origin); context.clearrect(originrect[0], originrect[1], originrect[2], originrect[3]);
2、事件处理
有了图形的绘制后,我们还需要处理玩家的输入事件,然后根据输入事件,来决定什么时候刷新视图。输入事件可以分为 3 种:在手机上有触屏事件;在 pc 上,有鼠标和键盘事件。
javascript 中对触屏和鼠标点击的监听是一样的,都是通过 canvas 的 onclick 事件进行回调,具体如下:
// 屏幕点击 background.onclick = function(e) { };
我们可以通过 e.offsetx 、 e.offsety 来获取触控点在 canvas 中的位置。
注: canvas 的坐标原点在左上角,即左上角的坐标是 (0, 0) 。
键盘的按键点击则是通过 document 的 onkeyup 、 onkeydown 等事件进行回调。 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 ,然后在屏幕点击和键盘按钮响应事件的开始处添加判断,如果已经结束,则不继续走方块移动的逻辑。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
上一篇: 与分区有关的那些事儿
下一篇: js实现简单模态框实例