游戏入口
这是大二夏季学期前端课的一个小作业,实现了Smove游戏的基本功能,并可以支持不同的棋盘大小。同时在多种设备上也都做了适配。
源代码部署在Github

代码架构

csshtml基本没有太多的信息量。

draw.js负责画布的渲染
game.js负责游戏的逻辑
key.js负责交互

由于当时还是js的初学者,而且这个小作业也就用了两天赶工出来,相对来说代码会脏一些,但从理解代码的角度来说还是可以接受的。

基本功能实现

游戏的主体循环为如下结构,每10ms执行一次。

1
2
3
4
5
6
7
8
9
10
if (bonus.draw) {
drawBonus();
} else {
changeColor();
drawLevelUp();
}
drawGrid();
drawBall();
drawPlayer();
check();

bonus.deg是实现bonus的旋转动画而添加的。
bonus.draw表征是否应该画bonus,该值为false当且仅当正在升级的过程中,此时渐变改变背景色,并重绘一些之前不需要每次重绘的元素如记分牌。然后依次绘制其他元素。事实上,若不做每个小球后面跟着的轨迹动画,则drawPlayer也不必每次重画。
drawGrid无需赘述,drawBall则是通过维护一个balls数组,擦除每个ball,并绘制下一个位置的ball以及轨迹动画。如果球飞出边界的话则擦除并移出balls数组。drawPlayer的擦除和绘制同理,但若没有移动操作的话则直接重绘即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
var bgrColor = {
r: 128,
g: 223,
b: 255,
color: "#80DFFF",
colors:["#80DFFF","#50EFB0","#F3D0BF", "#D0AAFF","#80D0DF","#30FFBF"],
index: 0,
dr: 0,
dg: 0,
db: 0,
textAlpha:0,
alphaIncrease:true,
}

该结构维护着背景色的信息。rgb是当前的rgb分量用于渐变,color则根据rgb值计算得到。colors则存储着选用的不同背景色的数组,可以很方便的添加/删除颜色。每当触发升级事件后,会先根据当前的color和下一个color计算出rgb分量每次的改变值dr、dg、db,然后在changeColor里不断更新rgb值并重新生成color,然后重绘背景。textAlpha和alphaIncrease则用于提示文字Level n的淡入淡出实现。

加分功能实现

适配不同设备

window.onload=function(){
    canvas = document.getElementById('background');
    ctx = canvas.getContext("2d");
    resize();
    canvas.addEventListener("touchstart", handleStart);
    canvas.addEventListener("touchend", handleEnd);
    canvas.addEventListener("touchcancel", handleCancel);
    window.addEventListener("resize", resize, false);
    window.addEventListener('keydown', whatKey, false);
}

这里注册了几个事件。keydown不必多说,touch事件则是根据touchstart和touchend的坐标来判定用户的操作是左移还是右移,设定了触发阈值以及xy方向变化量比值的阈值。而resize则根据当前视窗的大小,重新计算各类相关的长度值,并对已经存在的元素的坐标进行转化使其位置随着布局的变化而正确归位。因此可以支持电脑上浏览器视窗的更改,以及手机横、竖屏的切换。

局部渲染

整个游戏的渲染机制采取了“谁污染谁治理”的原则,对于需要不断重绘的元素如黑棋,则每次均擦除自己所在的痕迹然后绘制下一时刻的图像。对于背景、记分牌等元素则仅当改变的时候才重新绘制。

暂停机制

在handleStart里对右上角的触摸事件做出相应,执行gamePause/gameContinue操作。