圖形函式庫

林品儒

2017/03/10

圖形函式庫

包裝了用來繪圖的函式

可以從硬體或軟體方面繪圖

圖形顯示

顯示記憶體存放圖像資料

更動記憶體可以改變要顯示的圖形

可以由CPU或GPU負責

系統支援

要使用繪圖功能需要作業系統提供

分成軟體和硬體部份

軟體介面

使用CPU處理在記憶體中的繪圖資料

Windows使用GDI

Linux使用Xlib

硬體介面

使用GPU處理顯示記憶體的繪圖資料

效能較高且可以有更多功能

Windows使用DirectX,OpenGL

Linux使用OpenGL

未來還有Vulkan

繪圖函式庫

作業系統的功能太低階

於是把功能包裝後形成函式庫

除了繪圖可能還有視窗和事件的管理

遊戲開發需求可能還有音效功能

接著介紹幾款函式庫

SDL

Simple DirectMedia Layer

第1代的SDL只能用CPU畫圖效能差

可以把圖放在顯示卡記憶體但反而變慢

Windows下可以用DirectX或GDI當底層

Linux下使用Xlib

還有視窗和音效的功能

SFML

Simple and Fast Multimedia Library

跨平台還有多語言支援

比SDL高階但個人沒用過

想玩的可以玩玩看

SDL2

第2代的SDL

支援硬體2D繪圖

功能比第一代強但是比較複雜

想玩SDL建議從第1代玩起

OpenGL

硬體層面的3D繪圖函式庫

可以和很多函式庫合作

功能強但是複雜

除非必要不然別碰

DirectX

玩遊戲的一定都聽過

功能包山包海

部份遊戲可以用OpenGL取代其功能

Gosu

今天要來介紹的2D繪圖函式庫

不過其實算是遊戲開發函式庫

高階好寫容易入門

底層採用GPU繪圖效能高

Gosu

Gosu

2D遊戲開發函式庫

跨平台且支援Ruby和C++

繪圖部份底層為OpenGL

開源碼MIT授權

視窗

Gosu::Window

用來繼承自己的遊戲視窗

包含了繪圖以及事件的管理

基本迴圈

在遊戲中會有一個主要的迴圈

先進行輸入

再來對輸入做運算

然後繪圖輸出

Window類別

#initialize建構視窗

#update會在需要更新時呼叫

#draw會在需要繪圖時呼叫

#show呼叫後自動控管迴圈

#coding: utf-8
require "gosu"
class GameWindow < Gosu::Window
  def initialize
    super(800,600)
  end
  def update
  end
  def draw
  end
end
game = GameWindow.new
game.show

更改標題

#caption="新標題"

#caption可以取得標題

def initialize
  ...
  self.caption = "GameWindow"
end

圖層概念

Gosu是利用各個圖層分開繪圖後進行合成

因此可以不用顧慮繪圖順序

只要指定愈大的Z軸就會在愈上方

def initialize
  ...
  @Zorder = {Sky: 0, Sun: 1, Mountain: 2, Ground: 3,UI: 4}
end

繪製4邊形

由於Gosu是用3D功能來進行2D繪圖

因此可以有些特別的功能

可以給4個點畫出任意的4邊形

要順時針或逆時針繞圈

def draw
  draw_quad(  0,400,0xFF44BB22,800,400,0xFF117711,
            800,600,0xFF44BB33,  0,600,0xFF88BB33, @Zorder[:Ground])
  draw_quad(  0,  0,0xFF00FFFF,800,  0,0xFF00FFFF,
            800,400,0xFF00FFFF,  0,400,0xFF00FFFF, @Zorder[:Sky])
end

繪製三角形

四邊形實際是用兩個三角形相加而成

最基本的功能其實是畫三角形

當然還是要各點座標和顏色囉

def draw
  ...
  draw_triangle(  0,400,0xFF008000,
                150,400,0xFF338033,
                 75,300,0xFF508011, @Zorder[:Mountain])
end

圖形載入

Gosu支援多種類型圖檔

假如是BMP會將粉紅色#FF00FF當作透明色

建議還是用PNG自己指定透明吧

def initialize
  ...
  @sun = Gosu::Image.new(self,"./images/sun.png")
end

圖形顯示

圖像其實也可以畫成四邊形

不過當然是矩形比較順眼

還附上旋轉圖片的功能

def initialize
  ...
  @r = 200
  @angle = 0
  @v = 0.1
end
def draw
  ...
  @sun.draw_rot(400 + @r * Math.cos(@angle.degrees_to_radians),
                400 + @r * Math.sin(@angle.degrees_to_radians), @Zorder[:Sun],@angle)
end

更新方法

視窗中有個#update的方法

每個畫格都會被呼叫

所以要需要將輸入和處理寫在裡面

def update
  @angle -= @v
  @angle = @angle % 360
end

鍵盤處理

一般的函式庫要抓取事件然後判斷種類

Gosu可以直接看某顆鍵是否被按下

#button_down?(btn)就可以檢查

def update
  button_down?(Gosu::KbUp) and @r+=1
  button_down?(Gosu::KbDown) and @r-=1
  button_down?(Gosu::KbLeft) and @v+=0.01
  button_down?(Gosu::KbRight) and @v-=0.01
  button_down?(Gosu::KbEscape) and exit
  ...
end

字型繪製

可以將UTF-8的字串直接畫出來

也不用管字型檔的路徑在哪裡

預設是畫白色的字

def initialize
  ...
  @font = Gosu::Font.new(24)
end
def draw
  ...
  @font.draw("角度:%6.2f 半徑:%5d 速度:%.2f"%[@angle,@r,@v],10,10,@Zorder[:UI])
end

程式完成

利用以上的功能就可以做出小遊戲了

還有更多功能可以從官方網站取得歐