經過之前的學習,我們基本掌握了開發小遊戲所需要的語法知識和搭建方法,但是基礎C語言的視覺化與互動功能實在是太弱了

做遊戲,學程式設計(C語言) 7 學習EasyX圖形互動功能----flappy bird原始碼

利用免費的EasyX外掛,我們可以快速上手,簡單實現很酷的視覺效果

做遊戲,學程式設計(C語言) 7 學習EasyX圖形互動功能----flappy bird原始碼

EasyX安裝包下載連結:下載 —— EasyX Library for C++

怎樣安裝 EasyX? —— EasyX Library for C++

怎樣使用 EasyX?(Visual C++ 6。0) —— EasyX Library for C++

怎樣使用 EasyX?(Visual C++ 2008) —— EasyX Library for C++

官網還提供了一套非常好的入門教程,大家可以自學:VC繪圖/遊戲簡易教程——前言 —— EasyX Library for C++

對應的目錄:

–前言

–1:建立新專案

–2:簡單繪圖,學習單步執行

–3:熟悉更多的繪圖語句

–4:結合流程控制語句來繪圖

–5:數學知識在繪圖中的運用

–6:實現簡單動畫

–7:捕獲按鍵,實現動畫的簡單控制

–8:用函式簡化相同圖案的製作

–9:繪圖中的位運算

–10:用滑鼠控制繪圖/遊戲程式

–11:隨機函式

–12:陣列

–13:getimage / putimage / loadimag / saveimage / IMAGE 的用法

–14:透過位運算實現顏色的分離與處理

–15:窗體控制代碼(Windows 程式設計入門)

–16:裝置上下文控制代碼(Windows 程式設計入門2)

學習完後,大家可以試著將前面教程中學習的生命遊戲、反彈球、flappy bird、空戰遊戲用EasyX重新實現,達到類似這樣的效果:

做遊戲,學程式設計(C語言) 7 學習EasyX圖形互動功能----flappy bird原始碼

做遊戲,學程式設計(C語言) 7 學習EasyX圖形互動功能----flappy bird原始碼

做遊戲,學程式設計(C語言) 7 學習EasyX圖形互動功能----flappy bird原始碼

做遊戲,學程式設計(C語言) 7 學習EasyX圖形互動功能----flappy bird原始碼

大家可以在網上搜索諸如“flappy bird遊戲素材”,下載對應的圖片和音樂素材。也可以直接在原始遊戲中截圖,ps出需要的素材。

下面是用EasyX實現的flappy bird需要的圖片:

做遊戲,學程式設計(C語言) 7 學習EasyX圖形互動功能----flappy bird原始碼

素材程式碼可由百度雲盤下載:

http://

pan。baidu。com/s/1o8lnH7

0

,首先大家可以執行flappy bird\easyx bird\Debug\happyhappy。exe 檔案看看遊戲效果。

以下為遊戲程式碼,大家可以參考:

/*

畫面大小350*600

鳥的大小100*70

柱子寬處寬度140,窄處寬度100,寬處厚度30,顏色

*/

#include

#include

#include

#include

#include

// 引用 Windows Multimedia API

#pragma comment(lib,“Winmm。lib”)

void

print

();

void

begin

();

void

printstone

();

//人家才不是作柱子的呢

void

bird

();

//控制鳥的下降和上升

void

judgement

();

//判斷語句

void

scoleprint

();

void

endorretry

();

int

bird_x

=

150

bird_y

=

300

i

=

0

k

=

0

//鳥的左上角座標

int

scole

=

0

t

=

0

int

stone_x1

stone_y1

//上截柱子左下座標

int

stone_x2

stone_y2

//上截柱子左下座標

IMAGE

backgrand

bird1

4

],

bird2

4

],

scole1

10

],

scole2

10

],

stone_up1

stone_up2

stone_down1

stone_down2

stone_up3

stone_up4

stone_down3

stone_down4

//圖片儲存變數

MOUSEMSG

m

// 定義滑鼠訊息

int

main

()

{

if

t

==

0

{

begin

();

t

++

}

if

t

print

();

getch

();

//製造停頓

bird_y

=

300

bird_x

=

150

i

=

0

k

=

0

scole

=

0

while

1

{

bird

();

print

();

judgement

();

}

closegraph

();

return

0

}

void

print

()

{

putimage

0

0

&

backgrand

);

//背景影象

printstone

();

//畫柱子

putimage

bird_x

bird_y

&

bird1

i

%

3

],

NOTSRCERASE

);

