Hot questions for Using Lightweight Java Game Library in arraylist

Question:

So I have two issues with this code right now. I also do have a question, edited to be at the end.

  • When i generate tiles, it seems that my arraylist i add them to, appears empty when i read it, I do read it after I finish generating it, so it shouldnt appear empty, and they do get added from what I see. Anyone know whats wrong?

  • Also i have a function on my left mouse click to add a quad at the location, which gets added to the drawQuads list and then rendered, it seems that it should be in order? The very same list does add the other quads correctly and renders them just fine.

If it matters, I'm using netbeans. Been grinding away at this for awhile now, I actually made the generator while thinking about how to fix the quad issue and then I hit another one so I figured it would be time for some help.

import java.util.*;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.gluOrtho2D;


public class Main{
    Character tempChar;
Random rand = new Random();
    Timer t = new Timer();
    boolean randomChars = true;
    List<Character> listOfChars = new ArrayList<>();
    Render rend = new Render();
    Input input = new Input();
    Generator gen = new Generator();

    int dice = 0;

        int scrX = 1200;
        int scrY = 800;

        int mX;
        int mY;
        int currentFPS;

        long storedTime = System.nanoTime();
        int delta;
        int fps;
        long lastFPS;
        boolean secondPassed = false;
        int totalTime;

