第三章 WINDOWS 電玩程式
3.6 電玩程式
3.6.2 遊戲的架構
3.6.2.1 使用者控制輸入部分
否
是
否
是
在使用者控制輸入子系統中所要負責把使用者按下哪些件放開哪一些鍵紀錄 進一個 input 的結構中。
有按鍵 被按下
把被按下 的鍵紀錄 下來
有按鍵 被放開
把被放開 的鍵紀錄 下來
開始
結束
3.6.2.2 遊戲初始化設定
這裡主要的功能主要的功能是跟 WINDOWS 作業系統要求全螢幕模式執行、
設定畫面的解析度、設定有多少種顏色、要求 DIRECTX 的物件、從外部讀入圖檔 和背景檔、設定調色盤。但是它又可以更細分成遊戲環境設定和檔案讀取兩個子 系統。
3.6.2.2.1 遊戲環境設定
設定視窗格式
跟 windows 登記 視窗
產生視窗
畫出視窗
更新視窗
跟系統要求 directdraw 物件
設定全螢幕模式
設定 640×480 和 256 色
設定主顯示頁格 式
產生主顯示頁
設定副顯示頁格 式
產生副顯示頁
設定調色盤 開始
結束
3.6.2.2.2 檔案讀取
否
是
是
否 圖檔陣列 中還有圖 檔未讀入
一次讀入 一個圖檔 存到記憶 體
設定這個 圖檔的 colorkey
開啟背景檔
開檔失敗
中斷遊戲
讀入檔案
關閉檔案 開始
結束
3.6.2.3 遊戲運算和資料處理
這裡主要的功能是依照 input 結構中的資料來控制主角飛機的移動、產生敵機 物件、控制敵機物件、把敵機物件加入敵機串列等等….
3.6.2.3.1 飛機角色控制
否
3.6.2.3.2 敵機角色控制
是 否
否
是
否 是 counter
%30==0
產生一個敵機
把敵機加入串 列
counter%
400==0
產生一個升級盒
把升級盒子加 入串列
for a=敵機串 列的第一個 物件的指標 to a=敵機串列 的第一個物 件的指標
rand()%
100==0
1 a 所指向的 敵機發射 一個子彈
把子彈加 入子彈串 列
2 開始
1
a 指向敵機 串列中的 下一個敵 機物件
a 2
結束
83
3.6.2.3.4 所有精靈的移動
3.6.2.4 螢幕輸出
這裡只要要做的是就是依照遊戲運算和遊戲資料處理的所得結果來作輸出。
3.6.2.4.1 背景的繪製
移動我機子彈串列中 的所有我機子彈
移動敵機串列中的所 有敵機
移動敵機子彈串列中 的所有敵機子彈
移動升級盒串列中的 所有升級盒物件
移動火花串列中的所 有火花物件
開始
結束
i=0 to 15
j=0 to 20
在螢幕由(j×32,i×32)、
(j×32+32,i×32)、(j×32,i×32+32) (j×32+32,i×32+32)這四個點所為 成的區域畫圖
查詢 myout 檔案找出所要畫的 圖
呼叫 easydraw()畫圖
j 開始
結束 j
86
3.6.2.4.2 所有精靈的移動
否
是
是 否 i=1 to 5
drawarray[i]
!=NULL
drawarray[i]所指 的物件是否全部 位於螢幕內
只畫出螢幕內的 部分
畫出物件的全部
drawarray[i]=drawarray[i]
的下一個物件
i 開始
結束
3.6.2.4.3 字幕顯示
是 否 主角存
在
顯示分數 輸出字幕
告訴使用 者他已經 死了 開始
結束
3.6.2.4.4 主角的動畫製作
否
是
否 是 主角是 否存在
畫出主角
主角是 否是無 敵模式
畫出防護照 開始
結束
3.6.3
程式碼
程式碼中有注解說明。
3.6.3.1
飛機射擊遊戲的程式碼
3.6.3.1.1
input.h
//所有的使用者鍵盤輸入都定義在這,遊戲中需要判別這一些值
#ifndef __input_h__
#define __input_h__
/********************************************************************/
/*這是個定義使用者收入哪一些按鍵的結構 */
/********************************************************************/
struct inputstruct {
int fire;//使用者按了 ENTER 鍵 fire=1,使用者放開 ENTER 鍵 fire=0 int bomb;//使用者按了 B 鍵 bomb=1,使用者放開 B 鍵 bomb=0 int left;//使用者按了左鍵 left=1,使用者放開左鍵 left=0
int right;//使用者按了右鍵 right=1,使用者放開右鍵 right=0 int up;//使用者按了上鍵 up=1,使用者放開上鍵 up=0
int down;//使用者按了下鍵 down=1,使用者放開下鍵 down=0 int pause;//使用者按了 P 鍵 pause=1,使用者放開 P 鍵 pause=0
int space;//使用者按了 SPACE 鍵 space=1,使用者放開 SPACE 鍵 space=0 int decrease_game_speed;//使用者按了 D 鍵 decrease_game_speed=1,使用者放 開 D 鍵 decrease_game_speed=0
int increase_game_speed;//使用者按了 I 鍵 increase_game_speed=1,使用者放 開 I 鍵 increase_game_speed=0
};
#endif
3.6.2.1.2 myplane.h
//一些遊戲中要用到的類別的定義和函式的宣告
#ifndef __myplane_h__
#define __myplane_h__
#include <windows.h>
#include <windowsx.h>
#include <math.h>
#include <ddraw.h>
#define man_controlled 0
#define straight 1
#define move_to_enemy 2
/********************************************************************/
/*class moveobject 定義著遊戲中會動的物件(如子彈,敵機,飛彈等等...) */
/*的基本資料 */
/********************************************************************/
class moveobject {
public:
BOOL alive;//TRUE for alive,FALSE for dead
BOOL movable;//TRUE for it can move,FALSE for it can not move
int mode_of_flying;//這個物件飛行的方式
//0 表示由人控制 man_controlled //1 表示直線飛行 stright
//2 表示朝敵人方向飛行 move_to_enemy
int belongto;//表示這個移動物件是屬於哪一方的
//0 for player side,1 for 電腦控制的敵方,2 for 電腦控 制的中立
double xpos;//此物件的圖片的最左上角的點在螢幕中的 x 位置
double ypos;//此物件的圖片的最左上角的點在螢幕中的 y 位置
double angle;//此物件移動時的角度
double speed;//此物件移動時的速度
double x_speed;//此物件的 x 軸速度 double y_speed;//此物件的 y 軸速度
int x;//此物件的圖片的最左上角的 x 座標所在的圖檔的
int y;// 此物件的圖片的最左上角的 y 座標所在的圖檔的
int width;//此物件的圖片的寬度
int longth;//此物件的圖片的長度
LPDIRECTDRAWSURFACE lpDDoffscrean;//此物件的圖片所在的緩
衝顯示頁
moveobject(BOOL p_alive,BOOL p_movable,int p_mode_of_flying,double p_xpos,double p_ypos,double p_angle,
double p_speed,int p_x,int p_y,int
p_width,int p_longth,
LPDIRECTDRAWSURFACE p_lpDDoffscrean);//建構子 ~moveobject();//解構子
virtual void movable_object_control(struct object_draw_list *b,moveobject
*a,object_draw_list **c);//這個函示負責移動物件本身 };
/********************************************************************/
/*一個把 moveobject 物件串成 linking_list 的結構 */
/********************************************************************/
struct object_draw_list {
class moveobject *m_object;
struct object_draw_list *former;//前一個物件的指標 struct object_draw_list *next;//後一個物件的指標 };
/********************************************************************/
/*這個 sparkle 類別定義了飛機爆炸後的火花 */
/********************************************************************/
class sparkle:public moveobject {
protected:
int cycle;//這個 sparkle 的生命週期,當 cycle 為 0 時 sparkle 消失 public:
sparkle(BOOL p_alive,BOOL p_movable,int p_mode_of_flying,double p_xpos,double p_ypos,double p_angle,
double p_speed,int p_x,int p_y,int p_width,int p_longth,
LPDIRECTDRAWSURFACE p_lpDDoffscrean)
:moveobject(p_alive,p_movable,p_mode_of_flying,p_xpos,p_ypos,p_angle,
p_speed,p_x,p_y,p_width,p_longth,p_lpDDoffscrean)
{
cycle=0;
}//建構子 ~sparkle() {
}//解構子
void movable_object_control(struct object_draw_list *b,moveobject
*a,object_draw_list **c);//這個函式移動物件本身,參數 b 是物件 a 所在的串列結構 的頭的指標,而 c 是 b 的子標。
};
/********************************************************************/
/*這個類別定義了玩家的飛機 */
/********************************************************************/
class player_side_plane:public moveobject {
public:
UINT score;//玩家的分數 int powerlevel;//玩家的等級
int maxpowerlevel;//玩家的等級上限 int bombstock;//玩家的炸彈儲存量
int counter_to_next_powerlevel;//目前的所吃的 powerup box 總數除以 10 的餘數 int max_of_counter_to_next_powerlevel;//內定值為 10
BOOL protected_mode;//如果是 TRUE 的話玩家是無敵的 UINT protected_mode_start_time;
/********************************************************************/
/*class player_side_plane 的建構子 */
/*input BOOL p_aliveÎTRUE 表示這個物件是活的,FALSE 表示這個物件是 */
/*死的 */
/*input BOOL p_moveableÎTRUE 表示這個物件是可移動的,FALSE 表示這 */
/*這個物件是不可移動的 */
/*input int p_mode_of_flyingÎ0 表示由人控制 man_controlled */
/* 1 表示直線飛行 stright */
/* 2 表示朝敵人方向飛行 move_to_enemy */
/*input double p_xposÎ這個物件在螢幕中 x 的位置 */
/*input double p_yposÎ這個物件在螢幕中 y 的位置 */
/*input double p_angelÎ這個物件移動的角度 */
/*input double p_speedÎ這個物件移動的速度 */
/*input double p_xÎ這個物件的圖片在圖檔中 x 的位置 */
/*input double p_yÎ這個物件的圖片在圖檔中 y 的位置 */
/*input double p_widthÎ這個物件的圖片的寬度 */
/*input double p_longthÎ這個物件的圖片的長度 */
/*input LPDIRECTDRAWSURFACE p_lpDDoffscreanÎ這個物件的圖片要存入*/
/*顯示頁 */
/*input int p_powerlevelÎ這個物件的 powerlevel */
/*input int p_bombstock Î這個物件的炸彈存量 */
/*input BOOL p_protected_modeÎTRUE 表示無敵,FALSE 表示會死 */
/*input UINT p_protected_mode_start_timeÎ無敵模式的起始時間 */
/*沒有輸出直 */
/********************************************************************/
player_side_plane(BOOL p_alive,BOOL p_movable,int p_mode_of_flying,double p_xpos,double p_ypos,double p_angle, double p_speed,int p_x,int p_y,int p_width,int p_longth,
LPDIRECTDRAWSURFACE p_lpDDoffscrean,int p_powerlevel,int p_bombstock,BOOL p_protected_mode
,UINT p_protected_mode_start_time)
:moveobject(p_alive,p_movable,p_mode_of_flying,p_xpos,p_ypos,p_angle,
p_speed,p_x,p_y,p_width,p_longth,p_lpDDoffscrean) {
score=0;
powerlevel=p_powerlevel;
maxpowerlevel=6;
bombstock=p_bombstock;
protected_mode=p_protected_mode;
protected_mode_start_time=p_protected_mode_start_time;
counter_to_next_powerlevel=0;
max_of_counter_to_next_powerlevel=10;
}//建構子
/********************************************************************/
/* class player_side_plane 的解構子 */
/*沒有輸入值 */
/*沒有輸出值 */
/********************************************************************/
~player_side_plane() { }//解構子 };
/********************************************************************/
/* class guided_missile:public 這個類別定義了追蹤飛彈 */
/********************************************************************/
class guided_missile:public moveobject {
public:
moveobject *a_target;//追蹤飛彈的目標
object_draw_list **ptr_of_a_targets_list;//追蹤飛彈的目標所在的串列結構的頭 的指標
object_draw_list *targets_list; //追蹤飛彈的目標所在的串列結構的頭
/********************************************************************/
/*class player_side_plane 的建構子 */
/*input BOOL p_aliveÎTRUE 表示這個物件是活的,FALSE 表示這個物件是 */
/*死的 */
/*input BOOL p_moveableÎTRUE 表示這個物件是可移動的,FALSE 表示這 */
/*這個物件是不可移動的 */
/*input int p_mode_of_flyingÎ0 表示由人控制 man_controlled */
/* 1 表示直線飛行 stright */
/* 2 表示朝敵人方向飛行 move_to_enemy */
/*input double p_xposÎ這個物件在螢幕中 x 的位置 */
/*input double p_yposÎ這個物件在螢幕中 y 的位置 */
/*input double p_angelÎ這個物件移動的角度 */
/*input double p_speedÎ這個物件移動的速度 */
/*input double p_xÎ這個物件的圖片在圖檔中 x 的位置 */
/*input double p_yÎ這個物件的圖片在圖檔中 y 的位置 */
/*input double p_widthÎ這個物件的圖片的寬度 */
/*input double p_longthÎ這個物件的圖片的長度 */
/*input LPDIRECTDRAWSURFACE p_lpDDoffscreanÎ這個物件的圖片要存入*/
/* input object_draw_list **p_targets_list Î這個物件所要加入的串列的指標 */
/*的指標 */
/*沒有輸出值 */
/********************************************************************/
guided_missile(BOOL p_alive,BOOL p_movable,int p_mode_of_flying,double p_xpos,double p_ypos,object_draw_list **p_targets_list,
double p_speed,int p_x,int p_y,int p_width,int p_longth,
LPDIRECTDRAWSURFACE p_lpDDoffscrean,double p_angle);//建構子
/********************************************************************/
/* class guided_missile 的解構子 */
/*沒有輸入值 */
/*沒有輸出值 */
/********************************************************************/
~guided_missile();
void movable_object_control(struct object_draw_list *b,moveobject
*a,object_draw_list **c);//這個函示負責移動物件本身 };
/*void moveobject_init(struct moveobject *a,BOOL alive,BOOL movable,int xpos,
int ypos,int x_speed,
int y_speed,int x,int y,int width,int longth,
LPDIRECTDRAWSURFACE lpDDoffscrean);*/
BOOL add_object_into_object_draw_list(object_draw_list *a,moveobject
*b,object_draw_list **c);//這個函是把物件 b 加入到它所該加入到的串列 a 當中,而 c 是 a 的指標
//void movable_object_control(object_draw_list *b,moveobject *a,object_draw_list
**c);
void object_draw_list_control(object_draw_list *a,object_draw_list **b);//這個函式會 控制串列 a 中所有物件該做的動作而 b 是 a 的指標
sparkle *checkhit(object_draw_list *attacker,object_draw_list
*defender,object_draw_list **c,object_draw_list **d
,LPDIRECTDRAWSURFACE lpDDoffscrean);
//這個函式串列 attacker 中是否有某些物件跟串列 defender 中的否些物件相撞,如
果 attacker 串列中的 A 物件和 defender 串列中的 B 物件相撞,則把 A 物件由 attacker 串列中刪除,同時也把 B 物件由 defender 串列中刪除,且傳回一個指向 sparkle 的 指標。但是如果 attacker 串列和 defender 串列當中沒有任何物件相撞則這個函式傳 回 NULL
#endif
3.6.2.1.3 myplane.cpp
這是遊戲中要用到的函式
#include "myplane.h"
//這個函示負責初始化一個會移動的物件,類別 moveobject 的建構子
/********************************************************************/
/*class moveobject 的建構子 */
/* */
/*input BOOL p_aliveÎTRUE 表示這個物件是活的,FALSE 表示這個物件是 */
/*死的 */
/*input BOOL p_moveableÎTRUE 表示這個物件是可移動的,FALSE 表示這 */
/*這個物件是不可移動的 */
/*input int p_mode_of_flyingÎ0 表示由人控制 man_controlled */
/* 1 表示直線飛行 stright */
/* 2 表示朝敵人方向飛行 move_to_enemy */
/*input double p_xposÎ這個物件在螢幕中 x 的位置 */
/*input double p_yposÎ這個物件在螢幕中 y 的位置 */
/*input double p_angelÎ這個物件移動的角度 */
/*input double p_speedÎ這個物件移動的速度 */
/*input double p_xÎ這個物件的圖片在圖檔中 x 的位置 */
/*input double p_yÎ這個物件的圖片在圖檔中 y 的位置 */
/*input double p_widthÎ這個物件的圖片的寬度 */
/*input double p_longthÎ這個物件的圖片的長度 */
/*input LPDIRECTDRAWSURFACE p_lpDDoffscreanÎ這個物件的圖片要存入*/
/********************************************************************/
moveobject::moveobject(BOOL p_alive,BOOL p_movable,int p_mode_of_flying,double p_xpos,
double p_ypos,double p_angle,double p_speed,
int p_x,int p_y,int p_width,int p_longth,
LPDIRECTDRAWSURFACE p_lpDDoffscrean) {
//把外面傳進來的參數用來初始化物件的各個成員 alive=p_alive;//alive 用來表示物件是否還存在
movable=p_movable;//用來表示這個物件是可移動的 mode_of_flying=p_mode_of_flying;//物件飛行的模式
xpos=p_xpos;//物件圖片的最左上角的點在螢幕中的 X 位址
xpos=p_xpos;//物件圖片的最左上角的點在螢幕中的 X 位址