小白从零开发鸿蒙小游戏(1)“数字华容道”—【深鸿会学习小组学习心得及笔记】
文章目录
- 前言
- 概述
- 代码分析
- 主页面
- 插入“华容道“图像
- “开始游戏“按钮的设置
- 页面跳转
- 点击按钮后的页面跳转
- 设置一个滚动选择器
- 设置“进入游戏“按钮
- 游戏界面
- 创建界面
- 添加功能
- 总结
前言
我是深鸿会的一个学习小组组长,同时也是深大数院的一名学生。在上一周我们小组观看并学习了张荣超老师在鸿蒙学院发布的视频,而且在视频里学到了很多知识,同时我们也收到了启发。于是我们运用张老师视频里教过的知识独立开发了一个小游戏“数字华容道”。以下是参与开发的小组成员:
likaijie12138
JiaYi__xixi
wx13415801099
GTH1144754040
概述
数字华容道是用尽量少的步数,尽量短的时间,将棋盘上的数字方块,按照从左到右、从上到下的顺序重新排列整齐。而我们要做的就是把这个小游戏移植到鸿蒙系统上。以下是我们所完成的效果图
1.模式介绍
2.玩法介绍
代码分析
主页面
先上效果图
这个界面的组成为两个部分:华容道图片和开始游戏的按钮。
下面我将一步一步讲解如何完成这两个部分。
插入“华容道“图像
找到default文件夹,创建一个新的文件夹“common”,将准备好的logo图片粘贴到common文件夹中。
打开index.hml,在
代码如下:
<image src="/common/3.png" class="img"/>
打开index.css,删除原有的title类,创建一个img类,将图片的参数输入,(这里只输入了宽度和高度)。
代码如下:
.img{width: 250px;height:250px;
}
打开index.js,将data中的内容删除。
至此,就可以达到如下的效果。
“开始游戏“按钮的设置
打开index.hml,在
代码如下:
<input type="button" value="开始游戏" class ="btn" onclick="clickAction" />
打开index.css,创建一个类btn,调节字体大小(font-size)为38px,将按钮的背景颜色(background-color)设为橘色,按钮上的文字的颜色(color)和按钮边框上的颜色(border-color)都设为黑色,最后调节按钮的宽度(width)为200px,高度(height)为50px。
代码如下:
.
btn{font-size:38px;background-color: #F8C387;color: #000000;border-color: #000000;width:200px;height:50px;
}
至此,就可以达到如下效果图。
页面跳转
接下来我们将要实现的是,点击“开始游戏“按钮,跳转到下一个界面,用户选择游戏难度。模式分为三种:简单模式、普通模式、困难模式。
效果图如下
总共要实现三个功能:按下按钮跳转页面,设置一个滚动选择器,设置“确认”按钮
点击按钮后的页面跳转
在pages文件夹下创建一个新的js page,命名为xuanze。
创建完后可以在config.json中的pages看到自动添加了刚创建的文件夹的路径。
打开index.js,先插入一个含有router函数的头文件,创建一个函数clickAction,添加router.replace函数,里面的参数uri的值为跳转页面的路径。
代码如下:
import router from '@system.router';clickAction(){router.replace({uri:'pages/xuanze/xuanze'
});
设置一个滚动选择器
打开xuanze.hml,创建一个名为container1的区域组件,组件包含一个名为container2的区域组件和一个按钮组件。
<div class="container1"><div class="container2"></div>
</div>
创建一个名为pv1的滚动选择器,里面的数据picker1range通过动态绑定({{ }})的方式获得,把selected设置为"简单模式"使得初始选择简单模式,创建一个名为changeAction1的onchange事件,当滚动选择器中的数据发生改变的时候,会引发onchange事件。
<picker-view class="pv1" range="{{picker1range}}" selected="简单模式" onchange="changeAction1"/>
打开xuanze.css,设置样式
.container1 {flex-direction: column;justify-content: center;align-items: center;width: 454px;height: 454px;
}
.container2{flex-direction:row;justify-content:center;align-items:center;margin-top: 50ox;width:454px;height:250px;
}
.pv1{width:300px;height:300px;
}
打开xuanze.js,把数据赋予动态绑定的滚轮选择器中
export default {data: {picker1range:["简单模式","普通模式","困难模式"],}
}
设置“进入游戏“按钮
在第一个进入游戏界面时,我们已经学过了如何去设置一个“游戏开始“的按钮,所以设置”确认“按钮的步骤跟前面设置按钮的步骤基本一致,所以这里就不再重复了,如果忘了怎么设置按钮的小伙伴可以往前翻翻,有详细解析。然后我们打开xuanze.js,输入以下代码
clickAction(){router.replace({uri:'pages/youxi/youxi',params: {"data": pickervalue}});
},
changeAction1(pv){console.log("选中项:" + pv.newValue);pickervalue = pv.newValue;
}
第一个方法能够在跳转页面的同时把滑动选择器选择到的值通过字典的方式传递到下一个页面。第二个方法是在滑动选择器改变后获得滑动选择器改变后的值。
游戏界面
在pages文件夹下创建一个新的js page,命名为youxi。
创建界面
在创建游戏的时候,我们首先要画出一个棋盘,如下图所示。
首先我们打开youxi.hml,添加下面这段代码
<canvas class="canvas" ref="canvas" onswipe="swipeGrids"></canvas>
这样我们就创建了一个画布组件,而ref相当于画布组件的画笔,而onswipe为滑动事件,当我们手指在手表上面滑动时会引发swipeGrids()事件。
然后我们打开youxi.css,来为我们的canvas组件定制形状
.canvas {width: 305px;height: 305px;background-color:#CD853F;
}
为了让画布上能显示出我们想要的数字,我们创建三个数组来储存方格上面的数字
initGrids3() {grids_3 = [[1, 2, 3],[4, 5, 6],[7, 8, 0]];},initGrids4(){grids_4=[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,0]];},initGrids5(){grids_5=[[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20],[21,22,23,24,0]];},
当选择界面的滑动选择器选择不同内容的时候,能够画出不同的表格,我们把传递过来的值赋予给num,并建立对应数字的数组。
onInit() {pickervalue=this.dataif(pickervalue=="简单模式"){num=3;this.initGrids3();}if(pickervalue=="普通模式"){num=4;this.initGrids4();}if(pickervalue=="困难模式"){num=5;this.initGrids5();}this.addToGrids()},
到了最关键的时候了,怎么把数组乱序?我尝试过把二维数组转化为一维数组,然后用洗牌算法来把一维数组乱序,再把一维数组转化为二维数组。但是出现了一个问题,就是我这样乱序的话会出现一种无解的情况。我以3*3为例,这样乱序的情况下,会出现前两行是恢复正常的,但是最后一行的7与8是交互了的。我查了很多资料,资料都显示这种情况是无解的,所以这种算法是有弊端的。于是我用了另一种算法:随机出[0,3]的一个整数,当出现0的时候,向左滑一下,当出现1的时候向右滑一下…这样以此类推,然后循坏很多次,这样可以保证乱序出来的数组是可以有解的,乱序代码如下:
addToGrids(){let row_0;let column_0;let random;if(num==3){for(let i=0;i<num*num*num;i++){random=Math.floor(Math.random() * 4);for (let row = 0; row < num; row++) {for (let column = 0; column < num; column++) {if(grids_3[row][column]==0){row_0=row;column_0=column;}}}if(random==0||random==1){if(random==0){if(column_0!=num-1){let temp=grids_3[row_0][column_0];grids_3[row_0][column_0]=grids_3[row_0][column_0+1];grids_3[row_0][column_0+1]=temp;}}else{if(column_0!=0){let temp=grids_3[row_0][column_0];grids_3[row_0][column_0]=grids_3[row_0][column_0-1];grids_3[row_0][column_0-1]=temp;}}}if(random==2||random==3){if(random==2){if(row_0!=num-1){let temp=grids_3[row_0][column_0];grids_3[row_0][column_0]=grids_3[row_0+1][column_0];grids_3[row_0+1][column_0]=temp;}}else{if(row_0!=0){let temp=grids_3[row_0][column_0];grids_3[row_0][column_0]=grids_3[row_0-1][column_0];grids_3[row_0-1][column_0]=temp;}}}}}if(num==4){for(let i=0;i<num*num*num;i++){random=Math.floor(Math.random() * 4);for (let row = 0; row < num; row++) {for (let column = 0; column < num; column++) {if(grids_4[row][column]==0){row_0=row;column_0=column;}}}if(random==0||random==1){if(random==0){if(column_0!=num-1){let temp=grids_4[row_0][column_0];grids_4[row_0][column_0]=grids_4[row_0][column_0+1];grids_4[row_0][column_0+1]=temp;}}else{if(column_0!=0){let temp=grids_4[row_0][column_0];grids_4[row_0][column_0]=grids_4[row_0][column_0-1];grids_4[row_0][column_0-1]=temp;}}}if(random==2||random==3){if(random==2){if(row_0!=num-1){let temp=grids_4[row_0][column_0];grids_4[row_0][column_0]=grids_4[row_0+1][column_0];grids_4[row_0+1][column_0]=temp;}}else{if(row_0!=0){let temp=grids_4[row_0][column_0];grids_4[row_0][column_0]=grids_4[row_0-1][column_0];grids_4[row_0-1][column_0]=temp;}}}}}if(num==5){for(let i=0;i<num*num*num;i++){random=Math.floor(Math.random() * 4);for (let row = 0; row < num; row++) {for (let column = 0; column < num; column++) {if(grids_5[row][column]==0){row_0=row;column_0=column;}}}if(random==0||random==1){if(random==0){if(column_0!=num-1){let temp=grids_5[row_0][column_0];grids_5[row_0][column_0]=grids_5[row_0][column_0+1];grids_5[row_0][column_0+1]=temp;}}else{if(column_0!=0){let temp=grids_5[row_0][column_0];grids_5[row_0][column_0]=grids_5[row_0][column_0-1];grids_5[row_0][column_0-1]=temp;}}}if(random==2||random==3){if(random==2){if(row_0!=num-1){let temp=grids_5[row_0][column_0];grids_5[row_0][column_0]=grids_5[row_0+1][column_0];grids_5[row_0+1][column_0]=temp;}}else{if(row_0!=0){let temp=grids_5[row_0][column_0];grids_5[row_0][column_0]=grids_5[row_0-1][column_0];grids_5[row_0-1][column_0]=temp;}}}}}},
把数组乱序后,我们onReady()内设置好画笔,在onShow()中把表格画出来。其中由于我们不同模式需要画的表格都是不一样的。所以我根据张荣超老师的2048视频所讲的内容进行推断,推出SIDELEN 与所画表格的行数列数的关系为
SIDELEN = 300/num-5,
然后根据不同的num我可以画出不同的正方形方格出来。
onReady(){context = this.$refs.canvas.getContext('2d');},onShow(){this.drawGrids();},drawGrids(){const SIDELEN = 300/num-5;if(num==3){for (let row = 0; row < num; row++) {for (let column = 0; column < num; column++) {let gridStr = grids_3[row][column].toString();context.fillStyle=colors["3"];let leftTopX = column * (MARGIN + SIDELEN) + MARGIN;let leftTopY = row * (MARGIN + SIDELEN) + MARGIN;context.fillRect(leftTopX, leftTopY, SIDELEN, SIDELEN);context.font = "36px HYQiHei-65S";if (gridStr != "0") {context.fillStyle = "#FFFFFF";let offsetX = (4 - gridStr.length) * (SIDELEN / 8);let offsetY = (SIDELEN - 24) / 2;context.fillText(gridStr, leftTopX + offsetX, leftTopY + offsetY);}}}}if(num==4){for (let row = 0; row < num; row++) {for (let column = 0; column < num; column++) {let gridStr = grids_4[row][column].toString();context.fillStyle=colors["4"];let leftTopX = column * (MARGIN + SIDELEN) + MARGIN;let leftTopY = row * (MARGIN + SIDELEN) + MARGIN;context.fillRect(leftTopX, leftTopY, SIDELEN, SIDELEN);context.font = "30px HYQiHei-65S";if (gridStr != "0") {context.fillStyle = "#FFFFFF";let offsetX = (4 - gridStr.length) * (SIDELEN / 8);let offsetY = (SIDELEN - 24) / 2;context.fillText(gridStr, leftTopX + offsetX, leftTopY + offsetY);}}}}if(num==5){for (let row = 0; row < num; row++) {for (let column = 0; column < num; column++) {let gridStr = grids_5[row][column].toString();context.fillStyle=colors["5"];let leftTopX = column * (MARGIN + SIDELEN) + MARGIN;let leftTopY = row * (MARGIN + SIDELEN) + MARGIN;context.fillRect(leftTopX, leftTopY, SIDELEN, SIDELEN);context.font = "24px HYQiHei-65S";if (gridStr != "0") {context.fillStyle = "#FFFFFF";let offsetX = (4 - gridStr.length) * (SIDELEN / 8);let offsetY = (SIDELEN - 24) / 2;context.fillText(gridStr, leftTopX + offsetX, leftTopY + offsetY);}}}}},
这样我们就把我们所需要的方格在画布上画了出来。
添加功能
为了实现数字华容道的功能,我们需要在画布上添加滑动事件
<canvas class="canvas" ref="canvas" onswipe="swipeGrids"></canvas>
onswipe即为我们所添加的滑动事件,在youxi.js中滑动事件的名字为swipeGrids。当手指滑动的时候,我们需要做的就是把滑动的方向传递进滑动事件swipeGrids里。然后寻找0方格所在的位置,同时判断0方格能不能被移动,当0方格能被移动的时候,把0与滑动方向临近那个数字交换,这样就完成了一次滑动。代码如下
swipeGrids(event) {let newGrids = this.changeGrids(event.direction);if(num==3){grids_3 = newGrids;}if(num==4){grids_4 = newGrids;}if(num==5){grids_5 = newGrids;}this.drawGrids();
},
changeGrids(direction){let row_0;let column_0;if(num==3){let newGrids_3=grids_3;for (let row = 0; row < num; row++) {for (let column = 0; column < num; column++) {if(newGrids_3[row][column]==0){row_0=row;column_0=column;}}}if(this.isShow==false){if(direction=='left'||direction=='right'){if(direction=='left'){if(column_0!=num-1){let temp=newGrids_3[row_0][column_0];newGrids_3[row_0][column_0]=newGrids_3[row_0][column_0+1];newGrids_3[row_0][column_0+1]=temp;this.step+=1;}}else{if(column_0!=0){let temp=newGrids_3[row_0][column_0];newGrids_3[row_0][column_0]=newGrids_3[row_0][column_0-1];newGrids_3[row_0][column_0-1]=temp;this.step+=1;}}}if(direction=='up'||direction=='down'){if(direction=='up'){if(row_0!=num-1){let temp=newGrids_3[row_0][column_0];newGrids_3[row_0][column_0]=newGrids_3[row_0+1][column_0];newGrids_3[row_0+1][column_0]=temp;this.step+=1;}}else{if(row_0!=0){let temp=newGrids_3[row_0][column_0];newGrids_3[row_0][column_0]=newGrids_3[row_0-1][column_0];newGrids_3[row_0-1][column_0]=temp;this.step+=1;}}}}return newGrids_3;}if(num==4){let newGrids_4=grids_4;for (let row = 0; row < num; row++) {for (let column = 0; column < num; column++) {if(newGrids_4[row][column]==0){row_0=row;column_0=column;}}}if(this.isShow==false){if(direction=='left'||direction=='right'){if(direction=='left'){if(column_0!=num-1){let temp=newGrids_4[row_0][column_0];newGrids_4[row_0][column_0]=newGrids_4[row_0][column_0+1];newGrids_4[row_0][column_0+1]=temp;this.step+=1;}}else{if(column_0!=0){let temp=newGrids_4[row_0][column_0];newGrids_4[row_0][column_0]=newGrids_4[row_0][column_0-1];newGrids_4[row_0][column_0-1]=temp;this.step+=1;}}}if(direction=='up'||direction=='down'){if(direction=='up'){if(row_0!=num-1){let temp=newGrids_4[row_0][column_0];newGrids_4[row_0][column_0]=newGrids_4[row_0+1][column_0];newGrids_4[row_0+1][column_0]=temp;this.step+=1;}}else{if(row_0!=0){let temp=newGrids_4[row_0][column_0];newGrids_4[row_0][column_0]=newGrids_4[row_0-1][column_0];newGrids_4[row_0-1][column_0]=temp;this.step+=1;}}}}return newGrids_4;}if(num==5){let newGrids_5=grids_5;for (let row = 0; row < num; row++) {for (let column = 0; column < num; column++) {if(newGrids_5[row][column]==0){row_0=row;column_0=column;}}}if(this.isShow==false){if(direction=='left'||direction=='right'){if(direction=='left'){if(column_0!=num-1){let temp=newGrids_5[row_0][column_0];newGrids_5[row_0][column_0]=newGrids_5[row_0][column_0+1];newGrids_5[row_0][column_0+1]=temp;this.step+=1;}}else{if(column_0!=0){let temp=newGrids_5[row_0][column_0];newGrids_5[row_0][column_0]=newGrids_5[row_0][column_0-1];newGrids_5[row_0][column_0-1]=temp;this.step+=1;}}}if(direction=='up'||direction=='down'){if(direction=='up'){if(row_0!=num-1){let temp=newGrids_5[row_0][column_0];newGrids_5[row_0][column_0]=newGrids_5[row_0+1][column_0];newGrids_5[row_0+1][column_0]=temp;this.step+=1;}}else{if(row_0!=0){let temp=newGrids_5[row_0][column_0];newGrids_5[row_0][column_0]=newGrids_5[row_0-1][column_0];newGrids_5[row_0-1][column_0]=temp;this.step+=1;}}}}return newGrids_5;}},
这样我们就完成了滑动事件的创建。为了让游戏有趣一点,我们决定给游戏添加一个计步数功能。打开youxi.hml,添加txt组件,组件内容为步数,步数的值通过动态绑定的方式由youxi.js获得。
<text class="step">步数:{{step}}</text>
在youxi.js中初始化步数的值为0
data: {step:0,isShow:false},
在滑动的时候,每滑动一次,步数就添加1,如下代码所示
if(direction=='left'||direction=='right'){if(direction=='left'){if(column_0!=num-1){let temp=newGrids_3[row_0][column_0];newGrids_3[row_0][column_0]=newGrids_3[row_0][column_0+1];newGrids_3[row_0][column_0+1]=temp;this.step+=1;}}else{if(column_0!=0){let temp=newGrids_3[row_0][column_0];newGrids_3[row_0][column_0]=newGrids_3[row_0][column_0-1];newGrids_3[row_0][column_0-1]=temp;this.step+=1;}}}
这样我们完成了数字华容道的滑动功能和计数功能,接下来我们将为数字华容道加入游戏结束的功能。
打开youxi,hml,添加一个组件在画布上面,并在这个组件里包含有一个文本组件和一个控制文本组件是否显示的组件。文本是否显示通过动态绑定的方式由youxi.js获得
<stack class="stack"><canvas class="canvas" ref="canvas" onswipe="swipeGrids"></canvas><div class="subcontainer" show="{{isShow}}"><text class="gameover">游戏结束</text></div></stack>
打开youxi.js,先把文本组件设为不可见。
data: {step:0,isShow:false},
然后写一个方法GameOver,当游戏结束时,并把文本组件变为可见。
swipeGrids(event) {let newGrids = this.changeGrids(event.direction);if(num==3){grids_3 = newGrids;}if(num==4){grids_4 = newGrids;}if(num==5){grids_5 = newGrids;}this.drawGrids();if(this.GameOver()==true){colors = THEME.faded;this.drawGrids();this.isShow = true;}},GameOver(){if(num==3){for(let row=0;row<num;row++){for(let column=0;column<num;column++){if(row!=num-1||column!=num-1) {if (grids_3[row][column] != row * num + (column + 1)) {return false}}}}return true}if(num==4){for(let row=0;row<num;row++){for(let column=0;column<num;column++){if(row!=num-1||column!=num-1) {if (grids_4[row][column] != row * num + (column + 1)) {return false}}}}return true}if(num==5){for(let row=0;row<num;row++){for(let column=0;column<num;column++){if(row!=num-1||column!=num-1) {if (grids_5[row][column] != row * num + (column + 1)) {return false}}}}return true}},
这样我们就完成了游戏结束的显示了,为了使游戏结束时,游戏不能再继续进行了,我们需要在滑动事件里加一个判定,当文本组件为不可见的时候,才能进行滑动操作,代码示例如下
if(this.isShow==false){if(direction=='left'||direction=='right'){if(direction=='left'){if(column_0!=num-1){let temp=newGrids_3[row_0][column_0];newGrids_3[row_0][column_0]=newGrids_3[row_0][column_0+1];newGrids_3[row_0][column_0+1]=temp;this.step+=1;}}else{if(column_0!=0){let temp=newGrids_3[row_0][column_0];newGrids_3[row_0][column_0]=newGrids_3[row_0][column_0-1];newGrids_3[row_0][column_0-1]=temp;this.step+=1;}}}
为了使游戏画面好看一点,我们的方格需要不同的颜色。同时当游戏结束的时候,把颜色变淡一点,以方便看出来游戏结束已经结束了。首先我们创建两个字典normal和faded,字典的键和元素都为数字以及数字对应的颜色,当游戏未结束,颜色用normal字典的颜色,当游戏结束的时候,颜色字典变为faded,同时重新绘制一次方格。
const THEME = {normal: {"3":"#FB8B05","4":"#2775B6","5":"#DD8AF8"},faded:{"3":"#E3BD8D","4":"#66A9C9","5":"#F8D1EE"}
};
var colors = THEME.normal;if(this.GameOver()==true){colors = THEME.faded;this.drawGrids();this.isShow = true;}
总结
以上就是我们小组对于数字华容道的开发过程,其中也包括了我们的一些心得与学习体验,也有我们在开发过程中遇到的难题。总的来说,这次数字华容道的开发对于我们小组来也算说是一次宝贵的学习经验。
小白从零开发鸿蒙小游戏(1)“数字华容道”—【深鸿会学习小组学习心得及笔记】相关推荐
- 华为鸿蒙2048小游戏,《从零开发鸿蒙小游戏App》直播答疑(包含新版2048游戏代码)...
请到附件中下载新版2048游戏代码.最好能对该代码再做一些优化(见下述问题8),欢迎感兴趣的朋友随时跟我探讨,^_^ 问题1:如何将开发的Lite Wearable项目部署在鸿蒙手表Watch GT2 ...
- HarmonyOS(鸿蒙)运动手表第二个小游戏app——数字华容道
前言 这次博客是学完鸿蒙应用开发之后,自行开发的鸿蒙小游戏--数字华容道,这篇博客详细地讲了数字华容道的开发思路. 概述 本个demo将从零基础开始完成鸿蒙小游戏APP在可穿戴设备上的编译,此处以运动 ...
- egret制作小游戏:数字华容道及有解判断(代码注释)(评论区有源码下载~)
继续学习egret,最近写了数字华容道的小游戏,非常简单的小游戏.首先预览一下效果: 数字华容道就是通过移动方块,将方块按照数字的排序进行排列.功能很简单,主要有刷新,提升阶数,如何一定有解,以及简单 ...
- Qt小游戏之数字华容道(百行代码搭雏形,可玩;含源码+注释)
文章目录 一.数字华容道,样图如下 二.废话少说直接上代码 1.首先是代码文件分析 2.CLabel的源码 3.CMainWindow的源码 4.main文件 总结 一.数字华容道,样图如下 相信大家 ...
- 鸿蒙小游戏-俄罗斯方块
作者:225王宗振 前言 为了更好地熟练掌握鸿蒙手机应用开发,查阅资料和算法尝试开发鸿蒙小游戏--俄罗斯方块. 概述 完成鸿蒙小游戏APP在手机上的编译在项目中所使用到的软件为DevEco Studi ...
- HarmonyOS应用开发实战 | 开发运动手表小游戏
在学习完HarmonyOS应用开发文档后,有不少人进行了项目实践.下面本文将带大家从零开始完成鸿蒙小游戏App在运动手表上的编译,整体难度不高,属于入门级学习. 鸿蒙社区也非常期待大家的作品~ Har ...
- 如何使用egret开发微信小游戏(一)Hello World
如何使用egret开发微信小游戏(一)Hello World 微信小游戏上线以来,凭借微信海量的用户,取得了巨大的成功,从跳一跳到大家一起来滑水,从2d游戏到3d游戏,许多游戏开发者都赚的盆满钵满,我 ...
- 如何利用C#开发“扫雷”小游戏
本文详细说明了利用C#语言开发"扫雷"小游戏的开发过程.
- 如何不用服务器来开发一个小游戏
我是代长新,来自上海享物说,主要负责游戏客户端研发. 享物说是一个大家可以互相赠送物品,有趣.不花钱的社区平台.为了创造更好的社区氛围,我们决定通过小游戏来增加社区的趣味性和互动性. <乐享花园 ...
- 基于 Blazor 开发五子棋小游戏
今天是农历五月初五,端午节.在此,祝大家端午安康! 端午节是中华民族古老的传统节日之一.端午也称端五,端阳.此外,端午节还有许多别称,如:午日节.重五节.五月节.浴兰节.女儿节.天中节.地腊.诗人节. ...
最新文章
- MobPush精准把握用户的使用时间
- DirectShow 在VS2005中环境配置
- 【李宏毅机器学习】regress case study 回归案例研究(p3) 学习笔记
- 关于选择,说一个同学的真实故事
- 3.10 触发字检测
- 仅需8道题轻松掌握Python Web应用开发 | Python技能树征题
- 【收藏级教程】专业Finereport教程,帆软报表教程
- 2020 数学建模国赛 B 题参考思路
- eyoucms如何搬家?易优cms搬家教程
- Linux被熊孩子攻破了?
- oracle10gwin,win10肿么彻底卸载oracle10g
- Java编程语言学习:Java语言编程的基础知识之Java的变量与数据类型、符号、运算符、数组Array总结之详细攻略
- 【支付宝沙箱支付】麻瓜教程——申请----代码----修改测试----问题解决
- 2019经济寒冬,软件定制开发公司的竞争力在哪里??
- php access 教程 pdf,Access 2007 以PDF 格式保存文件
- Velocity模板语言(VTL):说明
- Win7 更新 80072EFE 错误
- 中国联通云数据有限公司总经理焦刚:沃筑生态,共创未来
- Ubuntu Linux 3D桌面完全教程 Ubuntu Linux 3D桌面完全教程
- 有密码的压缩包如何解压