• 沒有找到結果。

網路對戰遊戲

N/A
N/A
Protected

Academic year: 2021

Share "網路對戰遊戲"

Copied!
64
0
0

加載中.... (立即查看全文)

全文

(1)

逢甲大學

資訊工程學系專題報告

網路對戰遊戲

學生:唐大業

(四丁)

游浚彥(四丁)

張唐瑜(四丁)

張筱農(四丁)

指導老師:李維聰

中華民國九十一年十一月

(2)

目錄

---

Chapter1.前言

(1)製作動機與目的---1

Chapter2.遊戲開發工具介紹

(1) directX 簡介---3

(2)winsock 介紹---7

(2.1)Windows socket 簡介

---7

(2.2)Winsock 的優點

---8

(2.3)網路程式的輪廓與主要函式介紹

---11

(2.4)伺服器端要如何為連結作準備

---15

(2.5)用戶端要如何為連結作準備

---15

(2.6)伺服器端要如何完成連結

---16

Chapter3.遊戲製作流程和原理

(1) 遊戲方面

(1.1)設定程式協調層級

---20

(1.2)設定螢幕顯示模式

---21

(1.3)繪圖頁的概念

---21

(1.4)透空的效果

---22

(3)

(1.5)RGB 值的計算

---23

(1.6)顏色鍵的使用

---24

(1.7)動畫處理

---25

(1.8)人物移動

---25

(1.9)碰撞偵測

---26

(1.10)障礙物與邊

---26

(1.11)魔法攻擊

---27

(1.12)扣點的方法

---27

(2) 網路方面

(2.1)節點的資料結構

---28

(2.2)收集封包資料

---29

( 2.3 ) 亂數物品

---30

(3) 美工方面---33

Chapter4. 網路遊戲系統流程說明

(1) The flow chart of the winsock program

(1.1)遊戲開始前的準備

---42

(1.2)THE LOGICAL FLOW CHART OF THE INTERNET OF THE ONLINE GAME

---44

(2) The detail flow chart of the internet of the online game

(2.1)SERVER

---45

(4)

(2.2)CILENT

---49

Chapter5.評估討論與心得

討論與心得---55

Chapter6.遊戲使用說明

---58

Chapter7.參考資料

---59

致謝

---60

(5)

Chapter1.前言

(1)製作動機與目的

現在時下的青少年最嚮往的休閒運動是什麼?

我想玩線上遊戲一定也在排名之中,解釋的理由顯而易見,近來網咖盛 行,跟網路遊戲的發達有著相當的關係,許多廠商衝著這塊線上的大餅, 紛紛開發出 on-line game,或者去代理日本、韓國所製作的 on-line game,可見線上遊戲對於遊戲產業的影響之鉅,甚至已經有遊戲公司公開 上市。 我們的專題在選擇題目時,就因為我們都是愛好遊戲的狂熱者,再加上線 上遊戲在未來幾年必定還是整個遊戲產業的趨勢,無獨有偶,大多遊戲公 司必定會招募優秀人才去開發線上遊戲,這是我們選擇「多人線上遊戲」 的目的,雖然我們對於真正的萬人線上遊戲的架構,不是很清楚,不過這 卻是我們心血所換得的成果,對於未來應該有所幫助。 再者,因為再大三時修了一些網路的課程,對網路的架構、運作,還有各 各不同種類的網路的特性,我們都已有初步的認識,讀的也頗有心得,也 算打下了基礎。但是,對於撰寫一個網路程式,我們卻是連皮毛都沾不到, 雖然現在有許多跨平台的網路程式語言例如:java, 要撰寫一個網路程 式已經不是那麼困難,但是總覺得像建房子沒有建地基,這或許是為什麼 選擇用 socket 來撰寫我們專題的原因,socket 為最原始的一個介面提供

(6)

給使用者在 socket 間傳送資料,它提供的函式讓我清楚了解網路怎麼去 產生,要有什麼準備工作,如何完成,雖然寫起來挺麻煩的,而且也漸漸 地少被使用,退於趨勢,但各各步驟都很詳細,幫助我對網路的認識。 會選擇主從式架構(server-client mode)是因為它是時下最普及的網路架 構,再者線上遊戲利用主從式架構,server 與 client 的互動最清楚也最 好管理,這時 server 的效能便是重點,加上網路資料庫的應用,使的 server 的角色愈來愈重要,依賴主從式架構來管理必是線上遊戲的一個 趨勢,而且也最好撰寫網路程式的一種架構。 最後,當然是覺得想跟別人做一個不一樣的專題,大部分的人聽到製作網 路遊戲都會退卻,重點是我們也想挑戰看看,一個製作遊戲的困難度和團 隊的配合,各施長才,加以整合;當然我們也層遭遇困難想退縮過,從一 開始想做 3d 引擎遊戲到網路賽車遊戲到最後的線上對戰遊戲,無非是專 業技術缺乏或者考慮可行性的原因讓我們退而求其次。但是不管怎麼樣, 我們從一無所知道現在完成一個網路遊戲,不管我們做的結果好不好,對 我們將來絕對是有好無壞,助益無窮。

(7)

Chapter2.遊戲開發工具介紹

1) directX 簡介

DirectX SDK

DirectX SDK(DirectX Software Development Kit),是微軟所開發,主要用在 設計多媒體、2D、3D 遊戲及程式的 API,其中包含了各類與製作多媒體功 能相關的元件,各元件底下提供許多處理多媒體的介面與方法。底下列出 directx 所包含的一些元件: -DirectDraw -DirectInput -DirectSound -DirectMusic -DirectPlay -DirectSetup DirectX 的特色

-直接存取影像記憶體 -支援硬體加速 -網路連線功能 DirectX 可以視為一種程式設計師與硬體間溝通的橋樑,程式設計師不必再

(8)

去花費心思去思索如何去撰寫低階的程式碼來和硬體打交道,只要巧妙的 運用 DirectX 中的各種元件,就可以更簡單的製作出高效能的遊戲程式。 底下將對 DirectDraw 做進一步的說明 DirectDraw 特點: ‹ 直接存取影像記憶體 ‹ 自動的影像硬體輪廓 ‹ 自動使用可取的的硬體加速,不需程式設計師做額外的動作 ‹ 程式設計師可直接使用一些進階的圖形函式,不用自行撰寫

IDirectDrawSurface IDirectDrawPalette IUnknown

IDirectDrawClipper

DirectDraw 的架 構

(9)

DirectDraw 是由許多 COM 物件組合而成,如上圖,這些物件都由 Iunknown 這個基本類別所衍生出來。 -IDirectDraw 代表顯示裝置,通常是一個顯示卡。可以用一個 DirectDraw 的物件 來控制一些顯示裝置的基本性質,例如影像的顯示模式。 -IDirectDrawSurface 此物件表示影像記憶體的範圍,通常利用內建的點陣圖函式來儲 存影像,並將影像顯示在螢幕上。 -IDirectDrawPalette 此物件代表調色盤,可用來操控調色盤。通常一個 DirectDraewPalette 物件跟一個 DirectDrawSurface 物件相連,這樣再 顯示影像時才知道要使用哪一種顏色。 -IdirectDrawClipper 此物件會防止應用程式畫圖時超出特定範圍。當一個 DirectDraw 應用程式要在螢幕上顯示時,通常會使用裁剪程式(Clipper),物件才 不會畫出視窗客戶區(Client Area)之外。

(10)

