2D игры на Golang c Ebiten. Введение

Решил попробовать пописать простые 2D игры на Golang. Основная цель — развлечение и более углубленное понимание того как можно писать простые любительские 2D игры на Go.

В начале пути

Скорее всего это будет цикл небольших, но полезных статей для всех интересующихся 2D играми и Golang. Первое, что нам необходимо решить — каким инструментом мы будем пользоваться для разработки игры. Я остановился на довольно простом игровом фреймворке — Ebiten. Основная идея библиотеки — все что есть это просто изображение. Порядок, позиция, угол наклона и масштаб зависит от вашей игровой логики.

Игровой цикл:

  1. Инициализация игровых объектов
    1. Повторить:
    2. Проверка пользовательского ввода, данных по сети.
    3. Обновление игрового мира (один тик)
    4. Отрисовка

Цикл повторяется много много раз в секунду (тики): обновление координат игроков в зависимости от игровой логики, отрисовка и так далее. Итого задача сводится к инициализации игрового мира, ведения расчетов и отрисовки.

В Ebiten это сделано довольно элегантно. Ниже мой измененный пример базовой игровой структуры:

type Object struct {
	x, y int
	img  *ebiten.Image
}

func main() {
	var err error
	dir, err := os.Getwd()

	img, _, err := ebitenutil.NewImageFromFile(dir+"/assets/ball.png", ebiten.FilterDefault)
	firstPlayer := &Object{img: img}

	img, _, err = ebitenutil.NewImageFromFile(dir+"/assets/ball.png", ebiten.FilterDefault)
	secondPlayer := &Object{img: img}

	if err != nil {
		log.Fatal(err)
	}
	ebiten.SetWindowSize(screenXMax*2, screenYMax*2)
	ebiten.SetWindowTitle("Ball Bouncer")

	g := NewGame(fristPlayer,secondPlayer)
	if err := ebiten.RunGame(g); err != nil {
		log.Fatal(err)
	}
}

Итого вся логика будет написана в нашей структуре Game:

const (
	// Screen resolution
	screenXMax = 500
	screenYMax = 580
)

type  Game struct {
   scoreFirst, scoreSecond     int
   firstPlayer, secondPlayer   *Object
}
func (g *Game) Update(screen *ebiten.Image) error {
	// Here our update logic: checking player position, handler user inputs etc...
	return nil
}

func (g *Game) Draw(screen *ebiten.Image) {
	screen.Fill(color.RGBA{0, 0xff, 0, 0xff})
        // Here we just draw our players and other assets
}

func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
	return screenXMax, screenYMax
}

В следующих статьях рассмотрим более подробнее пользовательское взаимодействие, отрисовку игровых объектов, расчет коллизий.

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *