pixel icon indicating copy to clipboard operation
pixel copied to clipboard

Scale window?

Open nosmokingbandit opened this issue 6 years ago • 3 comments

Loving Pixel so far, but one bit of convenience for pixel-art games could be a means to scale the window output.

For example, if I have a game running at 256x224 (SNES resolution) I could display double-size by calling something like window.SetScale(2.0). It would render at 256x224, but increase the window size to 512x448 and scale the output to match.

Currently this can be done with some camera scale trickery, but the math gets complicated and it doesn't allow the window to be resized on the fly.

nosmokingbandit avatar Feb 17 '18 04:02 nosmokingbandit

This would be convenient if built in. (Like it is in Ebiten)

For now the raycaster community example supports scaling:

go run $GOPATH/src/github.com/faiface/pixel-examples/community/raycaster/raycaster.go -w 256 -h 224 -s 2

peterhellberg avatar Feb 20 '18 17:02 peterhellberg

This is currently doable (take a look at the platformer example, or the raycaster community example). The way you do it is you create a canvas that has the correct dimensions and then scale it to fit the window. Resizing is possible too, all you need to do is to resize the canvas according to the size of the window.

But, I guess I'd be willing to accept this feature into WindowConfig if anyone's willing to implement it.

faiface avatar Feb 20 '18 17:02 faiface

You can do this as a last operation on all matrices for drawing:

func WindowFit(m pixel.Matrix, virtualBounds pixel.Bounds) pixel.Matrix {
	winW, winH := window.Bounds().Size().XY()
        vWidth, vHeight := virtualBounds.Size().XY()

	if (vWidth / vHeight) > (winW / winH) {
		//Letterboxing
		factor := winW / vWidth
		m = m.Scaled(pixel.V(0, 0), factor)

		newH := vHeight * factor
		offset := (winH - newH) / 2
		m = m.Moved(pixel.V(0, offset))

	} else {
		//Pillarboxing
		factor := winH / vHeight
		m = m.Scaled(pixel.V(0, 0), factor)

		newW := vWidth * factor
		offset := (winW - newW) / 2
		m = m.Moved(pixel.V(offset, 0))
	}
	return m
}

I have a constant set for vWidth and vHeight so I dont need to pass that argument, which makes it a bit more convenient. This will however not take care of clearing the black boxes surrounding the content so you have to redraw the entire screen.

I dont know if it makes sense to include this operation on the matrix type. So if it is ok / there is a better place then feel free to use this.

Pixdigit avatar Jan 09 '19 21:01 Pixdigit