1.引言
這篇文章主要為大家詳細介紹了C語言實現(xiàn)——《球球大作戰(zhàn)項目》,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
游戲介紹:
這是一個大球吃小球的世界,玩家的目標是要努力吃成最大的球球。在游戲一開始,玩家出現(xiàn)在地圖上隨機位置,地圖里灑滿了小彩豆,玩家吃掉小彩豆體積就會增大,當(dāng)增大到比別人的球大時,就可以吃別人的球啦,當(dāng)然也得躲避更大的球。小球速度快,大球速度慢。球球到達一定重量后,可以分身,一個球變成等大的兩個球,可以再次分身,但是最多可以擁有16個分身。
效果圖展示
2.游戲設(shè)計:概述游戲的玩法和操作方式。
1.操作方式:
使用鍵盤控制球體的移動,如W、A、S、D 或者 上、下、左、右方向鍵。
2.玩法:
玩家控制的球體通過鍵盤控制進行移動,可以朝不同的方向移動以吞噬其他球體。
球體可以通過碰撞來吞噬其他較小的球體,從而增大自己的體積。
3.游戲?qū)崿F(xiàn)
此處包含需要用到的頭文件,一些聲明和定義 聲明一個結(jié)構(gòu)體可以讓食物,玩家和ai玩家用,避免重復(fù)的定義。
#include<stdio.h>
#include<easyx.h>//包含圖形庫頭文件
#include<stdlib.h>
#include<time.h>
#include<math.h>
#define FOOD_NUM 200 //食物數(shù)量
#define WIDTH 1024
#define HEIGHT 640
#define HEIFGT 10
#define AI_NUM 10//人工智障數(shù)量
/*
做游戲:1.窗口,畫圖,貼圖。。。。。easyx圖形庫的
食物:圓(圓心坐標,半徑,顏色,是否存在的標志)
*/
并且要明確要定義的對象
如下
struct Ball//小球結(jié)構(gòu),玩家,食物,人工智障
{
int x;
int y;
int r;//半徑
DWORD color;//顏色
bool flag;//是否存在
};
struct Ball food[FOOD_NUM];
struct Ball player;//玩家
struct Ball ai[AI_NUM];
(1)函數(shù) GameInit() 初始化游戲的函數(shù)。
1.設(shè)置隨機數(shù)種子:通過調(diào)用 srand((unsigned)time(NULL)),將隨機數(shù)種子設(shè)置為當(dāng)前時間的秒數(shù),以確保每次游戲運行時生成的隨機數(shù)序列是不同的。
2.初始化食物數(shù)據(jù):通過循環(huán)遍歷每個食物球體,為每個食物設(shè)置隨機的位置、半徑、顏色,并將存在標志 flag 設(shè)置為 true,表示初始狀態(tài)下食物存在。
3.初始化玩家數(shù)據(jù):生成玩家球體的初始位置、半徑、顏色,并將存在標志 flag 設(shè)置為 true。
4.初始化人工智能角色(AI)數(shù)據(jù):通過循環(huán)遍歷每個 AI 角色,為每個角色設(shè)置隨機的位置、半徑和顏色,并將存在標志 flag 設(shè)置為 true。
void GameInit()
{
//設(shè)置隨機數(shù)種子,時間是在不斷變化的
srand((unsigned)time(NULL));
for (int i = 0;i < FOOD_NUM; ++i)
{
food[i].x = rand() % WIDTH;
food[i].y = rand() % HEIGHT;
food[i].flag = true;//剛開始食物存在
food[i].r = rand() % 6 + 1;
food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
}
//初始化玩家數(shù)據(jù)
player.x = rand() & WIDTH+1;
player.y = rand() % HEIGHT+1;
player.r = 18;//只要比食物大就可以
player.flag = true;
player.color= RGB(rand() % 256, rand() % 256, rand() % 256);
//初始化ai
for (int i = 0; i < AI_NUM; ++i)
{
ai[i].x = rand() % WIDTH;
ai[i].y = rand() % HEIGHT;
ai[i].r = rand() % 10 + 5;
ai[i].flag = true;
ai[i].color= RGB(rand() % 256, rand() % 256, rand() % 256);
}
}
(2)函數(shù) GameDraw() 用于繪制游戲場景的函數(shù)。
BeginBatchDraw() 函數(shù)開始繪制,這可以避免屏幕閃爍。
setbkcolor(WHITE) 設(shè)置背景色為白色。
cleardevice() 清空屏幕,將整個屏幕顏色填充為背景色。
循環(huán)遍歷每個食物球體(FOOD_NUM 個),進行繪制。
如果 food[i].flag 為真,表示食物存在,則根據(jù) food[i] 的坐標和半徑,繪制一個填充圓,顏色為 food[i].color。
否則,表示食物已經(jīng)消失,在隨機位置重新生成一個食物。
void GameDraw()
{
//防止閃屏
BeginBatchDraw();
setbkcolor(WHITE);
cleardevice();//清屏
for (int i = 0; i < FOOD_NUM; ++i)
{
if (food[i].flag)
{
setfillcolor(food[i].color);//設(shè)置填充顏色
solidcircle(food[i].x, food[i].y,food[i].r);//畫一個填充圓
}
else
{
food[i].x = rand() % WIDTH;
food[i].y = rand() % HEIGHT;
food[i].flag = true;//剛開始食物存在
food[i].r = rand() % 6 + 1;
food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
}
}
繪制玩家球體:
設(shè)置填充顏色為 player.color。
根據(jù)玩家的坐標和半徑,繪制一個填充圓。
設(shè)置文本顏色為綠色。
設(shè)置文本樣式為大小為 30、字體為黑體。
設(shè)置文字背景為透明。
輸出文字在玩家球體的位置上。
//繪制玩家
setfillcolor(player.color);//設(shè)置填充顏色
solidcircle(player.x, player.y, player.r);
settextcolor(GREEN);
settextstyle(30, 0, L"黑體");
setbkmode(0);//設(shè)置文字背景透明
outtextxy(player.x-50, player.y, L"我是最靚的崽仔");
EndBatchDraw();
//繪制ai
for (int i = 0; i < AI_NUM;++i)
{
if (ai[i].flag)
{
setfillcolor(ai[i].color);
solidcircle(ai[i].x, ai[i].y, ai[i].r);
}
}
}
(3)函數(shù) keyControl(int speed) 負責(zé)處理鍵盤控制玩家球體移動
1.GetAsyncKeyState() 函數(shù)用于獲取鍵盤消息,判斷是否按下了特定的鍵。
2.鍵盤控制包括上、下、左、右四個方向鍵。根據(jù)按下的鍵,判斷移動的方向并更新玩家球體的位置。
3.如果按下了 ‘W’ 鍵或者上方向鍵 (VK_UP),并且玩家球體的 y 坐標大于等于 0,則向上移動,即 player.y -= speed。
其他位置都如上
4.根據(jù)按鍵的狀態(tài)和邊界限制,函數(shù)根據(jù)移動速度 speed 更新玩家球體的 函數(shù)
void keyControl(int speed)
{
//獲取鍵盤消息,按的是哪一個鍵
if ((GetAsyncKeyState('W') || GetAsyncKeyState(VK_UP))&&player.y>=0)//按了上鍵
{
player.y -= speed;
}
if ((GetAsyncKeyState('S') || GetAsyncKeyState(VK_DOWN))&& player.y<=HEIGHT)//按了下鍵
{
player.y += speed;
}
if ((GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT))&& player.x >= 0)//按了左鍵
{
player.x -= speed;
}
if ((GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT))&& player.x<=WIDTH)//按了右鍵
{
player.x += speed;
}
}
特別注意邊界,不能越界
(4)函數(shù) eatFood() 負責(zé)處理玩家吃食物
函數(shù)通過遍歷所有的食物球體,檢查玩家球體是否和食物重疊,并進行吃食物的操作。
對于每一個食物球體:
如果食物存在(food[i].flag 為真)且食物球體和玩家球體的距離小于等于玩家球體的半徑 player.r,則表示玩家球體吃到了該食物。
吃到食物后,將食物的存在標志 food[i].flag 設(shè)置為假,表示食物消失。
將玩家球體的半徑 player.r 增加吃到食物球體半徑 food[i].r 的1/4,以增加玩家球體的大小。
其中為判斷是否被吃,也就是距離問題,需要引入求距離函數(shù)
double distance(struct Ball a, struct Ball b)
{
return sqrt((double)(a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
玩家吃食物
void eatFood()
{
for (int i = 0; i < FOOD_NUM; ++i)
{
if (food[i].flag && distance(food[i], player) <= player.r)
{
food[i].flag = false;
player.r += food[i].r / 4;
}
}
}
(5)函數(shù) aiMove() 是用于AI角色移動
1.對于每個AI角色(AI_NUM 個):
2.如果AI角色存在(ai[i].flag 為真),則分別生成隨機的X軸和Y軸偏移量。
3.X軸偏移量通過 rand() % 5 - 2 生成一個介于-2到2之間的隨機數(shù)。
4.Y軸偏移量同樣通過 rand() % 5 - 2 生成一個介于-2到2之間的隨機數(shù)。
5.將隨機生成的偏移量加到AI角色的當(dāng)前位置上,實現(xiàn)隨機移動的效果。
void aiMove()
{
for (int i = 0; i < AI_NUM; ++i)
{
if (ai[i].flag)
{
ai[i].x += rand() % 5 - 2; // 生成隨機的X軸偏移量
ai[i].y += rand() % 5 - 2; // 生成隨機的Y軸偏移量
}
}
}
以下是優(yōu)化版本
void aiMove()
{
for (int i = 0; i < AI_NUM; ++i)
{
if (ai[i].flag)
{
int xOffset = rand() % 5 - 2; // 生成隨機的X軸偏移量
int yOffset = rand() % 5 - 2; // 生成隨機的Y軸偏移量
ai[i].x += xOffset;
ai[i].y += yOffset;
// 限制AI角色移動的范圍,確保不超出窗口邊界
if (ai[i].x < 0)
ai[i].x = 0;
else if (ai[i].x > WIDTH)
ai[i].x = WIDTH;
if (ai[i].y < 0)
ai[i].y = 0;
else if (ai[i].y > HEIGHT)
ai[i].y = HEIGHT;
}
}
}
優(yōu)化說明:
1.使用變量 xOffset 和 yOffset 存儲隨機生成的X軸和Y軸的偏移量,以減少重復(fù)的隨機數(shù)生成。
2.限制AI角色移動的范圍,確保AI角色的位置不會超出窗口的邊界。通過比較偏移量后的位置和窗口寬度和高度的大小來限制移動范圍。文章來源:http://www.zghlxwxcb.cn/news/detail-700756.html
(6)主函數(shù) int main() 控制游戲的主循環(huán)和整體
int main()
{
initgraph(WIDTH, HEIGHT);
GameInit();
while (1)
{
keyControl(1);
GameDraw();
eatFood();
aiMove();
}
getchar();
return 0;
}
4.最終代碼
#include<stdio.h>
#include<easyx.h>//包含圖形庫頭文件
#include<stdlib.h>
#include<time.h>
#include<math.h>
#define FOOD_NUM 200 //食物數(shù)量
#define WIDTH 1024
#define HEIGHT 640
#define HEIFGT 10
#define AI_NUM 10//人工智障數(shù)量
/*
做游戲:1.窗口,畫圖,貼圖。。。。。easyx圖形庫的
食物:圓(圓心坐標,半徑,顏色,是否存在的標志)
*/
struct Ball//小球結(jié)構(gòu),玩家,食物,人工智障
{
int x;
int y;
int r;//半徑
DWORD color;//顏色
bool flag;//是否存在
};
struct Ball food[FOOD_NUM];
struct Ball player;//玩家
struct Ball ai[AI_NUM];
void GameInit()
{
//設(shè)置隨機數(shù)種子,時間是在不斷變化的
srand((unsigned)time(NULL));
for (int i = 0; i < FOOD_NUM; ++i)
{
food[i].x = rand() % WIDTH;
food[i].y = rand() % HEIGHT;
food[i].flag = true;//剛開始食物存在
food[i].r = rand() % 6 + 1;
food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
}
//初始化玩家數(shù)據(jù)
player.x = rand() & WIDTH + 1;
player.y = rand() % HEIGHT + 1;
player.r = 18;//只要比食物大就可以
player.flag = true;
player.color = RGB(rand() % 256, rand() % 256, rand() % 256);
//初始化ai
for (int i = 0; i < AI_NUM; ++i)
{
ai[i].x = rand() % WIDTH;
ai[i].y = rand() % HEIGHT;
ai[i].r = rand() % 10 + 5;
ai[i].flag = true;
ai[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
}
}
//繪制
void GameDraw()
{
//防止閃屏
BeginBatchDraw();
setbkcolor(WHITE);
cleardevice();//清屏
for (int i = 0; i < FOOD_NUM; ++i)
{
if (food[i].flag)
{
setfillcolor(food[i].color);//設(shè)置填充顏色
solidcircle(food[i].x, food[i].y,food[i].r);//畫一個填充圓
}
else
{
food[i].x = rand() % WIDTH;
food[i].y = rand() % HEIGHT;
food[i].flag = true;//剛開始食物存在
food[i].r = rand() % 6 + 1;
food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
}
}
//繪制玩家
setfillcolor(player.color);//設(shè)置填充顏色
solidcircle(player.x, player.y, player.r);
settextcolor(GREEN);
settextstyle(30, 0, L"黑體");
setbkmode(0);//設(shè)置文字背景透明
outtextxy(player.x-50, player.y, L"我是最靚的崽仔");
EndBatchDraw();
//繪制ai
for (int i = 0; i < AI_NUM;++i)
{
if (ai[i].flag)
{
setfillcolor(ai[i].color);
solidcircle(ai[i].x, ai[i].y, ai[i].r);
}
}
}
void keyControl(int speed)
{
//獲取鍵盤消息,按的是哪一個鍵
if ((GetAsyncKeyState('W') || GetAsyncKeyState(VK_UP))&&player.y>=0)//按了上鍵
{
player.y -= speed;
}
if ((GetAsyncKeyState('S') || GetAsyncKeyState(VK_DOWN))&& player.y<=HEIGHT)//按了下鍵
{
player.y += speed;
}
if ((GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT))&& player.x >= 0)//按了左鍵
{
player.x -= speed;
}
if ((GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT))&& player.x<=WIDTH)//按了右鍵
{
player.x += speed;
}
}
//求兩點之間的距離
double distance(struct Ball a, struct Ball b)
{
return sqrt((double)(a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
//玩家吃食物
void eatFood()
{
for (int i = 0; i < FOOD_NUM; ++i)
{
if (food[i].flag && distance(food[i], player) <= player.r)
{
food[i].flag = false;
player.r += food[i].r / 4;
}
}
}
//ai移動
void aiMove()
{
for (int i = 0; i < AI_NUM; ++i)
{
if (ai[i].flag)
{
ai[i].x += rand() % 5-2;
ai[i].y += rand() % 5 - 2;
}
}
}
int main()
{
initgraph(WIDTH, HEIGHT);
GameInit();
while (1)
{
keyControl(1);
GameDraw();
eatFood();
aiMove();
}
getchar();
return 0;
}
其他具體功能讀者可自行添加。文章來源地址http://www.zghlxwxcb.cn/news/detail-700756.html
到了這里,關(guān)于【C++/C 實現(xiàn)球球大作戰(zhàn)】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!