    public static void main(String []args){
        Main main = new Main();
        main.Main();
}
    public void Main(){
        createDisplay();
        createInput();
        //makeChar();
        rend.makeTestBackground();
        //rend.makeTestGrid(33,32,55,36,10,21);
        //rend.makeTestQuads();
        gen.generateGrid(33,32,55,36,10,10,21);

        //Testing why it isnt working with the left click method.
        rend.testMakeQuads(1f,0f,0.5f, 100,400, 20,20); //this works, then 
why dont input click makeQuad??????? Hmm..

        initGL();
        resizeGL();

        getDeltaTime();
        lastFPS = getTime();

        while(!Display.isCloseRequested() && 
!Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
            //getDeltaTime(); why?
            updateFPS();

            if(secondPassed){
                totalTime++;
                //System.out.println(totalTime+"+1");
                secondPassed = false;
            }

            input.update();
            rend.render();
            displayUpdate();

            Display.setTitle("App @"+currentFPS+"fps "
                    +Mouse.getX()+"mX "+Mouse.getY()+"mY "
                    +"Running for "+totalTime+ "seconds");
        } 

        destroyAll();
    }  
    public void getDeltaTime(){
        long currentTime = System.nanoTime();
        delta = (int) ((currentTime-storedTime) / 1000000);
        storedTime = currentTime;
    }
    public long getTime(){
        return (Sys.getTime() * 1000) / Sys.getTimerResolution();
    }
    public void updateFPS() {
        if (getTime() - lastFPS > 1000) {
            currentFPS = fps;
            fps = 0;
            lastFPS += 1000;
            secondPassed = true;
        }
        fps++;
    }
    public void displayUpdate(){
        Display.update();
        Display.sync(60);
    }
    public void initGL(){
        glClearColor(0.0f,0.0f,0.0f,0.0f);
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_LIGHTING);
    }
    public void resizeGL(){ //If im honest i dont even know what im doing.
    glViewport(0,0,scrX,scrY);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0f,scrX,0.0f,scrY);
    glPushMatrix();

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glPushMatrix();
    }
    public void destroyAll(){
        System.out.println("Goodbye cruel world...");
        Display.destroy();
        Keyboard.destroy();
        Mouse.destroy();
        System.exit(0);
    }
    public void createDisplay(){
        try{
            Display.setDisplayMode(new DisplayMode(scrX,scrY));
            Display.setFullscreen(false);
            Display.setTitle("Nothing lasts for ever, not even this 
title.");
            Display.create();
        }catch(LWJGLException e) {
            System.exit(0);
        }
    }
    public void createInput(){
        try {
            Keyboard.create();
            Mouse.create();
            Mouse.setGrabbed(false); //Dat booty doe.
        } catch (LWJGLException ex) {
            System.out.println("Input error. This shouldnt happen.");
        }
    }
    //Should probably make a generator class. Think about it, nerd. 
    //Comment to self; who do you think you are ? Some sort of programming 
expert?
    //Reply to you; dont you dare talk to me that way, try me, i will del 
sys32.
    //Comment to self; Do it then? If you're so ba... *sizzling noises*
public void makeChar(){
    if(randomChars){
                int tStrStat = makeStat();
                int tStrMod = tStrStat-6;
                int tAgiStat = makeStat();
                int tAgiMod = tAgiStat-6;
                int tStaStat = makeStat();
                int tStaMod = tStaStat-6;
                int tChaStat = makeStat();
                int tChaMod = tChaStat-6;
                int tIntStat = makeStat();
                int tIntMod = tIntStat-6;
                int tempArrStat[] = {tStrStat, tAgiStat, tStaStat, tChaStat, 
tIntStat};
                int arrStats[] = findHighestNums(tempArrStat);

                System.out.println(Arrays.toString(arrStats));
                System.out.println("Highest stat is: "+arrStats[0]);

                /*tempChar = new Character("Random Char Class",
                    tStrStat, tStrMod, tStrMod, tStrMod,
        tAgiStat, tAgiMod, tAgiMod, tAgiMod,
        tStaStat, tStaMod, tStaMod, tStaMod,
        tChaStat, tChaMod, tChaMod, tChaMod,
        tIntStat, tIntMod, tIntMod, tIntMod);
        listOfChars.add(tempChar);
                */

    }else{
        System.out.println("Not using Random Values");

                    tempChar = new Character("Low Char Class",
                            0, 0, 0, 0,
            0, 0, 0, 0,
            0, 0, 0, 0,
            0, 0, 0, 0,
            0, 0, 0, 0);
        listOfChars.add(tempChar);

                    tempChar = new Character("Avg Char Class",
                            1, 1, 1, 1,
            1, 1, 1, 1,
            1, 1, 1, 1,
            1, 1, 1, 1,
            1, 1, 1, 1);
        listOfChars.add(tempChar);

                    tempChar = new Character("High Char Class",
                            2, 1, 1, 1,
            1, 1, 1, 1,
            1, 1, 1, 1,
            1, 1, 1, 1,
            1, 1, 1, 1);
        listOfChars.add(tempChar);
    }

            testChar();

}
    public void testChar(){
        for(Character tChar : listOfChars){
            String tempName = tChar.getName();
            System.out.println(tempName + " ");
            System.out.println("Strength: "+tChar.strength);
            System.out.println("Agility: "+tChar.agility);
            System.out.println("Stamina: "+tChar.stamina);
            System.out.println("Charisma: "+tChar.charisma);
            System.out.println("Intellect: "+tChar.intellect);
        } 
    }
    public int rollDSix(){
        int tRandChoose = rand.nextInt(30)+1;
            for(int i=0;
                i < 30; //Yo dawg, i heard yo liek random, so i put a random 
in your random, making it extra random.
                i++)
            {

                int tRand = rand.nextInt(6)+1;

                if(i == tRandChoose){
                    //System.out.println("The randomizer chose "+i);
                    //System.out.println("The Randomest number was " + 
tRand);
                    dice = tRand;
                }
            }
        return dice;
    }
    public int makeStat(){
        int tDOne = rollDSix();
        int tDTwo = rollDSix();
        int tResultOne = tDOne+tDTwo;
        //System.out.println("The Stat Became " + tResultOne);
        //System.out.println(tResultOne-6 + " Was the adjusted Modifier");

        return tResultOne;
    }
    public int[] findHighestNums(int arrTemp[]){
        List tempList = new ArrayList();
        int sortedArray[] = {0,0,0,0,0};
        Arrays.sort(arrTemp);
        //System.out.print(Arrays.toString(arrTemp));
        //System.out.println("");
        for(int i=arrTemp.length-1;
                i >= 0;
                i--){
            //System.out.println(arrTemp[i]);
            tempList.add(arrTemp[i]);
        }

        int tNum=0;
        for (Iterator it = tempList.iterator(); it.hasNext();) {
            int i = (int) it.next();
            sortedArray[tNum] = i;
            tNum++;
            //System.out.println(i);
        }
        //System.out.println(Arrays.toString(sortedArray));
        return sortedArray;
    }
}

heres the render class

import java.util.*;
import java.util.List;
import java.awt.*;
import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.GL11.*;