putimage

bird_x

bird_y

&

bird2

i

%

3

],

SRCINVERT

);

if

k

%

5

==

0

i

++

k

++

scoleprint

();

FlushBatchDraw

();

// 繪製

}

void

printstone

()

//柱子移動規律/哭

{

Sleep

30

);

if

stone_x1

>

210

//此時畫面存在兩根柱子

{

putimage

stone_x1

stone_y1

&

stone_up2

NOTSRCERASE

);

putimage

stone_x1

stone_y1

&

stone_up1

SRCINVERT

);

putimage

stone_x1

stone_y1

+

750

&

stone_down2

NOTSRCERASE

);

putimage

stone_x1

stone_y1

+

750

&

stone_down1

SRCINVERT

);

putimage

stone_x2

stone_y2

&

stone_up4

NOTSRCERASE

);

putimage

stone_x2

stone_y2

&

stone_up3

SRCINVERT

);

putimage

stone_x2

stone_y2

+

750

&

stone_down4

NOTSRCERASE

);

putimage

stone_x2

stone_y2

+

750

&

stone_down3

SRCINVERT

);

stone_x1

——

stone_x2

——

}

else

if

stone_x1

==

210

//左柱子消失,將stone_x2,stone_y2值歸位

{

stone_x2

=

stone_x1

stone_y2

=

stone_y1

putimage

stone_x1

stone_y1

&

stone_up2

NOTSRCERASE

);

putimage

stone_x1

stone_y1

&

stone_up1

SRCINVERT

);

putimage

stone_x1

stone_y1

+

750

&

stone_down2

NOTSRCERASE

);

putimage

stone_x1

stone_y1

+

750

&

stone_down1

SRCINVERT

);

stone_x1

——

stone_x2

——

}

else

if

stone_x1

<

210

&&

stone_x1

>

0

//畫面只存在一根柱子的情況

{

putimage

stone_x1

stone_y1

&

stone_up2

NOTSRCERASE

);

putimage

stone_x1

stone_y1

&

stone_up1

SRCINVERT

);

putimage

stone_x1

stone_y1

+

750

&

stone_down2

NOTSRCERASE

);

putimage

stone_x1

stone_y1

+

750

&

stone_down1

SRCINVERT

);

stone_x1

——

stone_x2

——

}

if

stone_x1

==

0

//柱子左端到站,生成新柱子

{

stone_y1

=

rand

()

%

310

-

555

stone_x1

=

350

putimage

stone_x1

stone_y1

&

stone_up2

NOTSRCERASE

);

putimage

stone_x1

stone_y1

&

stone_up1

SRCINVERT

);

putimage

stone_x1

stone_y1

+

750

&

stone_down2

NOTSRCERASE

);

putimage

stone_x1

stone_y1

+

750

&

stone_down1

SRCINVERT

);

stone_x1

——

stone_x2

——

}

}

void

begin

()

{

mciSendString

“open

\”

。。

\\

。。

\\

sounds

\\

background。mp3

\“

alias music ”

NULL

0

NULL

);

//背景音樂

mciSendString

“play music”

NULL

0

NULL

);

initgraph

350

600

);

// 獲取視窗控制代碼

HWND

hwnd

=

GetHWnd

();

// 設定視窗標題文字

SetWindowText

hwnd

“江超群製作”

);

IMAGE

beforegame

loadimage

&

beforegame

“。。

\\

。。

\\

素材庫

\\

beforegame。jpg”

);

putimage

0

0

&

beforegame

);

Sleep

1000

);

getch

();

BeginBatchDraw

();

// 開啟批次繪圖模式

loadimage

&

backgrand

“。。

\\

。。

\\

素材庫

\\

backgroundfd。jpg”

);

//載入背景圖片

//鳥

loadimage

&

bird2

0

],

“。。

\\

。。

\\

素材庫

\\

bird1-2。gif”

);

loadimage

&

bird1

0

],

“。。

\\

。。

\\

素材庫

\\

bird1-1。gif”

);

loadimage

&

bird2

1

],

“。。

\\

。。

\\

素材庫

\\

bird2-2。gif”

);

loadimage

&

bird1

1

],

“。。

\\

。。

\\

素材庫

\\

bird2-1。gif”

);

loadimage

&

bird2

2

],

“。。

\\

。。

\\

素材庫

\\

bird3-2。gif”

);

loadimage

&

bird1

2

],

“。。

\\

。。

\\

素材庫

\\

bird3-1。gif”

);

