2048纯手工制作

说明:
刚学完easyx.h的使用,做了一个2048小游戏
第一次制作,有些简陋,勿笑
游戏:C语言 2048自制版
使用开发软件:VS2010
游戏背景图来源于网络搜索
图片放于:工程文件夹/image/
重要库文件: graphics.h easyx.h
库文件安装来源:https://www.easyx.cn
工程适用编辑软件:vc6.0 vs2010 vs2012 等
作者信息:鼠瓜

游戏界面
运行界面
工程代码:
/*
2048.cpp
*/

#include "2048.h"

void main()
{
    initgraph(640, 480);            // 创建绘图窗口
    srand((unsigned)time(NULL));    // 设置随机种子

    Welcome();          // 绘制游戏界面
    InitImage();        // 初始化游戏图片
    InitGame();         // 初始化游戏数据
    char c;
    // 游戏过程
    while(1)    
    {
        c=GetCmd();     //获取按键命令,并处理
        if (c==27)  //检测是否结束
        {
            if(Quit())
            {   
                settextstyle(70, 50, _T("幼圆")); //设置字体样式
                settextcolor(RED);                  //设置字体颜色
                outtextxy(-200,152, _T("GAME OVER !!"));
                break;
            }
        }
        if(Checkover())         //检测是否结束
        {
            outtextxy(-200,152, _T("GAME OVER !!"));
            _getch();
            break;
        }
    }
        // 关闭图形模式
    closegraph();
}

/*
2048.h
*/

/*
游戏:C语言 2048自制版
使用开发软件:VS2010 
游戏背景图来源于网络搜索
图片放于:工程文件夹/image/
使用重要库文件:  graphics.h   easyx.h  
库文件安装来源:https://www.easyx.cn
工程适用编辑软件:vc6.0  vs2010  vs2012 等
作者信息:鼠瓜
拿走不用谢
请保留此处,敲代码不容易
*/
#include <graphics.h>
#include <time.h>
#include <stdio.h>
#include <conio.h>

#define W 640   //游戏界面宽
#define H 480   //游戏界面高



IMAGE   g_imgSight(350, 350);       // 游戏的视野
SIZE    g_szMap;                    // 2048的格子数 //这是一个SIZE结构体,里面有 LONG cx; LONG cy;两个变量

struct  gGEZI
{
    int num;    //格子的数字
    COLORREF rgb;   //格子的颜色
};
gGEZI  Gnum[4][4];      //定义4*4的格子数

int oldnum[4][4]={0};   //存放未按按键时格子上的数字
int Score;              //存放分数
TCHAR s[5];             //声明数组,用来存放字符串
IMAGE Clc;              //分数更新清除背景图

//函数
void    Welcome();                          // 绘制游戏界面
void    InitImage();                        // 初始化游戏图片
void    InitGame();                         // 初始化游戏数据
void    Paint();                            // 绘制数值更新图
char    GetCmd();                           // 获取用户输入的命令
void    DispatchCmd(int cmd);               // 处理用户输入的命令
void    OnUp();                             // 向上移动
void    OnLeft();                           // 向左移动
void    OnRight();                          // 向右移动
void    OnDown();                           // 向下移动
void    Randnum();                          //随机产生新的数字
bool    Checkover();                        //检测是否结束
bool    Quit();                             // 询问用户是否退出游戏


void Welcome()      // 绘制游戏界面
{
    IMAGE back;     //声明游戏界面背景图
    loadimage(&back,_T("..\\image\\back.jpg"),W,H+40);  //获取背景图
    putimage(0,0,W, H, &back,0,0);      //显示背景图

    // 设置字体样式       白色  字体背景透明
    settextcolor(BLACK);    
    setbkmode(TRANSPARENT);

    // 绘制标题
    settextstyle(36, 32, _T("宋体"));
    outtextxy(150, 40, _T("2048自制版"));
    settextstyle(30, 0, _T("幼圆"));
    outtextxy(200, 100, _T("经典版"));

    // 绘制操作说明
    settextstyle(18, 0, _T("宋体"));
    outtextxy(72,382, _T("控制说明:"));
    outtextxy(56, 400, _T("A/S/D/W:移动"));
    outtextxy(56, 420, _T("ESC:退出程序"));
    //等待1000ms
    Sleep(1000);
}