DirectDraw 硬體抽象層(HAL) 可以使使用者充分使用機器上提供的硬體加速裝置。除非要爲影像硬 體撰寫裝置驅動程式之外,否則不需直接處理 HAL。 DirectDraw 軟體模擬 軟體模擬,有時稱為 HEL,提供硬體無法支援的部分。如果應用程式需 要某些硬體無法支援的函式,HEL 將會組合原先硬體提供的功能來達 成所要的功能。 如下圖所示,通常透過 HAL,HEL,一個 DirectDraw 應用程式可以使用任何需 要的函式,而不需理會使用者的硬體是否支援這些功能。這樣的特性達成 了易修改及可攜性高的程式設計理念。 有 支 援 的 函 式 沒 有 支 援 的 函 式 應用程式要求函式 DirectDraw HEL HAL 硬體 DirectDraw,HAL 以及HEL

(11)

2) winsock 介紹

2.1)Windows socket 簡介

Winsock 網路 API 可以如此定義:「Windows Sockets:Microsoft Windows 下的開放式網路程式設計介面」

所謂的「開放式」的規格,就是指他是以合作的精神所開發出來,且不必 花費任何費用。

Windows Sockets API (WSA) 包函一組函式呼叫、資料結構、以及慣例。 WSA 提供任何 Microsoft Windows 程式一個標準的網路服務存取方式,你 可以透過Windows Sockets API 開發各種 TCP/IP 網路軟體。這個 API 相 當複雜且具有彈性,但他使你不用擔心底層網路的細節,因此他也相當簡 單乾淨。 Windows Sockets 規格清楚定義了網路軟體與網路協定層的之間的分工方 式。Winsock 軟體的工作是提供一個好的使用者介面以及處理資料,而 Winsock 協定層的工作是利用標準傳輸協定、驅動程式、及網路媒介來接 送資料。軟體提供內容,而協定層負責收送。

不像其他的API ,Windows Sockets 不只提供原始碼的相容性,亦提供機 器碼的相容性,因此當程式再不同網路系統或作業系統間做移植時,並不 需要修改。

(12)

2.2)Winsock 的優點

‹ 他是開放式標準 在現今的社會裡 我們十分依賴非正式或正式的標準,在電腦世界尤 其是如此,我們有標準檔案格式,視訊繪圖格式,印表機語言等。有的時 候標準反而比科技本身重要。開放式標準讓科技容易取得之外,還有助於 科技的散佈,TCP/IP 是 Internet 高速成長的大功臣,他的成功來自於他的 互通性,這個互通性是由發展中無數的協定層及軟體工程師不斷測試及改 進所獲得的。這種由競爭者一起合作開發大家都受惠的軟體的精神,正是 開放式標準的象徵,而Winsock 正是由這樣的精神所開發出來的。 ‹ 他提供了原始碼的移植性

Windows Sockets API 是由 4.3 版的 Berkeley Software

Distribution(BSD 4.3)中的 Berkeley Sockets API 衍生而來的。相同的, Windows Sockets 也能提供對不同協定層存取的能力,不過在 Windows Sockets1.1 版只針對 TCP/IP 設計。Windows Sockets API 定義了新的非同

步Socket 作業模式,但也同時保留了現有的同步模式。你仍可以用舊的

模式來開發軟體,也就是先等每個網路動作完成後才進行下一步的 (blocking),或者,用詢問的方式偵測動作是否完成(nonblocking)。對於 16 位元的 Windows 而言,他並非是真正的多工的作業系統。儘管如此, Windows Sockets 的 Berkeley Sockets 相容性仍使你更容易轉移到 Windows

(13)

環境,尤其是提供類似UNIX 之先佔式多工的 32 位元 Windows 環境(NT 與95)就更為容易。 ‹ 它支援動態連結 動態連結函式庫(DLL)是 Microsoft Windows 的主要特色,它們是 具有可執行程序的函次庫,有定義良好的介面。顧名思義,應用程式會在 執行時期動態地與他們連結,而非編譯時期與他們靜態地連結。這種技術 有許多優點: ˙當許多程式同時使用一個 DLL 檔,它們會用同一個程式碼區塊,有就 是只有一份 DLL 程式碼存在記憶體中。 ˙程式本身與 DLL 分開,所以你可以改變 DLL 而不必改變程式。反過來 說也成立。 ˙所有提供相容 API 的 DLLs,也提供一個相容的程式二元碼介面(ABI)。 ˙不須重新編譯或連結就能讓程式在不同廠商的 Winsock DLL 上執行。具 最高的彈性與便利。 Winsock 提供了直接存取(OSI 第四層)的能力,那一層是提供主要服務的 一段。依照不同程式的需求,可以選擇不同的傳輸協定,在TCP/IP 層有 兩個主要的通訊協定TCP 和 UDP 分別提供聯結導向式跟無連結式的服 務類型供選擇。 無連結導向式(Connectionless)服務:UDP

(14)

無連結導向式傳輸服務,亦稱為資料務服務(datgram services),是不具可 靠性的,他不一定保證能將封包送達,也不一定會照本來的順序送達。就 算是在半途中有損壞,也不會通知你這些情況。 無連結導向式傳輸服務很簡單,這也是他的優點,他的額外負擔很少,所 以能有高效率的表現,如果需要變成可靠的傳輸,須在應用程式中加入你 自己提供可靠的傳輸服務。

使用者資料物協定(Uer Datagram Protocol 簡稱 UDP)是 TCP/IP 協定組中 最主要的資料物協定,而網際網路控制訊息協定(Internet Control Message Protocol,簡稱 ICMP)是另一個資料物通訊協定。你必須用 SOCK_RAW sockets 來存取 ICMP,但由於 SOCK_RAW sockets 是 Windows Socket API 中可有可無的功能,ICMP 自然也非處處可用。 連結導向式服務(Connection-oriented)的服務:TCP 這和無連結導向是不一樣的地方,在於他是具可靠性。 連結導向式就很像電話服務一樣,當你撥通,聽到對方聲音時,連線已經 建立了,會一直有個虛擬電路(virtual circuit)存在,直到對方掛掉你的電 話。連結導向式沒有像無連結式一樣簡單,在建立跟釋放虛擬電路時、送 資料收條,重送資料,及封包排序都會有額外的負擔,但是也可以保證資 料可以照一定排序到達,不會遺失資料的優點。 TCP 所提供的子服務:資料收條、資料排序、資料重送、及刪除重覆的

(15)

資料,它同時提供流量控制和Out of band 的資料傳送。

2.3)網路程式的輪廓與主要函式介紹

所有的網路應用程式皆分為五個步驟: ‹ 開啟一個 Socket ‹ 為 Socket 命名 ‹ 與另一個 Socket 結合 ‹ 在 Socket 間傳送資料 ‹ 關閉該 socket

網路I/O 的流程跟檔案 I/O 十分類似,事實上網路 I/O 是由檔案 I/O 衍生 而來的

開啟一個Socket

socket( )

用戶端與伺服器端都需要一個socket 以存取網路資料,使用 socket( )函式 呼叫可以開啟一個socket

SOCKET PASCAL FAR socket( int af ,int type ,int protocol) af: address family ,也就是 socket 網域

type:socket 類型

protocol:所要使用的協定

(16)

SOCK_DGRAM socket 類代表的協定是 UDP,而 SOCK_STREAM socket 類型所代表的是TCP,在這種情況下,protocl 都會被忽略,但你最好將 他預設為0