loadimage

&

bird2

3

],

“。。

\\

。。

\\

素材庫

\\

bird4-2。gif”

);

loadimage

&

bird1

3

],

“。。

\\

。。

\\

素材庫

\\

bird4-1。gif”

);

//柱子

loadimage

&

stone_up1

“。。

\\

。。

\\

素材庫

\\

stone_up1。gif”

);

loadimage

&

stone_up2

“。。

\\

。。

\\

素材庫

\\

stone_up2。gif”

);

loadimage

&

stone_down1

“。。

\\

。。

\\

素材庫

\\

stone_down1。gif”

);

loadimage

&

stone_down2

“。。

\\

。。

\\

素材庫

\\

stone_down2。gif”

);

loadimage

&

stone_up3

“。。

\\

。。

\\

素材庫

\\

stone_up1。gif”

);

loadimage

&

stone_up4

“。。

\\

。。

\\

素材庫

\\

stone_up2。gif”

);

loadimage

&

stone_down3

“。。

\\

。。

\\

素材庫

\\

stone_down1。gif”

);

loadimage

&

stone_down4

“。。

\\

。。

\\

素材庫

\\

stone_down2。gif”

);

//數字

loadimage

&

scole1

0

],

“。。

\\

。。

\\

素材庫

\\

0_1。jpg”

);

loadimage

&

scole2

0

],

“。。

\\

。。

\\

素材庫

\\

0_2。jpg”

);

loadimage

&

scole1

1

],

“。。

\\

。。

\\

素材庫

\\

1_1。jpg”

);

loadimage

&

scole2

1

],

“。。

\\

。。

\\

素材庫

\\

1_2。jpg”

);

loadimage

&

scole1

2

],

“。。

\\

。。

\\

素材庫

\\

2_1。jpg”

);

loadimage

&

scole2

2

],

“。。

\\

。。

\\

素材庫

\\

2_2。jpg”

);

loadimage

&

scole1

3

],

“。。

\\

。。

\\

素材庫

\\

3_1。jpg”

);

loadimage

&

scole2

3

],

“。。

\\

。。

\\

素材庫

\\

3_2。jpg”

);

loadimage

&

scole1

4

],

“。。

\\

。。

\\

素材庫

\\

4_1。jpg”

);

loadimage

&

scole2

4

],

“。。

\\

。。

\\

素材庫

\\

4_2。jpg”

);

loadimage

&

scole1

5

],

“。。

\\

。。

\\

素材庫

\\

5_1。jpg”

);

loadimage

&

scole2

5

],

“。。

\\

。。

\\

素材庫

\\

5_2。jpg”

);

loadimage

&

scole1

6

],

“。。

\\

。。

\\

素材庫

\\

6_1。jpg”

);

loadimage

&

scole2

6

],

“。。

\\

。。

\\

素材庫

\\

6_2。jpg”

);

loadimage

&

scole1

7

],

“。。

\\

。。

\\

素材庫

\\

7_1。jpg”

);

loadimage

&

scole2

7

],

“。。

\\

。。

\\

素材庫

\\

7_2。jpg”

);

loadimage

&

scole1

8

],

“。。

\\

。。

\\

素材庫

\\

8_1。jpg”

);

loadimage

&

scole2

8

],

“。。

\\

。。

\\

素材庫

\\

8_2。jpg”

);

loadimage

&

scole1

9

],

“。。

\\

。。

\\

素材庫

\\

9_1。jpg”

);

loadimage

&

scole2

9

],

“。。

\\

。。

\\

素材庫

\\

9_2。jpg”

);

srand

time

0

));

//初始化種子

print

();

//第一根柱子,初始化

stone_y1

=

rand

()

%

310

-

555

stone_x1

=

350

stone_x2

=

stone_y2

=-

9999

}

void

bird

()

{

char

space

if

kbhit

())

//讀取空格

{

space

=

getch

();

if

space

==

‘ ’

{

bird_y

-=

80

}

else

if

space

==

27

getch

();

}

else

{

bird_y

+=

3

}

while

MouseHit

())

{

// 獲取一條滑鼠訊息

m

=

GetMouseMsg

();

switch

m

uMsg

{

case

WM_LBUTTONDOWN

bird_y

-=

80

break

case

WM_RBUTTONDOWN

getch

();

break

}

}

}

void

judgement

()

