欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

2048纯手工制作

程序员文章站 2022-04-07 19:13:24
...

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

2048纯手工制作
2048纯手工制作
工程代码:
/*
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);
}
相关标签: easyx