ebiten으로 동적으로sprite 생성

9138 단어 Go
저번의 계속.
지금까지 화면에 나타난 자원은 모두 원본 코드에 의해 하드코딩된 상태이기 때문에 입력에 따라 스prite를 동적으로 생성하는 것을 고려합니다.
소재는 캐릭터의 비행 도구, 마리오가 말한 화구다.

Sprite 생성


Sprite 생성 자체는 버튼 입력 등 호출NewSprite의 함수에 따라 struct를 동적으로 생성하면 된다.
그러나 스프릿을 생성한 후 어떤 방법으로 폐기할지 고려하지 않으면 메모리에 사용된 스프릿은 계속 유지되기 때문에 좋지 않다.
Go는 GC를 게재한 언어로 사용한 스프릿은 참조를 빼고 GC로 바꾸면 된다(대략. 이해가 애매하다).

소스 코드


  • 전체 차이는 다음과 같다.
  • https://github.com/zenwerk/go-pixelman3/commit/5c980b49bbb7cecc9a5a8aee92f9b5721c1c705d
  • sprite/ball.go
  • package sprite
    
    import (
        "image"
    
        "github.com/hajimehoshi/ebiten"
        "github.com/zenwerk/go-pixelman3/utils"
    )
    
    const (
        ball_img = `--+++--
    -+++++-
    -+++++-
    --+++--`
        ballSpeed    = 4
        screenWidth  = 320
        screenHeight = 240
    )
    
    type Balls []*Ball
    
    var (
        ballImg *ebiten.Image
    )
    
    func init() {
        tmpImage := image.NewRGBA(image.Rect(0, 0, 7, 4))
        utils.CreateImageFromString(ball_img, tmpImage)
        ballImg, _ = ebiten.NewImage(7, 4, ebiten.FilterNearest)
        ballImg.ReplacePixels(tmpImage.Pix)
    }
    
    type Ball struct {
        BaseSprite
    }
    
    func NewBall(pos position) *Ball {
        ball := new(Ball)
        ball.Images = []*ebiten.Image{
            ballImg,
        }
        ball.ImageNum = len(ball.Images)
        ball.Position = pos
        return ball
    }
    
    func (bs *Balls) Move(viewport position) {
        balls := *bs
    
        for i := 0; i < len(balls); i++ {
            b := balls[i]
            b.Position.X += ballSpeed
    
            // 表示領域外に出たら配列から削除する
            if b.Position.X > (screenWidth-viewport.X) || b.Position.Y > (screenHeight-viewport.Y) || b.Position.X < 0 || b.Position.Y < 0 {
                balls = append(balls[:i], balls[i+1:]...)
                i--
            }
        }
        *bs = balls
    }
    
    Move 함수가 표시 영역을 초과하면 슬라이스에서 삭제됩니다.나는 이렇게 하면 여분의 메모리를 사용하지 않을 것이라고 생각한다.
    디스플레이 영역 이외에 다른 스프릿과의 충돌 등을 통해 동일한 처리를 수행할 수도 있습니다.

    실행 결과



    참고 자료

  • Go에 대한 GC
  • http://deeeet.com/writing/2016/05/08/gogc-2016/
  • 필름이 구조체의 수신기일 때 요소를 삭제하는 방법
  • https://stackoverflow.com/questions/18566499/how-to-remove-an-item-from-a-slice-by-calling-a-method-on-the-slice
  • 슬라이스의 작동 일람
  • https://github.com/golang/go/wiki/SliceTricks
  • 좋은 웹페이지 즐겨찾기