除了這兩種類型以外,還有SOCK_RAW,在 1.1 版中的 winsock 可以接

受他,你可以利用SOCK_RAW sockets 去存取 TCP、UDP 之外的協定,例如ICMP

Socket 命名 要幫socket 命名就必須設定三項參數:協定、port、位址 sockaddr 結構 struct sockaddr{ u_short sa_family; /*位址家族*/ char sa_data[14]; /*未定義*/ }; sa_family: 位址家族 sa_data: 依照位址家族的定義值的位址結構資料區 sockaddr_in 結構

對TCP/IP 位址家族(PF_INET)而言,會使用到的是 sockaddr_in 結構,非 傳統的sockaddr 結構.

(17)

short sin_family;/*位址家族(PF_INET)*/ u_short sin_port; /*port*/

struct in_addr sin_addr/*IP 位址(32 位元)*/ char sin_zero[8]; /*<無用的填塞物>*/ }; sin_family : 位址家族 sin_port : 16 位元的 port 號碼 sin_addr : 32 位元的網際網路位址 PS:Port 號碼必須根據 RFC 中的規定: 0~1023: 給大家眾所皆知的固定服務(如:FTP) 1024~49151 :是給一些 IANA 列出來,給已註冊的 port 或一 般行程使用 49152~65535:是動態及私有 port bind( )

bind( )會利用 sockaddr_in 結構中的值來為本地的 socket 命名.

int PASCAL FAR bind(SOCKET s,struct sockaddr FAR *addr,int namelen)

s: socket handle

addr: 指向 socket 位址結構的指標(對 TCP/IP 而言一定是 sockaddr_in 結構)

(18)

與另一個Socket 結合 到目前為止我們已經在伺服器端與用戶端均開啟了一個 Socket,並至少 為伺服端的socket 命名,接下來伺服器端要準備接收封包,而用戶端要 準備發送封包,當這樣的準備工作完成後這兩端的sockets 就叫建立了一 個「結合」(association)。 如圖我們知道,在一個socket 結合中包含了 5 個部分: OSI 層號 7 6 5 --- 4 3 2 1 網路 網路 這兩個Sockets 名稱的組合就形成了一個「結合」。在這個組合的過程包 過3 個步驟: 1.伺服器為結合做準備 2.用戶端為結合設初值 3.伺服器完成這個結合 Windows Sockets 用戶端應用程式 用戶端socket handle 用戶端 socket (1) 協定 本地用戶端 遠端伺服端 2)連接埠號碼 4)連接埠號碼 3)IP 位址 5)IP 位址 Windows Sockets 伺服去端應用程式 伺服器端socket handle 伺服器端 socket (1) 協定 本地用戶端 遠端伺服端 2)連接埠號碼 4)連接埠號碼 3)IP 位址 5)IP 位址

(19)

2.4)伺服器端要如何為連結作準備

以TCP 的伺服器而言,他需要一些步驟讓用戶端使用它的 socket,請看 底下的listen( )函式。

Listen( )

Int PASCAL FAR listen(SCOKET s,int backlog); s: 一個已命名但尚未連結的 socket handle backlog: 等待連結的序列長度

Backlog 參數的意義是當伺服器在處理其他事情時,有多少個用戶送來的 連結要求可在序列中等待。當你完成此動作之後,你需要在呼叫一個函式 來完成此動作,有三種方法:accept( )、select( ),WSAAsyncSelect( )。

另一方面UDP 要做結合時,並不需要做任何是來完成,因為 UDP 伺服

器再接收到封包的時候就建立了結合。

2.5)用戶端要如何為連結作準備

Connect( )

Int PASCAL FAR connect(SOCKET s,struct sockaddr FAR *addr,int namelen);

s:socket handle

addr: 指向 socket 位址結構的指標(對 TCP/IP 而言一定是 sockaddr_in 結構)

(20)

Connect( )函式的參數與 bind( )函式的參數相同,但就 connect( )而言,你 受給sin_port 與 sin_addr 的初值是遠端的 socket 名稱,即伺服器用的 socket 名稱,而呼叫bind( )時設的是本地的 socket 名稱。

如果是對於UDP 的用戶端,有兩個方法設定結合。第一個方法你要用同

一個socket 送資料給多個不同的遠端主機時較適用,用的是 sendto( );另 一個方法,

先設定socket 結構,呼叫 connect( )函式,然後呼叫 send( )。當你的 UDP socket 會一直送資料給同一個遠端位址時,較常用此方法。

2.6)伺服器端要如何完成連結

對UDP 伺服器而言,只要用 recv( )或 recvform( )從用戶端接受資料即可。 TCP 伺服器則是要呼叫 accept( )。

Accept( )

SOCKET PASCAL FAR accept(SOCKET s,struct sockaddr FAR *addr,int FAR *addrlen);

s: socket handle

addr: 指向 socket 位址結構的指標(對 TCP/IP 而言一定是 sockaddr_in 結構)

addrlen: addr 所指向的 socket 結構的長度(對 TCP/IP 而言一定是 4)

(21)

結建立的工作。

Socket 間傳送資料

到這邊我們已經在用戶端和伺服器的sockets 間建立了結合。

----傳送資料—

send( )

int PASCAL FAR send(SOCKET s,const char FAR *buf,int len,int flags);

s:socket handle

buf:指向存放要送出的資料的緩衝區之指標 len:要送出資料的長度(以位元組為單位)

flags:影響送出方式的旗標(MSG_OOB、MSG_DONTROUTE)

就datagram(UDP) socket 而言,只有在你建立結合時呼叫 connect( )後, 才可以使用send( )傳送資料.

---接收資料---

recv( )

int PASCAL FAR recv(SOCKET s,char FAR *buf,int len,int flags); s: socket handle

buf:指向用來存放收到資料的緩衝區之指標 len:此緩衝區的長度(以位元組為單位)

(22)

要是在未建立連結的傳接資料

----傳送資料—

sendto( )

int PASCAL FAR sendto(SOCKET s,const char FAR *buf,int len,int flags,const struct sockaddr FAR *to,int tolen);

s:socket handle

buf:指向存放要送出的資料的緩衝區之指標 len:要送出資料的長度(以位元組為單位)

flags:影響送出方式的旗標(MSG_OOB、MSG_DONTROUTE) to:一個指向目的地的位址及 port 的 socket 結構的指標

tolen:由 to 所指向的結構的長度(TCP/IP 一定是 4)

就datagram(UDP) socket 而言,只有在你建立結合時呼叫 connect( )後, 才可以使用send( )傳送資料.

---接收資料---

recv( )

int PASCAL FAR recv(SOCKET s,char FAR *buf,int len,int flags, const struct sockaddr FAR *from,int FAR *fromlen);

s: socket handle

buf:指向用來存放收到資料的緩衝區之指標 len:此緩衝區的長度(以位元組為單位)

(23)

flags:影響接收方式的旗標(MSG_IIB,MSG_PEEK) form:一個指向用來發送端位址的結構的指標

fromlen:由 form 所指向的結構的長度的指標 關閉該socket

closesocket( )

int PASCAL FAR closesocket(SOCKET s); s: socket handle

對於datagram(UDP) socket 而言,呼叫 closesocket( )就是單純地將 socket 資源還給協定堆疊,而對資料流(TCP)socket 而言,呼叫 closesocket( )除

了將socket 資源還給協定堆疊外,他還會嘗試將以建立的連結關閉。

Shutdown( )

Int PASCAL FAR shutdown(SOCKET s,int how); s:socket handle

