gonutz / prototype

Simple 2D game prototyping framework.

Home Page:https://pkg.go.dev/github.com/gonutz/prototype/draw

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Is there a way to have the screen size smaller than the window size?

eboatwright opened this issue Β· comments

I want to use this for pixel art games, but I don't want to have a tiny window. So how do I make the screen size smaller than the window size? For example, having the window 960x600 but drawing on it like it's 320x200.

That is actually something I have wanted to do a couple of times myself. I like the Ebiten way of having a screen scale for this (if I remember correctly) but a focus for me is the minimalism of this framework and so far it has served my needs, e.g. just scaling up my pixel art. Drawing something scaled with DrawImageFilePart will use nearest neighbor filtering so you get pixellated images.

Of course you can also just scale up your assets beforehand and use larger images.

If I find a way to add something like this without complicating the API too much for my liking, then I might put it in.

Originally I created this lib because I wanted to get things going more quickly when wanting to try out new things, hence the name prototype and at first it was only graphics routines, hence the package name draw.

I actually have written a small Linux GUI program with this, because I wanted to use Go and Linux GUIs are a horror to create, even if you are free to choose any language you want. Thus I created a little immediate mode GUI in prototype and used that.

Another thing we regularly use at work is an extension of this lib to render interactive graphs, to visualize several types of data. I have found this library to be very versatile in practice and I am pretty sure that the small API surface is helpful in that.

Thank you! But, my problem with using DrawImageFilePart is that it won't be pixel perfect. So pixels can halfway overlap if you do that. πŸ˜• So, yeah. I can add it in an make a pull request and you can see if you like it πŸ˜„ I was just thinking something like 2 extra parameters in draw.RunWindow() to have like an "internalWidth" and "internalHeight" variables.

or maybe something in the Window type Β―_(ツ)_/Β―

nvm i can't figure out how to do it πŸ˜†

I just tried it with a 3x3 pixel image, here is the code:

func main() {
	draw.RunWindow("Pixels", 630, 320, func(window draw.Window) {
		window.DrawImageFilePart(
			"pixels.png",
			0, 0, 3, 3,
			10, 10, 300, 300,
			0,
		)
		window.DrawImageFilePart(
			"pixels.png",
			1, 1, 1, 1,
			320, 10, 300, 300,
			0,
		)
	})
}

image

This looks good to me on Windows, maybe there is a bug in the OpenGL rendering on Mac.

I basically have three versions of this library:

  1. The Windows version which uses the Windows API (Win32) and Direct3D9.
  2. A version based on GLFW, this is the default on Linux and Mac.
  3. An SDL2 version, this can be enabled with the go build tag sdl2.

As I said, I test on Linux and Windows, there might still be bugs. Can you run this sample and show me your output? Here is my 3x3 image:

image

No, it's not a bug. πŸ˜† I'm talking about something else. Let's say you're drawing it 3 times bigger. Since a pixel is being drawn is effectively 3 pixels, you can have a bigger pixel inside another bigger pixel. But, I figured it out. You have a PixelSize variable, and you just multiply destX, destY, destWidth, and destHeight by that PixelSize variable. πŸ˜„ Thank you for the help!

@gonutz I made a little engine / framework πŸ˜„ It's at https://github.com/eboatwright/melon

Nice, I checked out your code. I noticed that in the example when I move left, the character disappears. Is that the case for you too? This might be a strange rendering issue with mirroring or with coordinates being out of the texture. I might have to look into that if this works for you. As I said, whenever the direction is facing left, I see nothing.

You must just be on an old version, because it works fine for me. πŸ˜„

There I released v1.0.1, and it should work

Actually it does not work. I have modified your code to work on Windows, here it is:

package main

import (
	"github.com/eboatwright/melon"
	"github.com/gonutz/prototype/draw"
)

var (
	playerPos      = melon.VZERO
	playerVel      = melon.VZERO
	playerFriction = 0.85
	playerSpeed    = 0.7
	facingRight    = true
)

func main() {
	melon.Start(&melon.Game{
		Title: "Top Down Example - Melon",
		Update: func() {
			input := melon.Vector2{
				float64(melon.GetInputAxis([]draw.Key{draw.KeyA}, []draw.Key{draw.KeyD})),
				float64(melon.GetInputAxis([]draw.Key{draw.KeyW}, []draw.Key{draw.KeyS})),
			}
			if input.X > 0 {
				facingRight = true
			}
			if input.X < 0 {
				facingRight = false
			}
			input.Normalize()
			playerVel.Add(melon.Vector2Multiply(input, playerSpeed))
			playerVel.Multiply(playerFriction)
			playerPos.Add(melon.Vector2Floor(playerVel))
		},
		Draw: func() {
			melon.Clear(draw.White)
			if facingRight {
				melon.DrawImage(
					"data/img/player.png",
					int(playerPos.X), int(playerPos.Y), 9, 14,
					0, 0, 9, 14,
				)
			} else {
				melon.DrawImage(
					"data/img/player.png",
					int(playerPos.X), int(playerPos.Y), -9, 14,
					9, 0, 9, 14,
				)
			}
		},
	})
}

Hm. That's really weird! πŸ€”

I found the issue.

In your original code, you flip the destination rectangle left-to-right. In my version I flip the source rectangle left-to-right. This is what I documented on the DrawImageFilePart function.

The thing is, on Windows I enable back face culling with

device.SetRenderState(d3d9.RS_CULLMODE, d3d9.CULL_CCW)

which hides surfaces whose vertices are, in this case, counter clock-wise. This means that if you make the destination rectangle's width negative, the order of the vertices is CCW and this image does not show.

In the GLFW backend, which is what you use by default on Linux and Mac, I forgot to enable back face culling. I will enable it later today when I am on my Linux machine. From that point on you also get an invisible sprite for your example, but now you know how to fix it already ;-)

I think it is better to fail on all platforms the same way. That is why I will enable back face culling on Linux and Mac instead of disabling it on Windows. Graphics cards do strange things when options are not defined.

Here is a log of your parameters passed to DrawImageFilePart from your original example, and for comparison the parameters you get with the above code from my comment.

wrong:                 source     destination
data/img/player.png   0 0  9 14    0 0  27 42   0
data/img/player.png   0 0  9 14   27 0 -27 42   0
right:
data/img/player.png   0 0  9 14    0 0  27 42   0
data/img/player.png   9 0 -9 14    0 0  27 42   0

ooohhhhhhh That's interesting! πŸ˜„ thank you!

ok I fixed it! πŸ˜„ thanks

Call me fickle but after noticing that when you cull one direction or the other and you flip BOTH the x and y direction, culling would still show that. So instead of keeping it as it is, I will instead make sure that you can reverse the destination rectangle and it makes sense when you give it a negative width, height or both as the destination.

This means that your original code will probably run with the next version of this lib on Windows, but it is also nice that it works for now in any case. Sorry for the hassle :-)

No problem! πŸ˜„