L. Ballard L. Ballard - 7 months ago 14
Java Question

EDITED: Rows and columns with multidimensional array java

I don't normally ask for help since I like to figure things out for myself, but I have found that this problem I just cannot seem to figure out.

I am making/creating a Java based game for a High School class I am taking and the logic for it is escaping me.

The object of what I am trying to do is make a game that randomly generates a "terrain" square in a 24x24 grid on a JPanel (as I have found that is the most common Object to paint on) all on it's own without outside (user) help.

I am attempting this through a "for" loop that will take "coords[][]" and mark a certain "imaginary" position with a value Ex: floor.

But when I run it all it does is paint the very first 20x20 square at 0,0.

Now I have heard/read that there is no "multi-dimensional" array inside of Java like in for example Small Basic. But I do not understand what an array inside of an array does specifically. Some explanation on this front would be greatly appreciated.

Also any alternative suggestions that would either make it easier/smoother for my program would be most appreciated as I am a novice programmer at the moment.

I have looked for the solution to my problem in these posts but to no avail.

how to create dynamic two dimensional array in java?

How to insert values in two dimensional array programmaticaly?

how to automatically populate a 2d array with numbers

How to fill a two Dimensional ArrayList in java with Integers?

ArrayList.toArray() method in Java

How can I dynamically add items to a Java array?

Automatic adding of elements to an array

Here is the block of code that should be doing this action for me but is currently failing:

class gamePanel extends JPanel


{

public gamePanel()
{
setBounds(115,93,480,480);
setBackground(Color.white);
}

private Random generator = new Random();

int floor = 0; //initializes the variable floor to zero for later use
int dirt = 1;
int stone = 2;
int water = 3;
int lava = 4;
int iron = 5;
int gold = 6;
int emerald = 7;
int diamond = 8;
int bedrock = 9;

int width = 24;
int height = 24;
int x, y; // my x & y variables for coordinates

int[][] coords = new int[width][height]; //my array that I want to store the coordinates for later use in painting


int[] terrain = {floor, dirt, stone, water, lava, iron,
gold, emerald, diamond, bedrock}; //my terrain that will determine the color of the paint

public void mapGen() //what should mark/generate the JPanel
{
for(x = 0; x <= width; x++)
{

for(y = 0; y <= height; y++)
{

int z = generator.nextInt(20);// part of the randomization

if(z <= 11)
{
coords[x][y] = terrain[0]; //marks the coordinates as floor

}

else{};

}
}

coords[0][0] = terrain[0]; // sets coordinate 0,0 to floor //need to have these always be floor
coords[24][24] = terrain[0]; // sets coordinate 24,24 to floor //^^^^^^^^^^
}


@Override
public void paintComponent(Graphics g)//what will paint each 20x20 square on the grid what it is assigned
{
super.paintComponent(g);

if(coords[x][y] == terrain[floor])
{
g.setColor(new Color(46,46,46));
g.fillRect((x*20),(y*20),20,20);
}

else{};

}
}//end gamePanel


Any and all terms/code that are not considered "basic" in Java programming, would be greatly appreciated if they where explained in the response.

Please be as detailed and specific in your response as possible as I am still learning Java and it's workings.




**EDIT:**So this code somewhat works but it is not accomplishing what it should.

The way this program (portion at least) should work is as the loop goes each individual 20x20 square is marked as a specific terrain for those specific coordinates represented by "coords[x][y]"

Then after it has marked the coordinates it should go back and paint each respectively for it's assigned "terrain" within the "paintComponent"

In doing this the program should have created a map for the player to work their way through.

Instead what it does is cover the whole JPanel with only "terrain[dirt]" and none of the others

Here is a working model of the program and it's problem:

import java.awt.*;
import javax.swing.*;
import java.util.*;

public class gamePanel extends JPanel
{

public gamePanel()
{
setBounds(115,93,480,480);
setBackground(Color.white);
}

private Random generator = new Random();

int floor = 0; //initializes the variable floor to zero for later use
int dirt = 1;
int stone = 2;
int water = 3;

int width = 24;
int height = 24;
int x, y; // my x & y variables for coordinates

int[][] coords = new int[width][height]; //my array that I want to store the coordinates for later use in painting


int[] terrain = {floor, dirt, stone, water}; //my terrain that will determine the color of the paint

public void mapGen() //what should mark/generate the JPanel
{
for(x = 0; x <= width; x++)
{

for(y = 0; y <= height; y++)
{

int z = generator.nextInt(20);// part of the randomization

if(z <= 11)
{
coords[x][y] = terrain[0]; //should mark the coordinates as floor

}

if(z == 12)
{
coords[x][y] = terrain[3];//should mark the coordinates as water
}

if(z >= 13 && z <= 17)
{
coords[x][y] = terrain[2];//should mark the coordinates as stone
}

if(z >= 18 && z <= 20)
{
coords[x][y] = terrain[1];//should mark the coordinates as dirt
}

coords[0][0] = terrain[0]; // sets coordinate 0,0 to floor //need to have these always be floor
coords[24][24] = terrain[0]; // sets coordinate 24,24 to floor //^^^^^^^^^^
}
}


}


@Override
public void paintComponent(Graphics g)//what will paint each 20x20 square on the grid what it is assigned
{
super.paintComponent(g);

for(int x = 0; x < width; x++)
{
for(int y = 0; y < height; y++)
{
if(coords[x][y] == terrain[floor])//should paint the floor color at marked coordinates
{
g.setColor(new Color(46,46,46));
g.fillRect((x*20), (y*20), 20, 20);

}

if(coords[x][y] == terrain[dirt]);//should paint the dirt color at marked coordinates
{
g.setColor(new Color(135,102,31));
g.fillRect((x*20), (y*20), 20, 20);
}

if(coords[x][y] == terrain[stone])//should paint the stone color at marked coordinates
{
g.setColor(new Color(196,196,196));
g.fillRect((x*20),(y*20),20,20);
}

if(coords[x][y] == terrain[water])//should paint the water color at marked coordinates
{
g.setColor(new Color(85,199,237));
g.fillRect((x*20),(y*20),20,20);
}
}
}

}//end paintComponent

public static void main(String[] args)
{
gamePanel panel = new gamePanel();
JFrame frame = new JFrame();
frame.setSize(480,480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.setVisible(true);

}//end main

}// end gamePanel

Answer

Two main points:

  • Painting is destructive, each time paintComponent is called, you are expected to repaint the entire component state
  • x and y don't change in your paintComponent, they are the same value they were after mapGen is called

Instead, your paint method could look more like...

@Override
protected void paintComponent(Graphics g)//what will paint each 20x20 square on the grid what it is assigned
{
    super.paintComponent(g);

    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
            if (coords[x][y] == terrain[floor]) {
                g.setColor(new Color(46, 46, 46));
                g.fillRect((x * 20), (y * 20), 20, 20);
            } else ... {
                //...
            }
        }
    }

}

See Painting in AWT and Swing and Performing Custom Painting for more details

Personally, in mapGen, I would create a BufferedImage which was 24*20 wide and 24*20 high, paint all the tiles to it and the in the paintComponent method, paint the image