how:用來描述 shutdown 動作的旗標

how 是一個位元旗標,用來描述此 socket 要如何被 shutdown,他有三個 可用值

0:不允許接收(底層協定不受影響)

1:不允許發送(一個 TCP FIN 的訊息會送給遠端 socket)

2:不允許發送與接收(一個 TCP FIN 的訊息會送給遠端 socket)

(24)

Chapter3.遊戲製作流程和原理

3) 遊戲方面

1.1) 設定程式協調層級

在 Windows 中,OS 掌管所有可以用的資源,這些資源必須適當的分配 給每個程式使用,因此程式本身必須要告知 OS 要使用哪些資源,這就是為 何要設定協調層級的原因。 當建立 DirectDraw 物件後,要使用「SetCooperativeLevel」方法來設定 程式協調層級。程式片段如下: result = pDD7->SetCooperativeLevel(m_hWnd,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN|DDSCL_ALLOWREBOOT ); if(result !=DD_OK) MessageBox("設定程式協調層級失敗!"); 執行「SetCooperativeLevel」方法後,若回傳值為 DD_OK,表示設定協調層級 成功。此方法需要傳入兩個參數,參數 1 設為「m_hWnd」表示為應用程式 主視窗;參數 2 則用來設定旗標。 下表列出一些常用的設定旗標: 設定旗標 說明 DDSCL_ALLOWREBOOT 在獨占模式中,能接收 Ctrl+Alt+Del 的訊 息 DDSCL_EXCLUSIVE 設為獨占模式,需和 DDSCL_FULLSCREEN 一起使用

(25)

DDSCL_FULLSCREEN 設為全螢幕模式,需和 DDSCL_EXCLUSIVE 一起使用 DDSCL_NORMAL 正常視窗模式,不可和 DDSCL_EXCLUSIVE 或 DDSCL_FULLSCREEN 一起使用 DDSCL_NOWINDOWCHANGS 不允許最小化或改變視窗大小

1.2) 設定螢幕顯示模式

DirectDraw 中,使用「SetDisplayMode」方法設定螢幕顯示模式,如下列 程式片段: result=pDD7->SetDisplayMode(640,480,16,0,DDSDM_STANDARDVGAMODE ); if(result !=DD_OK) MessageBox("設定螢幕顯示模式失敗!"); 下表說明各參數的意義: 參數 說明 640 設定水平解析度 480 設定垂直解析度 16 設定螢幕色彩位元 0 設定螢幕更新頻率(0 表示使用目前预設 的更新頻率) DDSDM_STANDARDVGAMODE 需設為 DDSDM_STANDARDVGAMODE

1.3) 繪圖頁的概念

DirectDraw 中,利用繪圖頁配合貼圖、翻頁的方法來顯示點陣圖。繪圖 頁是一塊顯像或者暫存點陣圖的記憶體,依功能可分為: 1. 主繪圖頁:顯像記憶體,在主繪圖頁中的點陣圖會顯示在螢幕上

(26)

2. 後緩衝區:在後緩衝區中可以貼上點陣圖,當利用翻頁的方式切換至後 緩衝區時,此繪圖頁會變成主繪圖頁。 3. 幕後暫存區:用來暫存要使用點陣圖的繪圖頁。 幕後暫存區 主繪圖頁 幕後暫存區 後緩衝區 幕後緩衝區 後緩衝區 通常不會把點陣圖直接貼在主繪圖頁,而先貼到後緩衝區,在利用翻頁的方 式,將點陣圖顯示出來。這樣做,可以避免閃爍的問題發生。 主繪圖頁 主繪圖頁 主繪圖頁 後緩衝區 後緩衝區 後緩衝區 翻頁時,並不需要移動任何緩衝區中點陣圖的資料,只需移動指標將後緩衝 區設為主繪圖頁,就可以顯示其中的內容,在速度上會提升很多。

1.4) 透空的效果

在 DirecrDraw 中,要製作透空的方法,關鍵在於顏色鍵的使用。只要選 取圖片中想要透空的顏色當顏色鍵,如此一來該點陣圖中,任何顏色為顏色 鍵的部分都會自動地被透空。 貼圖 翻頁 翻頁

(27)

1.5)RGB 值的計算

以白色為例: 白色->(255,255,255) 24 位元的模式下 R G B 二進位值: 1111 1111 1111 1111 1111 1111 十六進位值: f f f f f f 16 位元的模式下 依使用者顯示卡的不同,分為二種方法表示: 一. 每個 RGB 值各佔 5 位元,最前面的位元為 0 R G B 二進位值: 0 111 11 11 111 1 1111 十六進位值: 7 f f f 二. RGB 值所佔位元各為 5、6、5 R G B 二進位值: 1111 1 111 111 1 1111 十六進位值: f f f f

(28)

1.6)顏色鍵的使用

DirectDraw 中,顏色鍵的結構定義如下 typedef struct _DDCOLORKEY{

DWORD dwColorSpaceLowValue; //最低顏色值 DWORD dwColorSpaceHignValue; //最高顏色值 }DDCOLORKEY,FAR* LPDDCOLORKEY; 通常會把最高顏色值和最低顏色值設為同一個顏色,來定義一個顏色鍵。 底下是定義顏色鍵的程式碼: DDCOLORKEY key Key.dwColorSpaceLowValue= 0x7fff; Key.dwColorSpaceHighValue= 0x7fff; 上面程式片段,最高顏色值和最低顏色值都設為白色。 其中,0x7fff 為在 16 位元第一種模式中的白色 RGB 值。 到此為止的部分是在定義一個顏色鍵,還要在把顏色鍵指定給繪圖頁使用, 設定繪圖頁顏色鍵的方法為「SetColorKey」,使用語法如下 HRESULT SetColorKey{ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey}; 第一個參數為設定旗標,若設為「DDCKEY_SRCBLT」時,幕後暫存區中被

(29)

設定為顏色鍵的顏色將不會顯示在螢幕上,如此就產生了透空的效果了。

1.7)動畫處理

遊戲中的動畫效果,像是人走路的動作、魔法攻擊等。動作原理,如下 在遊戲中所用到的人物、魔法等圖片,每張都向上圖所示一般,切成許多 格。程式中,變數 c 表示目前要貼的圖是哪一格。以上圖為例,假設每格都 是 100x100,目前要貼第 3 格,則此時 c=2,變數 xp=c*100,上圖貼圖時,只貼從 xp 處貼 100 個像素,然後 c 值在增加 1,這樣下次就會貼下一格。

1.8)人物移動

使用上、下、左、右四個鍵來控制 8 個方向的移動。 只按上鍵,則將顯示範圍的 y 座標值減少 只按下鍵,則將顯示範圍的 y 座標值增加 只按左鍵,則將顯示範圍的 x 座標值減少 只按右鍵,則將顯示範圍的 x 座標值增加 同時按上和左鍵,則將顯示範圍的 y 座標值減少、x 座標值減少 同時按上和右鍵,則將顯示範圍的 y 座標值減少、x 座標值增加 顯示範圍座標 大地圖 人物或魔法圖

(30)

同時按下和右鍵,則將顯示範圍的 y 座標值增加、x 座標值增加 不屬於上述 8 種情形,則不作相關的處理。 (1.9)碰撞偵測 遊戲進行中,可能會發生的碰撞情形有玩家碰到玩家、玩家碰到障礙 物、玩家被魔法擊中等。在遊戲中,利用碰撞點與區塊來判斷是否發生碰 撞。(見下圖)

