Saturday, September 8, 2018

opengl - Rending 2D Tile World (With Player In The Middle)


What I have at the moment is a series of data structures I'm using, and I would like to render the world onto the screen (just the visible parts).



I've actually already done this several times (lots of rewrites), but it's a bit buggy (rounding seems to make the screen jump ever so slightly every x tiles the player walks past).


Basically I've been confusing myself heavily on what I feel should be a pretty simple problem... so here I am asking for some help!


OK! So I have a 50x50 array holding the tiles of the world. I have the player position as 2 floats, x ([0, 49]) and y ([0, 49]) in that array. I have the application size exactly in pixels (x and y). I have an arbitrary TILE_SIZE static int (based on screen pixels).


What I think is heavily confusing me is using a 2d orthogonal projection in opengl which maps (0,0) to the top left of the screen and (SCREEN_SIZE_X, SCREEN_SIZE_Y) to the bottom right of the screen.


    gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();

glu.gluOrtho2D(0, getActualWidth(), getActualHeight(), 0);

gl.glMatrixMode(GL.GL_MODELVIEW);

gl.glLoadIdentity();

The map tiles are set so that the (0,0) in the array is the bottom left.


And the player has to be in the middle on the screen (SCREEN_SIZE_X/2, SCREEN_SIZE_Y/2).


What I've been doing so far is trying to render 1-2 tiles more all around what would be displayed on the screen so that I don't have to worry about figuring out rendering half a tile from the top left, depending where the player is.


It seems like such an easy problem but after spending about 40+hours on it rewriting it many times I think I'm at a point where I just can't think clearly anymore...


Any help would be appreciated. It would be great if someone can provide some very basic pseudo code on keeping the player in the middle when your projection is mapped to screen coordinates and only rendering basically the tiles that you would be any be see.


Thanks!



Answer



If I understand you correctly then I think the easiest way to solve this is to render the map always at the same coordinates.



So the render coordinates for the tiles would be something like: (x * TileWidth ; y * TileHeight). The location of the character is calculated just the same way. Now for the moving part you should translate of the OpenGL coordinates using glTranslatef. Using this function is you shift the origin location out of your screen. The values for the translate function would be something like: (playerPos.x * TileWidth - SCREEN_WIDTH/2; (playerPos.y * TileHeight - SCREEN_HEIGHT/2). You might have to alter the calculate by inverting the height by adding SCREEN_HEIGHT - (...). But I hope you get the general idea.


Now as for the problem that the screen coordinate are inverted compared to what you expected. You can fix this problem simply by using glScale. Using -1 as second parameter will invert the Y coordinate of all subsequent OpenGL calls. That should help you turning the coordinates as you need it.


And finally in detect if the tiles are on the screen and need to be rendered or not you can get use your render coordinates of your player character (playerPos.x * TileWidth; playerPos.y - TileHeight) and check if the location of the tile is within SCREEN_WIDTH/2 + TileWidth and SCREEN_HEIGHT/2 + TileHeight around your player location. If not you don't need to render the tile.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...