簡明目錄
寫在前面
所用素材若有侵權,聯繫我刪除。
素材和源碼在文末
另外,其實這是從我的一個大一點的項目中摘取出來的,儘管有所修改,但是難免有些問題,而且代碼非常繁瑣,沒有簡化,註釋也寫的不夠全面……
easyx庫
點擊這裏下載如下圖,點擊右上角黃色區域下載。
安裝:如下圖,安裝對應版本即可
準備工作
新建項目文件
新建文件的時候要注意,文件後綴使用.cpp而不是.c,因爲easyx庫的一些東西使用了C++,所以這樣最爲保險。
分析
我們先進行一定的分析,理一下思路。
void main()
{
//主函數
}
void set_map()
{
//地圖的初始化
}
int play()
{
//遊戲過程
}
int begin_menu()
{
//開始界面
}
int game_over()
{
//結束界面
}
素材分析
事實上,這個遊戲的實現就是通過調用不同的圖片來實現的。我收集了一些圖片:
上代碼吧
地圖表示
#include <graphics.h>//引用easyx庫
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
int map[6][6] = {{1,1,1,1,2,2},{2,2,5,5,2,2},{3,3,3,3,4,4},{5,5,6,6,6,6},{7,7,1,1,7,7},{8,8,4,4,8,8} };
我們用數組來表示地圖內容,數字分別代表圖片。
開始界面
int begin_menu()
{
initgraph(1152, 648);//界面繪製
IMAGE menu;//開始菜單圖片
loadimage(&menu, _T("begin_menu0.jpg"), 1152, 648);
IMAGE shuoming;//遊戲說明
loadimage(&shuoming, _T("begin_menu01.jpg"), 1152, 648);
putimage(0, 0, &menu);
MOUSEMSG mouse;
MOUSEMSG mouse2;
int x2, y2;
int x, y;
while (1)
{
mouse = GetMouseMsg();
if (mouse.uMsg == WM_LBUTTONDOWN)//左鍵按下
{
x = mouse.x;
y = mouse.y;//鼠標座標
if (x <= 635 && x >= 461 && y >= 185 && y <= 238)//開始遊戲
{
break;
}
else if (x <= 635 && x >= 461 && y >= 281 && y <= 330)//說明
{
cleardevice;
putimage(0, 0, &shuoming);
while (1)
{
mouse2 = GetMouseMsg();
if (mouse2.uMsg == WM_LBUTTONDOWN)
{
mouse2 = GetMouseMsg();
x2 = mouse2.x;
y2 = mouse2.y;
if (x2 <= 228 && x2 >= 52 && y2 >= 15 && y2 <= 65)//返回
{
putimage(0, 0, &menu);
break;
}
}
Sleep(10);
}
continue;
}
}
Sleep(10);
}
return 0;
closegraph();
}
地圖初始化(打亂)
void set_maps()
{
initgraph(800, 600);
setlinecolor(WHITE);
setfillcolor(BLACK);
fillrectangle(602, 1, 799, 599);
srand((unsigned int)time(NULL));//隨機數種子
for (int a = 0; a < 5; a++)//反覆打亂
{
for (int x = 0; x < 6; x++)
{
for (int y = 0; y < 6; y++)
{
int suijishu = rand() % 100;//產生隨機數
if (x == 0 && y == 0)
{
if (suijishu > 50)
{
chang_one(x, y, RIGHT)//和右邊數字交換
}
else
{
chang_one(x, y, DOWN);
}
}
//………………此處省略很多行
}
}
}
}
因爲涉及到邊角等塊的情況不同,所以我分類很多,而且用了隨機數來增加隨機性,所以分類就更多了。這裏爲了數字交換方便起見,我定義了一個change_one
函數,用於交換兩個數字。
void chang_one(int x, int y, int direction)
{
int t;
if (direction == RIGHT)
{
t = map[x][y];
map[x][y] = map[x][y + 1];
map[x][y + 1] = t;
}
else if (direction == DOWN)
{
t = map[x][y];
map[x][y] = map[x + 1][y];
map[x + 1][y] = t;
}
else if (direction == LEFT)
{
t = map[x][y];
map[x][y] = map[x][y - 1];
map[x][y - 1] = t;
}
else if (direction == UP)
{
t = map[x][y];
map[x][y] = map[x - 1][y];
map[x - 1][y] = t;
}
}
遊戲過程實現
int plays()
{
IMAGE imgs[10];//不同的圖片
loadimage(&imgs[0], _T("0.jpg"), 100, 100);
loadimage(&imgs[1], _T("1.jpg"), 100, 100);
loadimage(&imgs[2], _T("2.jpg"), 100, 100);
loadimage(&imgs[3], _T("3.jpg"), 100, 100);
loadimage(&imgs[4], _T("4.jpg"), 100, 100);
loadimage(&imgs[5], _T("5.jpg"), 100, 100);
loadimage(&imgs[6], _T("6.jpg"), 100, 100);
loadimage(&imgs[7], _T("7.jpg"), 100, 100);
loadimage(&imgs[8], _T("8.jpg"), 100, 100);
loadimage(&imgs[9], _T("yuanshi.jpg"), 100, 100);//背景圖
for (int x = 0; x < 6; x++)
{
for (int y = 0; y < 6; y++)
{
putimage(100 * y, 100 * x, &imgs[0]);//先放滿背景圖
Sleep(25);
}
}
MOUSEMSG mouse;
int x, y;//鼠標數組下標
int times = 0;
int t, x0 = -1, y0 = -1;
number_write(30, 650, 350, 0, WHITE);///自己定義的函數。用於書寫數字
while (1)
{
mouse = GetMouseMsg();
if (mouse.uMsg == WM_LBUTTONDOWN)
{
x = mouse.y / 100;
y = mouse.x / 100;
if (map[x][y] != 0 && mouse.x < 600)//防止點擊到右邊界面
{
if (((x0 != x) | (y0 != y)))//保證兩次點擊的不是同一張圖片
{
times++;
putimage(100 * y, 100 * x, &imgs[map[x][y]]);
}
if (times % 2 == 0)
{
if (map[x][y] != t)
{
Sleep(100);
putimage(100 * y0, 100 * x0, &imgs[0]);
putimage(100 * y, 100 * x, &imgs[0]);
t = -1;
x0 = -1;
y0 = -1;
}
else if (map[x][y] == t && ((x0 != x) | (y0 != y)))
{
Sleep(100);
putimage(100 * y0, 100 * x0, &imgs[9]);
putimage(100 * y, 100 * x, &imgs[9]);
map[x][y] = 0;
map[x0][y0] = 0;
jishuqi += 2;
}
}
else if (times % 2 == 1 && ((x0 != x) | (y0 != y)))
{
t = map[x][y];//記錄上一次點擊的數字
x0 = x;
y0 = y;
}
}
}
Sleep(2);
if (jishuqi == 36)//成功檢測
return SUCCESS;
}
}
主函數的實現
void main()
{
begin:begin_menu();
set_maps();
int result = plays();
int choice = game_over(result);
if (choice == 1)
{
closegraph();
initgraph(1152, 648);
goto begin;
}
system("pause");
}
測試
主界面大概就是這樣,下面看看遊戲界面,勉強湊活吧(太醜了)………………
優化
其實,上面的過程中有很多的問題沒有解決,下面優化一部分:
1、遊戲分數
遊戲的計分方式沒有設定,我就暫時先設定一下,
我的規則是下面這樣:
補充一點,遊戲最低分爲0分。
2、遊戲時間
我認爲遊戲應該是隨時顯示時間,並且不能無限玩下去吧??我就暫時先設置成60s吧……
3、number_write函數沒有給出
void number_write(int number_size, int x, int y, int number, COLORREF color)
{
TCHAR s[30];
_stprintf_s(s, _T("%d"), number);//需要先把數字進行轉換
settextstyle(number_size, 0, _T("黑體"));
settextcolor(color);
outtextxy(x, y, s);
}
4、遊戲結束函數
int game_over(int result)//1返回,0下一關
{
IMAGE over[2];
loadimage(&over[0], _T("success.jpg"), 500, 350);
loadimage(&over[1], _T("failed.jpg"), 500, 350);
if (result == 1)//遊戲成功
{
putimage(50, 125, &over[0]);
MOUSEMSG mouse;
int x, y;
while (1)
{
mouse = GetMouseMsg();
if (mouse.uMsg == WM_LBUTTONDOWN)
{
x = mouse.x;
y = mouse.y;
if (x >= 200 && x <= 304 && y >= 248 && y <= 286)//返回
{
return 1;
}
else if (x >= 383 && x <= 486 && y >= 248 && y <= 286)//下一關
{
return 0;
}
}
Sleep(10);
}
}
else//失敗
{
putimage(50, 125, &over[1]);
MOUSEMSG mouse1;
int x1, y1;
while (1)
{
mouse1 = GetMouseMsg();
if (mouse1.uMsg == WM_LBUTTONDOWN)
{
x1 = mouse1.x;
y1 = mouse1.y;
if (x1 >= 204 && x1 <= 412 && y1 >= 340 && y1 <= 405)//返回
{
return 1;
}
}
Sleep(10);
}
}
}
5、遊戲下一關的設定
這一塊由於時間倉促,暫時還沒有給出………………
6、遊戲重新進入
這裏有一個問題,如果退出以後,其實數組的值就已經改變了,,再次開始以後,不能初始化了??
這裏,我們做一個修改
int map1[6][6] = { {1,1,1,1,2,2},{2,2,5,5,2,2},{3,3,3,3,4,4},{5,5,6,6,6,6},{7,7,1,1,7,7},{8,8,4,4,8,8} };
//定義一個數組來記錄原來數組的值
void main()
{
……
if (choice == 1)
{
closegraph();
initgraph(1152, 648);
for (int x = 0; x < 6; x++)
{
for (int y = 0; y < 6; y++)
{
map[x][y] = map1[x][y];//數組值初始化
}
}
goto begin;
}
system("pause");
}
7、分數顯示
其實這裏有一個問題。文偉我的分數模式會導致分數上升以後還有下降可能,所以會有問題。
比如,我的分數是10分,但是後來又變成了9分,由於分數書寫時覆蓋原來數字的,所以,9(一位數)不能完全覆蓋10(兩位數),所以,就會呈現出90分的樣子……
所以,我的解決方法是用黑圖片覆蓋原來分數……
8、返回優化
如果遊戲中想要返回呢?我就增加一個返回按鈕吧。
******************初始化函數的一點修改
IMAGE back;
loadimage(&back, _T("back.jpg"), 160, 50);
putimage(620, 500, &back);
……………………^…………^……
……………………………………主函數一點修改
if (mouse.x >= 620 && mouse.x <= 780 && mouse.y >= 500 && mouse.y <= 550)
{
return FAIL;
}
else if (map[x][y] != 0 && mouse.x < 600)
…………………………………………
效果展示
遊戲效果展示
待優化部分
1、下一關的問題,大家自行解決吧,也不難……
2、背景音樂的問題,雖然這個不難,但是沒找到合適的素材,大家自己解決吧。
3、重點問題,
時間的問題,因爲循環中,如果你的鼠標沒有動作,那麼程序就停在那裏了????這咋辦??
源碼和素材
我放在微信公衆號後臺了。
點擊獲取…………