Ein Beispiel, das eine Uhr mit einer Spiel-Engine namens [ebiten] zeichnet (https://github.com/hajimehoshi/ebiten)
Die Uhr ist einfach.
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)
}
}
Mit der Bedeutung eines Samples können Sie die Uhr stoppen, indem Sie die Escape-Taste drücken.
Ich denke nicht darüber nach, wie ich es benutzen soll.
Ein Programm, das das wesentliche Uhrbild erzeugt
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 //Andere Speicherleitungen
M5 = 26 //5 Minuten Speicherleitung
)
dc := gg.NewContext(Width, Height)
dc.SetHexColor("#ffffff")
dc.Clear()
//Speicherzeichnung
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 Zeichnung
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)
//Der Winkel des kurzen Zeigers um 0 Uhr=Da wir es auf 0 Grad einstellen möchten, drehen Sie es vorher um 90 Grad gegen den Uhrzeigersinn.
dc.RotateAbout(gg.Radians(-90), CenterX, CenterY)
dc.DrawCircle(CenterX, CenterY, R)
dc.Stroke()
//Zeichnung der kurzen 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()
//Zeichnung der langen 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()
//Den Sekundenzeiger zeichnen
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()
}
Vergeht die Zeit und gibt ein Uhrbild zurück, das diese Zeit zeigt
Es gibt fast keine Erklärung, aber ich würde es gerne aktualisieren, wenn mir eine verständlichere Erklärung einfällt.
Persönlich denke ich, dass Go eine einfach zu schreibende Sprache ist, aber die Typkonvertierung ist in der Regel redundant.
Wird es weniger Fehler geben, indem die implizite Typkonvertierung eliminiert wird, oder wird mehr Code geschrieben ...
Recommended Posts