Destroyed 畫布、顏色與矩形 (markdown)

Yami Odymel 2016-11-12 02:17:43 +08:00
parent e393600606
commit 82fedbf55c

@ -1,179 +0,0 @@
在上一章我們提到了如何建立一個基本的遊戲框架,但那還不足以構成一個遊戲(*畢竟只有一串文字嘛*),在那之前,我們需要知道更多有關遊戲畫面的資訊,所以接下來要提到的就是「**螢幕畫布**」。
螢幕畫布是整個遊戲中**最重要的地方**,螢幕畫布用來**呈現任何你能夠看見的東西**,在你不注意的時候螢幕畫布可能已經更新了數百次,但是因為**速度夠快所以你並不會察覺**。
現在讓我們接續上次的程式碼吧!如果你忘記了上次的程式碼長怎樣,我已經幫你帶到這邊來了,*順帶一提,我稍稍加上了一些註釋 :)*。
```go
package main
import (
"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/ebitenutil"
)
func update(screen *ebiten.Image) error {
// 顯示一串除錯用的文字
ebitenutil.DebugPrint(screen, "Our first game in Ebiten!")
return nil
}
func main() {
// 初始化 Ebiten並不斷呼叫 update()
ebiten.Run(update, 320, 240, 2, "Hello world!")
}
```
還記得這會出現下面這樣的畫面,對吧?
![](http://i.imgur.com/In5N0Ck.png)
姆⋯⋯這看起來有點無聊呢,稍微**色彩一下畫布背景**如何?
# 顏色建構體
在替你的畫布著色之前,**你需要建立一個顏色建構體**,這很簡單,如果你先前有用過**相片軟體**或是**網頁設計**,你就會知道所謂的 **Hex 色碼**`#FF0000`。
**但是等一下**!為了要建立一個顏色建構體供稍後著色用,你會**需要用到 `image/color` 套件**,想要新增一個套件你需要修改程式碼中 `import` 的區塊,像下面這樣:
```go
import (
"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/ebitenutil"
"image/color"
)
```
棒呆了!現在是時候新增一個顏色了,嗯⋯⋯紅色如何?**紅色的色碼是 `#FF0000`**,換成**十六進制**就是 `0xff, 0x00, 0x00`,所以就會像這樣(最後面的 `0xff` 不用動):
```go
color.NRGBA{0xff, 0x00, 0x00, 0xff}
```
好了,你已經知道怎麼建立顏色了,接著就是來幫畫布著色了。
# 畫布填色
在 Ebiten 中,畫布有個 `Fill(clr color.Color)` 函式,這個意思是你**需要傳入一個資料型態是 `color.Color` 的值**,這剛好是**我們剛才建立的顏色建構體的資料型態**!事不宜遲,趕快來看看如何替我們的畫布著色。
還記得我們的 `update` 函式嗎?就是那個**會不斷被執行的函式**,我們要在這裡替我們的畫布著色(你總不會希望顏色閃一下就沒了,*對吧*?)。
```go
func update(screen *ebiten.Image) error {
// 先幫畫布填上 #FF0000 顏色
screen.Fill(color.NRGBA{0xff, 0x00, 0x00, 0xff})
// 顯示一串除錯用的文字
ebitenutil.DebugPrint(screen, "Our first game in Ebiten!")
return nil
}
```
在這裡你需要**注意執行的優先順序**,你必須**先替畫布著色**,然後再顯示文字,**不然你的文字會被顏色給蓋過去**喔!
儲存你的檔案,透過跟上次一樣的指令 `go run ./main.go` 執行看看是不是長得像下面這樣了呢?
![](http://i.imgur.com/qMhWeY3.png)
# 建立矩形
接下來我們要在畫布上畫幾個矩形,這樣才比較像遊戲,不是嗎?雖然它不會動,但相信我,**之後的幾個章節我們會讓它動起來的** ;)。
## 矩形其實是個新畫布
在這裡希望你先釐清一個觀念,**Ebiten 其實沒有矩形**。**任何東西都是一個畫布***只是遊戲背景的那一個比較大而已*),所以我們等一下要建立的**其實就是一個新的畫布**,但是比起畫面背景的那個畫布還要小就是了,所以看起來很像矩形或方塊。
## 新建畫布並將其填色
像剛才說的,其實**矩形就只是畫布**而已,所以在這裡我會稱其為「**畫布**」,**記住這一點**,然後我們繼續往下看。
在 Ebiten 裡透過 `ebiten.NewImage(width, height int, filter Filter)` 你可以**建立另一個畫布**,其中你要提供的值有:
* `width` 是新畫布的**寬度**,以像素表示。
* `height` 是新畫布的**高度**,同樣以像素表示。
* `filter` 這個是渲染的過濾器,這個我們可以不要管它,等一下照做就好了。
現在像下面這樣**建立一個 16x16 的新畫布**,長得就**像一般的正方形**,然後程式會將它**儲存至 `square` 變數**中供稍後使用,實際上你愛怎麼稱呼這個變數都行,不過記得,你**只能夠用英文混合數字**來替他命名。
```go
// 建立一個 16x16 的新畫布
square, _ := ebiten.NewImage(16, 16, ebiten.FilterNearest)
// 替 square 畫布填上白色
square.Fill(color.White)
```
在尾端我們用了跟剛才所學到的著色方法來替我們的新畫布上了 `color.White` 顏色。你總不希望他是透明的,對吧?
你可能會好奇 `color.White` 是什麼用法?其實在 `image/color` 套件中有提供**兩個預設的顏色**,分別是**黑**`color.Black`)與**白**`color.White`)。
## 調整位置然後渲染至主畫布
當你建立了新畫布之後,**你需要將它渲染到主畫布上**,不然他不會出現在螢幕上,但在渲染之前你需要**建立一個名為 `DrawImageOptions{}`** 的「選項建構體」,這個建構體主要是用來**敘述我們的新畫布應該如何被渲染**,但現在可以先留白,等一下才會提及。
先來個完整的範例,然後我們再逐一解釋。上面這些範例都是在 `update` 中撰寫的,讓我們看看你的 `update` 應該長成怎麼樣:
```go
func update(screen *ebiten.Image) error {
// 先幫畫布填上 #FF0000 顏色
screen.Fill(color.NRGBA{0xff, 0x00, 0x00, 0xff})
// 顯示一串除錯用的文字
ebitenutil.DebugPrint(screen, "Our first game in Ebiten!")
// 建立一個 16x16 的新畫布
square, _ := ebiten.NewImage(16, 16, ebiten.FilterNearest)
// 替 square 畫布填上白色
square.Fill(color.White)
// 建立一個空白選項建構體
opts := &ebiten.DrawImageOptions{}
// 渲染 square 畫布到 screen 主畫布上並套用空白選項
screen.DrawImage(square, opts)
return nil
}
```
`DrawImage(image *Image, options *DrawImageOptions)` 是渲染畫布的功能,看起來真長!不過放心,其實用起來的方法很簡單。**第一個值你需要傳入我們的新畫布****第二個則是渲染選項**,沒了。簡單吧!
實際上也沒有新增很多的程式碼,老樣子,儲存完之後我們就用 `go run ./main.go` 來執行看看吧。
![](http://i.imgur.com/IdFYBoH.png)
啊!我們的文字被遮蔽了!其實這是因為我們沒有**設定新畫布座標**的緣故,這會是這章最終的教學。
# 畫布變形
在 Ebiten 中,**畫布並沒有座標配置**,但是**你可以透過變形達到同樣效果**,變形的方法**有很多種**,日後會提到,這裡先提及基本的 `x軸``y軸` 的**座標移動變形**。
我們可以**將「座標移動變形」的效果加入至「選項建構體」**,其方法是 `Translate(tx, ty float64)``float64` 是**浮點數**的意思,**你也可以當作整數用沒關係**,在這裡你有兩個值要顧慮:
* `tx` 是距離螢幕左側的值,也就是 `x軸` 偏移。
* `ty` 是距離螢幕頂部的值,也就是 `y軸` 偏移。
所以在你的選項建構體下方新增一行程式碼用來告訴渲染函式**我們希望這個新的畫布有座標移動的變形效果**。
```go
// 剛才的空白選項建構體
opts := &ebiten.DrawImageOptions{}
// 修改選項,新增 Translate 變形效果
opts.GeoM.Translate(64, 64)
```
儲存檔案,執行你的程式,你就會看見新畫布會向螢幕左側和頂部偏移 64 個像素點。
![](http://i.imgur.com/ChN4qp9.png)
順帶一提,如果你新增了很多個畫布,你可以逐一調整每個畫布的位置,然後就可以達到下面這樣的效果。
![](http://i.imgur.com/BVh8SO6.png)
靜止不動看起來還真是無趣,但之後我們會讓它動起來的!讓我們在下個章節見面吧!