ebiten에서 캐릭터가 걷는 모션을 만들어 봅니다.

15457 단어 5ebiten

소개



게임을 만들려고 하면, 역시 캐릭터에 움직임은 필요하네요.
우선 걷는 모션만으로도 만들고 싶네요.
저는 만들고 싶어서 만들어 보았습니다.

샘플 코드의 animation을 살펴보기



ebiten 설치 → 샘플의 animation을 본다 → 엄청 널 늘 움직이는 얀. . .
우선 이 샘플을 해석합시다.

필요한 곳만 추출해 해설합니다.
const (
    screenWidth  = 320
    screenHeight = 240

    frameOX     = 0         // フレーム開始時点のX座標
    frameOY     = 32        // フレーム開始時点のY座標
    frameWidth  = 32        // 1フレームで表示する横幅
    frameHeight = 32        // 1フレームで表示する縦幅
    frameNum    = 8         // 表示させる画像の数
)

var (
    // イメージの宣言(今回省略したmain関数の中で画像自体の読み込みをしています)
    runnerImage *ebiten.Image
)

type Game struct {
    count int
}

func (g *Game) Update() error {
    // マイフレーム毎にgを増加させていく
    g.count++
    return nil
}

func (g *Game) Draw(screen *ebiten.Image) {
    // 画像のオプションを宣言
    op := &ebiten.DrawImageOptions{}

    // 画像をスクリーンの中心点へ移動
    op.GeoM.Translate(-float64(frameWidth)/2, -float64(frameHeight)/2)
    op.GeoM.Translate(screenWidth/2, screenHeight/2)

    // 5フレーム毎に1つの絵が切り替わるようにする
    // もし 5 ではなく60 で割った時、 g.count / 60 が 1になるのは 1秒後(60FPS)
    // 1 % frameNum は 1となる
    // 2秒後には 120 / 60 となるので、 2 % 8 = 2
    // つまりここの数字は何フレーム経過後に変数iが変わっていくか?を制御している
    i := (g.count / 5) % frameNum

    // sx は基準となるframeOX(=0)にframeWidth(=32)をiの数だけ足したもの
    // つまりsxはi*32の数になり、基準点が右に動いていく
    // sy は常にframeOY(=32)
    sx, sy := frameOX+i*frameWidth, frameOY

    // 表示させる画像を切り出す
    // Xの範囲は sx から sx+frameWidth
    // Yの範囲は常に sy(=32)
    // つまり、画像の中段を、5フレーム毎に右にズレながら切り出していく
    var this_frame_img *ebiten.Image = runnerImage.SubImage(image.Rect(sx, sy, sx+frameWidth, sy+frameHeight)).(*ebiten.Image)

    // 画像を表示させる
    screen.DrawImage(this_frame_img, op)
}


중간 단계의 이미지는 빨간색으로 둘러싸인 부분입니다.

5프레임마다 32픽셀씩 오른쪽으로 어긋나 가면서 꺼내서 표시하고 있기 때문에, 그런 식으로 늘어져 움직이고 있었군요.

보행 모션을 만들어 보자



이미지 준비



토끼와 모서리 모두 이미지가 필요합니다.
피포야 창고씨의 소재와 「캐릭터 어떻게든 J」로 만들었습니다.


모션 정보



그런데, 기본적인 보행 모션의 부착 방법은 샘플과 같습니다만, 하나 다른 것이
「오른손→중립→왼손→중립→오른손→...」이라고 하는 움직임 방법이 되는 점입니다.
왼쪽에서 오른쪽으로 루프 시키면
「오른손→중립→왼손→오른손→중립→왼손→...」이 되어 버리므로, 여기를 고려하면서 만듭니다.

완성된 코드



마지막 기사 로 만든 이미지 표시의 오리지널 패키지를 사용해 이미지 표시시킵니다
package main

import (
    "log"
    "image"
    _ "image/png"

    "github.com/hajimehoshi/ebiten/v2"
    "github.com/hajimehoshi/ebiten/v2/ebitenutil"
    "github.com/username/projectname/src/picture"  // 画像表示のオリジナルパッケージ
)

const (
    frameOX = 0             // フレーム開始時点のX座標
    frameOY = 0             // フレーム開始時点のY座標
    frameWidth = 32     // 1フレームで表示する横幅
    frameHeight = 32    // 1フレームで表示する縦幅
    frameNum = 4            // 表示させる画像の数
)


var character *ebiten.Image

// 最初に画像を読み込む
func init() {
    var err error
    character, _, err = ebitenutil.NewImageFromFile("character.png")
    if err != nil {
        log.Fatal(err)
    }
}

type Game struct{
    count int
}

func (g *Game) Update() error{
    // 毎フレーム毎にgを増加させていく
    g.count++
    return nil
}

func(g *Game) Draw(screen *ebiten.Image){
    // 13フレームに一度画像を更新する
    i := (g.count / 13) % frameNum

    // i が3 すなわち右手→ニュートラル→左手→ここ の時にニュートラルを表示させる
    if i == 3 {
        i = 1
    }

    sx, sy := frameOX + i * frameWidth, frameOY

    // 表示する画像を切り出す
    var this_frame_img *ebiten.Image = character.SubImage(image.Rect(sx, sy, sx + frameWidth, sy + frameHeight)).(*ebiten.Image)

    // 画像を表示させる
    picture.Show(screen, this_frame_img, 1, 100,100,0)
}



func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
    return 320, 240
}

func main() {
    ebiten.SetWindowSize(640, 480)
    ebiten.SetWindowTitle("walk")
    if err := ebiten.RunGame(&Game{}); err != nil {
        log.Fatal(err)
    }
}

완성





다음은 십자 키로 움직이고 싶습니다.

좋은 웹페이지 즐겨찾기