1.10)障礙物與邊

怎麼樣算碰到障礙物和邊 也是利用碰撞偵測的方法(見下圖) 遊戲中,人物都有設定各自的區塊與碰撞點。當玩家的碰撞點進入了另一 玩家的人物區塊,就表示發生碰撞。同理,偵測是否碰到障礙物、是否被魔 法擊中,也是用同樣的方法判斷。 人物區塊 碰撞點

(31)

1.11)魔法攻擊

每給人所放出的魔法都視為一個物件。同時按下 A+Q、W、E、R 四 個鍵的其中一個,只要有足夠的 mp,就可以施放出魔法。 魔法存在的時間是固定的,時間長度約 1~2 秒。時間到該魔法就會消 失。

1.12)扣點的方法

生命值部分,當被魔法擊中時,會減少。扣多少的判斷,則是看該魔法的 威力來計算。威力越大的魔法,所造成的傷害也越大。 魔力值的部分,則是每當發射一次魔法就減少一定的值,減少的多寡,則 視所發射的魔法強弱來決定,使用威力越強的魔法,所消耗的魔力值就越 多。 至於判斷被擊中的方法,則和判斷人物是否發生碰撞的方法一樣,在此並 不多述,可以參考上面有關碰撞偵測的部分。 至於生命值和魔力值,最大都只到 100。遊戲進行中,恢復生命值和魔力 值的方法,只有撿到地上亂數出現的物品,才可能恢復。

(32)

4) 網路方面

2.1)節點的資料結構

將節點資料結構定義如下: struct nodes //封包結構 { int id_num; //1 位數 編號 short int x; //4 位數 x 座標 short int y; //4 位數 y 座標 short int d; //2 位數 d:紀錄上次按下ㄉ方向鍵 short int xp; //4 位數 xp:人物貼圖ㄉ x 座標 short int attk; //1 位數 是否在攻擊狀態

short int hp; //2 位數 hp:生命值 short int mp; //2 位數 mp:魔力值 short int attk_type; //1 位數 哪一種攻擊 short int attk_x; //4 位數 攻擊的 x 座標 short int attk_y; //4 位數 攻擊的 y 座標

short int attk_d; //2 位數 紀錄上次攻擊的方向 struct nodes *link;

};

struct nodes *head=NULL; struct nodes *rear=NULL; struct nodes *newnode;

利用此結構建立一個鏈結串列,節點資訊及是封包內的資料,利用串列對 節點的存取,就可以知道各各使用者的狀態情形是如何的。

(33)

2.2)收集封包資料

利用 strncat()函式

語法char *strncat(char *dest,const char *source,size_t maxlen)

功能:此函數醬來源字串source 的前 maxlen 個字元連結到目的地字串 dest。 收集程式碼的程式片斷如下; _itoa(my_num,Buffer,10);strncat(Buffer,",",1); _itoa(people[0].abX,Temp,10);strncat(Temp,",",1); strncat(Buffer,Temp,5); _itoa(people[0].abY,Temp,10);strncat(Temp,",",1); strncat(Buffer,Temp,5); _itoa(people[0].d,Temp,10);strncat(Temp,",",1); strncat(Buffer,Temp,2); _itoa(people[0].xp,Temp,10);strncat(Temp,",",1); strncat(Buffer,Temp,5); _itoa(people[0].attk,Temp,10);strncat(Temp,",",1); strncat(Buffer,Temp,2); _itoa(people[0].hptemp,Temp,10);strncat(Temp,",",1); strncat(Buffer,Temp,3); _itoa(people[0].mptemp,Temp,10);strncat(Temp,",",1); strncat(Buffer,Temp,3); _itoa(people[0].magic.type,Temp,10);strncat(Temp,",",1); strncat(Buffer,Temp,2); _itoa(people[0].magic.abX,Temp,10);strncat(Temp,",",1); strncat(Buffer,Temp,5); _itoa(people[0].magic.abY,Temp,10);strncat(Temp,",",1); strncat(Buffer,Temp,5); _itoa(people[0].magic.d,Temp,10);strncat(Temp,"|",1); strncat(Buffer,Temp,3); 上述程式裡用此函式將所有資料包裝起來然後傳送給server,server 也是

(34)

( 2.3 ) 亂數物品

物品架構 struct Item{ int Item_Kind; short int x; short int y; }Item[物品陣列] // Item_Kind: -1,0,1,2,3… (-1 表示不出現,0 表示將出現,其他表示物品種類) SERVER 與 CLIENT 端的處理物品出現的過程,我們以流程圖來說明 其網路方面的流程請參考第4 章。 遊戲中,如果有物品被吃了,就必須傳送封包告訴SERVER,讓 SERVER 去通知每一使用者,說某某人已經吃了某一樣物品,此外,每一物品都有 一個亂數的出現時間,時間一到便會亂數出現在地圖的某個座標上,並且 不會出現在障礙物與人物的座標範圍內,用星號(*)來分辦是物品封包或 者普通封包,Client 端收到封包 decode 後,若有星號(*)就是普通封包, 沒有星號(*)就是物品封包。 流程如下頁:

(35)

///////////////////////////////////server///////////////////////////////////////// //If 亂數被啟動且開始配置物品完成 No

Yes

No //yes 表示,物品出現 的時間已到,亂數給 物品座標 //是否接收到所有 client 與物品種類 端訊息 ,然後傳送 每一個 Yes client 端 //是否收到物品的 陣列index 封包 Yes No //收滿所有 client 端 //No 表示遊戲中 封包,封包最前面加上”*” 沒有物品被吃到 ,包好後送給每一個人 不需傳送訊息告知 //若 yes,表示遊戲中 有物品被吃了,必須 傳送封包通知每一 client 端有人吃了物品,這時也必須把 item_kind 歸 0,並起動亂數時間種子 傳送物品 封包給 client 端 傳送座標封包 給每一client 端 收下一個人 的封包 傳送物品封包 給client 端

(36)

///////////////////////////////////////////////////////client///////////////////////////////////////////////// //if 自己有吃掉物品 Yes No //有吃掉物品 //即是傳送基本資 必須告知server, 訊 讓server 去通知每一個人 //封包前面是否有”*” Yes No //這裡我們用*來分辨是座標 or 物品封包 傳送物品陣 列 index 傳送自己 座標封包 收座標封包 收物品封包 接收封包 from server

(37)

3) 美工方面

本遊戲的美工大都是以 3D 軟體繪製而成的,另在配合 2D 的軟體來 一起作整合處理。 3D STUDIO MAX 介紹 首先是 3D 繪圖所採用的是 3D STUDIO MAX 來完成 3D 部分,要畫 出想要的物件要先了解介面設定,包括:使用者介面、視圖、場景檢視方 法、動畫操作選項。 接著是模組建構部分,分為:基本物件、延伸形式物件、門窗物件、 複合物件、造型與成形物件、塊面物件以及 NURB 物件。 模組編輯部分有:物件位向編輯、幾何物件編輯、立體造型物件編輯、 進階編輯、特殊物件編輯。 材質與外部設定:光源與攝影機、基本貼圖、進階材質、環境設定。 人物 3D 的製作是最複雜的,要對身體有所了解,頭部、身體骨骼及 肌肉,男女頭部、身體的比例,以 Modeling 方式運用 Polygon、Patch、NURBS 來製作,一步步的分別製作眼睛、鼻子、嘴巴、耳朵、頭髮,然後把臉部 結合起來,頭部就完成了,接著是製作手指、腳指頭、角背、腳掌、腳腕 子、脖子、胸部、腰、臀部、胳臂、腿,也通通組合起來完成身體部分。

