CC++專案開發:《火柴人遊戲》,500行原始碼開發

C/C++專案開發:《火柴人遊戲》,500行原始碼開發

hello,各位學程式設計的小夥伴們!學習C語言C++已經這麼久了,你們的語法知識已經學到哪裡了來了呢?不會還只停留在完成學校老師佈置的小作業這樣的基礎層次吧!

C/C++專案開發:《火柴人遊戲》,500行原始碼開發

今天這篇文章主要就是帶你突破目前的瓶頸,學會了基礎語法後,我們就要把它變成我們的能力展現對不對!大家都是已經是成年人了,改寫成熟的程式碼啦!所以今天我們就來試試《火柴人遊戲》,用C++結合圖形庫,將它開發出來吧!

程式碼也不多哦~也就幾百行吧!

PS:要安裝easyx圖形庫哦 #include / #include (文末領取)編譯器建議VS2019/2022,因為其他的編譯器可能要自己配置easyX的環境哦~

第一步:建立一個專案工程,並將準備好的素材資源放到同級目錄下(素材可以在文章最下方領取)如圖:

C/C++專案開發:《火柴人遊戲》,500行原始碼開發

第二步:首先我們新增必要的標頭檔案,然後將一些必要的識別符號定義,這裡也用到了類封裝,C++的話類封裝還是很重要的哦:

#include

#include

#include

#include

#include

using namespace std;

/******全域性變數******/

#define STEPDISTANCE 6 // 一步的距離。數值越大,移動速度越快

#define JUMPSPEED 10 // 數值越小,跳得越遠

#define ROLLDISTANCE 30 // 滾動的總步數。數值越大,滾得越遠

/******全域性變數******/

int s_v = STEPDISTANCE; //障礙物和人物移動速度

int p_v = JUMPSPEED; //人物跳躍速度

int score = 0; //分數

int max_s = 0;

char keydown; //按鍵值

/********************/

void move();

void Login();

/*************************************障礙物類****************************************/

// 障礙物

class zhangai

{

public:

int left;

int top;

int right;

int bottom;

int r;

public:

void draw(int l, int t, int r, int b); // 繪製障礙物

void style(); // 障礙物型別

} s1, s2, s3;

// 障礙物型別

void zhangai::style()

{

int a;

srand((unsigned int) time(NULL));

a = rand() % 5 + 1;

switch(a)

{

case 0:

case 1:

case 2:

case 3:

case 4:

top = 330;

bottom = 361;

break;

case 5:

top = 260;

bottom = 291;

break;

}

}

//障礙物初始化

void zhangai::draw(int l,int t,int ri,int b)

{

left=l;

top=t;

right=ri;

bottom=b;

solidrectangle(l, t, ri, b);

}

/**************************************人物類***********************************/

class people

{

public:

int i; // 控制人物移動幀數

int b; // 控制人物滾動幀數

int b1; // 控制人物滾動時間

int j; // 人物跳躍上升的速度

int k; // 人物下降的速度

int left;

int top;

int right;

int bottom;

private:

IMAGE img1[8]; // 人物影象

IMAGE img2[8]; // 滾動影象

IMAGE img3; // 跳躍影象

public:

people(); // 建構函式

void jump(); // 人物跳躍

void move(); // 人物移動

void roll(); // 人物滾動

bool impact(zhangai *ps); // 碰撞

} p;

第三步:寫一個建構函式來加載出我們的火柴人圖片資源:

people::people()

{

// 載入跑動影象

loadimage(&img1[0], _T(“rc\\picture\\move8_1。jpg”), 70, 100);

loadimage(&img1[1], _T(“rc\\picture\\move8_2。jpg”), 70, 100);

loadimage(&img1[2], _T(“rc\\picture\\move8_3。jpg”), 70, 100);

loadimage(&img1[3], _T(“rc\\picture\\move8_4。jpg”), 70, 100);

loadimage(&img1[4], _T(“rc\\picture\\move8_5。jpg”), 70, 100);

loadimage(&img1[5], _T(“rc\\picture\\move8_6。jpg”), 70, 100);

loadimage(&img1[6], _T(“rc\\picture\\move8_7。jpg”), 70, 100);

loadimage(&img1[7], _T(“rc\\picture\\move8_8。jpg”), 70, 100);

// 載入滾動影象

loadimage(&img2[0], _T(“rc\\picture\\gun8_1。jpg”), 50, 50);

loadimage(&img2[1], _T(“rc\\picture\\gun8_2。jpg”), 50, 50);

loadimage(&img2[2], _T(“rc\\picture\\gun8_3。jpg”), 50, 50);

loadimage(&img2[3], _T(“rc\\picture\\gun8_4。jpg”), 50, 50);

loadimage(&img2[4], _T(“rc\\picture\\gun8_5。jpg”), 50, 50);

loadimage(&img2[5], _T(“rc\\picture\\gun8_6。jpg”), 50, 50);

loadimage(&img2[6], _T(“rc\\picture\\gun8_7。jpg”), 50, 50);

loadimage(&img2[7], _T(“rc\\picture\\gun8_8。jpg”), 50, 50);

// 載入跳躍影象

loadimage(&img3, _T(“rc\\picture\\move8_5。jpg”), 70, 100);

}

