package main
import (
"log"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
)
定义Game结构。Game实现ebiten.Game接口。ebiten.Game具有 Ebiten 游戏的必要函数:Update、Draw和Layout。让我们一一看看。
func (g *Game) Update() error {
return nil
}
定义(*Game).Update函数,每个刻度都会调用。Tick 是逻辑更新的时间单位。默认值为 1/60 [s],然后Update默认每秒调用 60 次(即 Ebiten 游戏以每秒 60 次滴答运行)。
Update更新游戏的逻辑状态。这个 hello-world 示例没有任何状态,然后这个函数什么都不做。
Update返回错误值。在此代码中,Update始终返回nil.?一般来说,当更新函数返回非零错误时,Ebiten 游戏暂停。由于这个程序从不返回非零错误,除非用户关闭窗口,否则 Ebiten 游戏永远不会停止。
func (g *Game) Draw(screen *ebiten.Image) {
定义(*Game).Draw函数,即每帧调用一次。帧是渲染的时间单位,这取决于显示器的刷新率。如果显示器的刷新率为 60[Hz],Draw则称为每秒 60 次。
Draw接受一个参数screen,它是一个指向 an 的指针ebiten.Image。在 Ebiten 中,所有图像,如从图像文件创建的图像、屏幕外图像(临时渲染目标)和屏幕都被表示为ebiten.Image对象。screen参数是渲染的最终目的地。该窗口显示screen每一帧的最终状态。
ebitenutil.DebugPrint(screen, "Hello, World!")
}
ebitenutil.DebugPrint是一个实用函数,用于在图像上呈现调试消息。在这种情况下,screen作为调试打印的渲染目标传递。由于screen复位(或其他字清零)时Draw被调用,DebugPrint应该叫每次。
func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
return 320, 240
}
定义(*Game).Layout功能。Layout接受外部尺寸,即桌面上的窗口尺寸,并返回游戏的逻辑屏幕尺寸。此代码忽略参数并返回固定值。这意味着无论窗口大小如何,游戏屏幕大小始终相同。Layout将更有意义,例如,当窗口可调整大小时。
ebiten.SetWindowSize(640, 480)
ebiten.SetWindowTitle("Hello, World!")
if err := ebiten.RunGame(&Game{}); err != nil {
log.Fatal(err)
}
}
ebiten.RunGame是运行 Ebiten 游戏主循环的函数。参数是一个Game对象,它实现ebiten.Game.?ebiten.RunGame发生错误时返回非零错误值。在这个程序中,当返回一个非 nil 错误时,这个错误被记录为一个致命错误。
2、图像填充
代码
package main
import (
"image/color"
"log"
"github.com/hajimehoshi/ebiten/v2"
)
type Game struct{}
func (g *Game) Update() error {
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
screen.Fill(color.RGBA{0xff, 0, 0, 0xff})
}
func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
return 320, 240
}
func main() {
ebiten.SetWindowSize(640, 480)
ebiten.SetWindowTitle("Fill")
if err := ebiten.RunGame(&Game{}); err != nil {
log.Fatal(err)
}
}
代码如何工作
screen.Fill(color.RGBA{0xff, 0, 0, 0xff})