examples: Use RunGame

Updates #1111
This commit is contained in:
Hajime Hoshi 2020-04-12 19:12:57 +09:00
parent 7b77164710
commit 6529629d29
6 changed files with 123 additions and 78 deletions

View File

@ -39,14 +39,17 @@ const (
)
var (
count = 0
gophersImage *ebiten.Image
extraImages []*ebiten.Image
lost = false
)
func loseAndRestoreContext(context js.Value) {
if lost {
type Game struct {
count int
lost bool
}
func (g *Game) loseAndRestoreContext(context js.Value) {
if g.lost {
return
}
@ -61,7 +64,7 @@ func loseAndRestoreContext(context js.Value) {
ext.Call("loseContext")
fmt.Println("Lost the context!")
fmt.Println("The context is automatically restored after 3 seconds.")
lost = true
g.lost = true
// If and only if the context is lost by loseContext, you need to call restoreContext. Note that in usual
// case of context lost, you cannot call restoreContext but the context should be restored automatically.
@ -71,11 +74,11 @@ func loseAndRestoreContext(context js.Value) {
time.Sleep(3 * time.Second)
ext.Call("restoreContext")
fmt.Println("Restored the context!")
lost = false
g.lost = false
}()
}
func update(screen *ebiten.Image) error {
func (g *Game) Update(screen *ebiten.Image) error {
if inpututil.IsKeyJustPressed(ebiten.KeySpace) {
doc := js.Global().Get("document")
canvas := doc.Call("getElementsByTagName", "canvas").Index(0)
@ -86,26 +89,29 @@ func update(screen *ebiten.Image) error {
context = canvas.Call("getContext", "experimental-webgl")
}
}
loseAndRestoreContext(context)
g.loseAndRestoreContext(context)
return nil
}
count++
if ebiten.IsDrawingSkipped() {
g.count++
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
w, h := gophersImage.Size()
op := &ebiten.DrawImageOptions{}
// For the details, see examples/rotate.
op.GeoM.Translate(-float64(w)/2, -float64(h)/2)
op.GeoM.Rotate(float64(count%360) * 2 * math.Pi / 360)
op.GeoM.Rotate(float64(g.count%360) * 2 * math.Pi / 360)
op.GeoM.Translate(screenWidth/2, screenHeight/2)
screen.DrawImage(gophersImage, op)
ebitenutil.DebugPrint(screen, "Press Space to force to lose/restore the GL context!\n(Browser only)")
}
return nil
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
return screenWidth, screenHeight
}
func main() {
@ -130,7 +136,9 @@ func main() {
extraImages = append(extraImages, eimg)
}
if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Context Lost (Ebiten Demo)"); err != nil {
ebiten.SetWindowSize(screenWidth*2, screenHeight*2)
ebiten.SetWindowTitle("Context Lost (Ebiten Demo)")
if err := ebiten.RunGame(&Game{}); err != nil {
log.Fatal(err)
}
}

View File

@ -33,7 +33,6 @@ const (
var (
pixels = make([]byte, screenSize*4)
firePixels = make([]byte, screenSize)
firePalette = []color.RGBA{
{R: 7, G: 7, B: 7, A: 255}, // 0
{R: 31, G: 7, B: 7, A: 255}, // 1
@ -75,29 +74,37 @@ var (
}
)
func init() {
type Game struct {
firePixels []byte
}
func NewGame() *Game {
firePixels := make([]byte, screenSize)
for i := screenSize - screenWidth; i < screenSize; i++ {
firePixels[i] = 36
}
return &Game{
firePixels: firePixels,
}
}
func updateFirePixels() {
func (g *Game) updateFirePixels() {
for i := 0; i < screenWidth; i++ {
for j := 0; j < screenHeight; j++ {
idx := i + (screenWidth * j)
updateFireIntensityPerPixel(idx)
g.updateFireIntensityPerPixel(idx)
}
}
}
func updateFireIntensityPerPixel(currentPixelIndex int) {
func (g *Game) updateFireIntensityPerPixel(currentPixelIndex int) {
below := currentPixelIndex + screenWidth
if below >= screenSize {
return
}
d := rand.Intn(3)
newI := int(firePixels[below]) - d
newI := int(g.firePixels[below]) - d
if newI < 0 {
newI = 0
}
@ -105,11 +112,11 @@ func updateFireIntensityPerPixel(currentPixelIndex int) {
if currentPixelIndex-d < 0 {
return
}
firePixels[currentPixelIndex-d] = byte(newI)
g.firePixels[currentPixelIndex-d] = byte(newI)
}
func renderFire() {
for i, v := range firePixels {
func (g *Game) renderFire() {
for i, v := range g.firePixels {
p := firePalette[v]
pixels[i*4] = p.R
pixels[i*4+1] = p.G
@ -118,22 +125,26 @@ func renderFire() {
}
}
func update(screen *ebiten.Image) error {
updateFirePixels()
if ebiten.IsDrawingSkipped() {
func (g *Game) Update(screen *ebiten.Image) error {
g.updateFirePixels()
return nil
}
renderFire()
func (g *Game) Draw(screen *ebiten.Image) {
g.renderFire()
screen.ReplacePixels(pixels)
return nil
}
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
return screenWidth, screenHeight
}
func main() {
rand.Seed(time.Now().UnixNano())
if err := ebiten.Run(update, screenWidth, screenHeight, 6, "Doom Fire (Ebiten Demo)"); err != nil {
ebiten.SetWindowSize(screenWidth*6, screenHeight*6)
ebiten.SetWindowTitle("Doom Fire (Ebiten Demo)")
if err := ebiten.RunGame(NewGame()); err != nil {
log.Fatal(err)
}
}

View File

@ -187,7 +187,7 @@ type Game struct {
sprites []*Sprite
}
var theGame *Game
var ebitenImage *ebiten.Image
func init() {
// Decode image from a byte slice instead of a file so that
@ -203,8 +203,10 @@ func init() {
if err != nil {
log.Fatal(err)
}
ebitenImage, _ := ebiten.NewImageFromImage(img, ebiten.FilterDefault)
ebitenImage, _ = ebiten.NewImageFromImage(img, ebiten.FilterDefault)
}
func NewGame() *Game {
// Initialize the sprites.
sprites := []*Sprite{}
w, h := ebitenImage.Size()
@ -218,7 +220,7 @@ func init() {
}
// Initialize the game.
theGame = &Game{
return &Game{
strokes: map[*Stroke]struct{}{},
sprites: sprites,
}
@ -264,7 +266,7 @@ func (g *Game) updateStroke(stroke *Stroke) {
stroke.SetDraggingObject(nil)
}
func (g *Game) update(screen *ebiten.Image) error {
func (g *Game) Update(screen *ebiten.Image) error {
if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) {
s := NewStroke(&MouseStrokeSource{})
s.SetDraggingObject(g.spriteAt(s.Position()))
@ -282,11 +284,10 @@ func (g *Game) update(screen *ebiten.Image) error {
delete(g.strokes, s)
}
}
if ebiten.IsDrawingSkipped() {
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
draggingSprites := map[*Sprite]struct{}{}
for s := range g.strokes {
if sprite := s.DraggingObject().(*Sprite); sprite != nil {
@ -308,12 +309,16 @@ func (g *Game) update(screen *ebiten.Image) error {
}
ebitenutil.DebugPrint(screen, "Drag & Drop the sprites!")
}
return nil
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
return screenWidth, screenHeight
}
func main() {
if err := ebiten.Run(theGame.update, screenWidth, screenHeight, 2, "Drag & Drop (Ebiten Demo)"); err != nil {
ebiten.SetWindowSize(screenWidth*2, screenHeight*2)
ebiten.SetWindowTitle("Drag & Drop (Ebiten Demo)")
if err := ebiten.RunGame(NewGame()); err != nil {
log.Fatal(err)
}
}

View File

@ -36,11 +36,14 @@ var (
ebitenImage *ebiten.Image
)
func update(screen *ebiten.Image) error {
if ebiten.IsDrawingSkipped() {
type Game struct {
}
func (g *Game) Update(screen *ebiten.Image) error {
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
ebitenutil.DebugPrint(screen, "Nearest Filter (default) VS Linear Filter")
op := &ebiten.DrawImageOptions{}
@ -55,8 +58,10 @@ func update(screen *ebiten.Image) error {
// Specify linear filter.
op.Filter = ebiten.FilterLinear
screen.DrawImage(ebitenImage, op)
}
return nil
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
return screenWidth, screenHeight
}
func main() {
@ -79,7 +84,9 @@ func main() {
// Specify FilterDefault here, that means to prefer filter specified at DrawImageOptions.
ebitenImage, _ = ebiten.NewImageFromImage(img, ebiten.FilterDefault)
if err := ebiten.Run(update, screenWidth, screenHeight, 1, "Filter (Ebiten Demo)"); err != nil {
ebiten.SetWindowSize(screenWidth, screenHeight)
ebiten.SetWindowTitle("Filter (Ebiten Demo)")
if err := ebiten.RunGame(&Game{}); err != nil {
log.Fatal(err)
}
}

View File

@ -46,11 +46,14 @@ var (
}
)
func update(screen *ebiten.Image) error {
if ebiten.IsDrawingSkipped() {
type Game struct {
}
func (g *Game) Update(screen *ebiten.Image) error {
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
const (
ox = 10
oy = 10
@ -80,7 +83,10 @@ func update(screen *ebiten.Image) error {
op.ColorM.Translate(r, g, b, 0)
screen.DrawImage(ebitenImage, op)
}
return nil
}
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
return screenWidth, screenHeight
}
func main() {
@ -99,7 +105,9 @@ func main() {
}
ebitenImage, _ = ebiten.NewImageFromImage(img, ebiten.FilterDefault)
if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Flood fill with solid colors (Ebiten Demo)"); err != nil {
ebiten.SetWindowSize(screenWidth*2, screenHeight*2)
ebiten.SetWindowTitle("Flood fill with solid colors (Ebiten Demo)")
if err := ebiten.RunGame(&Game{}); err != nil {
log.Fatal(err)
}
}

View File

@ -41,11 +41,7 @@ var (
sampleText = `The quick brown fox jumps over the lazy dog.`
mplusNormalFont font.Face
mplusBigFont font.Face
counter = 0
kanjiText = []rune{}
kanjiTextColor color.RGBA
)
var jaKanjis = []rune{}
func init() {
@ -115,28 +111,33 @@ func init() {
rand.Seed(time.Now().UnixNano())
}
func update(screen *ebiten.Image) error {
type Game struct {
counter int
kanjiText []rune
kanjiTextColor color.RGBA
}
func (g *Game) Update(screen *ebiten.Image) error {
// Change the text color for each second.
if counter%ebiten.MaxTPS() == 0 {
kanjiText = []rune{}
if g.counter%ebiten.MaxTPS() == 0 {
g.kanjiText = nil
for j := 0; j < 4; j++ {
for i := 0; i < 8; i++ {
kanjiText = append(kanjiText, jaKanjis[rand.Intn(len(jaKanjis))])
g.kanjiText = append(g.kanjiText, jaKanjis[rand.Intn(len(jaKanjis))])
}
kanjiText = append(kanjiText, '\n')
g.kanjiText = append(g.kanjiText, '\n')
}
kanjiTextColor.R = 0x80 + uint8(rand.Intn(0x7f))
kanjiTextColor.G = 0x80 + uint8(rand.Intn(0x7f))
kanjiTextColor.B = 0x80 + uint8(rand.Intn(0x7f))
kanjiTextColor.A = 0xff
g.kanjiTextColor.R = 0x80 + uint8(rand.Intn(0x7f))
g.kanjiTextColor.G = 0x80 + uint8(rand.Intn(0x7f))
g.kanjiTextColor.B = 0x80 + uint8(rand.Intn(0x7f))
g.kanjiTextColor.A = 0xff
}
counter++
if ebiten.IsDrawingSkipped() {
g.counter++
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
const x = 20
// Draw info
@ -147,14 +148,19 @@ func update(screen *ebiten.Image) error {
text.Draw(screen, sampleText, mplusNormalFont, x, 80, color.White)
// Draw Kanji text lines
for i, line := range strings.Split(string(kanjiText), "\n") {
text.Draw(screen, line, mplusBigFont, x, 160+54*i, kanjiTextColor)
for i, line := range strings.Split(string(g.kanjiText), "\n") {
text.Draw(screen, line, mplusBigFont, x, 160+54*i, g.kanjiTextColor)
}
return nil
}
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
return screenWidth, screenHeight
}
func main() {
if err := ebiten.Run(update, screenWidth, screenHeight, 1, "Font (Ebiten Demo)"); err != nil {
ebiten.SetWindowSize(screenWidth, screenHeight)
ebiten.SetWindowTitle("Font (Ebiten Demo)")
if err := ebiten.RunGame(&Game{}); err != nil {
log.Fatal(err)
}
}