第四步:實現火柴人的各種動作(包括跳躍、移動和滾動),需要理解一下邏輯:

//人物跳躍

void people::jump()

{

if(j >= 70) //上升

{

putimage(left,j, &img3);

clearrectangle(40,j+100,120,j+120);

p。top = j;

p。bottom = p。top + 120;

j=j-p_v;

k=j;

}

else if(k <= 240) //下降

{

putimage(left,k+20, &img3);

clearrectangle(40,70,120,k+20);

p。top = k;

p。bottom = p。top + 120;

k=k+p_v;

}

}

//人物移動

void people::move()

{

putimage(50, 260, &img1[p。i]);

p。left = 50;

p。top = 240;

p。right = p。left + 65;

p。bottom= p。top + 120;

p。i++; // 改變人物幀數

if(p。i == 8) // 人物迴圈移動

{

p。i = 0;

}

}

//人物滾動

void people::roll()

{

putimage(50, 300, &img2[p。b]);

p。left=50;

p。top =300;

p。right = p。left + 50;

p。bottom = p。top + 50;

p。b1++;

p。b++; // 改變人物滾動幀數

if(p。b==8) // 人物迴圈滾動

{

p。b=0;

}

}

第五步:然後寫出關於火柴人遊戲的一個障礙部分(包括設定障礙,障礙物的生成和移動,障礙的刪除和人物和障礙的觸碰等等),具體程式碼如下:

// 返回是否與指定障礙發生碰撞

bool people::impact(zhangai *ps)

{

return (max(left, ps->left) < min(right, ps->right) && max(top, ps->top) < min(bottom, ps->bottom));

}

/*************************函式********************************/

// 隨機障礙

void zhangai_rnd()

{

s1。r=rand() % 200 + 200;

s2。r=rand() % 200 + 200;

s3。r=rand() % 200 + 200;

}

// 初始化障礙

void chushi()

{

s1。left = 640;

s2。left = s1。left + s1。r;

s3。left = s2。left + s2。r;

s1。style();

s2。style();

s3。style();

}

// 繪製障礙

void show_zhangai()

{

s1。draw(s1。left, s1。top, s1。left + 40, s1。bottom);

s2。draw(s2。left, s2。top, s2。left + 40, s2。bottom);

s3。draw(s3。left, s3。top, s3。left + 40, s3。bottom);

}

// 刪除障礙

void delete_zhangai()

{

clearrectangle(s1。left, s1。top, s1。left+40, s1。bottom);

clearrectangle(s2。left, s2。top, s2。left+40, s2。bottom);

clearrectangle(s3。left, s3。top, s3。left+40, s3。bottom);

}

// 障礙物迴圈

void xunhuan()

{

if(s1。left+40<=0)

{

s3。r = rand() % 200 + 200;

s1。left = s3。left + s3。r;

s1。style();

}

else if(s2。left+40<=0)

{

s1。r = rand() % 200 + 200;

s2。left = s1。left + s1。r;

s2。style();

}

else if(s3。left + 40 <= 0)

{

s2。r = rand() % 200 + 200;

s3。left = s2。left + s2。r;

s3。style();

}

}

// 設定障礙移動速度

void set_speed()

{

s1。left -= s_v;

s2。left -= s_v;

s3。left -= s_v;

}

第六步:實現分數和排行榜,這裡會用到檔案操作的知識,所以說語法是我們實現一切的前提,大家一定要學好哦!

// 儲存成績

void gave_score()

{

ofstream outfile(“score。txt”, ios::out);

if(!outfile)

{

cerr << “open error!” << endl;

exit(1);

}

outfile << score << “ ”;

outfile。close();

}

// 讀取最高分

void max_score()

{

int value;

ifstream infile(“score。txt”, ios::in);

if(!infile)

{

cerr << “open error!” << endl;

exit(1);

}

infile>>value;

infile。close();

max_s = value;

}

// 改變最高分

void change_score()

{

int value;

ifstream infile(“score。txt”, ios::in);

if(!infile)

{

cerr << “open error!” << endl;

exit(1);

}

infile>>value;

infile。close();

if(score>value)

{

gave_score();

}

}

第七步:實現火柴人的移動和障礙的碰撞檢測,如果人和障礙的座標有重疊,那麼就說明撞了,遊戲結束:

// 遊戲結束

void game_over()

{

FlushMouseMsgBuffer(); //清空滑鼠快取區

change_score();

Sleep(1000);

p。i = 0;

cleardevice();

Login();

}

// 碰撞

void pengzhuang()

