目录
一、效果展示
二、代码分享
三、原理分析
3.1、界面搭建
3.2、方块创建
3.3、方块旋转
3.4、方块移动
3.5、移动判断
3.6、下落判断与清除
3.7、得分计算
得分: {{
score
}}
等级: {{
level
}}
消除: {{
times
}}
暂停/开始
变换
向左
向右
向下
工具函数:
//渐变色
export const color = [
[
'linear-gradient(180deg, #FFA7EB 0%, #F026A8 100%)',
'linear-gradient(180deg, #DFA1FF 0%, #9A36F0 100%)',
'linear-gradient(180deg, #9EAAFF 0%, #3846F4 100%)',
'linear-gradient(180deg, #7BE7FF 2%, #1E85E2 100%)',
'linear-gradient(180deg, #89FED8 0%, #18C997 100%)',
'linear-gradient(180deg, #FFED48 0%, #FD9E16 100%)',
'linear-gradient(180deg, #FFBA8D 1%, #EB6423 100%)',
],
[
'#2B7AF5','#2B9DF5','#79CFFF','#1B67DD','#4F94FF','#2180F2','#3FD0FF',
],
];
//7种方块元素
export const blockMod = (color) => {
let a = {
site: [0, 1, 0, 2, 1, 2, 2, 2],
color: color[0],
};
let b = {
site: [0, 1, 1, 1, 1, 2, 2, 2],
color: color[1],
};
let c = {
site: [1, 1, 1, 2, 2, 1, 2, 2],
color: color[2],
};
let d = {
site: [1, 0, 1, 1, 1, 2, 1, 3],
color: color[3],
};
let e = {
site: [0, 2, 1, 1, 1, 2, 2, 1],
color: color[4],
};
let f = {
site: [0, 1, 0, 2, 1, 1, 2, 1],
color: color[5],
};
let g = {
site: [1, 1, 2, 0, 2, 1, 2, 2],
color: color[6],
};
return ([a, b, c, d, e, f, g]);
};
//旋转规则
export const transition = [
[
{
x: 1, y: 1,
}, {
x: 1, y: 0,
}, {
x: 0, y: -2,
}, {
x: -2, y: 1,
}
],
[
{
x: 1, y: 1,
}, {
x: 1, y: 0,
}, {
x: 0, y: -2,
}, {
x: -2, y: 1,
}
],
[
{
x: 0, y: 1,
}, {
x: 1, y: 0,
}, {
x: 0, y: -1,
}, {
x: -1, y: 0,
}
],
[
{
x: -1, y: 2,
}, {
x: 1, y: 1,
}, {
x: 2, y: -1,
}, {
x: -2, y: -2,
}
],
[
{
x: 2, y: 0,
}, {
x: 0, y: -1,
}, {
x: -1, y: -1,
}, {
x: -1, y: 2,
}
],
[
{
x: 1, y: 1,
}, {
x: 1, y: 0,
}, {
x: 0, y: -2,
}, {
x: -2, y: 1,
}
],
[
{
x: 0, y: 0,
}, {
x: 1, y: 0,
}, {
x: -1, y: 0,
}, {
x: 0, y: 0,
}
],
]
主界面的20X10,类似贪吃蛇,副界面的随机方块,则是4x4,都是双重for循环。初始化的时候调用gameFrame()即可。
主要说明一下随机生成的方块,每个都是有4个小方格组成,组成了7种基本样式,在自身基础上进行四个方向的旋转,就是下落的所有可能性。参考坐标如右图所示:
旋转 b:当前方块 d:渲染的位置 z:渲染的对象现在还是下一个 xz:当前旋转角度,在change(b, d, z, xz)里进行旋转,这里用到了工具函数里的transition,旋转核心就是找到一个固定的点,看出x和Y坐标的变化,即(x=y,y=-x),加上工具函数里的blockMod,就可以依次生成对应的下落方块。
在生成一个的同时,要考虑的下一个方块的生成与随机旋转,所以 b:方块,d:位置,n:0擦除,1生成,2确定落到最下层,在renderBlock(b, d, n)方法里进行形状的渲染。
我们有三个方向:moveDown()、moveLeft()、moveRight(),这里的原理和贪吃蛇基本类似,不过在向下移动时考虑因素较多,下落时旋转要考虑 b:当前方块 xz:当前旋转角度change1()方法,为了保持原来的形状,所以多处用到了深拷贝。
预判能否移动或变化 e:1右移 2左移 3下移 4变化,在 canMove(e)方法里实现。主要是判断下一个位置是否被占用,到了底部:确定位置不能再动,保证上面其他方块下落时不会将它穿透,是要考虑的问题。
判断是否可以消除:遍历整个界面,当一行被占满,将该行的方块依次删去,并保留上面附着的方块位置不变,形成“被吞噬”的现象。在消掉满了的一行时,要让上面方块下移,从下往上判断,再清除当前方块,避免冲突。
分数消除一行100,两行300,三行600,四行1000,消掉一行,带分数增加,以此同时,随着等级的增加,速度也会越来越快,难度增加。