World Tile Generator - java

I have a game, and recently decided to switch from TilED (a tile map editor), to doing it manually. I've been searching all over google for some help, but to no avail. Here's my code that renders my background using sky tiles:
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
map[x][y] = AIR;
if(map[x][y] == AIR) {
air.draw(x * tilesize, y * tilesize);
}
}
}
This just creates a new 16 * 16 map and fills it with sky tiles. My question is, how do I specify levels for other tiles to go? So like grass tiles go on layer 10, dirt goes through 9 - 6, and stone fills the rest?

To do it on each level you would just do another for loop:
for(int x = 0; x < 16; x++) {
map[x][10] = GRASS;
}
And that is how you would make it work. Hope it helps!

you can look at the source of "AndEngine", an open source android game engine which reads TMX tiles created from Tiled:
there are lots of classes, but here is a start:
http://code.google.com/p/andengine/source/browse/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTiledMap.java
you can try to create a map with tiled then step though the tmx loader as is parses the map.

Related

Problem with Scan-Line Polygon Filling algorithm in java

(please don't mark this question as not clear, I spent a lot of time posting it ;) )
Okay, I am trying to make a simple 2d java game engine as a learning project, and part of it is rendering a filled polygon as a feature.
I am creating this algorithm my self, and I really can't figure out what I am doing wrong.
My though process is something like so:
Loop through every line, get the number of points in that line, then get the X location of every point in that line,
Then loop through the line again this time checking if the x in the loop is inside one of the lines in the points array, if so, draw it.
Disclaimer: the Polygon class is another type of mesh, and its draw method returns an int array with lines drawn through each vertex.
Disclaimer 2: I've tried other people's solutions but none really helped me and none really explained it properly (which is not the point in a learning project).
The draw methods are called one per frame.
FilledPolygon:
#Override
public int[] draw() {
int[] pixels = new Polygon(verts).draw();
int[] filled = new int[width * height];
for (int y = 0; y < height; y++) {
int count = 0;
for (int x = 0; x < width; x++) {
if (pixels[x + y * width] == 0xffffffff) {
count++;
}
}
int[] points = new int[count];
int current = 0;
for (int x = 0; x < width; x++) {
if (pixels[x + y * width] == 0xffffffff) {
points[current] = x;
current++;
}
}
if (count >= 2) {
int num = count;
if (count % 2 != 0)
num--;
for (int i = 0; i < num; i += 2) {
for (int x = points[i]; x < points[i+1]; x++) {
filled[x + y * width] = 0xffffffff;
}
}
}
}
return filled;
}
The Polygon class simply uses Bresenham's line algorithm and has nothing to do with the problem.
The game class:
#Override
public void load() {
obj = new EngineObject();
obj.addComponent(new MeshRenderer(new FilledPolygon(new int[][] {
{0,0},
{60, 0},
{0, 60},
{80, 50}
})));
((MeshRenderer)(obj.getComponent(MeshRenderer.class))).color = CYAN;
obj.transform.position.Y = 100;
}
The expected result is to get this shape filled up.(it was created using the polygon mesh):
The actual result of using the FilledPolygon mesh:
You code seems to have several problems and I will not focus on that.
Your approach based on drawing the outline then filling the "inside" runs cannot work in the general case because the outlines join at the vertices and intersections, and the alternation outside-edge-inside-edge-outside is broken, in an unrecoverable way (you can't know which segment to fill by just looking at a row).
You'd better use a standard polygon filling algorithm. You will find many descriptions on the Web.
For a simple but somewhat inefficient solution, work as follows:
process all lines between the minimum and maximum ordinates; let Y be the current ordinate;
loop on the edges;
assign every vertex a positive or negative sign if y ≥ Y or y < Y (mind the asymmetry !);
whenever the endpoints of an edge have a different sign, compute the intersection between the edge and the line;
you will get an even number of intersections; sort them horizontally;
draw between every other point.
You can get a more efficient solution by keeping a trace of which edges cross the current line, in a so-called "active list". Check the algorithms known as "scanline fill".
Note that you imply that pixels[] has the same width*height size as filled[]. Based on the mangled output, I would say that they are just not the same.
Otherwise if you just want to fill a scanline (assuming everything is convex), that code is overcomplicated, simply look for the endpoints and loop between them:
public int[] draw() {
int[] pixels = new Polygon(verts).draw();
int[] filled = new int[width * height];
for (int y = 0; y < height; y++) {
int left = -1;
for (int x = 0; x < width; x++) {
if (pixels[x + y * width] == 0xffffffff) {
left = x;
break;
}
}
if (left >= 0) {
int right = left;
for (int x = width - 1; x > left; x--) {
if (pixels[x + y * width] == 0xffffffff) {
right = x;
break;
}
}
for (int x = left; x <= right; x++) {
filled[x + y * width] = 0xffffffff;
}
}
}
return filled;
}
However this kind of approach relies on having the entire polygon in the view, which may not always be the case in real life.

Render gray-scale pixels based on an array of values between 0 and 1

I am trying to render pixels from an array.
I have an array of data that looks like this (except much larger). From this array I would like to somehow render it so that each number in the array corresponds to a pixel with a shade of gray based on the number value. (0.0 would be white, and 1.0 would be black)
I don't know where to start.
For the array you have given; If you know the width and height of the image you want rendered you can do this:
int indx = 0;
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
glColor3d(data[indx],data[indx],data[indx]);
//drawing of it goes here; assuming glVertex2d(x,y);
indx++;
}
}
For this to work it should be known that width*height < data.length. Increment index for each pixel drawn to go to the next number in the array and draw it accordingly.
Modify the x and y so it draws where you want. Say if locX = locY = 10 then depending on the viewport you should have already set up, then the image will start rendering 10px away from (probably) either the top left or bottom left corner. This part is simple maths if you have already started to learn how to draw in OpenGl and/or LWJGL.
int locX, locY;
int indx = 0;
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
glColor3d(data[indx],data[indx],data[indx]);
glVertex2d(locX + x, locY + y);
indx++;
}
}
Hope this helps.