{

// 指向當前障礙的指標

zhangai *ps;

// 獲取當前障礙

ps = &s1;

if (s2。left < ps->left) ps = &s2;

if (s3。left < ps->left) ps = &s3;

// 檢測碰撞

if (p。impact(ps))

{

p_v = 0;

s_v = 0;

game_over();

}

}

// 移動

void move()

{

keydown=‘ ’; // 清空鍵盤快取區

setfillstyle(BS_SOLID); // 設定繪圖樣式

cleardevice();

solidrectangle(0, 360, 640, 400);

char s[10];

char max[10];

char ss[] = “分數:0”;

char sss[] = “最高分:”;

max_score(); // 最高分

settextcolor(BLUE);

sprintf(max, “%d”, max_s); // 數值格式化

outtextxy(490, 40, max); // 輸出最高分

outtextxy(58, 40, ss);

outtextxy(400, 40, sss);

p。i = 0;

p。b = 0;

p。b1 = 0;

p。j = p。k = p。top = 240;

p。left = 50;

zhangai_rnd();

chushi();

IMAGE img1;

loadimage(&img1, _T(“rc\\picture\\move8_1。jpg”),70,100);

putimage(50,260, &img1);

while(true)

{

keydown=getch();

while(!kbhit())

{

sprintf(s,“%d”,score);

outtextxy(120,40,s);

show_zhangai();

if(keydown == ‘w’)

{

p。i = 0;

p。b1 = 0;

p。jump();

if(p。k > 240)

{

keydown = ‘ ’;

p。j = 240;

}

}

else if(keydown == ‘s’)

{

if(p。b1 == 0)

clearrectangle(50, 240, 120, 361);

if(p。k >= 240)

p。roll();

else

keydown=‘w’;

}

else

{

if(p。k >= 240)

p。move();

else

keydown = ‘w’;

if(p。b1 == 0)

p。move();

else

keydown = ‘s’;

}

if(p。b1 >= ROLLDISTANCE)

{

p。b1 = 0;

keydown = ‘ ’;

p。b = 0;

}

Sleep(20);

pengzhuang();

delete_zhangai();

set_speed();

score++; // 分數

xunhuan(); // 障礙物迴圈移動

}

}

}

最後一步:介面部分!主要功能都實現了,作為一個遊戲,當然還是需要一個美美的介面咯!

void Login()

{

setfillstyle(BS_SOLID);

setbkcolor(LIGHTBLUE);

char s[] = “開始遊戲”;

char ss[] = “退出遊戲”;

char sss[] = “遊戲說明: W 鍵 = 跳躍 S 鍵 = 滾動”;

MOUSEMSG m;

solidrectangle(240, 100, 380, 150);

solidrectangle(240, 160, 380, 210);

settextcolor(BLUE); // 設定字型顏色

outtextxy(260, 113, s);

outtextxy(260, 173, ss);

setbkcolor(WHITE);

outtextxy(110, 250, sss);

setfillcolor(LIGHTBLUE);

solidrectangle(0, 360, 640, 400);

while(true)

{

m = GetMouseMsg(); // 判斷是否按下滑鼠

if(m。x >= 240 && m。x <= 380 && m。y >= 100 && m。y <= 150)

{

setlinecolor(RED); // 選中框框線條顏色

rectangle(235, 95, 385, 155);

if(m。uMsg==WM_LBUTTONDOWN )

{

clearrectangle(240, 100, 380, 150);

clearrectangle(240, 160, 380, 210);

setbkcolor(WHITE);

cleardevice();

game_again();

}

}

else if(m。x >= 240 && m。x <= 380 && m。y >= 160 && m。y <= 210)

{

setlinecolor(RED); // 選中框框線條顏色

rectangle(235, 155, 385, 215);

if(m。uMsg==WM_LBUTTONDOWN)

{

exit(1);

}

}

else

{

setlinecolor(WHITE);

rectangle(235, 95, 385, 155);

rectangle(235, 155, 385, 215);

}

}

}

/***********************************************************************/

// 介面初始化

void UI()

{

initgraph(640, 400); // 視窗初始化大小

setbkcolor(WHITE); // 設定背景顏色

cleardevice();

setlinecolor(BLACK); // 設定繪圖顏色

settextcolor(BLACK); // 設定文字顏色

setfillcolor(LIGHTBLUE); // 設定填充顏色

settextstyle(25, 0, _T(“宋體”)); // 字型樣式大小

srand((unsigned int) time(NULL)); // 設定隨機種子

}

/*******************************主函式**********************************/

void main()

{

UI(); // 介面初始化

Login(); // 登入介面

getch(); // 按任意鍵繼續

closegraph(); // 關閉圖形介面

}

好啦,重要的基礎程式碼就這些~需要完整原始碼對照的同學可以在文章末領取!

火柴人遊戲教程就到此結束啦,大家趕緊試試吧!

原始碼素材獲取通道:

後臺發【程式設計交流】有資料與學習交流群哦!

而且你可以在群裡面交流提問C語言/C++的相關程式設計問題哦!