Destroyed 画布、颜色与矩形 (markdown)

Yami Odymel 2016-11-12 02:17:38 +08:00
parent 26a4577e0e
commit e393600606

@ -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)
静止不动看起来还真是无趣,但之后我们会让它动起来的!让我们在下个章节见面吧!