I haven’t been writing for a while mostly because of my studies and my laziness. But I have spent my free time on game development. In my previous post I mentioned changing my development framework into Libgdx (http://libgdx.badlogicgames.com). Oh and I also finished my first Android application and published it in Google Play (https://play.google.com/store/apps/details?id=com.game.simplewordgame). It has been a good choice and my code quality is now better and I get things done more faster without the horrible learning curve with plain OpenGL ES.
In this blog I’m going to write about 2D ray casting. Ray casting is a test to find out which object intersects first with a ray casted from another object. So basically in game world it would mean which objects block another object’s view and which object is seen by another object.
In 2D strategy games ray casting is needed to tell does the game character see another game character or is something blocking its view. Here is my demonstration of ray casting.
Lines representing line casting are the red straight lines fanning out from the game character.
The game characters turns around and now the casted lines intersect with the other game object thus coming visible for the game character and the player.
Here we can see how the wall stops the lines so that we don’t see if there are any game objects behind the walls.
The Code
Basically ray casting is just a loop that checks if the coordinates along the straight line intersect with anything. When ray intersects with an visual obstruction the further point won’t be checked for overlaps so the object behind the obstruction won’t be seen. In my case it might have been easier if I my game world would have been composed of square or hexagon cells. In that case the loop could go through the cells and be sure if there is anything in the cell or not. But I did it through the hard way. No cells, just plain coordinates in the game world. Here is my loop for ray casting.
//Defines how many rays (I’ve named these as lines) private final static int LINE_AMOUNT = 10; // How long the rays are private float[] lineScale = new float[LINE_AMOUNT]; // Are the lines overlapped with with an object private boolean[] linesStopped = new boolean[LINE_AMOUNT]; /** * * @param actors = objects in libgdx framework */ public void countPoint(Array actors){ /** * makes sure that new calculations are made only if the character * turns more than 5 degrees so it will be faster and more practical. */ if (Math.abs(previousAngle - te.charInTurn.getDirection()) > 5) { previousAngle = te.charInTurn.getDirection(); falsifyLineStopped(); //Every line has 180 points to be checked between 0.013f for (int i = 0; i < 180; i++) { for (int j = 0; j < lineScale.length; j++) { // if line hasn’t overlapped with an object it will continue // calculate further points if (!linesStopped[j]) { lineScale[j] = (0.013f * i); linesStopped[j] = adjustLinescales(i, j, actors); } } } } } /** * Reboots the lines as not stopped. */ private void falsifyLineStopped() { for (int i = 0; i < linesStopped.length; i++) { linesStopped[i]=false; } }
As one can see this loop can be very slow for processor to calculate. So it’s more practical to limit the amount of rays and points along the rays where overlapping is checked. Rays should also have a limited length or the loop will continue infinitely. This however can make paper thin visual obstructions invisible and make farther objects less likely to be seen. I also made an if statement so that game doesn’t go through a new ray casting loop unless the game character turns more then 5 degrees from the previous angel of ray casting.