Advertisement
cwchen

Drawing animated items in an Ebiten program

Oct 19th, 2016
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 3.27 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "errors"
  5.     "log"
  6.     "math/rand"
  7.     "time"
  8.  
  9.     "github.com/hajimehoshi/ebiten"
  10.     "github.com/hajimehoshi/ebiten/ebitenutil"
  11. )
  12.  
  13. const (
  14.     SCREEN_WIDTH  = 320
  15.     SCREEN_HEIGHT = 240
  16.     SCALE_FACTOR  = 2
  17.     APP_TITLE     = "Draw Items"
  18. )
  19.  
  20. var image *ebiten.Image
  21. var sprites Sprites
  22. var random = rand.New(rand.NewSource(time.Now().UnixNano()))
  23.  
  24. type Sprite struct {
  25.     img   *ebiten.Image
  26.     op    *ebiten.DrawImageOptions
  27.     x     float64
  28.     y     float64
  29.     vx    float64
  30.     vy    float64
  31.     count int
  32. }
  33.  
  34. func NewSprite(image *ebiten.Image) (*Sprite, error) {
  35.     s := new(Sprite)
  36.  
  37.     // Set Image
  38.     s.img = image
  39.  
  40.     // Set DrawImageOptions obj
  41.     s.op = new(ebiten.DrawImageOptions)
  42.  
  43.     w, h := s.img.Size()
  44.  
  45.     // Set x
  46.     x := float64(random.Intn(SCREEN_WIDTH - w))
  47.     err := s.setX(x)
  48.     if err != nil {
  49.         return s, err
  50.     }
  51.  
  52.     // Set y
  53.     y := float64(random.Intn(SCREEN_HEIGHT - h))
  54.     err = s.setY(y)
  55.     if err != nil {
  56.         return s, err
  57.     }
  58.     s.op.GeoM.Translate(s.x, s.y)
  59.  
  60.     // Set vx
  61.     s.vx = s.getVelocity()
  62.  
  63.     // Set vy
  64.     s.vy = s.getVelocity()
  65.  
  66.     return s, nil
  67. }
  68.  
  69. func (s *Sprite) setX(x float64) error {
  70.     w, _ := s.img.Size()
  71.     if x < 0 || x > float64(SCREEN_WIDTH-w) {
  72.         return errors.New("Invalid x value")
  73.     }
  74.  
  75.     s.x = x
  76.     return nil
  77. }
  78.  
  79. func (s *Sprite) setY(y float64) error {
  80.     _, h := s.img.Size()
  81.     if y < 0 || y > float64(SCREEN_HEIGHT-h) {
  82.         return errors.New("Invalid y value")
  83.     }
  84.  
  85.     s.y = y
  86.     return nil
  87. }
  88.  
  89. // Get random velocity other than zero
  90. func (s *Sprite) getVelocity() float64 {
  91.     m := 0
  92.     v := 0.0
  93.  
  94.     for m == 0 {
  95.         v = float64(random.Intn(9) - 4)
  96.         m = int(v)
  97.     }
  98.  
  99.     return v
  100. }
  101.  
  102. func (s *Sprite) GetImg() *ebiten.Image {
  103.     return s.img
  104. }
  105.  
  106. func (s *Sprite) GetOp() *ebiten.DrawImageOptions {
  107.     return s.op
  108. }
  109.  
  110. func (s *Sprite) Update() {
  111.     w, h := s.img.Size()
  112.  
  113.     // Rotate the image in place
  114.     theta := 0.2
  115.     if s.vx < 0 {
  116.         theta = -theta
  117.     }
  118.     s.op.GeoM.Translate(-s.x-float64(w)/2, -s.y-float64(h)/2)
  119.     s.op.GeoM.Rotate(theta)
  120.     s.op.GeoM.Translate(s.x+float64(w)/2, s.y+float64(h)/2)
  121.  
  122.     // Move the image
  123.     s.x += s.vx
  124.     s.y += s.vy
  125.     s.op.GeoM.Translate(s.vx, s.vy)
  126.  
  127.     // Basic collision detection
  128.     // Revert the direction if hit the edge of screen
  129.     if s.x <= 0.0 || s.x >= float64(SCREEN_WIDTH-w) {
  130.         s.vx = -s.vx
  131.     }
  132.  
  133.     // Basic collision detection
  134.     // Revert the direction if hit the edge of screen
  135.     if s.y <= 0.0 || s.y >= float64(SCREEN_HEIGHT-h) {
  136.         s.vy = -s.vy
  137.     }
  138. }
  139.  
  140. type Sprites struct {
  141.     sprites []*Sprite
  142. }
  143.  
  144. func (s *Sprites) Append(ss *Sprite) {
  145.     s.sprites = append(s.sprites, ss)
  146. }
  147.  
  148. func (s *Sprites) Init(image *ebiten.Image) error {
  149.     numOfBottles := random.Intn(31) + 20
  150.  
  151.     for i := 0; i < numOfBottles; i++ {
  152.         ss, err := NewSprite(image)
  153.         if err != nil {
  154.             return err
  155.         }
  156.         s.Append(ss)
  157.     }
  158.  
  159.     return nil
  160. }
  161.  
  162. func (s *Sprites) Update(screen *ebiten.Image) error {
  163.     for _, ss := range s.sprites {
  164.         ss.Update()
  165.         if err := screen.DrawImage(ss.GetImg(), ss.GetOp()); err != nil {
  166.             return err
  167.         }
  168.     }
  169.  
  170.     return nil
  171. }
  172.  
  173. func init() {
  174.     var err error
  175.  
  176.     image, _, err = ebitenutil.NewImageFromFile("beerBottle.png",
  177.         ebiten.FilterNearest)
  178.     if err != nil {
  179.         log.Fatal(err)
  180.     }
  181.  
  182.     sprites = Sprites{}
  183.     if err = sprites.Init(image); err != nil {
  184.         log.Fatal(err)
  185.     }
  186. }
  187.  
  188. func update(screen *ebiten.Image) error {
  189.     if err := sprites.Update(screen); err != nil {
  190.         return err
  191.     }
  192.  
  193.     return nil
  194. }
  195.  
  196. func main() {
  197.     ebiten.Run(update, SCREEN_WIDTH, SCREEN_HEIGHT, SCALE_FACTOR, APP_TITLE)
  198. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement