C語言實現(xiàn)推箱子小游戲
推箱子是一款非常經(jīng)典的游戲,我們一起來實現(xiàn)它吧!
一、要完成這個游戲,首先要知道實現(xiàn)那些功能,需要哪些知識點。
1.實現(xiàn)圖形的界面*
二維數(shù)組,初始化賦值,圖形庫貼圖
2.人物的移動
for循環(huán),switch,以及人物推動箱子等等一切邏輯的判斷!
人物往前走的時候,遇到的情況:
(1表示圍墻,0表示空地,2表示人,3表示目的地,4表示箱子,5表示箱子進入目的地,6表示人進入目的地)
①.人物面前是空地,人往前走,對人原本位置進行判斷,如果站在目的地就是3,如果站在空地就是0,進行賦值
②.人面前是站在空地上的箱子,再判斷箱子的面前是空地還是空的目的地,箱子往前走,人往前走,站在原本箱子呆的地方,人站在空地上,人原本的位置也要進行判斷,再賦值
③:人面前是空的目的地,人進入空目的地,對人原本的位置進行判斷,人可以站在空地也可以站在空的目的地上
④:人面前是進入目的地的箱子,判斷箱子的面前是什么,空地還是空目的地,箱子往前走,人進入箱子原本的位置,箱子離開了,人也就是進入空目的地,再判斷人原本的位置,進行賦值
3.游戲的勝利條件
判斷勝利的函數(shù),判斷失敗的條件
4.第一關勝利之后,會自動換關
5.播放音樂
6.悔棋功能:
*用另一個數(shù)組,保存我們?nèi)宋镆苿拥臅r候,還沒動的時候的位置,如果要悔棋,就替換呢元素
二、運行結(jié)果給大家看看


