added implementation in GO lang
This commit is contained in:
180
internal/modes/geometry.go
Normal file
180
internal/modes/geometry.go
Normal file
@ -0,0 +1,180 @@
|
||||
package modes
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
"math"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||
|
||||
"kidskeyboard/internal/ui"
|
||||
)
|
||||
|
||||
type shapeKind int
|
||||
|
||||
const (
|
||||
shapeCircle shapeKind = iota
|
||||
shapeRect
|
||||
shapeTriangle
|
||||
shapeLine
|
||||
shapeStar
|
||||
)
|
||||
|
||||
type shape struct {
|
||||
kind shapeKind
|
||||
x float32
|
||||
y float32
|
||||
w float32
|
||||
h float32
|
||||
size float32
|
||||
color color.NRGBA
|
||||
}
|
||||
|
||||
type GeometryMode struct {
|
||||
ctx Context
|
||||
shapes map[ebiten.Key]*shape
|
||||
order []ebiten.Key
|
||||
}
|
||||
|
||||
func NewGeometryMode(ctx Context) *GeometryMode {
|
||||
return &GeometryMode{ctx: ctx, shapes: map[ebiten.Key]*shape{}}
|
||||
}
|
||||
|
||||
func (m *GeometryMode) Name() string { return "CTRL+F2 Geometry" }
|
||||
func (m *GeometryMode) OnEnter() {}
|
||||
func (m *GeometryMode) OnLeave() {}
|
||||
|
||||
func (m *GeometryMode) HandleInput() {
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyDelete) {
|
||||
m.shapes = map[ebiten.Key]*shape{}
|
||||
m.order = nil
|
||||
return
|
||||
}
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyArrowLeft) {
|
||||
m.moveLast(-20, 0)
|
||||
}
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyArrowRight) {
|
||||
m.moveLast(20, 0)
|
||||
}
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyArrowUp) {
|
||||
m.moveLast(0, -20)
|
||||
}
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyArrowDown) {
|
||||
m.moveLast(0, 20)
|
||||
}
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyEqual) || inpututil.IsKeyJustPressed(ebiten.KeyNumpadAdd) {
|
||||
m.scaleLast(1.12)
|
||||
}
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyMinus) || inpututil.IsKeyJustPressed(ebiten.KeyNumpadSubtract) {
|
||||
m.scaleLast(0.88)
|
||||
}
|
||||
|
||||
for _, key := range justPressedKeys() {
|
||||
if !childKey(key) || geometryControlKey(key) {
|
||||
continue
|
||||
}
|
||||
if _, ok := m.shapes[key]; ok {
|
||||
delete(m.shapes, key)
|
||||
m.removeOrder(key)
|
||||
continue
|
||||
}
|
||||
m.shapes[key] = m.randomShape()
|
||||
m.order = append(m.order, key)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *GeometryMode) Update() {}
|
||||
|
||||
func (m *GeometryMode) Draw(screen *ebiten.Image) {
|
||||
screen.Fill(color.Black)
|
||||
for _, key := range m.order {
|
||||
if s := m.shapes[key]; s != nil {
|
||||
drawShape(screen, s)
|
||||
}
|
||||
}
|
||||
ui.Text(screen, "CTRL+F2", 20, 20, color.White, 2)
|
||||
}
|
||||
|
||||
func (m *GeometryMode) randomShape() *shape {
|
||||
w, h := 1280, 720
|
||||
x := float32(80 + m.ctx.RNG.Intn(max(1, w-160)))
|
||||
y := float32(80 + m.ctx.RNG.Intn(max(1, h-160)))
|
||||
size := float32(35 + m.ctx.RNG.Intn(100))
|
||||
return &shape{
|
||||
kind: shapeKind(m.ctx.RNG.Intn(5)),
|
||||
x: x,
|
||||
y: y,
|
||||
w: size + float32(m.ctx.RNG.Intn(90)),
|
||||
h: size + float32(m.ctx.RNG.Intn(90)),
|
||||
size: size,
|
||||
color: color.NRGBA{
|
||||
R: uint8(80 + m.ctx.RNG.Intn(176)),
|
||||
G: uint8(80 + m.ctx.RNG.Intn(176)),
|
||||
B: uint8(80 + m.ctx.RNG.Intn(176)),
|
||||
A: 255,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func drawShape(screen *ebiten.Image, s *shape) {
|
||||
switch s.kind {
|
||||
case shapeCircle:
|
||||
ui.Circle(screen, s.x, s.y, s.size, s.color)
|
||||
case shapeRect:
|
||||
ui.Rect(screen, s.x-s.w/2, s.y-s.h/2, s.w, s.h, s.color)
|
||||
case shapeTriangle:
|
||||
ui.Triangle(screen, s.x, s.y-s.h/2, s.x-s.w/2, s.y+s.h/2, s.x+s.w/2, s.y+s.h/2, s.color)
|
||||
case shapeLine:
|
||||
ui.Line(screen, s.x-s.w/2, s.y-s.h/2, s.x+s.w/2, s.y+s.h/2, float32(math.Max(4, float64(s.size/8))), s.color)
|
||||
case shapeStar:
|
||||
ui.Star(screen, s.x, s.y, s.size, s.size*0.45, 5, s.color)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *GeometryMode) moveLast(dx, dy float32) {
|
||||
last := m.last()
|
||||
if last == nil {
|
||||
return
|
||||
}
|
||||
last.x += dx
|
||||
last.y += dy
|
||||
}
|
||||
|
||||
func (m *GeometryMode) scaleLast(factor float32) {
|
||||
last := m.last()
|
||||
if last == nil {
|
||||
return
|
||||
}
|
||||
last.w *= factor
|
||||
last.h *= factor
|
||||
last.size *= factor
|
||||
}
|
||||
|
||||
func (m *GeometryMode) last() *shape {
|
||||
for i := len(m.order) - 1; i >= 0; i-- {
|
||||
if s := m.shapes[m.order[i]]; s != nil {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GeometryMode) removeOrder(key ebiten.Key) {
|
||||
next := m.order[:0]
|
||||
for _, k := range m.order {
|
||||
if k != key {
|
||||
next = append(next, k)
|
||||
}
|
||||
}
|
||||
m.order = next
|
||||
}
|
||||
|
||||
func geometryControlKey(key ebiten.Key) bool {
|
||||
switch key {
|
||||
case ebiten.KeyDelete, ebiten.KeyArrowLeft, ebiten.KeyArrowRight, ebiten.KeyArrowUp, ebiten.KeyArrowDown,
|
||||
ebiten.KeyEqual, ebiten.KeyMinus, ebiten.KeyNumpadAdd, ebiten.KeyNumpadSubtract:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user