public class Render {
Tile tile;
Quads quad;
List<Quads> drawQuads = new ArrayList<>();
List<Tile> tileMapOne = new ArrayList<>();

//int qX = 600; //half of screen
//int qY = 400;
//int qSize = 380;

public void render(){
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();

    for (Quads q : drawQuads) {
        glTranslatef(0f,0f,0f);
        glRotatef(0.0f,0.0f,0.0f,0.0f);
        glColor3f(q.colorR,q.colorB,q.colorG);
        glBegin(GL_QUADS);
        GL11.glVertex2f(q.posX-q.sizeX,q.posY-q.sizeY);
        GL11.glVertex2f(q.posX+q.sizeX,q.posY-q.sizeY);
        GL11.glVertex2f(q.posX+q.sizeX,q.posY+q.sizeY);
        GL11.glVertex2f(q.posX-q.sizeX,q.posY+q.sizeY);
        glEnd();
    }
    //readGridMap();
    renderGridMap();
}
public void readGridMap(){
    for(Tile t : tileMapOne){
        System.out.println(t.tileID);
    }
}
public void renderGridMap(){
    //System.out.println(tileMapOne.size()); empty?
    for (Tile t : tileMapOne){
        System.out.println("Do i get here?");
        glTranslatef(0f,0f,0f);
        glRotatef(t.rotation,0.0f,0.0f,0.0f);
        glColor3f(t.colorR,t.colorB, t.colorG);
        glBegin(GL_QUADS);
            /*GL11.glVertex2f(50-20,50-20);
            GL11.glVertex2f(50+20,50-20);
            GL11.glVertex2f(50+20,50+20);
            GL11.glVertex2f(50-20,50+20);*/
            GL11.glVertex2f(t.posX-t.sizeX,t.posY-t.sizeY);
            GL11.glVertex2f(t.posX+t.sizeX,t.posY-t.sizeY);
            GL11.glVertex2f(t.posX+t.sizeX,t.posY+t.sizeY);
            GL11.glVertex2f(t.posX-t.sizeX,t.posY+t.sizeY);
        glEnd();
    }
}
public void makeTestBackground(){
    quad = new Quads(0f,0f,0f, 600f, 400f, 600f, 400f);
    drawQuads.add(quad);
    quad = new Quads(1f,1f,1f, 600f, 400f, 595f, 395f);
    drawQuads.add(quad);
    quad = new Quads(0f,0f,0f, 600f, 400f, 580f, 380f);
    drawQuads.add(quad);
}
public void makeTestQuads(){
    /*quad = new Quads(1f,0f,0f, 720f, 400f, 20f, 100f);
    drawQuads.add(quad);
    quad = new Quads(0f,0f,1f, 880f, 200f, 30f, 60f);
    drawQuads.add(quad);
    quad = new Quads(0f,1f,0f, 1000f, 450f, 50f, 80f);
    drawQuads.add(quad);*/
}
public void makeTestGrid(int gridPosX, int gridPosY, 
                        int gridSizeX, int gridSizeY, 
                        int gridTileSize, int gridTileSpacing){
    // making a grid
    for(int iX = 0;
            iX< gridSizeX;
            iX++){
        for(int iY = 0;
                iY < gridSizeY;
                iY++){
            quad = new Quads(0.1f+iX,0.1f+iY,1f,
                    gridPosX+iX*gridTileSpacing,
                    gridPosY+iY*gridTileSpacing,
                    gridTileSize, gridTileSize);
            drawQuads.add(quad);
        }
    }
}
public void testMakeQuads(float cR, float cG, float cB,
                    float pX, float pY, 
                    float sX, float sY){

    for (int i = 0;
            i < 11;
            i++)
    {
        makeQuads(cR, cG, cB,
            pX+i*100, pY, 
            sX, sY);
    }
}
public void makeQuads(float cR, float cG, float cB,
                    float pX, float pY, 
                    float sX, float sY){
    quad = new Quads(cR,cG,cB, pX, pY, sX, sY);
    drawQuads.add(quad);
}
}

Here's the generator and tile class

public class Generator {
Render rend = new  Render();
Tile tile;

int tempID = 0;
public void Generator (){
}
public void generateGrid(int gridPosX, int gridPosY, 
                        int gridSizeX, int gridSizeY, 
                        int gridTileSizeX, int gridTileSizeY, 
                        int gridTileSpacing){
    // making a grid
    for(int iX = 0;
            iX< gridSizeX;
            iX++){
        for(int iY = 0;
                iY < gridSizeY;
                iY++){
            tempID++;
            tile = new Tile(0.2f,1f,0.3f,
                    gridPosX+iX*gridTileSpacing,
                    gridPosY+iY*gridTileSpacing,
                    gridTileSizeX, gridTileSizeY,
                    0f, tempID);
            rend.tileMapOne.add(tile);
        }
    }
}
}