void    InitImage()                     // 初始化游戏图片
{
    cleardevice();                  // 清屏

    //绘制游戏背景
    IMAGE gback;        
    loadimage(&gback,_T("..\\image\\dgback.jpg"),W,H);
    putimage(0,0, &gback);
    setorigin(250,65);// 设置坐标原点  145, 65
    //画线条
    //设置线条样式  实线
    setlinestyle(PS_SOLID,1);
    setlinecolor(RGB(128,128,0));//设置线条颜色
    for(int i=0;i<5;i++)    
    {
        for(int j=0;j<10;j++)
        {
            line(90*i+j, 0, 90*i+j,368);
            line(0, 90*i+j, 368, 90*i+j);
        }
    }
    //画格子
    setfillcolor(RGB(85,85,0));
    for(int i=0; i<4; i++)      
    {
        for(int j=0;j<4; j++)
        {
            solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
        }       
    }

    //绘制必要的文字
    settextstyle(32, 0, _T("幼圆"));
    outtextxy(-200, -60, _T("2048经典版"));
    settextstyle(20, 15, _T("幼圆"));
    outtextxy(50, -40, _T("得 分:       分"));
    outtextxy(50, 380, _T("暂 停"));
    outtextxy(150, 380, _T("继 续"));
    outtextxy(250, 380, _T("退 出"));
    settextstyle(18, 0, _T("宋体"));
    outtextxy(-222,335, _T("控制说明:"));
    outtextxy(-240,360, _T("A/S/D/W:移动"));
    outtextxy(-240,380, _T("ESC:退出程序"));

    //显示分数
    Score=0;
    swprintf(s, 5,_T("%d"), Score);          //将整形score转换成字符串
    settextstyle(40, 20, _T("微软雅黑"));     //设置字体
    settextcolor(YELLOW);                    // 设置文字颜色为黄色
    getimage(&Clc,150,-50,200,40);
    outtextxy(150, -50, s); 
}

