Updated translate? (Extended Convo)

EDIT: I wanna say I’m using Lwjgl 2 and slick, no other libraries

So, I started asking about this back in my “Rendering” Thread. I’ve been messing with this for the last couple of days, but I’m running into little issues, and thought I should ask. I’ve also been spending hours trying to research this, but I keep finding different answers, and just don’t know what’s right for my situation.

I have a player object in my game, and I’m trying to simulate a “camera” that follows the player. Also, when it reaches the end or start of the level, the camera doesn’t follow it (so it doesn’t look in front/behind the level).

I was also told to follow this:

clear the transform (glLoadIdentity)
glTranslatef(-player.x, -player.y)
for each entity (including the player)
  push matrix stack (glPushMatrix)
  glTranslatef(entity.x, entity.y)
  render entity
  pop matrix stack (glPopMatrix)
end for

Now the thing is, glTranslate is deprecated, and I don’t know what’s best to use that isn’t deprecated.

I also don’t really get how this all works I guess, even though it was explained before. I’ve tried messing with it a bunch, but still I’ve been told glTranslate isn’t something I should be using.

To be clear, for the player I have a moveLeft and moveRight method that runs when called.

	public void moveLeft(float length)
	{
		direction = 0;
		//Safely moves left by the length provided if possible
		if(canMove("Left",length) == true)
		{
			//checks if the user will stay in the position it should and can actually move to where it wants to
			if ((this.x - length) >= 350 && (this.x - length) <= 4050)
			{
				GL11.glTranslatef(length,0,0);
				this.x -= length;
			}
			else if(((this.x - length) >= 0 && (this.x - length) < 350) || ((this.x - length) > 4050 && (this.x - length) <= 4500))
			{
				this.x -= length;
			}
		}
	}
	public void moveRight(float length)
	{
		direction = 1;
		//Safely moves right by the length provided if possible
		if(canMove("Right",length) == true)
		{
			//checks if the user will stay in the position it should and can actually move to where it wants to
			if ((this.x + length) >= 350 && (this.x + length) <= 4050)
			{
				GL11.glTranslatef(-length,0,0);
				this.x += length;
			}
			else if(((this.x + length) > 0 && (this.x + length) < 350) || ((this.x + length) > 4050 && (this.x + length) < 4500))
			{
				this.x += length;
			}
		}
	}

So if anyone can give it another go explain the best thing to change for me, that would be great. The code above also has a few issues which I can’t seem to find (the “length” messes things up for some reason).

I was told keep the translate to the render code, but for what I want at the start and the end of the level, I don’t know why or how I would do it like that. I guess my question is just what’s the best way to simulate a camera, since I guess OpenGL moves the actual map, and doesn’t have a camera (again things I found when researching this).

Slick’s Graphics class has a translate method. Use it exactly as you would glTranslatef but remember than in Slick it’s Y-down.

Maybe you should look at the handy javadoc.

If I understand this correctly, isn’t that for an image/texture? Cause That’s not what I’m really asking about. I’m asking about the “camera”, which I thought is OpenGL/Lwjgl. Cause I’m moving around the images fine, and all I was told to use slick for was to load in images/text/sound and maybe draw text and run sound, i don’t know.

Looking at the handy javadoc it says the Graphics.translate method does:

It basically acts like a camera, translating everything.

Slick is a sort of wrapper for LWJGL.

Ok well I’m either really missing something or idek what. From your first post, I looked at the javadoc… and tried the translate method. The only way I got it to even show up working was Graphics.translate(x,y), but that says it’s only for int,int . On the javadoc, it says it’s for floats, so I feel like I’m calling it wrong. I tried other ways, but nothing else works. To add on to that, it will still do the same thing as OpenGL’s… and I guess that brings me back to the same question on the best way to implement this.

Here is my ridiculously old Camera code from when I used to use Slick. You’ll have to modify some things to fit what you want, or just use it an example.

http://www.java-gaming.org/?action=pastebin&id=1309

You could use the Matrix4f class from JOML, it has a translate method.

I think I was the one who offered that pseudocode. That was in the context of using the fixed-function pipeline, but the concepts are similar with the programmable pipeline. So, don’t get hung up on glTranslatef(), etc. being deprecated. That’s just a detail; the concepts are more general than that.

