一、引言
经过一学期的学习,运用自己学习的知识,自己实践完成了一个简单的小游戏。
二、游戏介绍
完成一个2048小游戏,在一个4×4的空间中,可以实现上下左右移动,相同块消除形成倍数块,如果没有可移动块,则游戏结束。否则游戏可一直进行。
三、程序设计
(1)页面实现
在4×4的表格中随机生成2或者4的数块,通过移动数块来完成游戏运行,如果数块沾满16个格游戏则结束。
生成表格。
@Component
struct setText {
@Link grids: number[]
build() {
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center, direction: FlexDirection.Row }) {
ForEach(this.grids,
(item: number) => Text(item == 0 ? '' : item.toString())
.width(70)
.height(70)
.textAlign(TextAlign.Center)
.fontSize(30)
.margin({ left: 5, top: 5, right: 5, bottom: 5 })
.backgroundColor(colors[item.toString()])
.fontColor((item == 2 || item == 4) ? '#645B52' : '#FFFFFF'),
(item: number) => (number++) + item.toString())
}
}
}
使用装饰器@Component,自定义一个每一行的组件,用装饰器@Link定义一个数组grids。在build()里面添加弹性布局Flex,使用循环渲染ForEach来绘制组件Text。对于每一个Text组件,文本判断是否为0,如果值为0,则不显示,背景颜色采用刚才定义好的背景颜色字典colors对应的背景颜色,文本颜色判断其值是否为2或4,如果为2或4,则采用颜色#645B52,否则采用背景颜色白色。
同理,使用装饰器@Component,自定义一个按钮Button组件,用以绘制上下左右四个按钮。
@Component
struct setButton {
private dirtext: string
private dir: string
@Link Grids: number[][]
@Link grid1: number[]
@Link grid2: number[]
@Link grid3: number[]
@Link grid4: number[]
build() {
Button(this.dirtext)
.width(60)
.height(60)
.fontSize(30)
.fontWeight(FontWeight.Bold)
.align(Alignment.Center)
.backgroundColor('#974B31')
.fontColor('#FFFFFF')
.margin({ left: 5, top: 3, right: 5, bottom: 3 })
}
}
(2)逻辑代码
在结构体setButton中添加四个函数:
addTwoOrFourToGrids():用以随机生成一个新的方格数字,数字为2或4。
addTwoOrFourToGrids() {
let array = [];
for (let row = 0; row < 4; row++)
for (let column = 0;column < 4; column++)
if (this.Grids[row][column] == 0)
array.push([row, column]);
let randomIndes = Math.floor(Math.random() * array.length);
let row = array[randomIndes][0];
let column = array[randomIndes][1];
if (Math.random() < 0.8) {
this.Grids[row][column] = 2;
} else {
this.Grids[row][column] = 4;
}
}
swipeGrids(direction):用以实现方格的重新生成。
swipeGrids(direction) {
let newGrids = this.changeGrids(direction);
if (newGrids.toString() != this.Grids.toString()) {
this.Grids = newGrids;
}
}
changeGrids(direction):用以实现方格的上下左右移动。
changeGrids(direction) {
let newGrids = [[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]];
if (direction == 'left' || direction == 'right') {
let step = 1;
if (direction == 'right') {
step = -1;//step作为循环时数组下标改变的方向
}
for (let row = 0; row < 4; row++) {//每一层
let array = [];
let column = 0;//如果为left则从0开始right从3开始,
if (direction == 'right') {
column = 3;
}
for (let i = 0; i < 4; i++) {
if (this.Grids[row][column] != 0) {//把所有非零元依次放入数组中
array.push(this.Grids[row][column]);
}
column += step;//当direction为left时则从0向3递增,为right时则从3向0递减
}
for (let i = 0; i < array.length - 1; i++) {//访问当前元素及他的下一个元素,所有循环次数为length-1
if (array[i] == array[i + 1]) {//判断是否可合并,
array[i] += array[i + 1];//合并,
array[i + 1] = 0;//合并后参与合并的第二个元素消失
i++;
}
}
column = 0;
if (direction == 'right') {
column = 3;
}
for (const elem of array) {
if (elem != 0) {//跳过array里的空元素
newGrids[row][column] = elem;//把合并后的状态赋给新数组grids,
column += step;
}
}
}
} else if (direction == 'up' || direction == 'down') {//同理
let step = 1;
if (direction == 'down') {
step = -1;
}
for (let column = 0; column < 4; column++) {
let array = [];
let row = 0;
if (direction == 'down') {
row = 3;
}
for (let i = 0; i < 4; i++) {
if (this.Grids[row][column] != 0) {
array.push(this.Grids[row][column]);
}
row += step;
}
for (let i = 0; i < array.length - 1; i++) {
if (array[i] == array[i + 1]) {
array[i] += array[i + 1];
array[i + 1] = 0;
i++;
}
}
row = 0;
if (direction == 'down') {
row = 3;
}
for (const elem of array) {
if (elem != 0) {
newGrids[row][column] = elem;
row += step;
}
}
}
}
return newGrids;
}
changeString():用以将二维数组分成四个一维数组。
changeString() {
this.grid1 = [this.Grids[0][0], this.Grids[0][1], this.Grids[0][2], this.Grids[0][3]]
this.grid2 = [this.Grids[1][0], this.Grids[1][1], this.Grids[1][2], this.Grids[1][3]]
this.grid3 = [this.Grids[2][0], this.Grids[2][1], this.Grids[2][2], this.Grids[2][3]]
this.grid4 = [this.Grids[3][0], this.Grids[3][1], this.Grids[3][2], this.Grids[3][3]]
}
最后在Button组件的属性里添加一个点击事件,依次调用函数swipeGrids(direction)、addTwoOrFourToGrids()和changeString()。
四、总结
通过上半学期的学习,也算给鸿蒙课画上一个圆满的句号,能够完成这次作业,少不了老师3个月的指导和学习,网上学习一些课外知识,找了一些课外优秀作品,参考了一些其他博客的优秀作品,突发灵感,选择了这个选题,代码量适中,中间也遇到了一些困难,但是通过参考一些文献也是修改出来。老师也说过,想要深入学习,这三个月也是不够的,这仅仅只是基础,我也会继续努力,刻苦学习编程。