main.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright 2020 The Ebiten Authors
  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. // Mascot is a desktop mascot on cross platforms.
  15. // This is inspired by mattn's gopher (https://github.com/mattn/gopher).
  16. package main
  17. import (
  18. "bytes"
  19. "image"
  20. _ "image/png"
  21. "log"
  22. "math/rand/v2"
  23. "github.com/hajimehoshi/ebiten/v2"
  24. rmascot "github.com/hajimehoshi/ebiten/v2/examples/resources/images/mascot"
  25. )
  26. const (
  27. width = 200
  28. height = 200
  29. )
  30. var (
  31. gopher1 *ebiten.Image
  32. gopher2 *ebiten.Image
  33. gopher3 *ebiten.Image
  34. )
  35. func init() {
  36. // Decode an image from the image file's byte slice.
  37. img1, _, err := image.Decode(bytes.NewReader(rmascot.Out01_png))
  38. if err != nil {
  39. log.Fatal(err)
  40. }
  41. gopher1 = ebiten.NewImageFromImage(img1)
  42. img2, _, err := image.Decode(bytes.NewReader(rmascot.Out02_png))
  43. if err != nil {
  44. log.Fatal(err)
  45. }
  46. gopher2 = ebiten.NewImageFromImage(img2)
  47. img3, _, err := image.Decode(bytes.NewReader(rmascot.Out03_png))
  48. if err != nil {
  49. log.Fatal(err)
  50. }
  51. gopher3 = ebiten.NewImageFromImage(img3)
  52. }
  53. type mascot struct {
  54. x16 int
  55. y16 int
  56. vx16 int
  57. vy16 int
  58. count int
  59. }
  60. func (m *mascot) Layout(outsideWidth, outsideHeight int) (int, int) {
  61. return width, height
  62. }
  63. func (m *mascot) Update() error {
  64. m.count++
  65. sw, sh := ebiten.Monitor().Size()
  66. ebiten.SetWindowPosition(m.x16/16, m.y16/16+sh-height)
  67. if m.vx16 == 0 {
  68. m.vx16 = 64
  69. }
  70. m.x16 += m.vx16
  71. if m.x16/16 > sw-width && m.vx16 > 0 {
  72. m.vx16 = -64
  73. }
  74. if m.x16 <= 0 && m.vx16 < 0 {
  75. m.vx16 = 64
  76. }
  77. // Accelerate the mascot in the Y direction.
  78. m.vy16 += 8
  79. m.y16 += m.vy16
  80. // If the mascot is on the ground, stop it in the Y direction.
  81. if m.y16 >= 0 {
  82. m.y16 = 0
  83. m.vy16 = 0
  84. }
  85. // If the mascto is on the ground, cause an action in random.
  86. if rand.IntN(60) == 0 && m.y16 == 0 {
  87. switch rand.IntN(2) {
  88. case 0:
  89. // Jump.
  90. m.vy16 = -240
  91. case 1:
  92. // Turn.
  93. m.vx16 = -m.vx16
  94. }
  95. }
  96. return nil
  97. }
  98. func (m *mascot) Draw(screen *ebiten.Image) {
  99. img := gopher1
  100. if m.y16 == 0 {
  101. switch (m.count / 3) % 4 {
  102. case 0:
  103. img = gopher1
  104. case 1, 3:
  105. img = gopher2
  106. case 2:
  107. img = gopher3
  108. }
  109. }
  110. op := &ebiten.DrawImageOptions{}
  111. if m.vx16 < 0 {
  112. op.GeoM.Scale(-1, 1)
  113. op.GeoM.Translate(width, 0)
  114. }
  115. screen.DrawImage(img, op)
  116. }
  117. func main() {
  118. ebiten.SetWindowDecorated(false)
  119. ebiten.SetWindowFloating(true)
  120. ebiten.SetWindowSize(width, height)
  121. ebiten.SetWindowMousePassthrough(true)
  122. op := &ebiten.RunGameOptions{}
  123. op.ScreenTransparent = true
  124. op.SkipTaskbar = true
  125. if err := ebiten.RunGameWithOptions(&mascot{}, op); err != nil {
  126. log.Fatal(err)
  127. }
  128. }