小游戏案例之2048制作教程
背景:有人私信我说:“诶,Zhoumy,你能不能给点实例教程啊?”Zhoumy就写下了本教程。
欢迎来到2048的制作教程,本游戏用到EGE,未安装的看这里
虽然本代码给了部分代码,但还是建议自己不看教程自己敲一便,要不然做出来了也没啥用,不能自己吸收
1. 首先理一理思路,大家可以先看看下面的问题
Q1.怎么存那些数字?
Q2.怎么移动?
Q3.怎么显示?
Q4.怎么叠加?
Q4.怎么结束?
Q5.怎么随机放数字?
A1.可以用二维数组完成存储
A2.数组字符移动
A3.先画表格,后画数字
A4.类似a[i][j+1]*=2
A5.特判
A6.random,详情看下面
2. 来实现
(1)初始化
long ▓ map[5][5]={{},{▓,2},{0,2}▓{}};
(▓是一些简单的填空)
楼上就是一个5*5的数组,long long是为了防止溢出,上面的两个2是初始给的2个默认的2。
(2)可视化 先用
setfont(33,0,"宋体");
outtextxy(0,0, " ┌┐┌┐┌┐┌┐");
outtextxy(0,33," └┘└┘└┘└┘");
setfont(25,0,"宋体");
outtextxy(37,22, "↑");
outtextxy(102,22,"▓");
outtextxy(170,22,"←");
outtextxy(237,22,"→");
setfont(60,0,"宋体");
outtextxy(0,80, "┌┬┬┬┐");
outtextxy(0,140,"├┼┼▓┤");
outtextxy(0,200,"├┼┼┼┤");
outtextxy(0,260,"├┼┼┼┤");
outtextxy(0,320,"└┴┴┴┘");
(▓是一些简单的填空)
类似的代码绘制完表格 后用类似
for(int j=0;j<▓;j++){
for(int i=0;i<▓;i++){
setfont(32,0,"宋体");
char s[10];
sprintf(s,"%d",map[i][j]);
if(map[i][j]==0){}
else if(map[i][j]<10)outtextxy(i*60+50,j*60+120,▓);
else if(map[i][j]<100)outtextxy(i*60+42,j*60+120,▓);
else if(map[i][j]<1000)outtextxy(i*60+32,j*60+120,▓);
}
}
(▓是一些简单的填空)
绘制完数字。
本代码的思路很简单,就不说了。
代码里面有不懂得会有ege教程,请耐心等待
(3)怎么结束游戏
int much=0;
for(int j=0;j<4;j++)for(int i=0;i<4;i++)if(map[i][j]==0)▓++;
if(much==▓){
setfont(55,0,"宋体");
outtextxy(20,20,"游戏▓束");
Sleep(233333);
}
(▓是一些简单的填空)
本代码的思路是判断有多少个没数字(为0)的数字,如果到0就结束
(4)怎么随机出数字
int ran=random(1,much);
much=0;
for(int j=0;j<4;j++){
for(int i=0;i<▓;i++){
if(map[i][j]==0)much++;
if(ran==much){
if(random(1,▓)==1)map[i][j]=4;
else map[i][j]=2;
}
}
}
}
(▓是一些简单的填空)
本代码思路是从为0的格子里选出一个,并给它2或4的值
(5)怎么判断按下那个键 (半重点)
先说思路,首先找到鼠标的位置,并给现在要的形态进行标记,如果没形态就不运行下面的
msg=getmouse();
while(▓){
if(msg.is_down()){
if(msg.is_left()){
int x, y;
mousepos(&x, &y);
if(x>▓&&x<65&y>16&y<47){
mod=▓;
break;
}
if(x>99&&x<133&y>16&y<47){
mod=2;
break;
}
if(x>166&&x<199&y>16&y<47){
mod=3;
break;
}
if(x>231&&x<266&y>16&y<47){
mod=4;
break;
}
Sleep(100);
}
}
}
(▓是一些简单的填空)
(6)怎么进行叠加和移动 (难、重点)
思路:按mod进行分类,依次进行枚举
先做移动
if(mod==1){
for(int j=0;j<▓;j++){
for(int i=0;i<4;i++){
if(map[i][j]!=0){
int x=i,y=j;
if(y>0&&map[x][y-1]==0){
map[x][y▓]=map[x][y];
map[x][y]=▓;
y--;
}
}
}
}
}
(▓是一些简单的填空)
先理解上方代码,讲的是先判断mod,然后枚举一遍所有的格子,看能不能移动,如果能一动就动,但是可能有这种情况
1 1 1 1
0 0 0 0
0 0 0 0
0 0 0 0
玩家让它们往下
这样就不可行了,因为没有一次性一倒最低端 我们可以用while循环来解决这个问题
while(1){
if(y>0&&map[x][y-1]==0){
map[x][y-1]=map[x][y];
map[x][y]=▓;
y--;
}
else break;
}
(▓是一些简单的填空)
给中间加一个这个,这样就可以移动了! (里面的Y大于0是因为如果是0就不可能移动)所以就弄出了这样的代码
移动说完了再谈叠加,根据上面的经验,你应该已经会怎么做了
else if(y>0&&map[x][y]==map[x][y-1]){
map[x][y-1]*=2;
map[x][y]=0;
break;
}
加一个特判就可完成,但有一个事情
Q.为什么里面要break呢?
A.因为移动后就不能判断了,叠加之后是不可能在移动的,如果下面是0那就无限循环了
(7)加工和更新界面花缀
思路:这里是花缀!
setcaption("元气Zhoumy BY-Zhoumy");
setbkcolor_f(EGERGB(30,60,130));
cleardevice();
setfont(45,0,"宋体");
outtextxy(40,25,"Zhoumy游戏");
setfont(19,0,"宋体");
outtextxy(80,95,"游戏健康忠告");
outtextxy(20,115,"抵制不良游戏,拒绝盗版游戏。");
outtextxy(20,135,"注意自我保护,谨防受骗上当。");
outtextxy(20,155,"适度游戏益脑,沉迷游戏伤身。");
outtextxy(20,175,"合理安排时间,享受健康生活。");
比如可以加个健康游戏忠告、改个名字什么的,好的,本次的讲解就到这里了