CC++專案開發:《火柴人遊戲》,500行原始碼開發
hello,各位學程式設計的小夥伴們!學習C語言C++已經這麼久了,你們的語法知識已經學到哪裡了來了呢?不會還只停留在完成學校老師佈置的小作業這樣的基礎層次吧!
今天這篇文章主要就是帶你突破目前的瓶頸,學會了基礎語法後,我們就要把它變成我們的能力展現對不對!大家都是已經是成年人了,改寫成熟的程式碼啦!所以今天我們就來試試《火柴人遊戲》,用C++結合圖形庫,將它開發出來吧!
程式碼也不多哦~也就幾百行吧!
PS:要安裝easyx圖形庫哦 #include
第一步:建立一個專案工程,並將準備好的素材資源放到同級目錄下(素材可以在文章最下方領取)如圖:
第二步:首先我們新增必要的標頭檔案,然後將一些必要的識別符號定義,這裡也用到了類封裝,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++的相關程式設計問題哦!