public class Tile {
float colorR; float colorB; float colorG;
float posX; float posY; 
float sizeX; float sizeY;
float rotation;
int tileID;

    Render rend = new Render();

public Tile(float cR, float cB, float cG,
                    float pX, float pY, 
                    float sX, float sY,
                    float rot, int tID){
    this.colorR = cR;
    this.colorB = cB;
    this.colorG = cG;

    this.posX = pX; this.posY = pY;
    this.sizeX = sX; this.sizeY = sY;
    this.rotation = rot;
    this.tileID = tID;
    System.out.println("Tile made with ID"+tileID);

}
public void setPosX(float tNum){
    this.posX = tNum;
}
public void setPosY(float tNum){
    this.posY = tNum;
}
public void setSizeX(float tNum){
    this.sizeX = tNum;
}
public void setSizeY(float tNum){
    this.sizeY = tNum;
}
public void setColor(float cR, float cB, float cG){
    this.colorR = cR;
    this.colorB = cB;
    this.colorG = cG;
}
public int getID(){
    return tileID;
}
public void setRot(float tNum){
    this.rotation = tNum;
}
public void Tile (){
}
}

here's the input class

 import org.lwjgl.input.Keyboard;
 import org.lwjgl.input.Mouse;

 public class Input {
    Render rend = new Render();

    int mX; int mY;
    boolean leftClicking = false;
    boolean rightClicking = false;
    boolean keyPressed = false;

    float tPX; float tPY;
    float tSX; float tSY;
    float tCR; float tCG; float tCB;

public void Input(){
}
public void update(){
    mX = Mouse.getX();
    mY = Mouse.getY();

    checkForClick();
    checkForKey();
}
public void checkForKey(){
    if(Keyboard.isKeyDown(Keyboard.KEY_SPACE /*&& !keyPressed*/)){
            System.out.println("Baby.. I think we need more space..");
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_RETURN)){
        System.out.println("*Enters the door* Honey! Im hooome!");
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_1)){
        System.out.println("When the moon hits the sky");
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_2)){
        System.out.println("Like a big pizza pie");
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_3)){
        System.out.println("Thats, amoré!");
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_4)){
        System.out.println("Shot to the heart, and you're to blame -");
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_5)){
        System.out.println("Darlin', you give love, a bad name!");
    }
}
public void checkForClick(){
    if(Mouse.isButtonDown(0) && !leftClicking){
        //wrong
        //Hmm.. Click and hold, without activating this? Methinks

        System.out.println("Click!");
        leftClick();
    } leftClicking = Mouse.isButtonDown(0);

    if(Mouse.isButtonDown(1) && !rightClicking){
        //right

        //context menu goes here, hmm.
    } rightClicking = Mouse.isButtonDown(1);
}
public void leftClick(){
    tPX = mX;
    tPY = mY;
    //temp
    tCR = 0.6f; tCG = 0.8f; tCB = 1f;
    tSX = 50f; tSY = 50f;

    rend.makeQuads(tCR, tCG, tCB,
            tPX, tPY, tSX, tSY);

    /*while(!leftClicking){      //HMMMMMMMMM!!!!!!!!!!
        if(Mouse.isButtonDown(0)){
            System.out.println("Keeping on clicking!");
        }else{
            leftClicking = Mouse.isButtonDown(0);
        }
    }*/
}
}

This one shouldnt be relevant, but here's the quad class anyway for good measure

public class Quads {
float colorR; float colorG; float colorB;
float posX; float posY; float sizeX; float sizeY;


public Quads(float cR, float cG, float cB,
                    float pX, float pY, 
                    float sX, float sY){
    this.colorR = cR;
    this.colorG = cG;
    this.colorB = cB;

    this.posX = pX; this.posY = pY;
    this.sizeX = sX; this.sizeY = sY;

    System.out.println("Made a quad! @ X"+posX+" Y"+posY);

}
}

Sorry if my mistakes were too obvious. Getting back into it after a year of no coding.

  • Edit: Almost forgot my question, how do i read mouse input as a single click, while if i hold the thing down, it should continue to do some other function? - Because so far, it only wants to do one or the other, or both at once, yet i'd like to be able to do both for two different things.

  • Edit: Bump, anyone? I could really use some help, cant for the life of me figure this out.

  • Edit: Been grinding away at it, here's what i tried:

    • Checking if it was reading before or during the loop as it was trying to render, it wasnt.
    • Checking if i wasnt reading the list correctly, i was.
    • Checking if the instance wasnt properly initialized, it was, also works with the other instances anyway.
    • Checking if it would work if i moved the list to its own class, still no
    • Checking if my generator was using the correct values and adding correctly, it is.
    • Checking if i was recieving some stack error it wasnt displaying, none.
    • Checking if anything was interrupting or editing the list, nothing does.