void    InitGame()                          // 初始化游戏数据
{
    int i,j;
    //初始化格子数据
    for( i = 0; i<4; i++)   
    {
        for( j=0; j<4; j++)
        {
            Gnum[i][j].num=0;
            Gnum[i][j].rgb=RGB(85,85,0);        //数字为0时显示格子本身颜色
            oldnum[i][j]=Gnum[i][j].num;        //
        }
    }
    //随机在一个格子产生初始数值  2 或4
    i=rand()%4;
    j=rand()%4;
    Gnum[i][j].num=(rand()%2+1)*2;      //产生随机数 2 或 4
    oldnum[i][j]=Gnum[i][j].num;        //更新oldnum的数值
    Paint();                            //绘制图像
}
void    Paint()                         //绘制
{
    settextcolor(WHITE);            //设置文字颜色
    for(int i = 0; i < 4; i++)      //重新绘制一遍
    {
        for(int j = 0; j  < 4; j++)
        {
            switch(Gnum[i][j].num)      //
            {
                case 0: 
                {
                    //设置格子填充色
                    setfillcolor(RGB(85,85,0));         
                    //填充格子
                    solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
                    break;
                }
                case 2: 
                {
                    //设置格子填充色   下同
                    setfillcolor(RGB(128,64,0));
                    //填充格子      下同
                    solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
                    //设置格子上的数字字体,大小 ,下同
                    settextstyle(70, 70, _T("幼圆"));
                    //输出文字      ,下同
                    outtextxy(80*i+10*(i+1)+5, 80*j+10*(j+1)+5, _T("2"));
                    break;
                }
                case 4: 
                {
                    setfillcolor(RGB(0,64,64));
                    solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
                    settextstyle(70, 70, _T("幼圆"));
                    outtextxy(80*i+10*(i+1)+5, 80*j+10*(j+1)+5, _T("4"));
                    break;
                }
                case 8: 
                {
                    setfillcolor(RGB(0,128,128));
                    solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
                    settextstyle(70, 70, _T("幼圆"));
                    outtextxy(80*i+10*(i+1)+5, 80*j+10*(j+1)+5, _T("8"));
                    break;
                }
                case 16: 
                {
                    setfillcolor(RGB(128,0,64));
                    solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
                    settextstyle(40, 30, _T("幼圆"));
                    outtextxy(80*i+10*(i+1)+5, 80*j+10*(j+1)+20, _T("16"));
                    break;
                }
                case 32: 
                {
                    setfillcolor(MAGENTA);
                    solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
                    settextstyle(40, 30, _T("幼圆"));
                    outtextxy(80*i+10*(i+1)+5, 80*j+10*(j+1)+20, _T("32"));
                    break;
                }
                case 64: 
                {
                    setfillcolor(RGB(0,255,255));
                    solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
                    settextstyle(40, 30, _T("幼圆"));
                    outtextxy(80*i+10*(i+1)+5, 80*j+10*(j+1)+20, _T("64"));
                    break;
                }
                case 128: 
                {
                    setfillcolor(CYAN);
                    solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
                    settextstyle(35, 20, _T("幼圆"));
                    outtextxy(80*i+10*(i+1)+10, 80*j+10*(j+1)+25, _T("128"));
                    break;
                }
                case 256: 
                {
                    setfillcolor(GREEN);
                    solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
                    settextstyle(35, 20, _T("幼圆"));
                    outtextxy(80*i+10*(i+1)+10, 80*j+10*(j+1)+25, _T("256"));
                    break;
                }
                case 512: 
                {
                    setfillcolor(YELLOW);
                    solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
                    settextstyle(35, 0, _T("幼圆"));
                    outtextxy(80*i+10*(i+1)+15, 80*j+10*(j+1)+35, _T("512"));
                    break;
                }
                case 1024: 
                {
                    setfillcolor(RGB(255,126,0));
                    solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
                    settextstyle(25, 0, _T("幼圆"));
                    outtextxy(80*i+10*(i+1)+10, 80*j+10*(j+1)+35, _T("1024"));
                    break;
                }
                case 2048: 
                {
                    setfillcolor(RED);
                    solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
                    settextstyle(25, 0, _T("幼圆"));
                    outtextxy(80*i+10*(i+1)+10, 80*j+10*(j+1)+35, _T("2048"));
                    break;
                }
                case 4096: 
                {
                    setfillcolor(RED);
                    solidrectangle(80*i+10*(i+1), 80*j+10*(j+1), 80*i+10*(i+1)+80, 80*j+10*(j+1)+80);
                    settextstyle(25, 0, _T("幼圆"));
                    outtextxy(80*i+10*(i+1)+10, 80*j+10*(j+1)+35, _T("4096"));
                    break;
                }
            }
        }
    }
    //显示分数

    putimage(150,-50,200,40,&Clc,0,0);      //清除原来的分数
    swprintf(s, 5,_T("%d"), Score);          //将整形score转换成字符串
    settextstyle(40, 20, _T("微软雅黑"));     //设置字体
    settextcolor(YELLOW);                    // 设置文字颜色为黄色
    outtextxy(150, -50, s);                 //显示新的分数
}

// 获取用户输入的命令并处理
char GetCmd()
{
    char c = 0;
    if (_kbhit())       //判断是否有按键按下
        {
            Sleep(20);  //延时
            if (_kbhit())   
            {
                c = _getch();   //获取所按下的按键
                switch(c)
                {
                    case 'w': OnUp();break;     //向上
                    case 'a': OnLeft();break;   //向左
                    case 's': OnDown(); break;  //向下
                    case 'd': OnRight();break;  //向右
                    case 27:   break;           //ESC键  退出
                }

            }
    }
    return c;
}