Using a String to Instantiate an object in Greenfoot?

So, as part of my college coursework we are working in teams to develop simplistic games in Greenfoot, partly to develop on teamwork skills, and partly for actual programming.
Our game features a perlin/simplex generated map to render tessellated terrain tiles for our gameplay, however I need a way to reference the tiles individually, in order for a given tile to interact with it's neighbours.
Is there an easy way I can instantiate a worldTile object by passing a string such as their x/y coordinates (eg ter_12_142)? Or is there a simpler method to go about this?
Here's my code for placing tiles in the world;
private void tilePlacement() {
for (int y = 1; y < rows - 1; y++) {
for (int x = 2; x < cols - (cols / 4); x++) {
int w = (getColor(noise[x][y][0]));
int isAForest = (isForest(noise[x][y][1]));
addObject(new worldTile(w, isAForest), x * scl, y * scl);
}
}
}

Draw a triangle from scratch given three points

I'm learning how to draw basic shapes using points in my graphics course, and I can't figure out how to draw a triangle. I thought it would be similar to drawing a rectangle, but a lot of variables (such as slope and different kinds of triangles) need to be taken into account.
Below is my working function of drawing a rectangle
drawRectangle(point 1, point 2){
xStart = min(point 1.x, point 2.x)
yStar = min(point 1.y, point 2.y)
xEnd = max(point 1.x, point 2.x)
yEnd = max(point 1.y, point 2.y)
for(int i = yStart, i<= yEnd, i++){
for(int j = xStart, j<= yEnd, j++){
drawPoint(i, j);
}
}
}
drawRectangle is pretty straight forward, since I just have to loop over the starting point to the ending points of the vertices. However, a triangle has three points, what should I do? I thought about maybe dividing a triangle into two halves, so each half would have a flat "base", but I am not sure if that's a viable approach or not.
Edit: Maybe I was unclear, when I say draw a triangle, I meant a color-filled triangle
You should use the Graphics interface for this. You just need to connect your three points with lines, like this:
void drawTriangle(Point one, Point two, Point three, Graphics g){
g.drawLine(one.x, one.y, two.x, two.y);
g.drawLine(one.x, one.y, three.x, three.y);
g.drawLine(two.x, two.y, three.x, three.y);
}
This will draw a triangle, given three points and an instance of the Graphics object. This is a lot easier than using for loops.
EDIT:
Here is how to do this "from scratch", pixel by pixel using only the methods in your class (I am assuming that drawPoint draws 1 pixel), using the same "connect the dots" idea but with for loops:
drawTriangle(point 1, point 2, point 3) {
for(int x = 1.x, x <= 2.x, x++){
for(int y = 1.y, y <= 2.y, y++){
drawPoint(x, y);
}
}
for(int x = 1.x, x <= 3.x, x++){
for(int y = 1.y, y <= 3.y, y++){
drawPoint(x, y);
}
}
for(int x = 2.x, x <= 3.x, x++){
for(int y = 2.y, y <= 3.y, y++){
drawPoint(x, y);
}
}
}
This connects all 3 points to each other.

2d randomly generated tiled game Libgdx Java

So i am trying to create a game that is top down 2d and using a pixel tiled map style format. They way i would like to do it is have say 4 different tiles, different shades of green and brown for grass.
I would like to generate these 4 tiles randomly around the 1920*1080 pixel area to give a semi realistic effect.
So something like this:
But with randomly generated different tiles in there.
What would be the best way of doing this?
Just use a for loop and place a random tile at each location
for(int i = 0; i < numTilesY; i++)
{
for(int j = 0; j < numTilesX; j++)
{
placeRandomTile(i, j);
}
}
placeRandomTile would just use java's Random class to choose a random number, and depending on the number will place the corresponding tile. For example, if randomNumber == 2, place grass tile.
If you want the tiles to form a realistic looking world similiar to Minecraft, you should use some sort of a noise function like Perlin Noise. It will be random in that every time you generate a new world, the world will be different.
EDIT:
int[][] map= new int[32][32]; //create 32x32 tile map
public void placeRandomTile(int xIndex, int yIndex)
{
Random rand = new Random();
int value = rand.nextInt(5);//get value between 0 and 5
int tile = 0;
if(value == 0)
{
tile = 1; //1 corresponds to GRASS tile
}
if(value == 1)
{
tile = 2; //WATER tile
}
this.map[xIndex][yIndex] = tile;
}
Now that you have your map data stored in a 2D array, you just need to loop through the data and draw each tile accordingly at the proper locations.
In your drawing method, you would just draw each tile from the map like so:
public void draw(float x, float y, Graphics g)
{
for(int i = 0; i < map.length; i++)
{
for(int j = 0; j < map[i].length; j++)
{
int tileType = map[i][j]; //get tile type
if(tileType == Tile.grass.id)
{
Tile.grass.draw(x + (j * Tile.WIDTH), y + (i * Tile.HEIGHT));//draw grass
}
}
}
}
Since you are using libgdx, you will need to look into these classes: TiledMap, TiledMapTileLayer, Screen, Texture, and OrthogonalTiledMapRenderer. You basically create a TiledMap and draw Textures using a TiledMapRenderer.
You can view a sample game I have on Github from a while ago that does what you want. It's here. Look at Dungeon class and screens/GameScreen class

Categories

Resources