三、接下面來編寫代碼
/************************************************************************
* 項目名稱:推箱子
* 項目描述:按鍵操作
* 項目環(huán)境:VS2013
* 生成日期:2019-11-20
* 作者所屬:追夢
*************************************************************************/
#include<stdio.h>
#include<easyx.h>
#include<stdlib.h>
#include<conio.h>//_getch()函數(shù)的頭文件
#include<Windows.h>
#pragma comment(lib,"winmm.lib")//添加庫,音樂
int arr[3][10][10] =
{
{
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 4, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 2, 4, 3, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 4, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
{ 1, 3, 1, 0, 0, 0, 0, 0, 3, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
},
{
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 3, 0, 1, 0, 0, 0, 0, 3, 1 },
{ 1, 0, 0, 1, 0, 0, 4, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 4, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 2, 0, 1, 1, 1 },
{ 1, 4, 0, 1, 0, 0, 4, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 3, 0, 0, 0, 1 },
{ 1, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
{ 1, 3, 1, 0, 0, 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
},
{
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 3, 1, 0, 0, 0, 3, 0, 1 },
{ 1, 1, 0, 1, 0, 0, 0, 0, 0, 1 },
{ 1, 1, 0, 0, 0, 4, 0, 0, 0, 1 },
{ 1, 1, 0, 0, 4, 2, 4, 0, 0, 1 },
{ 1, 1, 1, 1, 0, 0, 4, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
{ 1, 3, 4, 0, 0, 3, 0, 0, 3, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
},
};//這個關卡難易程度自己改
int map[10][10];//游玩時候的地圖
int map1[10][10];//保存移動前的數(shù)組的值
IMAGE image[6];//圖片數(shù)組
int life = 0;//判斷游戲勝利
int level = 0;//第幾關
void drawMenu()
{
initgraph(640, 450);
setbkcolor(WHITE);
cleardevice();
setfillcolor(BLUE);
settextstyle(30, 0, "宋體");
setbkmode(TRANSPARENT);
fillrectangle(240, 100, 380, 150);
fillrectangle(240, 100 + 60, 380, 150 + 60);
outtextxy(240 + 13, 100 + 13, "開始游戲");
outtextxy(240 + 13, 100 + 13 + 60, "退出游戲");
settextcolor(RED);
outtextxy(130, 280, "追夢團隊拼圖游戲v1.2.0版本");
MOUSEMSG m;
while (1)
{
m = GetMouseMsg();
if (m.x >= 240 && m.x <= 380 && m.y >= 100 && m.y <= 150)
{
setlinecolor(BLACK);
rectangle(240 - 5, 100 - 5, 380 + 5, 150 + 5);
if (m.uMsg == WM_LBUTTONDOWN)
{
break;
}
}
else if (m.x >= 240 && m.x <= 380 && m.y >= 160 && m.y <= 210)
{
setlinecolor(BLACK);
rectangle(240 - 5, 160 - 5, 380 + 5, 210 + 5);
if (m.uMsg == WM_LBUTTONDOWN)
{
exit(0);
}
}
else
{
setlinecolor(WHITE);
rectangle(240 - 5, 100 - 5, 380 + 5, 150 + 5);
rectangle(240 - 5, 160 - 5, 380 + 5, 210 + 5);
}
}
closegraph();
}
//初始化地圖
void init()
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
map[i][j] = arr[level][i][j];
}
}
}
//貼圖
void drawmap()
{
BeginBatchDraw();//開始批量貼圖
putimage(0, 0, &image[0]);//貼背景
for (int i = 0; i < 10; i++)//for循環(huán)遍歷map地圖的所有元素進行貼圖
{
for (int j = 0; j < 10; j++)
{
switch (map[i][j])//判斷地圖元素進行對應的貼圖
{
case 1://墻的貼圖
putimage(50 * j, 50 * i, &image[1]);
putimage(0, 0, &image[1]);
break;
case 2://人的貼圖
putimage(50 * j, 50 * i, &image[2]);
break;
case 3://目的地的貼圖
putimage(50 * j, 50 * i, &image[3]);
break;
case 4://箱子的貼圖
putimage(50 * j, 50 * i, &image[4]);
break;
case 5://箱子進入目的地的貼圖
putimage(50 * j, 50 * i, &image[5]);
break;
case 6://人進入目的地的貼圖
putimage(50 * j, 50 * i, &image[2]);
break;
}
}
}
EndBatchDraw();//結(jié)束批量貼圖
}
//悔棋函數(shù)
void huiqi()//記錄還沒移動的時候,數(shù)組元素的值
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
map1[i][j] = map[i][j];
}
}
}
//移動
void play()
{
int i, j;//表示人在數(shù)組中的下標
for (int n = 0; n < 10; n++)//遍歷數(shù)組找人的位置
{
for (int m = 0; m < 10; m++)
{
if (map[n][m] == 2 || map[n][m] == 6)//找到了人
{
i = n;
j = m;
}
}
}
char key = _getch();//_getch()是字符按鍵接收,不會回顯到控制臺
switch (key)//判斷按鍵
{
case'r':case'R'://回撤一步
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
map[i][j] = map1[i][j];
}
}
break;
case'w':case'W'://區(qū)分大小寫
huiqi();//保存還沒移動前的數(shù)據(jù)
if (map[i - 1][j] == 0)//如果人面前是空地
{
map[i - 1][j] = 2;//人往前走
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i - 1][j] == 3)//人面前是空的目的地
{
map[i - 1][j] = 6;//人站在目的地里面
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i - 1][j] == 4)//人得面前是空地上的箱子
{
if (map[i - 2][j] == 0)//箱子的面前是空地
{
map[i - 2][j] = 4;//箱子推到空地上
map[i - 1][j] = 2;//人站在箱子原本的位置上
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i - 2][j] == 3)//箱子的前面是空的目的地
{
map[i - 2][j] = 5;//箱子推進目的地里
map[i - 1][j] = 2;//人進入原本箱子的位置
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
}
else if (map[i - 1][j] == 5)//人的面前是站在目的地的箱子
{
if (map[i - 2][j] == 0)//箱子的面前是空地
{
map[i - 2][j] = 4;//箱子推到空地上
map[i - 1][j] = 6;//人站在目的地上了
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i - 2][j] == 3)//箱子的面前是空的目的地
{
map[i - 2][j] = 5;//箱子推到目的地
map[i - 1][j] = 6;
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
}
break;
case's':case'S':
huiqi();//保存還沒移動前的數(shù)據(jù)
if (map[i + 1][j] == 0)//如果人面前是空地
{
map[i + 1][j] = 2;//人往前走
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i + 1][j] == 3)//人面前是空的目的地
{
map[i + 1][j] = 6;//人站在目的地里面
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i + 1][j] == 4)//人得面前是空地上的箱子
{
if (map[i + 2][j] == 0)//箱子的面前是空地
{
map[i + 2][j] = 4;//箱子推到空地上
map[i + 1][j] = 2;//人站在箱子原本的位置上
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i + 2][j] == 3)//箱子的前面是空的目的地
{
map[i + 2][j] = 5;//箱子推進目的地里
map[i + 1][j] = 2;
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
}
else if (map[i + 1][j] == 5)//人的面前是站在目的地的箱子
{
if (map[i + 2][j] == 0)//箱子的面前是空地
{
map[i + 2][j] = 4;//箱子推到空地上
map[i + 1][j] = 6;//人站在目的地上了
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i + 2][j] == 3)//箱子的面前是空的目的地
{
map[i + 2][j] = 5;//箱子推到目的地
map[i + 1][j] = 6;
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
}
break;
case'a':case'A':
huiqi();//保存還沒移動前的數(shù)據(jù)
if (map[i][j - 1] == 0)//如果人面前是空地
{
map[i][j - 1] = 2;//人往前走
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i][j - 1] == 3)//人面前是空的目的地
{
map[i][j - 1] = 6;//人站在目的地里面
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i][j - 1] == 4)//人得面前是空地上的箱子
{
if (map[i][j - 2] == 0)//箱子的面前是空地
{
map[i][j - 2] = 4;//箱子推到空地上
map[i][j - 1] = 2;//人站在箱子原本的位置上
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i][j - 2] == 3)//箱子的前面是空的目的地
{
map[i][j - 2] = 5;//箱子推進目的地里
map[i][j - 1] = 2;
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
}
else if (map[i][j - 1] == 5)//人的面前是站在目的地的箱子
{
if (map[i][j - 2] == 0)//箱子的面前是空地
{
map[i][j - 2] = 4;//箱子推到空地上
map[i][j - 1] = 6;//人站在目的地上了
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i][j - 2] == 3)//箱子的面前是空的目的地
{
map[i][j - 2] = 5;//箱子推到目的地
map[i][j - 1] = 6;
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
}
break;
case'd':case'D':
huiqi();//保存還沒移動前的數(shù)據(jù)
if (map[i][j + 1] == 0)//如果人面前是空地
{
map[i][j + 1] = 2;//人往前走
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i][j + 1] == 3)//人面前是空的目的地
{
map[i][j + 1] = 6;//人站在目的地里面
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i][j + 1] == 4)//人得面前是空地上的箱子
{
if (map[i][j + 2] == 0)//箱子的面前是空地
{
map[i][j + 2] = 4;//箱子推到空地上
map[i][j + 1] = 2;//人站在箱子原本的位置上
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i][j + 2] == 3)//箱子的前面是空的目的地
{
map[i][j + 2] = 5;//箱子推進目的地里
map[i][j + 1] = 2;
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
}
else if (map[i][j + 1] == 5)//人的面前是站在目的地的箱子
{
if (map[i][j + 2] == 0)//箱子的面前是空地
{
map[i][j + 2] = 4;//箱子推到空地上
map[i][j + 1] = 6;//人站在目的地上了
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
else if (map[i][j + 2] == 3)//箱子的面前是空的目的地
{
map[i][j + 2] = 5;//箱子推到目的地
map[i][j + 1] = 6;
//對人本身進行判斷
if (map[i][j] == 6)//如果人本身是站在目的地里
map[i][j] = 3;//恢復成空目的地
else//人站在空地
map[i][j] = 0;//恢復成空地
}
}
break;
}
}
//判斷游戲勝利
void win()
{
int number = 0;//假設所有的箱子都進入了目的地,地圖上就沒有了箱子,number用來表示站在空地上的箱子的數(shù)量
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (map[i][j] == 4)//說明空地上還有箱子
number++;
}
}
for (int i = 0; i < 10; i++)//判斷游戲失敗
{
for (int j = 0; j < 10; j++)
{
if (map[i][j] == 4)//對某個箱子進行判斷
{
if (map[i - 1][j] == 1 || map[i + 1][j] == 1)//判斷上下是否有一個是圍墻
{
if (map[i][j - 1] == 1 || map[i][j + 1] == 1)
//判斷左右是否有一個是圍墻
{
life = 2;//游戲失敗
}
}
}
}
}
if (number == 0)//如果地圖上站在空地上的箱子數(shù)為0
life = 1;//表示游戲勝利
}
int main()
{
drawMenu();
initgraph(500, 500);//初始化圖形環(huán)境
loadimage(&image[0], "背景.PNG", 500, 500);//加載背景圖片
loadimage(&image[1], "墻.PNG", 50, 50);//墻
loadimage(&image[2], "推人.PNG", 50, 50);//人
loadimage(&image[3], "目的地.PNG", 50, 50);//目的地
loadimage(&image[4], "箱子.png", 50, 50);//箱子
loadimage(&image[5], "箱子和目的地重合.PNG", 50, 50);//箱子和目的地重合
init();//初始化地圖
drawmap();//給地圖元素貼圖
mciSendString("open attheage.mp3", 0, 0, 0);//打開
mciSendString("play attheage.mp3", 0, 0, 0);//播放
//Sleep(5000);//延遲五秒
//mciSendString("stop attheage.mp3", 0, 0, 0);//停止
while (1)
{
play();//移動一次
drawmap();//貼一次圖
win();//判斷游戲是否勝利
if (life == 1)//游戲勝利
{
if (MessageBox(GetHWnd(), "游戲勝利!", "是否要繼續(xù)游戲?", MB_YESNO) == IDYES)//彈窗,按下'是',進入if語句
{
life = 0;//下次循環(huán)不會進入if語句
level++;//關卡+1
if (level == 3)//說明第三關結(jié)束了
{
if (MessageBox(GetHWnd(), "最后一關!", "是否要回到第一關!", MB_YESNO) == IDYES)//按下'是',進入if語句,回到第一關
{
level = 0;
}
else return 0;
}
init();//重新初始化
drawmap();//貼圖
}
else return 0;//按下'否',退出程序
}
if (life == 2)//游戲失敗
{
life = 0;
if (MessageBox(GetHWnd(), "游戲失敗!", "是否重新開始本關卡", MB_YESNO) == IDYES)//按下'是',重新開始游戲
{
init();
drawmap();
}
}
}
system("pause");
closegraph();//關閉圖形庫
return 0;
}
主要還是人物的移動判斷,弄清楚一個方向之后,其他的方向只需要稍微修改一下即可。這是我19年11月份寫的,存在一些問題,不過我改了。有錯誤就有進步,希望大家可以指點一下,謝謝您們!
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
C/C++?Qt?TabWidget?實現(xiàn)多窗體創(chuàng)建詳解
TabWidget組件配合自定義Dialog組件,可實現(xiàn)一個復雜的多窗體分頁結(jié)構(gòu)。這篇文章就主要介紹了如何通過TabWidget實現(xiàn)多窗體的創(chuàng)建,感興趣的小伙伴可以了解一下2021-12-12
C++?move()函數(shù)及priority_queue隊列使用記錄
move(obj)函數(shù)的功能是把obj當做右值處理,可以應用在對象的移動上,這篇文章主要介紹了C++?move()函數(shù)及priority_queue隊列使用記錄,需要的朋友可以參考下2023-01-01
C++ std::make_unique和std::make_shared用法小結(jié)
本文主要介紹了C++ std::make_unique和std::make_shared用法,使用std::make_unique和std::make_shared能夠簡化動態(tài)分配內(nèi)存和構(gòu)造對象的過程,提高代碼的安全性和可讀性,感興趣的可以了解一下2023-11-11
詳解C++的靜態(tài)內(nèi)存分配與動態(tài)內(nèi)存分配
內(nèi)存分配 (Memory Allocation) 是指為計算機程序或服務分配物理內(nèi)存空間或虛擬內(nèi)存空間的一個過程,本文主要介紹了C++的靜態(tài)內(nèi)存分配與動態(tài)內(nèi)存分配,感興趣的同學可以參考閱讀2023-06-06
C語言堆與二叉樹的順序結(jié)構(gòu)與實現(xiàn)
堆是計算機科學中一類特殊的數(shù)據(jù)結(jié)構(gòu)的統(tǒng)稱,通常是一個可以被看做一棵完全二叉樹的數(shù)組對象。而堆排序是利用堆這種數(shù)據(jù)結(jié)構(gòu)所設計的一種排序算法。本文將詳細介紹堆與二叉樹的順序結(jié)構(gòu)與實現(xiàn),需要的可以參考一下2022-05-05