// 向上移动处理
void OnUp()
{
    for(int i = 0; i < 4; i++ )
    {
        for(int j = 0; j < 3; j++)
        {
            if(Gnum[i][0].num==0)
            {
                Gnum[i][0].num=Gnum[i][1].num;
                Gnum[i][1].num=Gnum[i][2].num;
                Gnum[i][2].num=Gnum[i][3].num;
                Gnum[i][3].num=0;
            }
            if(Gnum[i][1].num==0)
            {
                Gnum[i][1].num=Gnum[i][2].num;
                Gnum[i][2].num=Gnum[i][3].num;
                Gnum[i][3].num=0;
            }
            if(Gnum[i][2].num==0)
            {
                Gnum[i][2].num=Gnum[i][3].num;
                Gnum[i][3].num=0;
            }
        }
    }
    for(int i = 0; i < 4; i++ )
    {
            if(Gnum[i][0].num == Gnum[i][1].num )
            {
                Gnum[i][0].num =Gnum[i][0].num+Gnum[i][1].num;
                Gnum[i][1].num=Gnum[i][2].num;
                Gnum[i][2].num=Gnum[i][3].num;
                Gnum[i][3].num=0;
            }
            if(Gnum[i][1].num == Gnum[i][2].num )
            {
                Gnum[i][1].num =Gnum[i][1].num+Gnum[i][2].num;
                Gnum[i][2].num=Gnum[i][3].num;
                Gnum[i][3].num=0;
            }
            if((Gnum[i][2].num == Gnum[i][3].num ) )
            {
                Gnum[i][2].num =Gnum[i][2].num+Gnum[i][3].num;
                Gnum[i][3].num=0;
            }
    }
    Randnum();  //产生新的2或4的格子
}


// 向左移动处理
void OnLeft()
{
    for(int j = 0; j < 4; j++ )
    {
        for(int i = 0; i < 4; i++)
        {
            if(Gnum[0][j].num==0)
            {
                Gnum[0][j].num=Gnum[1][j].num;
                Gnum[1][j].num=Gnum[2][j].num;
                Gnum[2][j].num=Gnum[3][j].num;
                Gnum[3][j].num=0;
            }
            if(Gnum[1][j].num==0)
            {
                Gnum[1][j].num=Gnum[2][j].num;
                Gnum[2][j].num=Gnum[3][j].num;
                Gnum[3][j].num=0;
            }
            if(Gnum[2][j].num==0)
            { 
                Gnum[2][j].num=Gnum[3][j].num;
                Gnum[3][j].num=0;
            }
        }
    }
    for(int j = 0; j < 4; j++ )
    {
            if(Gnum[0][j].num == Gnum[1][j].num )
            {
                Gnum[0][j].num=Gnum[0][j].num+Gnum[1][j].num;
                Gnum[1][j].num=Gnum[2][j].num;
                Gnum[2][j].num=Gnum[3][j].num;
                Gnum[3][j].num=0;
            }
            if(Gnum[1][j].num == Gnum[2][j].num )
            {
                Gnum[1][j].num=Gnum[1][j].num+Gnum[2][j].num;
                Gnum[2][j].num=Gnum[3][j].num;
                Gnum[3][j].num=0;
            }
            if(Gnum[2][j].num == Gnum[3][j].num )
            {
                Gnum[2][j].num=Gnum[2][j].num+Gnum[3][j].num;
                Gnum[3][j].num=0;
            }
    }
    Randnum();  //产生新的2或4的格子
}


// 向右移动处理
void OnRight()
{
    for(int j = 3; j >=0; j-- )
    {
        for(int i = 3; i >=0; i--)
        {
            if(Gnum[3][j].num==0)
            {
                Gnum[3][j].num=Gnum[2][j].num;
                Gnum[2][j].num=Gnum[1][j].num;
                Gnum[1][j].num=Gnum[0][j].num;
                Gnum[0][j].num=0;
            }
            if(Gnum[2][j].num==0)
            {
                Gnum[2][j].num=Gnum[1][j].num;
                Gnum[1][j].num=Gnum[0][j].num;
                Gnum[0][j].num=0;
            }
            if(Gnum[1][j].num==0)
            {
                Gnum[1][j].num=Gnum[0][j].num;
                Gnum[0][j].num=0;
            }
        }
    }
    for(int j = 3; j >=0; j-- )
    {
            if(Gnum[3][j].num == Gnum[2][j].num )
            {
                Gnum[3][j].num =Gnum[3][j].num+Gnum[2][j].num;
                Gnum[2][j].num=Gnum[1][j].num;
                Gnum[1][j].num=Gnum[0][j].num;
                Gnum[0][j].num=0;
            }
            if(Gnum[2][j].num == Gnum[1][j].num )
            {
                Gnum[2][j].num =Gnum[2][j].num+Gnum[1][j].num;
                Gnum[1][j].num=Gnum[0][j].num;
                Gnum[0][j].num=0;
            }
            if(Gnum[1][j].num == Gnum[0][j].num )
            {
                Gnum[1][j].num =Gnum[1][j].num+Gnum[0][j].num;
                Gnum[0][j].num=0;
            }
        //}
    }
    Randnum();      //产生新的2或4的格子
}


