一、预备知识
1.使用EasyX必须要知道的一些基础函数
2.选择结构 if , switch
3.循环结构 for, while
4.多维数组 arr1[N], arr2[N][N] , arr3[N][N][N]
5.函数封装
二、游戏逻辑
想要写出推箱子,首先要知道推箱子游戏都有哪些元素和规则
1.五子棋元素
1.棋盘 2.黑子 3.白子
有了素材,先来一个加载资源函数Loadimg()
#define SIZE 30
#define BOARD 610
IMAGE img[3];//存放图片
void Loadimg()
{
loadimage(&img[0],L"./images/0.jpg",BOARD,BOARD);
loadimage(&img[1],L"./images/1.jpg",SIZE,SIZE);
loadimage(&img[2],L"./images/2.jpg",SIZE,SIZE);
}
2.五子棋规则
1.黑子先行,黑白交替落子
2.首先连成五个子 (包括横着 竖着 和 斜着) 的一方获胜
3.棋盘下满未分出胜负则平局
三、游戏设计
知道游戏元素和规则就可以开始设计游戏了
1.地图设计
地图用二维数组表示,棋盘初始化全为0,用1来代表黑子,2来代表白子,写一个绘制地图函数Drawmap()
#define NUM 19
int map[NUM][NUM]={0};
void Drawmap()
{
for(int i=0;i<NUM;i++)
{
for(int j=0;j<NUM;j++)
{
if(map[i][j]==1)
putimage(4+i*32,4+j*32,&img[1]);
if(map[i][j]==2)
putimage(4+i*32,4+j*32,&img[2]);
}
}
}
2.点击设计
上文提到
1.黑子先行,黑白交替落子
定义两个全局变量black和white,记录当前子的数目,如果一样,则下黑子,如果黑子多,则下白子
int black=0,white=0;//棋盘上黑子数和白子数
int ipos,jpos;//鼠标位置
ExMessage m;//消息全局变量
void Hitboard()
{
m = getmessage(EM_MOUSE);//得到鼠标消息
if(m.message == WM_LBUTTONDOWN)
{//如果鼠标左键按下
ipos=(m.x-4)/32;//换算鼠标位置
jpos=(m.y-4)/32;
if(map[ipos][jpos]==0 && black==white)
{//如果点的地方没子,且黑子和白子一样多
map[ipos][jpos]=1;
black++;//下黑子
}
else if(map[ipos][jpos]==0 && black>white)
{//如果点的地方没子,且黑子比白子多
map[ipos][jpos]=2;
white++;//下白子
}
}
}
3.结束设计
上文提到
2.首先连成五个子 (包括横着 竖着 和 斜着) 的一方获胜
3.棋盘下满未分出胜负则平局
由于黑子和白子对于判断胜负来说是等效的,写一个带参函数,来根据参数a不同,判断黑白子的获胜情况,参数a=1时,判断黑子,a=2时,判断白子
int Gameover(int a)
{
for(int i=0;i<NUM;i++)
{
for(int j=0;j<NUM;j++)//注意避免数组越界
{
if(j+4<NUM && map[i][j]==a && map[i][j+1]==a && map[i][j+2]==a && map[i][j+3]==a && map[i][j+4]==a)
return 1;//判断一行是否有五连子
else if(i+4<NUM && map[i][j]==a && map[i+1][j]==a && map[i+2][j]==a && map[i+3][j]==a && map[i+4][j]==a)
return 1;//判断一列是否有五连子
else if(i+4<NUM && j+4<NUM && map[i][j]==a && map[i+1][j+1]==a && map[i+2][j+2]==a && map[i+3][j+3]==a && map[i+4][j+4]==a)
return 1;//判断右下是否有五连子
else if(i+4<NUM && j+4<NUM && map[i+4][j]==a && map[i+3][j+1]==a && map[i+2][j+2]==a && map[i+1][j+3]==a && map[i][j+4]==a)
return 1;//判断左下是否有五连子
}
}
return 0;//没有五连子
}
再写一个判断平局的函数Tie()
int Tie()
{//判断是否平局
for(int i=0;i<NUM;i++)
{
for(int j=0;j<NUM;j++)
{
if(map[i][j]==0)//如果地图上还有空格
return 0;
}
}
return 1;//地图上没空格
}
4.整体设计
下面把上面的函数组合起来就是推箱子游戏,再来点音乐
#include<easyx.h>//图形库
#include<mmsystem.h>//音乐
#pragma comment(lib,"winmm.lib")//库文件
int main()
{
initgraph(BOARD,BOARD);//创建窗口
Loadimg(); //加载图片资源
putimage(0,0,&img[0]);//显示棋盘
//循环播放背景音乐
mciSendString(L"open ./images/bg.mp3 ", 0, 0, 0);
mciSendString(_T("play ./images/bg.mp3 repeat"), 0, 0, 0);
while(true){
Hitboard();//落子
Drawmap();//更新地图
if(Gameover(1))
{//判断黑子是否获胜
PlaySound(L"./images/success.wav", nullptr, SND_FILENAME | SND_ASYNC);
MessageBox(NULL,_T("黑子获胜!"),_T("游戏提示"),MB_OK | MB_SYSTEMMODAL) ;
break;
}
if(Gameover(2))
{//判断白子是否获胜
PlaySound(L"./images/success.wav", nullptr, SND_FILENAME | SND_ASYNC);
MessageBox(NULL,_T("白子获胜!"),_T("游戏提示"),MB_OK | MB_SYSTEMMODAL) ;
break;
}
if(Tie())
{//如果游戏平局
PlaySound(L"./images/over.wav", nullptr, SND_FILENAME | SND_ASYNC);
MessageBox(NULL,_T("平局,旗鼓相当的对手!"),_T("游戏提示"),MB_OK | MB_SYSTEMMODAL) ;
break;
}
}
system("pause");
return 0;
}
把上面所有代码复制到一个cpp文件里,再把素材改好命名放到images文件夹里,images文件夹在cpp文件旁边,就可以编译运行了!