main.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright 2016 Hajime Hoshi
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package main
  15. import (
  16. "bytes"
  17. "fmt"
  18. "image"
  19. _ "image/jpeg"
  20. "log"
  21. "math"
  22. "github.com/hajimehoshi/ebiten/v2"
  23. "github.com/hajimehoshi/ebiten/v2/colorm"
  24. "github.com/hajimehoshi/ebiten/v2/ebitenutil"
  25. "github.com/hajimehoshi/ebiten/v2/examples/resources/images"
  26. "github.com/hajimehoshi/ebiten/v2/inpututil"
  27. )
  28. const (
  29. screenWidth = 640
  30. screenHeight = 480
  31. )
  32. var (
  33. gophersImage *ebiten.Image
  34. )
  35. // clamp clamps v to the range [min, max].
  36. func clamp(v, min, max int) int {
  37. if min > max {
  38. panic("min must <= max")
  39. }
  40. if v < min {
  41. return min
  42. }
  43. if max < v {
  44. return max
  45. }
  46. return v
  47. }
  48. type Game struct {
  49. hue128 int
  50. saturation128 int
  51. value128 int
  52. inverted bool
  53. }
  54. func NewGame() *Game {
  55. return &Game{
  56. saturation128: 128,
  57. value128: 128,
  58. }
  59. }
  60. func (g *Game) Update() error {
  61. // Adjust HSV values along with the user's input.
  62. if ebiten.IsKeyPressed(ebiten.KeyQ) {
  63. g.hue128--
  64. }
  65. if ebiten.IsKeyPressed(ebiten.KeyW) {
  66. g.hue128++
  67. }
  68. if ebiten.IsKeyPressed(ebiten.KeyA) {
  69. g.saturation128--
  70. }
  71. if ebiten.IsKeyPressed(ebiten.KeyS) {
  72. g.saturation128++
  73. }
  74. if ebiten.IsKeyPressed(ebiten.KeyZ) {
  75. g.value128--
  76. }
  77. if ebiten.IsKeyPressed(ebiten.KeyX) {
  78. g.value128++
  79. }
  80. g.hue128 = clamp(g.hue128, -256, 256)
  81. g.saturation128 = clamp(g.saturation128, 0, 256)
  82. g.value128 = clamp(g.value128, 0, 256)
  83. if inpututil.IsKeyJustPressed(ebiten.KeyI) {
  84. g.inverted = !g.inverted
  85. }
  86. return nil
  87. }
  88. func (g *Game) Draw(screen *ebiten.Image) {
  89. // Center the image on the screen.
  90. s := gophersImage.Bounds().Size()
  91. op := &colorm.DrawImageOptions{}
  92. op.GeoM.Translate(-float64(s.X)/2, -float64(s.Y)/2)
  93. op.GeoM.Scale(2, 2)
  94. op.GeoM.Translate(float64(screenWidth)/2, float64(screenHeight)/2)
  95. // Change HSV.
  96. hue := float64(g.hue128) * 2 * math.Pi / 128
  97. saturation := float64(g.saturation128) / 128
  98. value := float64(g.value128) / 128
  99. var c colorm.ColorM
  100. c.ChangeHSV(hue, saturation, value)
  101. // Invert the color.
  102. if g.inverted {
  103. c.Scale(-1, -1, -1, 1)
  104. c.Translate(1, 1, 1, 0)
  105. }
  106. colorm.DrawImage(screen, gophersImage, c, op)
  107. // Draw the text of the current status.
  108. msgInverted := "false"
  109. if g.inverted {
  110. msgInverted = "true"
  111. }
  112. msg := fmt.Sprintf(`Hue: %0.2f [Q][W]
  113. Saturation: %0.2f [A][S]
  114. Value: %0.2f [Z][X]
  115. Inverted: %s [I]`, hue, saturation, value, msgInverted)
  116. ebitenutil.DebugPrint(screen, msg)
  117. }
  118. func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
  119. return screenWidth, screenHeight
  120. }
  121. func main() {
  122. // Decode an image from the image file's byte slice.
  123. img, _, err := image.Decode(bytes.NewReader(images.Gophers_jpg))
  124. if err != nil {
  125. log.Fatal(err)
  126. }
  127. gophersImage = ebiten.NewImageFromImage(img)
  128. ebiten.SetWindowSize(screenWidth, screenHeight)
  129. ebiten.SetWindowTitle("HSV (Ebitengine Demo)")
  130. if err := ebiten.RunGame(NewGame()); err != nil {
  131. log.Fatal(err)
  132. }
  133. }