小游戏案例之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,"合理安排时间,享受健康生活。");

比如可以加个健康游戏忠告、改个名字什么的,好的,本次的讲解就到这里了

你们都学会了吗???求点赞!