A sample that draws a clock using a game engine called ebiten
The clock is simple.
main.go
package main
import (
. "clock"
"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/inpututil"
"log"
"time"
)
type Game struct {
time time.Time
stop bool
}
func (g *Game) Update(screen *ebiten.Image) error {
if inpututil.IsKeyJustPressed(ebiten.KeyEscape) {
g.stop = !g.stop
}
if !g.stop {
g.time = time.Now()
}
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
m := ClockImage(g.time)
em, _ := ebiten.NewImageFromImage(m, ebiten.FilterDefault)
screen.DrawImage(em, &ebiten.DrawImageOptions{})
}
func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
return 320, 320
}
func main() {
game := &Game{}
ebiten.SetWindowSize(320, 320)
ebiten.SetWindowTitle("Hello, World!")
if err := ebiten.RunGame(game); err != nil {
log.Fatal(err)
}
}
With the meaning of a sample, you can stop the clock by pressing the escape key.
I'm not thinking about how to use it.
A program that generates the essential clock image
clock.go
package clock
import (
"image"
"github.com/fogleman/gg"
"github.com/golang/freetype/truetype"
"golang.org/x/image/font/gofont/gomedium"
"time"
)
func ClockImage(t time.Time) image.Image {
const (
R = 160
Long = 108 //Second
Midium = 85 // Minute
Short = 50 // Hour
Width = R*2 + 1
Height = R*2 + 1
CenterX = Width / 2
CenterY = Height / 2
M = 15 //Other memory line segments
M5 = 26 //5 minute memory line segment
)
dc := gg.NewContext(Width, Height)
dc.SetHexColor("#ffffff")
dc.Clear()
//Memory drawing
dc.Push()
dc.SetHexColor("#000000")
for i := 0; i < 60; i++ {
dc.Push()
var m float64 = M
if i%5 == 0 {
dc.SetLineWidth(2)
m = M5
}
dc.MoveTo(CenterX, CenterY-R+m)
dc.LineTo(CenterX, 0)
dc.Stroke()
dc.Pop()
dc.RotateAbout(gg.Radians(float64(6)), CenterX, CenterY)
}
dc.Pop()
dc.SetHexColor("#000")
// AM /PM drawing
var AMPM = "AM"
if t.Hour() >= 12 {
AMPM = "PM"
}
f, _ := truetype.Parse(gomedium.TTF)
face := truetype.NewFace(f, &truetype.Options{Size: 34})
dc.SetFontFace(face)
dc.DrawString(AMPM, CenterX+37, CenterY+7)
//Angle of the hour hand at 0 o'clock=Since we want to set it to 0 degrees, rotate it 90 degrees counterclockwise in advance.
dc.RotateAbout(gg.Radians(-90), CenterX, CenterY)
dc.DrawCircle(CenterX, CenterY, R)
dc.Stroke()
//Drawing of the short hand
dc.Push()
dc.SetLineWidth(8)
dc.MoveTo(CenterX, CenterY)
HD := t.Hour()%12*30 + int(float64(t.Minute())*0.5) //t.Hour() range [0,23] 360/12 == 30
if HD != 0 {
dc.RotateAbout(gg.Radians(float64(HD)), CenterX, CenterY)
}
dc.LineTo(CenterX+Short, CenterY)
dc.Stroke()
dc.Pop()
//Drawing of the long hand
dc.Push()
dc.SetLineWidth(4)
dc.MoveTo(CenterX, CenterY)
MD := t.Minute() * 6 // t.Minute() range [0,59] 360/60 == 6
if MD != 0 {
dc.RotateAbout(gg.Radians(float64(MD)), CenterX, CenterY)
}
dc.LineTo(CenterX+Midium, CenterY)
dc.Stroke()
dc.Pop()
//Drawing the second hand
dc.Push()
dc.SetLineWidth(2)
dc.MoveTo(CenterX, CenterY)
SD := t.Second() * 6 // t.Second() range [0,59] 360/60 == 6
if SD != 0 {
dc.RotateAbout(gg.Radians(float64(SD)), CenterX, CenterY)
}
dc.LineTo(CenterX+Long, CenterY)
dc.Stroke()
dc.Pop()
return dc.Image()
}
Passes time and returns a clock image showing that time
There is almost no explanation, but I would like to update it if I can think of a more understandable explanation.
Personally, I think Go is an easy-to-write language, but type conversion tends to be redundant.
Will there be fewer bugs by eliminating implicit type conversions, or will more code be written ...
Recommended Posts