[quote]I was told keep the translate to the render code, but for what I want at the start and the end of the level, I don’t know why or how I would do it like that.
[/quote]
There’s nothing about limiting the camera as you describe that would require you to modify the OpenGL matrix stack in your movement code as you’re doing currently. As for why it’s best not to mix update and render code, there are several reasons, but to keep this short I’ll just say there’s seldom if ever a reason to do so, and it’s generally cleaner not to (look up ‘separation of concerns’ for more info).

There’s nothing about limiting the camera as you describe that would require you to modify the OpenGL matrix stack in your movement code as you’re doing currently. As for why it’s best not to mix update and render code, there are several reasons, but to keep this short I’ll just say there’s seldom if ever a reason to do so, and it’s generally cleaner not to (look up ‘separation of concerns’ for more info).
[/quote]
Ya, it was you who helped me out before. But just to clarify why I’m having such a hard time understanding this, I Idon’t get how I can use a button press (left or right) to move the camera if in the right position according to how you said to do it. Right now, I’m doing it in i guess the update code, cause my render code draws everything based off an x and a y. so because of this, the camera follows it based off of when it moves. I could change it to be in the render code, but my issue for doing still stands at how I would actually do that. Before you said

clear the transform (glLoadIdentity)
glTranslatef(-player.x, -player.y)
for each entity (including the player)
  push matrix stack (glPushMatrix)
  glTranslatef(entity.x, entity.y)
  render entity
  pop matrix stack (glPopMatrix)
end for

and even though it was for a different pipeline, the point is… how would this work. I’ve tried asking for this stuff in theory I guess, but this just isn’t clicking.

Let’s just say I have a moveLeft and moveRight method called from the left arrow and right arrow. That moves the player… let’s say 10 pixels in the given direction.

so for moveLeft and moveRight, what exactly am I supposed to do there? Just move the x/y? Cause if I do that, how would I update the camera in the render code when it moves? You said glTranslatef(-player.x, -player.y), but I still don’t get what that does. From what I’ve seen, that moves the bottom left of the “camera” to the right and up based on the players x and y. So since that happens every time, it wouldn’t come close to staying with the player. I guess that just doesn’t make any sense to me, so if that gives you an understanding of how I’m taking this, I don’t know… I just wanna do this right, and also I do understand modularity and encapsulation. So the SoC (which I googled) makes perfect sense. I just struggle to understand the better way to actually implement it.

Imagine in the Graphics class there are two floats. It’s the camera position.

When you render a sprite, you’ll just render it at its normal positions. What you don’t see is that each time you render a sprite, it gets passed to the graphics class and the graphics class will add its coordinates to the sprite coordinates. When you translate it with negative positions, the position is now negative and thus when it adds its position it’ll be subtraction. Untranslating merely reverses it by summing it to 0.

Now when I started using libgdx I could not understand the camera class for the life of me so I just made my own. Unfortunately the downside is everything must be translated in-code and not through a Graphics class.

I had to actually subtract the camera position from the rendering position which seems very counter-intuitive. The reason for this is that say you have an entity that’s at 100, 100 (Y-down). Each unit is 8 pixels, so it’s actually at 800, 800. If 800, 800 is outside of the window, you can’t see it. In order to move 800, 800 into the screen you have to subtract from it. Adding to it merely makes it go further away.

Just to clarify, I’m only using slick-util and lwjgl. I don’t want to use any other libraries. I looked through both “camera’s/rendering” you offered chris, but that still doesn’t really answer my question I guess. It’s the same thing I said to Jesse, you can give me a camera and say here, but I don’t see how I would implement it into like the rendering and work the way I want it to. I’m really trying to figure this out, but I just don’t get it.

In the rendering part of your code, you could have your own Camera class. It would hold the position of the camera.

Every frame, before ANY rendering occurs, change the camera’s position so it looks at the player (basic math). Then, translate the Graphics instance to the camera’s position but negative (translate(-camera.x, -camera.y)). Render the entire world. After that, re-translate the Graphics instance to the camera position but positive. That way it reverts to 0, 0. Now you can render on-screen elements like the HUD, gui, etc.

