Using a String to Instantiate an object in Greenfoot? - java

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);
}
}
}

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.

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.

How to fully make 2d to 3d?

I'm using the method of dividing the x and y coordinates by the z value, then rendering it just like you would a 2D game/thing to create 3D looking thing. The problem is when the z value is less then 0 it flips the quadrants for the coordinate and looks very weird. At the moment there is only movement if someone could help me fix the negative z value thing and show me how to rotate. I'm not using and matrices only vectors that take in x,y and z for the maths if that helps. I'm making this using Java with no extra libraries.
Thanks for the help.
I used the perspective matrix and multiplied it by my vector but it didn't work here is my code there might be something wrong with it. I just turned the vector into a 1 by 3 matrix and then did this.
public Matrix multiply(Matrix matrix)
{
Matrix result = new Matrix(getWidth(),getHeight());
for(int y = 0; y < getHeight()-1; y++)
{
for(int x = 0; x < getWidth()-1; x++)
{
float sum = 0.0f;
for(int e = 0; e < this.getWidth()-1; e++)
{
sum += this.matrix[e + y * getWidth()] * matrix.matrix[x + e * matrix.getWidth()];
}
result.matrix[x + y * getWidth()] = sum;
}
}
return result;
}
Just guessing here, but it sounds like you are trying to do a projection transform: You are modeling 3D objects (things with X, Y, and Z coordinates) and you want to project them onto a 2D window (i.e., the screen).
The meaning of Z in the naive projection transform is the distance between the point and a plane parallel to the screen, that passes through your eyeball. If you have points with -Z, those represent points that are behind your head.
Sounds like you need to translate the Z coordinates so that Z=0 is the plane of the screen, or a plane parallel to and behind the screen. (In other words, Add a constant to all of your Zs, so that none of them is negative.)
http://en.wikipedia.org/wiki/3D_projection

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

World Tile Generator

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.

Categories

Resources