Skip to content

Drawing a Sprite

Michal Štrba edited this page Apr 2, 2017 · 30 revisions

In this part, we'll learn how draw pictures on the screen using sprites.

What's sprite?

Sprite is an ancient concept in video game development. In the old times, a sprite was usually a 16x16px or 32x32px "stamp" that could be stamped on the screen. One sprite could be the picture of the player, more sprites could be used to display enemies and platforms, and so on. This allowed efficient drawing of complicated scenes. Here's a screenshot of an old C64 game shamelessly taken from Wikipedia.

Today, sprites still follow the same concept, however, allow for much wider range of possibilities. A sprite is basically a picture, which can be drawn somewhere on the screen. In Pixel, as we'll learn later, sprites (alongside all other graphical objects) can be drawn not only on the screen, but onto an arbitrary Target.

Previous lesson

We'll start off with the code from the end of the previous lesson.

package main

import (
	"github.com/faiface/pixel"
	"github.com/faiface/pixel/pixelgl"
	"golang.org/x/image/colornames"
)

func run() {
	cfg := pixelgl.WindowConfig{
		Title:  "Pixel Rocks!",
		Bounds: pixel.R(0, 0, 1024, 768),
		VSync:  true,
	}
	win, err := pixelgl.NewWindow(cfg)
	if err != nil {
		panic(err)
	}

	win.Clear(colornames.Skyblue)

	for !win.Closed() {
		win.Update()
	}
}

func main() {
	pixelgl.Run(run)
}

Picture

Before we can draw any sprites, we first need to have some pictures to use. If scroll through the Pixel documentation, you'll find this function.

func PictureDataFromImage(img image.Image) *PictureData

What's PictureData? Well, don't get scared, it's simple. In Pixel, pictures can have a large variety of forms. There are pictures stored in the memory, there are pictures stored in the video memory, and so on. What does this hint? Yes, there's an interface called Picture. To create a sprite, we just need a picture of any form, and PictureData is the simplest one to obtain, it's just some pixels stored in the memory. Also, as you can see, we can create it from the standard Go's image.Image.

So, we first need to load an image.Image. If you're not familiar with the image package from the standard library, I highly recommend you to read this article.

First, we need to import the image package and we also need to "underscore import" the image/png package to load PNG files. We also need to import the os package to load files from the filesystem.

import (
	"image"
	"os"

	_ "image/png"

	"github.com/faiface/pixel"
	"github.com/faiface/pixel/pixelgl"
	"golang.org/x/image/colornames"
)

Next, we'll write a short helper function to load pictures.

func loadPicture(path string) (pixel.Picture, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	img, _, err := image.Decode(file)
	if err != nil {
		return nil, err
	}
	return pixel.PictureDataFromImage(img), nil
}