(38)

使用 3D STUDIO MAX 所繪製的人物的圖: 為了使人物看起來有立體感,並且因為要製作人物的八方向,所以用 3D 建模人物,因為用 2D 來畫的話,人物的八方向製作起來會有些煩索, 每個方向都要重頭繪製一次,用鏡射的方法也至少要畫 4 個出來,且個方 向的大小相似度不好捉拿,所以選擇用 3D 建模的方法來製作人物,這樣 做有幾點好處,視角可以有 3D 化的效果,做法人物向前傾 15 度產生立 體感,而人物的八個方向作法直接用 Z 軸旋轉的功能依次 45 度角八次, 並用轉成程式所要用的 BMP 圖檔一一轉換,就完成了初步人物的八個方 向圖。

(39)

人物某一走路分解動作的八個方向的圖: 遊戲中所使用之圖的製作 人物的動畫的製作:走路、施放魔法的動作,一般說來是要看起來有 連貫性,所以並不是只有簡簡單單的兩三張圖就可完成的,所以先把人物 的身體各個部分的關節分別地獨立出模組,以方便分別的移動、旋轉出想 要的姿勢,把那些姿勢組合出一連串的動作連貫,分別的依上述的方法旋 轉八個方向並製成 BMP 圖檔,就完成了人物最難作的動作方向。 為了節省程式讀取圖檔的時間、方便程式寫作次數,因此把剛剛那些 轉成 BMP 的圖檔分別地調整到最合適大小,然後把那些圖檔做分類,走 路的單方向一組,施放魔法的單方向一組,所以走路就有八方向八組,魔 法施放也是八組,分別地把各組的動作結合成一張圖表,為了要製成一張 圖表,所以把一張新的長條大圖畫分成數同等份大小的格子,把同一方向 的走路圖檔的十六個動作放進去製成一長條狀的一張連續圖檔,也同樣把

(40)

同一方向的魔法施放圖檔的五個動作放進去製成一長條狀的一張連續圖 檔,這樣做程式只要控制下張貼長條圖的某一格子那裡就行了,製作所用 的軟體為 Photoshop,先畫出一長條狀圖,並且規畫出裡面所放置的圖, 依次的拉進去,然後再以藍色為透明色,因為要是以黑色作為透明色,3D 轉成的圖檔的陰影將會不好處理,做顏色的選取時會取的不乾淨,所以這 就是以藍色為透明色的原因。 在 PHOTOSHOP 中製成某方向的魔法攻擊的圖: Í 遊戲中使用的圖

(41)

走路的圖也是同樣的製法: 物品的處理也仿效人物的方法一樣,先用 3D 繪圖繪出四種主要的物 品,再用五種顏色的來配合製出 20 種的物品種類,然後再用 Photoshop 處理,只不過不用做八個方向以及動作的處理,作起來簡單多了,也把所 有的物品也作成一 20 格的長條狀圖,就完成物品欄的製作了。 物品的圖表: 魔法的做法是完全用 2D 製成的,每種魔法的動畫分別以十格的連續 圖檔,分別的每一類的魔法製成長條狀圖,依這方法完成四種魔法。 切成十格再依先後播放順序放入魔法的圖:

(42)

遊戲中圖形大小及座標 人物走路的圖每張大小為 100*100 像素,有 16 個分解動作所以一連串 的動作所構成的長條圖大小為 1600*100 像素。 人物魔法攻擊的圖每張大小為 100*100 像素,有 5 個分解動作所以一 連串的動作所構成的長條圖大小為 500*100 像素。 魔法的圖每張大小為 150*150 像素,有 10 個分解動作所以一連串的動 作所構成的長條圖大小為 1500*100 像素。 物品的圖每張大小為 50*50 像素,有 20 個物品所以所構成的長條圖 大小為 1600*100 像素。 遊戲中各種人物走路、人物魔法攻擊、魔法、物品的像素大小的決定, 都是以符合比例的方式來算出,然而大地圖、主畫面、障礙物的像素大小 和座標位置的處理,則是先以手繪的方格紙畫出,並決定各圖座標、大小, 然後才依此圖為藍本在繪圖軟體中製作。 大地圖部分的建造是用 3D 繪製而成的,以俯視視角來繪畫,且在其 中加入障礙物,以方格算出障礙物所有的座標值、像素大小,以方便遊戲 製作時碰撞點的處理。

(43)

方格的圖:

(44)

在 PHOTOSHOP 中大地圖結合方格圖算出座標值: 大地圖大小為 2400*1800 像素,去掉四周不可走區域真正可走的範圍 為 1600*1200 像素,障礙物有七個,中間最大基台、上下各一座小牆、左 右兩邊各二座小牆。 遊戲的主畫面部分用 2D 製成的,包含不可視的陰影部份、四個人物 的狀態表,其中人物名稱、HP、MP 也必須計算出座標值,讓程式只要鎖 定那位置來改變數值即可。

(45)

遊戲主畫面的圖:

(46)

Chapter4. 網路遊戲系統流程說明

(3) The flow chart of the winsock program (Tcp mode)

1.1) 遊戲開始前的準備

在稍前曾經介紹過,所有網路應用程式皆可分為5 個步驟:

開啟一個socket->為 socket 命名->與另一個 socket 結合->在 socket 間 傳送資料->關閉該 socket

下圖描述的即是上述前3 個步驟的流程,遊戲啟動前,網路所要做的準

備,為server 與 client 架構運作前的準備,流程圖的各各狀態的說明已在 前面介紹過了(請參考 P 11~P15)

(47)

Server

端 Client

yes yes no no yes no yes no yes no 上述的準備工作完成後,就開始進入遊戲主體了,我先說明遊戲的邏輯的 網路架構,讓您更了解網路在我們遊戲的運作。 start Socket() Bind() error Listen() error WSACleanup() exit start Socket() error error Connect() error WSACleanup() exit

(48)

( 1.2)THE LOGICAL FLOW CHART OF THE INTERNET OF THE

ONLINE GAME

上圖中,server 本是無窮迴圈的,除非所有人都登出ㄌ,server 便會停止 服務;而clinet 端在開始遊戲遊戲後,也是無窮迴圈的傳、收座標,除非 使用者要求登出。不過,上圖並不能完全表達網路在整個遊戲中的服務角 色,所以下面將是一步一步的詳細說明整個遊戲流程,分server 與 client 來討論,網路做好遊戲前的準備工作之後

(49)

(4) The detail flow chart of the internet of the online game

(2.1)SERVER

/////////////////////////////Server///////////////////////////// yes no //第一要求連結的為 1 號,以此類推,把編 //號與 xy 座標塞入 node,然後把 node 加入 //鏈結串列中。如圖: null Yes //取得上一次錯誤訊息 no //每接受一連結,連線人數就加 1 no yes //檢查連線人數是否到達指定人數, //是則開局,否則繼續等待連結 Accept() 給定編號和初始的亂數座標 Error WSACleanup() 動態配置一個節點並塞入資料 後,將 node 加入串列中 傳送號碼、x 和 y 座標給要求 連結的client Error WSAGetLastError(); 連線人數加1 Check

(50)

