From 90b6e3871aebe3fc56636f6d4ddfbff0ad6fd420 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Fri, 29 Jul 2016 01:26:44 +0900 Subject: [PATCH] examples/2048: Draw colored tiles --- examples/2048/2048/board.go | 62 +++++++++++++++++++++++++++++----- examples/2048/2048/colors.go | 64 ++++++++++++++++++++++++++++++++++++ examples/2048/2048/game.go | 27 +++++++++++++-- 3 files changed, 142 insertions(+), 11 deletions(-) create mode 100644 examples/2048/2048/colors.go diff --git a/examples/2048/2048/board.go b/examples/2048/2048/board.go index 2b13a6157..823a35bc7 100644 --- a/examples/2048/2048/board.go +++ b/examples/2048/2048/board.go @@ -15,12 +15,11 @@ package twenty48 import ( - "fmt" + "image/color" "math/rand" "sort" "github.com/hajimehoshi/ebiten" - "github.com/hajimehoshi/ebiten/ebitenutil" ) type Board struct { @@ -144,19 +143,66 @@ func (b *Board) Move(dir Dir) { b.addRandomTile() } +const ( + tileSize = 80 + tileMargin = 4 +) + +var ( + tileImage *ebiten.Image +) + +func init() { + var err error + tileImage, err = ebiten.NewImage(tileSize, tileSize, ebiten.FilterNearest) + if err != nil { + panic(err) + } + if err := tileImage.Fill(color.White); err != nil { + panic(err) + } +} + +func colorToScale(clr color.Color) (float64, float64, float64, float64) { + r, g, b, a := clr.RGBA() + rf := float64(r) / 0xffff + gf := float64(g) / 0xffff + bf := float64(b) / 0xffff + af := float64(a) / 0xffff + // Convert to non-premultiplied alpha components. + rf /= af + gf /= af + bf /= af + return rf, gf, bf, af +} + +func (b *Board) Size() (int, int) { + x := b.size*tileSize + (b.size+1)*tileMargin + y := x + return x, y +} + func (b *Board) Draw(screen *ebiten.Image) error { - str := "" + if err := screen.Fill(frameColor); err != nil { + return err + } for j := 0; j < b.size; j++ { for i := 0; i < b.size; i++ { t := b.tileAt(i, j) + v := 0 if t != nil { - str += fmt.Sprintf("[%4d]", t.value) - } else { - str += "[ ]" + v = t.value + } + op := &ebiten.DrawImageOptions{} + x := i*tileSize + (i+1)*tileMargin + y := j*tileSize + (j+1)*tileMargin + op.GeoM.Translate(float64(x), float64(y)) + r, g, b, a := colorToScale(tileBackgroundColor(v)) + op.ColorM.Scale(r, g, b, a) + if err := screen.DrawImage(tileImage, op); err != nil { + return err } } - str += "\n" } - ebitenutil.DebugPrint(screen, str) return nil } diff --git a/examples/2048/2048/colors.go b/examples/2048/2048/colors.go new file mode 100644 index 000000000..100f48393 --- /dev/null +++ b/examples/2048/2048/colors.go @@ -0,0 +1,64 @@ +// Copyright 2016 The Ebiten Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package twenty48 + +import ( + "image/color" +) + +var ( + backgroundColor = color.RGBA{0xfa, 0xf8, 0xef, 0xff} + frameColor = color.RGBA{0xbb, 0xad, 0xa0, 0xff} +) + +func tileColor(value int) color.Color { + switch value { + case 2, 4: + return color.RGBA{0x77, 0x6e, 0x65, 0xff} + case 8, 16, 32, 64, 128, 256, 512, 1024, 2048: + return color.RGBA{0xf9, 0xf6, 0xf2, 0xff} + } + panic("not reach") +} + +func tileBackgroundColor(value int) color.Color { + switch value { + case 0: + return color.NRGBA{0xee, 0xe4, 0xda, 0x59} + case 2: + return color.RGBA{0xee, 0xe4, 0xda, 0xff} + case 4: + return color.RGBA{0xed, 0xe0, 0xc8, 0xff} + case 8: + return color.RGBA{0xf2, 0xb1, 0x79, 0xff} + case 16: + return color.RGBA{0xf5, 0x95, 0x63, 0xff} + case 32: + return color.RGBA{0xf6, 0x7c, 0x5f, 0xff} + case 64: + return color.RGBA{0xf6, 0x5e, 0x3b, 0xff} + case 128: + return color.RGBA{0xed, 0xcf, 0x72, 0xff} + case 256: + return color.RGBA{0xed, 0xcc, 0x61, 0xff} + case 512: + return color.RGBA{0xed, 0xc8, 0x50, 0xff} + case 1024: + return color.RGBA{0xed, 0xc5, 0x3f, 0xff} + case 2048: + return color.RGBA{0xed, 0xc2, 0x2e, 0xff} + } + panic("not reach") +} diff --git a/examples/2048/2048/game.go b/examples/2048/2048/game.go index fc14edbbc..321e47b1e 100644 --- a/examples/2048/2048/game.go +++ b/examples/2048/2048/game.go @@ -32,8 +32,9 @@ const ( ) type Game struct { - input *Input - board *Board + input *Input + board *Board + boardImage *ebiten.Image } func NewGame() *Game { @@ -54,7 +55,27 @@ func (g *Game) Update() error { } func (g *Game) Draw(screen *ebiten.Image) error { - if err := g.board.Draw(screen); err != nil { + if g.boardImage == nil { + var err error + w, h := g.board.Size() + g.boardImage, err = ebiten.NewImage(w, h, ebiten.FilterNearest) + if err != nil { + return err + } + } + if err := screen.Fill(backgroundColor); err != nil { + return err + } + if err := g.board.Draw(g.boardImage); err != nil { + return err + } + op := &ebiten.DrawImageOptions{} + sw, sh := screen.Size() + bw, bh := g.boardImage.Size() + x := (sw - bw) / 2 + y := (sh - bh) / 2 + op.GeoM.Translate(float64(x), float64(y)) + if err := screen.DrawImage(g.boardImage, op); err != nil { return err } return nil