I'm currently working on a MUD project. I'd like to figure out how to use a static background IMAGE as a map. (These maps are like graph paper. Squares represent rooms, and lines connect the squares to show cardinal direction exits.) There will be custom "hand-drawn" maps for each area in the game.
On my GUI, there will be a section of the frame dedicated to showing this static map. When a player MOVES (goes east, west, northwest, etc), a red DOT will be drawn over the current room the player is in.
This is similar to other MUD maps, except in most cases those maps are ASCII/text. I would really like to be able to use an image as the background, and only "draw" the red dot representing player location.
Also, the distance between rooms would not be uniform, so I cannot blindly just move the dot say 50 pixels left for a western movement.
How would I go about programming this? I imagine I will need to pre-define where the dot would be displayed for each room.
Any help in the right direction would be appreciated.
I've made a few 2D games using JPanels and the Graphics draw methods. For the game I'm currently working on, I'd like to be able track the player as they walk, from an aerial view (sort of like the earlier Pokemon games, where as you move the camera tracks you), but without having to hard code it (make it that when I walk, the x and y values of every other feature including the background moves the opposite direction). Is there another way to do this or will I have to hard code it?
Use Graphics.translate(x,y) where x and y positions are the positions of your camera or player. This will translate the origin of the graphics context to the point x, y.
Over the past few weeks I've been attempting to learn the libGDX library. I'm finding it hard, especially for my first endeavor toward game development, to comprehend the system of Camera/viewport relationships. One line of code that I've been told to use, and the API mentions, is:
batch.setProjectionMatrix(camera.combined);
Despite a good 4 hours of research, I'm still lacking a complete understanding of the functionality of this code. It is to my basic understanding that it "tells" the batch where the camera is looking. My lack of comprehension is depressing and angering, and I'd appreciate if anyone could assist me. Another issue with the code snippet is that I'm unsure of when it's necessary to implement (in the render method, create method, etc).
Consider taking a picture with a camera. E.g. using your smartphone camera taking a picture of a bench in the park. When you do that, then you'll see the bench in the park on the screen of your smartphone. This might seem very obvious, but let's look at what this involves.
The location of the bench on the picture is relative to where you were standing when taking the photo. In other words, it is relative to the camera. In a typical game, you don't place object relative to the object. Instead you place them in your game world. Translating between your game world and your camera, is done using a matrix (which is simply a mathematical way to transform coordinates). E.g. when you move the camera to the right, then the bench moves to the left on the photo. This is called the View matrix.
The exact location of the bench on the picture also depends on the distance between bench and the camera. At least, it does in 3D (2D is very similar, so keep reading). When it is further away it is smaller, when it is close to the camera it is bigger. This is called a perspective projection. You could also have an orthographic projection, in which case the size of the object does not change according to the distance to the camera. Either way, the location and size of the bench in the park is translated to the location and size in pixels on the screen. E.g. the bench is two meters wide in the park, while it is 380 pixels on the photo. This is called the projection matrix.
camera.combined represents the combined view and projection matrix. In other words: it describes where things in your game world should be rendered onto the screen.
Calling batch.setProjectionMatrix(cam.combined); instruct the batch to use that combined matrix. You should call that whenever the value changes. This is typically when resize is called and also whenever you move or otherwise alter the camera.
If you are uncertain then you can call that in the start of your render method.
The other answer is excellent, but I figure a different way of describing it might help it to click.
You generally deal with your game in "world space", a coordinate system that is analogous to the real world. In linear algebra, you can convert points in space from one coordinate system to another by multiplying the point's coordinates by a matrix that represents the relation between two coordinate systems.
The view matrix is multiplied by a point to convert it from world space to camera space (the camera's point of view). The projection matrix is used to convert a point from camera space to screen space (the flat 2D rectangle of your device's screen). When you call update() on a camera in Libgdx, it applies your latest changes to position, orientation, viewport size, field of view, etc. to its view and projection matrices so they can be used in shaders.
You rarely need to deal with stuff in camera space in 2D, so SpriteBatch doesn't need separate view and projection matrices. They can be combined into a single matrix that converts straight from world space to screen space, which is already done automatically in the Camera, hence the camera.combined matrix.
SpriteBatch has a default built-in shader that multiplies this projection matrix by all the vertices of your sprites so they will be properly mapped to the flat screen.
You should call setProjectionMatrix whenever you have moved the camera or resized the screen.
There is a third type of matrix called a model matrix that is used for 3D stuff. A model matrix describes the model's orientation, scale, and position in world space. So it is multiplied by coordinates in the model to move them from local space to world space.
Take for example a basic sidescrolling game. As the player moves to the side, the camera pans to follow them. This means that where objects are in the world doesn't necessarily correspond to where they are on the screen, since the screen and the world move relative to each other.
Here's an example: say your screen is 100px*100px square (for some reason). You place an object at position (50, 0), so it's now in the middle and at the bottom of the screen. Now say you move your player over to the right, and the whole screen pans to follow the player. This means that the object you placed earlier should have moved left on the screen. So it's still at (50, 0) in the world, since it didn't actually move relative to the rest of the scenery, but it should now be drawn at, say, (10, 0) on the screen, since which part of the world the screen is looking at has changed. This is the difference between "worldspace" (where an object is in the world) and "screenspace" (where the object is drawn on the actual display).
When you try to draw with a SpriteBatch, it is by default going to assume worldspace coordinates are the same as screenspace coordinates: when you say "draw at (50, 0)", it's going to draw the object at (50, 0) on the screen. Even if the camera moves, it's always going to draw at (50, 0) on the screen, so as the camera pans, the object will follow and stay stuck to the same place on the screen.
Since you usually don't want that, you give the SpriteBatch a projection matrix, which is a transformation matrix that tells how to convert screenspace coordinates to worldspace coordinates, and vice versa. This way, when you tell the batch "draw at (50, 0)", it can look at the matrix it got from the camera and see that, since the camera has moved, (50, 0) in the world actually means (10, 0) on the screen, and it will draw your sprite in the right place.
I know do a horizontal and vertical scroller game (like Mario), in this game type, the character is always in the same distance from user. The character only moves to left and right in horizontal scroller and to down and up in vertical scroller.
But there are games in 2D that the character can move freely in the scene, like for example graphic adventures.
So how can I do that ground in order to move the character freely on the ground with depth sense?
An example can see in this video: http://youtu.be/DbZZVbF8fZY?t=4m17s
Thanks you.
This is how I would do that:
First imagine that you are looking at your scene from the top to the ground. Set your coordinate system like that. So all object on your scene will have X and Y coordinates. All your object movements and checking (when character bumps into a wall or something), calculations do in that 2D world.
Now, to draw your world, if you want simpler thing, without some isometric perspective 3D look you just to draw your background image first, and then order all your objects far to near and draw them that way. Devide your Y coords to squeeze movement area a bit. Add some constant to Y to move that area down. If you characters can jump or fly (move trough Y axe) just move Y coord to for some amount.
But if you want it to be more 3D you'll have to make some kind of perspective transformation - multiply your X coordinate with Y and some constant (start with value 1 for constant and tune it up until optimal value). You can do similar thing with Y coord too, but don't think it's needed for adventure games like this.
This is probably hard to understand without the image, but it's actually very simple transformation.
I'm making a game in libGDX and I decided to use box2dlights to render the lights. I did not used cameras so much up to this point, because I already had most of the code done in pure LWJGL. There are two main operations that I need to do with the coordinates of everything.
The first is to translate the screen to the position of the map (the map is bigger than the screen, and the position of the player defines what portion of the map is visible). So for example, if the player is at (50, 30), I translate everything by (-50, -30), so that the player is in the middle.
The second thing is to multiply everything by a constant, that is the conversion from box2d meters to pixels on screen.
However, since I do not have access to box2dlights rendering, I need to pass these two information to the ray handler, and the only way to do that is via Camera. So I created an Orthographic Camera and translate it in deltaS every tick before drawing, instead of manually subtracting deltaS from every coordinate. That part works perfectly. On the other hand, the zoom thingy does not seem to work, because it zooms in and out based in the middle of the screen. For example, if I set zoom = 2, the screen is reduced twice, but it is centered on the screen. The coordinate (0,0) is not (0,0), as I would expect, but instead is screen.width/4.
Is there any way to set the camera so that it multiplies every coordinate by a number, you would assume zoom function should do OR is there any way to do it directly on box2dlights?
I don't know if my problem is very clear or common, but I can't find anything anywhere.
I finally figured it out! The problem was that I needed to set the zoom before I used
camera.setToOrtho(true, SCREEN_WIDTH, SCREEN_HEIGHT);
Because that method uses the current zoom to set its properties. Hope this helps!