Result? Should be working,.no errors, it works perfectly fine for the other object list that im rendering. The other issue? Still not gotten any further either

So would anyone please check over and see if they see something i dont? I cant progress my code until i figure this out, and i just cant, clearly. Thankyou..


Answer:

So! I actually figured out a janky way to fix the issue- moving the generator code into my render class - albeit this was just a workaround, but then i went to check up on this and i see the delightful "alex" having answered the question with what i was going to ask specifically.

The issue was; The instance itself seemed to be initialized twice, while it should have just used the same instance(?) it apparently decided not to. So now i just gotta find a way to use the same instance and transfer it over. Thankyou all for the help! I wish i could contribute this answer to alex, but im not sure how to upvote or set a comment as an answer?

So theres the fix if anyone runs into this same issue! Its probably using several instances.

  • Here is a good way to resolve it for anyone else! Its what i used. Java: Using same instance of a class in various other classes

Edit: A thankyou to alex https://imgur.com/a/ilPPC

Question:

Okay, so currently I have a static world (can't be resized). I would like to know how I can convert this into an ArrayList instead of my current situation:

    for(int xP = 0; xP < WORLD_SIZE_X; xP++) {
        for(int zP = 0; zP < WORLD_SIZE_Z; zP++) {
            for(int yP = 0; yP < WORLD_SIZE_Y; yP++) {
            }  
        }  
    }

My question is, how can I make is so I can use

for(int i = 0; i < blocks.length; i++) {}

but still get the [x][y][z] coordinates?

Currently I'm using this to get the block:

blocks[x][y][z];

How would I get the XYZ with a dynamic ArrayList?

If you need more information, please tell me. I'll be glad to help you understand my situation.


Answer:

ArrayList's equivalent of .length is .size(), and its equivalent of [...] is .get(...).

That said, an ArrayList<ArrayList<ArrayList<...>>> is a pretty unwieldy structure to work with; and although it's theoretically "dynamic", in practice it's difficult to resize, because any resizing involves creating many new elements that you have to initialize.

If your goal is merely to be able to specify the size at runtime (but have the size remain constant after that), then you might find it easier to stick with arrays, but using variables worldSizeX and worldSizeY and worldSizeZ rather than constants.

Question:


Answer:

public class Quad {
static Vector3f Cord1;
static Vector3f Cord2;
static Vector3f Cord3;
static Vector3f Cord4;
public Quad(Vector3f cord1,Vector3f cord2,Vector3f cord3,Vector3f cord4) {
Cord1 = cord1;
Cord2 = cord2;
Cord3 = cord3;
Cord4 = cord4;
}

You have made the CordN variables static, so each field has just 1 value, shared between all instances of the class. As such, each time you create a new instance of the class, the previous values are overwritten.

Remove the static modifier.


Also, note that it's good practice to make member variables final unless you absolutely need them not to be. That does not appear to be the case here, so make them final - and this would have caught your issue automatically, because you wouldn't be able to reassign a static final field in the constructor.

Question:


Answer:

You are removing an item from ArrayList while iterating it and cause it to throw ConcurrentModificationException.

Let's trace your code;

    public synchronized void HandleItems() {
        if (!items.isEmpty()) {
            for (Item i : items) {
                i.Update();
            }
        }
    }

This calls Update() on Item object, which is:

    public void Update() {
        Draw();
        CheckPickUp();
    }
    public void CheckPickUp(){
        if(Canvas.isColliding(Game.p.getX(), Game.p.getY(), Game.p.getX() + 32, Game.p.getY() - 32, x, y));
        System.out.println("Colliding");
        this.ToBag();
    }

    public void ToBag() {
        Inventory i = null;
        i = Game.p.getI();
        Game.world.getItems().remove(this);
        i.getInventory().add(new BagItem(type, i, tex, texturefactor, durability, power));
    }

Pay attention to toBag(). You are removing the Item object from your collection which you are actually in process of iterating.

Basically, you have to use an iterator instead of directly removing from the arraylist.

For further explanation refer to similar questions in this site: Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop