C語言 風靡一時的黃金礦工遊戲實現流程詳解
遊戲的玩法主要是通過不斷采集地下的黃金和鉆石,來得到更高的積分。隻有完成任務目標,才可以通過相應的關卡。遊戲畫面中沙灘上的人物便是玩傢的角色,下方深褐色的部分是地下,而黃金和鉆石就是玩傢需要采集的物品。人物右邊的四個方框裡的物品是遊戲中可以使用的道具。 畫面中的虛線就是遊戲中的探測器,探測器會不斷的左右擺動,當擺動到地下的黃金和鉆石的位置時,隻需要點擊礦坑任意處,便可以發射勘探頭采集到這些物品,當然一定要瞄準好再出手呦。
當然想要順利采集到豐富的資源也不是那麼簡單的,地下礦坑中,會有各式各樣的困難和阻礙來幹擾玩傢的采集,這時我們就要用到人物右邊的各種道具瞭,當礦坑中采集到石塊的時候,玩傢可以使用炸藥棒來炸毀這些石塊。當礦坑中有大量石塊阻礙玩傢的采集時,這時就可以用炸彈來拖拽到礦坑中石塊群的位置,會一次性炸毀所有礙事的石塊。當礦坑中煙霧桶被引爆後,看不清地下情況的時候,我們可以使用電風扇,它會把所有的煙霧都吹散,讓玩傢可以清楚的徹底看清礦坑的分佈。礦坑中不時也會有小老鼠來搗亂,不用擔心,我們有老鼠藥來對付這些小東西,隻要把老鼠藥拖拽到老鼠所在的位置,就會瞬間消滅這些小麻煩,讓玩傢更順利的采集到想要得到的資源。 緊張刺激的對戰,輕松有趣的玩法,豐富多樣的道具,還有精美細致的畫面,這就是我們今天要完成的項目《黃金礦工》
在此之前呢,和大傢說明一下,因為這是一個比較大的項目瞭,所以展示所有代碼會有些困難,從中還要數據庫的參與,所以我裁剪瞭主要部分的代碼,主要目的的讓大傢明白實現這個項目的難點以及邏輯思路,希望大傢可以理解
好瞭,話不多說,開始瞭
首先我們先創建一個頭文件,把一些結構體以及枚舉類型的函數放進去,這樣會讓整個項目看起來更加有序,更好理解,先把枚舉類型放進去
enum ATTR { //圖片對應的數組下標 i_gold=1, i_money=3, i_role=5, i_stone=9, i_bk= i_stone+1, //窗口尺寸 WIDTH = 1080, HEIGHT= 640, //物品數量 MINE_NUM=10, }; enum TYPE { //物品類型 GOLD, //金塊 MONEY, //錢袋 STONE, //石頭 //擺動方向 LEFT, RIGHT, //擺動狀態 M_LONG, M_NORMAL, M_SHORT, };
之後把我們的老朋友結構體也放進去
struct Role { int x; //貼圖的位置 int y; int width;//圖片寬度和高度 int height; int coin;//金幣 }; struct Mine //物品 { int x; int y; int size;//用來計算碰撞 int flag;//物品是否存在 int type;//物品類型,錢袋,石頭,金塊 int gold;//價值 }; //鉤子 struct Hook { double x;//繩子開始坐標,固定不變的 double y; double endx;//末端變化的坐標 double endy; int len;//繩子長度 int dir;//擺動方向 double angle;//擺動角度 double speed;//速度 double vx;//速度分量 double vy; int swing;//是否在擺動 int state;//伸長狀態,伸長,正常,縮短 int index;//抓到的物品下標 };
OK,接下來就是我們的主要函數main.Cpp瞭,記得開始的時候加上我們寫的頭文件,先寫初始化函數
void GameInit() { //初始化隨機數種子 srand(GetTickCount()); //初始化角色數據 role.coin = 0; role.width = 140; role.height = 120; role.x = WIDTH / 2 - role.width / 2;//讓角色圖片居中顯示 role.y = 0; //加載圖片 for (int i = 0; i < 10; i++) { char fileName[20]; sprintf(fileName, "./images/%d.jpg", i); if (i <= 1) { loadimage(&img[i], fileName,73,62); } else { loadimage(&img[i], fileName); } } loadimage(&img[i_bk], "./images/bk.jpg",WIDTH,HEIGHT-role.height); //初始化物品 for (int i = 0; i < MINE_NUM; i++) { mine[i].flag = 1; mine[i].size = 60; mine[i].type = rand() % 3; mine[i].x=rand()%(WIDTH-mine[i].size); mine[i].y=rand()%(HEIGHT-role.height-100)+ role.height+ 50; mine[i].gold = rand()%600+rand()%200; } //初始化鉤子 hook.x = role.x+45; hook.y = role.y+100; hook.len = 50; hook.endx = hook.x; hook.endy=hook.y+hook.len; hook.angle = 0.0; hook.dir = RIGHT; hook.state = M_NORMAL; hook.vx = 0; hook.vy = 0; hook.speed = 5.0; hook.index = -1; }
再寫我們的繪制函數,這個比較簡單,就是貼圖
void Gamedraw() { BeginBatchDraw(); //設置背景顏色 setbkcolor(GREEN); cleardevice(); putimage(0, role.height, &img[i_bk]); //透明貼圖 兩張圖片,一張掩碼圖,一張原圖 putimage(role.x, role.y, &img[i_role-1],SRCAND);//掩碼圖 putimage(role.x, role.y, &img[i_role],SRCPAINT);//原圖 //繪制鉤子 setlinestyle(PS_SOLID, 5); setlinecolor(BROWN); line(hook.x, hook.y, hook.endx, hook.endy); //繪制物品 for (int i = 0; i < MINE_NUM; i++) { if (mine[i].flag) { switch (mine[i].type) { case GOLD: putimage(mine[i].x, mine[i].y, &img[i_gold-1],SRCAND); putimage(mine[i].x, mine[i].y, &img[i_gold],SRCPAINT); break; case MONEY: putimage(mine[i].x, mine[i].y, &img[i_money-1], SRCAND); putimage(mine[i].x, mine[i].y, &img[i_money], SRCPAINT); break; case STONE: putimage(mine[i].x, mine[i].y, &img[i_stone-1], SRCAND); putimage(mine[i].x, mine[i].y, &img[i_stone], SRCPAINT); break; } } } //繪制分數 char s[30]; sprintf(s, "金幣:%d", role.coin); settextstyle(50, 0, "黑體"); outtextxy(50, 50, s); EndBatchDraw(); }
鉤子擺動的函數,鉤子該如何的擺,主要是讓他不要往天上擺就行
//鉤子擺動 void hookRock() { if (hook.state == M_NORMAL) { if (hook.dir == RIGHT) { hook.angle++; } else { hook.angle--; } if (hook.angle > 80) { hook.dir = LEFT; } else if (hook.angle < -80) { hook.dir = RIGHT; } hook.endx = hook.x + sin(π / 180 * hook.angle) * hook.len; hook.endy = hook.y + cos(π / 180 * hook.angle) * hook.len; } } int distance(struct Hook hook) { double dis=sqrt((hook.x-hook.endx)* (hook.x - hook.endx) + (hook.y-hook.endy) * (hook.y - hook.endy)); return dis <= hook.len; } void keyControl() { //按空格伸長 if (GetAsyncKeyState(VK_SPACE) && hook.state == M_NORMAL) { hook.state = M_LONG; hook.vx = sin(π / 180 * hook.angle) * hook.speed; hook.vy = cos(π / 180 * hook.angle) * hook.speed; } if (hook.endx <= 0 || hook.endx >= WIDTH || hook.endy >= HEIGHT) { hook.state = M_SHORT; } if (hook.state == M_LONG) { hook.endx += hook.vx; hook.endy += hook.vy; } else if (hook.state == M_SHORT) { hook.endx -= hook.vx; hook.endy -= hook.vy; //如果縮短到原來的長度,就停止縮短,判斷起點和末端的距離是否等於,長度 if (distance(hook)) { hook.state = M_NORMAL; } } }
接下來是我們的抓取函數,也是比較簡單
void grap() { //找到抓取的是哪個物品 for (int i = 0; i < MINE_NUM; i++) { if (mine[i].flag && hook.endx > mine[i].x && hook.endx<mine[i].x + mine[i].size && hook.endy>mine[i].y && hook.endy < mine[i].y + mine[i].size) { hook.index = i;//保存抓到的物品的下標 break; } } if (hook.index != -1) { hook.state = M_SHORT; mine[hook.index].x = hook.endx-mine[hook.index].size/2; mine[hook.index].y = hook.endy- mine[hook.index].size / 2; if (distance(hook)) { hook.state = M_NORMAL; mine[hook.index].flag = 0; role.coin += mine[hook.index].gold; hook.state = M_NORMAL; hook.index = -1; } } }
最後是我們的主函數
int main() { initgraph(WIDTH,HEIGHT,1); GameInit(); while (1) { printf("%lf,%lf vxy(%lf,%lf)\n", hook.endx, hook.endy,hook.vx,hook.vy); hookRock(); Gamedraw(); keyControl(); grap(); } closegraph(); return 0; }
這就是我們《黃金礦工》的主要代碼瞭,有人會問瞭,好像也不多呀,從代碼上看確實還好,但這個項目牽扯的東西有點多,包括數據庫,考慮到有些同學看不懂我就不放在這裡瞭,有興趣的同學可以進去領取源碼之後自己學習,最後想說的是,寫遊戲項目其實還好,主要是理清初始化函數以及更新函數,包裝起來就很好理解瞭,好啦,希望大傢可以在這裡得到自己想要的知識以及快樂吧,也希望大傢可以給UP主一個關註,非常感謝大傢瞭!!!
到此這篇關於C語言 風靡一時的黃金礦工遊戲實現流程詳解的文章就介紹到這瞭,更多相關C語言 黃金礦工內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!