// 向下移动处理
void OnDown()
{
    for(int i = 3; i >=0; i-- )
    {
        for(int j = 3; j >=0; j--)
        {
            if(Gnum[i][3].num==0)
            {
                Gnum[i][3].num=Gnum[i][2].num;
                Gnum[i][2].num=Gnum[i][1].num;
                Gnum[i][1].num=Gnum[i][0].num;
                Gnum[i][0].num=0;
            }
            if(Gnum[i][2].num==0)
            {
                Gnum[i][2].num=Gnum[i][1].num;
                Gnum[i][1].num=Gnum[i][0].num;
                Gnum[i][0].num=0;
            }
            if(Gnum[i][1].num==0)
            {
                Gnum[i][1].num=Gnum[i][0].num;
                Gnum[i][0].num=0;
            }
        }
    }
    for(int i = 3; i >=0; i-- )
    {
        /*for(int j = 3; j >=0; j--)
        {*/
            if(Gnum[i][3].num == Gnum[i][2].num )
            {
                Gnum[i][3].num =Gnum[i][3].num+Gnum[i][2].num;
                Gnum[i][2].num=Gnum[i][1].num;
                Gnum[i][1].num=Gnum[i][0].num;
                Gnum[i][0].num=0;
            }
            if(Gnum[i][2].num == Gnum[i][1].num )
            {
                Gnum[i][2].num =Gnum[i][2].num+Gnum[i][1].num;
                Gnum[i][1].num=Gnum[i][0].num;
                Gnum[i][0].num=0;
            }
            if((Gnum[i][1].num == Gnum[i][0].num ) )
            {
                Gnum[i][1].num =Gnum[i][1].num+Gnum[i][0].num;
                Gnum[i][0].num=0;
            }
        //}
    }
    Randnum();  //产生新的2或4的格子
}

void    Randnum()                           //随机产生新的数字 2或4
{
    int i,j,flag=0;
    for(i=0;i<4;i++)        //判断格子上的数字是否有改的
    {
        for(j=0;j<4;j++)
        {
            if(oldnum[i][j]!=Gnum[i][j].num)
                flag=1;
        }
    }
    if(flag==1)     //有
    {
        i=rand()%4;     
        j=rand()%4;
        while(Gnum[i][j].num !=0)   //判断随机位置上是否有数字,没有则跳出
        {
            i=rand()%4;
            j=rand()%4;
        }
        Gnum[i][j].num=(rand()%2+1)*2;      //产生随机数 2 或 4

        //加分处理
        if(Score<200)
            Score+=2;
        if(Score<1000&&Score>=200)
            Score+=4;
        if(Score<3000&&Score>=1000)
            Score+=8;
        Paint();    //绘制
    }
    for(i=0;i<4;i++)    //更新oldnum数值
    {
        for(j=0;j<4;j++)
        {
            oldnum[i][j]=Gnum[i][j].num;    
            flag=0;

        }
    }
}
bool    Checkover()                         //检测是否结束
{
    for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            if(Gnum[i][j].num == 0)
                return false;
            if(j<3)
            {
                if((Gnum[i][j].num == Gnum[i][j+1].num))
                    return false;
            }

        if(i<3)
        {
            if((Gnum[i][j].num == Gnum[i+1][j].num))
                return false;
        }

        }
    }
    Sleep(200);
    return true;
}

bool Quit() // 询问用户是否退出游戏
{
    HWND hwnd = GetHWnd();
    return (MessageBox(hwnd, _T("您确定要退出游戏吗?"), _T("询问"), MB_OKCANCEL | MB_ICONQUESTION) == IDOK);
}

猜你喜欢

转载自blog.csdn.net/keilert/article/details/81670446