In this post we would be focusing on adding game objects automatically in random positions to make high score/infinite mode similar to the one in Polar.
Grid:
To start off we make a Grid, i.e. we divide the playable screen area into small squares/rectangles of equal size. Then each grid piece would store information like its index/position and the type of object in it.
public class GridUnit{ public int XIndex; public int YIndex; public int ObjectType; int width; int height; public Grid(int width,int height,int xindex,int yindex,int type){ this.width=width; this.height=height; this.XIndex=xindex; this.YIndex=yindex; this.ObjectType=type; } }
For ObjectType either we can create an enum or we can have constant integer values.
public class Grid{ static final int GRID_EMPTY=0; static final int GRID_ENEMY=1; static final int GRID_STAR=2; public GridUnit[][] gridUnits; static final int GRID_WIDTH=8; static final int GRID_HEIGHT=8; int gridLeft; int gridTop; int gridBottom; int gridRight; int gridColumns; int gridRows; public Grid(int playAreaLeft,int playAreaTop,int playAreaRight,int playAreaBottom){ gridLeft=playAreaLeft; gridRight=playAreaRight; gridTop=playAreatop; gridBottom=playAreaBottom; gridColumns=(Math.abs(playAreaRight-playAreaLeft)/GRID_WIDTH) gridRows=(Math.abs(playAreaBottom-playAreaTop)/GRID_HEIGHT); gridUnits=new GridUnit[gridRows][gridColumns]; for(int i=0;i<gridRows;i++){ for(int j=0;j<gridColumns;j++){ gridUnits[i][j]=new GridUnit(GRID_WIDTH,GRID_HEIGHT,i,j,GRID_EMPTY); } } } public void SetObjectAt(int x,int y,int type){ int yindex=(x-gridLeft)/GRID_WIDTH; int xindex=(y-gridTop)/GRID_HEIGHT; gridUnits[xindex][yindex]=type; } public void RemoveObjectAt(int x,int y){ SetObjectAt(x,y,GRID_EMPTY); } public Vector2 GetFreeIndex(){ Random r=new Random(); while(true){ int y=r.NextInt(gridColumns); int x=r.NextInt(gridRows); if(gridUnits[x][y]==GRID_EMPTY) return new Vector2(x*GRID_WIDTH+gridLeft,y*GRID_HEIGHT+gridTop); } } public int GetObjectTypeAtIndex(int gx,int gy){ return gridUnits[gx][gy]; } }
Whenever a collision occurs the result of which has to be reflected in the corresponding grid then RemoveObjectAt(int xcoord,int ycoord) can be called to update the it and whenever a new object has to be created we can get the position from GetFreeIndex and update in grid with SetObjectAt.
Improvements:
The above implementation can be improved in many ways and it depends on the particular scenario.
Sparse vs Dense Filled Grid:
If most of the grid units are filled most of the time then it would be wiser to store empty gridunits in a list and update the list whenever a grid updates.
Grid inside Grid:
We can have bigger gridUnits of much larger size maybe diving the whole screen into 3by3 and then store the count of each object type in each bigger gridUnit. Then while looking for an empty space to generate an object we can just search in the bigger grid Units to see the most empty area and get free grid Position from that part of the screen. The main objective here is faster lookup.
Avoid Moving Objects:
Now we can have an issue that an object’s position updates on every frame so its grid’s position also updates. In that case we can store Old GridPosition and Current GridPosition of the object and whenever its current grid position changes and old grid position gets updated we can update the main Grid by removing the reference of the object in the old grid position.
More than 1 Object:
If we want to have more than one object in a grid then rather than having an int/enum value holding the information of object type in the grid we could have a list of int/enum in gridunit class to hold the information of all the objects in the grid.
Next Tutorial:
In last tutorial we saw that we can post scores in facebook using Scoreloop, but if we want to post scores without using Scoreloop we can use the sdk given by facebook. We will go thourgh that in the next post.
Let us know any of your doubts/suggestions; please put them in the comments section and we would try to answer them.
Thank you for the patience.