//到這裡為止,link_list 已經建立完成,節點個數即是連線 yes //人數;節點資料也已放在節點裡了,包括號碼、X、Y 座 //標比如: //Head Rear null //這兩個狀態是說明:server 要等待收到 play 的訊 //息才開始遊戲,而第一個要求連結的人,也就是 //1 號,有決定開局的權利,要送 play 訊息給 server //知道。 No //而 server 判斷接收到的訊息是否為”play” //若是 no:則回到上一狀態繼續等待接收 play 訊息 Yes //若是 yes:就傳送”Beginniig”訊息告知每一個 //連結者,遊戲要開始了 // for(Sent=0;Sent<connect_people;Sent++) {retval= send(msgsock[Sent],Buffer,sizeof(Buffer),0)} //如果 connect_people=4,表示有 4 個 client,利用 //for 迴圈將訊息傳遞出去

說明:到這裡為止,Server 與 Client 均準備要進入真正的遊戲主體,Server 要準備的是接收client 端傳來的封包,Client 端要準備的是收集資訊包 好封包後傳送給Server 端。 1 X Y 2 X Y 3 X Y 4 X Y 接收「Play」 訊息 是否為”Play” 傳送”Begining”給每一個 client 端

(51)

//大 while 迴圈

No Yes

//Buffer 代表每當 server 收到一個 client 端送來的封包時

//封包資料是放在 buffer 裡,其資料結構為陣列 //而 collection 代表將”所有”cilent 端的封包收集在 //collection 裡,用分隔符號「|」分別不同 client 端的封包 //其資料結構也是陣列 //從串列的頭開始存取 No(見下頁) Yes //明白的來說,就是當從串列的頭開始存取時,收到第 //一筆封包,放入 buffer,節點指標往後移,再收第二 //筆封包,再放入 buffer,節點指標再往後移,一直做 //下去,直到 head=null 為止 Yes No

While(1) Break big while

清空collection 和 Buffer While(Hea d!=NULL) Receive 封包 from client 沒收到、user 斷線或跳出 將 buffer 的資料收集到 collection 節點指標往後移 (Head=Head->link) 1. 刪除節點 2. 連線人數減 1 3.節點指標往後移 (Head=Head->link) End

(52)

依循著上頁箭頭 //No表示所有client 封包收集完畢 或 已經沒有連線者 //檢查有無 client 在線上 Yes//表示沒有連線者了 No //表示還有 client 在線上 //這裡還需考慮物品封包之存在(參考 P31&P32) Yes No //Server 繼續服務, //回到 big while 迴圈 備註:在回傳給線上的client 端之前,collection 陣列的情形如下: 1 號封包 2 號封包 3 號封包 ... ..

1,x,y, , , , ,|2,x,y, , , , ,|3. x,y, , , , ,|... ..| If(connect_people ==0) 把collection 陣列裡的資料傳送 給還在線上的client 端(看備註) Close_stream=1 if(close_stream==1)

TCP server looping back for more requests

Break big while

(53)

因client 端網路與遊戲程式是整合起來的,所以將合起來一起說明,建議 是與 server 的流程圖對照著看,將會更清楚聊解網路遊戲的運作。

(2.2)CILENT

yes no //自己為 people[0],其他 則為people[1、2、3、、、] 設定自己初始狀態,如 people[0].num=my_num; yes people[0].attk=FALSE; //people[0].abX=myData_x; No //people[0].abY=myData_y; …….等等。 //load picture //地圖裡有一些障礙物 //初始設定 或邊,必須設定不能通 過。 //等待開始遊戲 //就是前面講 的connect()步驟 換頁連接點 no Yes 接下頁 Start 1. 建立 DirectDraw 物件 2. 設定協調層級 3. 設定顯示模式 4. 建立主繪圖頁 5. 連結後緩衝區 失敗 開頭畫面 title() 建立環狀link_list Check_in() error 遊戲準備 工作失敗 接收號碼與初 始的xy 座標 error WSACleanup() 給定 自己 的初 始值 設定不能走的區域

(54)

接上頁 //檢查自己 Yes 是否為1 號 (是否為第一 No 個連線使用者) //若不是則等待 server 傳來的” beginning”訊息 ,收到後即可開始遊戲 Yes No Yes //準備進入遊戲真正主 體 換頁連接點 接下頁 if(my_num==1) 傳送”play”訊息給 server Error MessageBox("等待開始失敗!"); 等待接收”beginning”訊息 是否收到 為”beginning” 的訊息

(55)

//判斷自己是否還活著 Yes //設定人物的碰撞點 因人物在移動時是 No 不可重疊的 //偵測是否有按下攻擊 如果是就會產生魔法 Yes //取得鍵盤狀態 判斷是否按上下左右 左上左下右上右下 並把座標存絕對座標 //繼 attk()之後,若有產生魔法, 就去計算魔法的碰撞點 //重新開始 //這個動作是去判斷別的使用者是否 遊戲 也產生魔法,其資訊來自封包 如果有就設定其魔法的資訊值,以便 往後貼魔法時的使用 //設定不能走的區域 //判斷是否被攻擊到 及計算生命值扣的值 yes No //這裡需考慮物品封包 //取得其他使用者的狀態,包 請參考(P31 & P32) 括alive,x,y,mp,hp,xp,attk,...等 if(people[0].alive == TRUE) Attk() Move() 備註一 SetHitPoint() Fight() 備註二 SetOtherMagic() Continue play? Exit End 1. people[0].alive =TRUE 2. 重新給定 xy 座標 3. 設定 hp=mp=100 NotWalkArea() MagicHitPeople() 備註三 Send_and_Recieve() 備註四 Error MessageBox("網路連線失敗!"); GetOtherPlayerState() 備註五

(56)

備註一: //上,下,左,右,左上,左下,右上,右下 共八個方向 Yes //d:紀錄上次按下ㄉ方向鍵 xp:人物貼圖ㄉ x 座標 c:計算在某方向貼上哪張圖 Yes No//往下一步驟 備註二: //檢查是否有魔法產生 no//往下一步驟 yes 往下一步驟 紀錄舊的xy 座標 是否按下 方向鍵 取得貼圖狀態,設 定貼圖座標 Hit()偵 測碰撞 設定地圖座標 if(people[0].magic. exist == TRUE) 設定魔法的碰撞點 及魔法貼圖狀態

(57)

備註三: 備註四: //,x,y,mp,hp,xp attk,c, ,d, magic.type, No//往下一步驟 magic.abx, Yes magic.aby, magic.d 及 編號 //判斷自己有無生命值 等於0 表示死了 Yes no yes 往下一步驟 No 往下一步驟 yes no yes no //將收到的封包解析 才能取得其他使用者 資訊 往下一步驟 判斷是否 被攻擊 計算扣點值 if(people[0].hp == 0) people[0].alive=FALSE 包封包(將自 己的各各資訊 包裝起來) Send to server error 接收封包from server WSACleanup() Server 關閉 error DecodePacket(Buffer) End

(58)

備註五: No 往下一步驟 Yes //要設定其絕對座標為-1 始其在貼圖時不貼出來 往下一步驟 備註六: //貼自己的魔法圖與其他人的魔法圖 //貼自己的人物圖 //貼其他人的人物圖 //螢幕下方的訊息方塊, 顯示每個使用者目前的hp 和 mp 的值 往下一步驟 依decode 出來的資 料,設定其他使用者的 狀態 判斷有人結 束或跳出 設定其絕對座標為-1 PostMagic() PostGamePic() OtherGamer() 貼螢幕下方的訊息 方塊

(59)