{

if

((

stone_x1

>

10

&&

stone_x1

<

20

||

stone_x1

>

174

&&

stone_x1

<

184

))

{

if

((

bird_y

>

stone_y1

+

576

&&

bird_y

<

stone_y1

+

600

))

||

((

bird_y

>

stone_y1

+

726

))

&&

bird_y

<

stone_y1

+

750

)))

endorretry

();

//結束遊戲

}

else

if

stone_x1

>=

20

&&

stone_x1

<=

174

{

if

bird_y

>

stone_y1

+

600

&&

bird_y

<

stone_y1

+

726

)))

endorretry

();

//結束遊戲

}

if

bird_y

>

576

endorretry

();

//結束遊戲

if

stone_x1

==

150

scole

++

}

void

endorretry

()

{

if

bird_y

<

550

&&

stone_x1

>

160

{

while

bird_y

<

550

{

putimage

0

0

&

backgrand

);

//背景影象

putimage

stone_x1

stone_y1

&

stone_up2

NOTSRCERASE

);

putimage

stone_x1

stone_y1

&

stone_up1

SRCINVERT

);

putimage

stone_x1

stone_y1

+

750

&

stone_down2

NOTSRCERASE

);

putimage

stone_x1

stone_y1

+

750

&

stone_down1

SRCINVERT

);

putimage

stone_x2

stone_y2

&

stone_up4

NOTSRCERASE

);

putimage

stone_x2

stone_y2

&

stone_up3

SRCINVERT

);

putimage

stone_x2

stone_y2

+

750

&

stone_down4

NOTSRCERASE

);

putimage

stone_x2

stone_y2

+

750

&

stone_down3

SRCINVERT

);

putimage

bird_x

bird_y

&

bird1

3

],

NOTSRCERASE

);

putimage

bird_x

bird_y

&

bird2

3

],

SRCINVERT

);

FlushBatchDraw

();

bird_y

++

}

}

IMAGE

gameover1

gameover2

atlast

loadimage

&

gameover1

“。。

\\

。。

\\

素材庫

\\

gameover1。gif”

);

loadimage

&

gameover2

“。。

\\

。。

\\

素材庫

\\

gameover2。gif”

);

putimage

80

200

&

gameover1

NOTSRCERASE

);

putimage

80

200

&

gameover2

SRCINVERT

);

FlushBatchDraw

();

Sleep

1000

);

loadimage

&

atlast

“。。

\\

。。

\\

素材庫

\\

atlast。jpg”

);

putimage

0

0

&

atlast

);

scoleprint

();

FlushBatchDraw

();

getch

();

//第一根柱子

stone_y1

=

rand

()

%

310

-

555

stone_x1

=

350

stone_x2

=

stone_y2

=-

9999

bird_y

=

300

scole

=

0

main

();

}

void

scoleprint

()

{

IMAGE

*

fen1

6

],

*

fen2

6

];

int

he

weishu

=

1

i

=

0

sdsf

=

scole

if

sdsf

==

0

{

putimage

250

50

&

scole1

0

],

NOTSRCERASE

);

putimage

250

50

&

scole2

0

],

SRCINVERT

);

}

while

sdsf

>

0

{

he

=

sdsf

%

10

fen1

i

=&

scole1

he

];

fen2

i

=&

scole2

he

];

putimage

300

-

50

*

weishu

50

fen1

i

],

NOTSRCERASE

);

putimage

300

-

50

*

weishu

50

fen2

i

],

SRCINVERT

);

sdsf

/=

10

i

++

weishu

++

}

}

做出flappy bird,也可以按照我們之前教程的思路,step by step地實現,遇到問題再參考上面的程式碼。自己從無到有實現一遍,就能學會類似遊戲的開發了。大概步驟可以為:

1。 背景圖片的顯示

2。 加入小鳥圖片

3。 小鳥自由下落,按鍵後上升

4。 加入靜態的障礙物

5。 障礙物向左移動

6。 判斷小鳥和障礙物的碰撞

7。 障礙物移動出左邊界後,在右邊重新出現

8。 加入記分模組

9。 加入音效效果

10。 加入開始介面、結束介面

11。 繼續完善細節、整理程式碼

flappy bird相對比較簡單,大家可以先從這個案例開始學習。學會理解別人的程式碼,也是一個非常重要的能力,大家可以透過這種逐步重現的方法來學習。後面我們再一起學習更復雜的EasyX遊戲程式碼,EasyX官網上也有很多遊戲案例可以借鑑參考:

範例程式 —— EasyX Library for C++

CodeBus | 分享程式碼,一起進步~

下一個教程:英雄聯盟連連看 知乎專欄