I hope that helps. :point:

wait, let me just make sure I understand this.

Start of level
bottom left is 0,0
camera is centered on player by default
render everything

every frame

This is where I’m getting confused. I know how to render every object in the level, but the thing that’s confusing me is this.

[quote]change the camera’s position so it looks at the player (basic math). Then, translate the Graphics instance to the camera’s position but negative (translate(-camera.x, -camera.y)).
[/quote]
Again, I’m not using a “Graphics Instance”, unless that’s just the instance of the level. That being said, by default I just spawn my player in the middle of the screen (x = 350 y = 1 width = 100 height = 100), and I use moveLeft and moveRight to use glTranslate which in my eyes moves the world. So I guess, when you say to do those 2 things, I think of them as both glTranslate if that makes sense. Is there something I’m just not getting? Or is there something else I should be using?

Slick’s state classes have a render(GameContainer, Graphics) method. You use the graphics object passed into the render method.

Input should move the player. The camera should move to the player.

What I’m saying is, I’m not using the Graphics or GameContainer.

So from a simple standpoint, where there’s a level, and within that there’s a player then other objects and what not, and all i want is for a “camera” to follow the player.

Input (moving) changes the x and y of the player.

it renders every frame.

Within the render, I should constantly set the camera to the players location, right?

I thought that was as easy as:

GL11.glTranslatef(-x,0,0);

but that makes everything freak out. Do I do this before I render the player? Before I do anything?

The way you’re saying using Graphics and GameContainer doesn’t exactly apply to my situation. Let’s say you don’t have those 2 things to use, how would you go about it then?

Do this every frame and before you render anything:


GL11.glLoadIdentity();
GL11.glTranslatef(-x, -y, 0.0f);

You cannot “just” call GL11.glTranslatef as that will apply a translation to any existing previously defined transformation, so your glTranslatef’s would add up. Therefore, you need to reset the matrix to the identity with glLoadIdentity().

Ok first of all, this would set my actual player to the bottom left at all times. so I just changed it to:

GL11.glTranslatef(-x + 350, 0.0f, 0.0f);

and I also tried it at both before the player renders and at the start of the level render. Both work the same way, so i would just put it in the players render code. So if I made a camera, would it just run that line of code? Or would the better thing to do be to have a camera run that method at the start of the render, and if i made, let’s say a wave, where the camera moved to the new location, at the end set it back to the player? Now THAT makes sense. The translate method starts at 0,0 every time when you run GL11.glLoadIdentity();? Correct? and then you just move in to the place you want it to? That would make perfect sense. Nobody explained what that did xD.

One could quibble with the wording I suppose, but I think you have the right idea.

[quote]Nobody explained what that did xD.
[/quote]
Well, I don’t know about that ;D My pseudocode from earlier says that glLoadIdentity() clears the transform, among other things. But, if it’s starting to click now, that’s the important thing :slight_smile:

You had it, but I guess I didn’t realize you were talking about that line xD. Ya it just clicked though, so thanks for the help everyone.

ok, so now I got the camera all working exactly how I want it to for each given level, but what you say for making the hud and suck doesn’t make sense to me. Since I set the camera to 0,0, then move it to the player’s position, how would I go about getting the correct coords for the hud? I’m assuming I would draw the hud based on the camera’s coords, but I don’t think that’s the right approach. Since I’m not using the Graphics instance, what does translating positive vs. negative do?

Also a random question lol. So I know for lwjgl you make a game loop, and I have that all working (duh), but since I have different levels, should I make a game loop for each level, or do I just render it every frame through the main game loop.

Structure:

GameMain (Does all the OpenGL stuff, creates the main loop)

  • based on a enum, runs (screen).loadscreen
  • that method just renders everything in that screen, and if it’s a game it’s doign everything a level would each frame.

The reason why I ask is because when I’m setting the camera up, when the player dies i reopen the start screen, but if i want to play again i ave to make another instance of the game. Of course I know a sketchy way of doing this with a boolean variable, but I tried an infinite loop in the game just to see what would happen, and it froze and almost crashed my computer. So I didn’t know if there was like a standard to doing multiple levels/screeens in a game and how to render the whole thing.