Chapter5.評估討論與心得

評估討論 server 端在收集座標方面,會採用輪詢的方法,然後在送出每個人的 座標到所有使用者,當如果有一使用者網路速度較慢的時候。 會發現網路會有 lag 發生,網路的封包大小 256bytes,平均一秒中傳 25 次(遊戲每 0.04 秒執行整個程式一次,所以平均一秒中傳 25 次)寬算 法...256*(1 秒鐘傳出 25)= 所需頻寬=6.25kbytes/ps=50bps。 網路方面,要修改的是必須固定其傳輸速率,一個人在線上的速度和 4 個人在線上的速度必須相等,還有就是 server 功能可以在增多,比如說 增加踢人或者利用壓縮技術將資料壓縮等功能,還有把介面改成視窗化, 這樣比較方便管理。 遊戲方面,貼圖效率跟網路傳輸效率相同,平均一秒中傳 25 次(遊戲每 0.04 秒執行整個程式一次,所以平均一秒中傳 25 次),需要加強的地方 先是畫面可以再細膩一點,再來是加強一些遊戲性下去,增加一些有趣的 點子或戲劇性的風格,比如說刺激性與冒險性等等。 最重要的是加強玩 者與玩者的平衡,美中不足的是我們的程式玩起來總有些不知道怎麼解決 的小 bug,讓戰鬥有一點點小小的不公平發生,雖然無傷大雅,但還是希 望讓不同的玩者之間,除了個人的技巧以外,不致於佔到更多的優勢,遊 戲中可能會出現一些運氣成份,但是必須讓所以玩者都有相同的機會。

(60)

心得 其實,我們的專題的起初是要做一 3D 引擎,不過了解到要使用到很 多數學的東西後,因此就退堂鼓了,進而轉向動手一起完成一遊戲軟體的 方面。 不過還是以 3D 遊戲為出發點,經過了一番和專題老師、組員的討論 後,先以一多人 3D 線上賽車遊戲為主要開發方向,不過經由一段時間的 研發討論後,發覺這個多人 3D 線上賽車的可行性不高,光是遊戲畫面的 轉變就昏頭轉向了,因為我們沒有專業的繪圖、算圖能力,所以又退為求 其次,做一多人線上連線遊戲,不在那麼地執著於一定要用 3D 引擎來跑 遊戲,因為光是一 3D 引擎就可當作一專題來做了。 最後我們就以多人線上遊戲為專題,經過了數個月的努力下來後 終於也完成了遊戲的基本雛型,也學到了如何的建構遊戲,使用 DirectX 完成遊戲製作的方面,以及用 WinSock 完成網路連線方面的機制,這方面 是覺得收獲滿多的,但是,往上面瞧發覺與外面賣的遊戲品質有段最顯的 差距,這也許就是時間與人力的不足的結果。因為以前從未有過開發一個 完整的遊戲的經驗,一開始一切的很陌生,不知道要從何著手。首先花了 不少時間去找資料,和學習操作所需要用到的工具,再和組員一起討論遊 戲的內容規格,然後一步一步慢慢朝目標邁進。

(61)

雖然我們大都能依照每次定的進度都完成,但有時候灰心之餘,使進 度落後,使之原本設想中的功能沒能如期的完成,像遊戲美工方面因為都 沒學過正統的電腦繪圖,導至原來還有打算要製作的動畫也因技術、能力 的不足而作罷,且整個遊戲畫面也沒當初想的那般亮眼吸引人,還有音 樂、音效方面也是因缺乏這方面的人材,所以也沒能做好,不過值得欣慰 的一點是至少我們勇於挑戰做個線上的遊戲,從起初的什麼都不懂一直奮 鬥到能連線對戰,雖然我們的作品並不大,但這就是我們努力出來的成 果,也得到了和隊友分工合作完成一個專案的經驗、體驗到開發一個遊戲 的困難度。不管我們做的結果好不好,對我們將來絕對是有好無壞,助益 無窮,相信有了這次的經驗之後,下次要做相似的專題時會來得簡單的 多,而且更能表現的更上一層樓,不論是遊戲性上、結構上、連線上、畫 面上、音樂音效上……都能大大的驅於完美。最後我只能說,做專題的日 子,很辛苦,但是很充實。

(62)

Chapter6.遊戲使用說明

執行程式後,將會出現一個開頭畫面,請用滑鼠按下開始遊戲,等待開局 人數到齊後,變進入遊戲畫面了,您可以按鍵盤方向鍵控制人物移動的方 向←↑→↓或, 同時按住上和左(↖)或, 同時按住下和左(↙)或, 同時按住上和右(↗)或, 同時按住下和右(↘), 當看到其他使用者在適當距離便可開始攻擊, 攻擊鍵為按住A 加上 Q 或 W 或 E 或 R 發出魔法, 發魔法將扣魔法值,依其攻擊的情形扣生命值, 在隨地游走當中,您可以吃出現的物品,已補充生命值與魔法值, 當您的生命值為0,此時會出現是否繼續遊戲的畫面,按 yes 重頭開始遊 戲,按no 則離開。

(63)

Chapter7.參考資料

書名 作者(翻譯) 出版社 1.Visual C++遊戲設計 普悠瑪數位科技 第三波 2.DirectX 發展手冊 Jason Kolb(劉登榮) 松格

3.Visual C++入門進階 位元文化 文魁

-從 C++ 物件導向到視窗程式設計 4.MAX 的養成教育

3D STUDIO MAX R.3 汪洋 文魁 5.人體建模必成功略 Shin dong Chan 美工科技

3D STUDIO MAX 、 Yu Yeong Chang 共著 6.電腦遊戲結構與設計 大衛.莫理斯 電腦玩家 :理論篇 安德魯.羅林 7.超解析winsock 鄧全良 金禾 網路程式設計 8.Turboc C/C++完全征服 蔡明志 碁峰 9.資料結構使用 c 語言 陳峰琪策劃 知城 教育小組編著

(64)

致謝: 一路走來我們要感謝, 李維聰老師 王益文老師 竇其仁老師 劉振緒老師 林志敏老師 徐弘洋老師 戴禪玲老師 黃溪春老師 林國貴老師 陳德生老 師 林秀峰老師 周俊文老師以及林財寶老師 還有助教們,應該算是全系 的老師我們都要說聲謝謝,因為全資訊系的老師我們都曾請教過,老話一 句,沒有你們的栽培,就沒有我們現在的成就。

參考文獻

相關文件

了解電腦網路的原理,學習使用 個人網誌及簡易的網頁設計,具 備電子商務的觀念、網路安全以 及網路犯罪與相關法規.

分區技能競賽 資訊與網路技術. 正式賽

微分方程式法

由於較大型網路的 規劃必須考慮到資料傳 輸效率的問題,所以在 規劃時必須將網路切割 成多個子網路,稱為網 際網路。橋接器是最早

背景:一名小學生家長投訴學校在沒有通 知家長的情況下,向網絡程式供應商提供

 想要設計一個具有兩個輸入G(gate閘控)和 D(data資料)以及一個輸出Q的閘控閂電 路。當G等於1時,在輸入D出現的二進位資料

背景:一名小學生家長投訴學校在沒有通 知家長的情況下,向網絡程式供應商提供

無線感測網路是個人區域網路中的一種應用,其中最常採用 Zigbee 無線通訊協 定做為主要架構。而 Zigbee 以 IEEE802.15.4 標準規範做為運用基礎,在下一小節將 會針對 IEEE