Problem with delaying a method

Hi guys,

Iv’e been struggling for a while trying to figure out how to create a 1 second delay inside a method I wrote. My objective is that I have an array of geometries and I am trying to get them to appear one after another with a 1 second delay. Iv’e tried using thread.sleep(1000) that doesnt work it just delays the entire program and makes all of the geometries appear after 1 second. I also tried implementing Timer but still struggling with that. Anyone can help me out with this?

Thanks :smile:
Arsen.

Yeah a sleep will make the application with update sleep so essentially the entire program.

You need a class to contain these geometries, be it the main or some other, in which you have something like

int numberToRelease = 0;
int timeBetweenReleases = 60;
float currentTime;

Then you have an update(float tfp) method in which…

currentTime+= tfp;
if(currentTime >= timeBetweenReleases)
{
        currentTime = 0;
        someNode.attachChild(geometry[numberToRelease]);
        numberToRelease++;
        if(numberToRelease==geometry.length) //if this is true stop adding them since its done
}

Something like that? That’s what I would do. I use something similar to release players into an arena 1 at a time.
This method runs every frame, and if enough time has passed it’ll show another geometry. What it doesn’t take into account is if you’re program runs at < 1fps. You could improve it with something like

currentTime = currentTime - timeBetweenReleases;

Which would make it more accurate if you wanted.

3 Likes

Or make a new thread and then you can use Thread.sleep() without freezing your whole game.

And struggle with concurrency problems and the need to enqueue the changes to the scene graph. That will end up more complicated and problematic. I suggest to solve it exactly like JESTERRRRRR proposes.

6 Likes

i like this guy

1 Like

Is there no way to do it within the method?

public boolean dropBomb(Geometry [][][] cube,LinkedList<MyPoint> aiPlacedSubs, Material mat, Material grey){
    MyPoint [] aiSubs = new MyPoint[aiPlacedSubs.size()];
    aiSubs = aiPlacedSubs.toArray(aiSubs);
    MyPoint [] hitPointsArray = new MyPoint[hitPoints.size()];
    hitPointsArray = hitPoints.toArray(hitPointsArray);  
    int positionX = currentPoint.x;
    int positionY = currentPoint.y;
    for(int i = cube.length-1; i>=0; i--){
        for(int j = 0; j< aiSubs.length;j++){
            if(aiSubs[j].equals(new MyPoint(positionX,i,positionY))){
                cube[positionX][i][positionY].setMaterial(mat);
                aiPlacedSubs.remove(aiSubs[j]);
                hitPoints.add(new MyPoint(positionX,i,positionY));
                return true;
            }
            else{
                cube[positionX][i][positionY].setMaterial(grey);
            }
            for(int k = 0; k< hitPointsArray.length; k++){
                        if(hitPointsArray[k].equals(new MyPoint(positionX,i,positionY))){
                            cube[positionX][i][positionY].setMaterial(mat);
                        }
            }
        }
    }
    return false;
}

I need to introduce something or anything within the first for loop so that when the bomb is dropped it reveals the geometries one by one each second until it comes across the if statement that makes the loop finish. I’m sure there was a simply way to introduce a 1 second delay using “long” but I did this a while ago and cant remember. All I need is a delay in the method and making another class entirely for this one method will mess things up a bit. Any ideas?

You need to fundamentally shift your thinking about how games work. All action is executed a tiny slice at a time.

So something that happens in 1 second is really happening FPS slices from now. Move all of your action (even the delays) forward by a little slice every time.

That’s game development.

Edit:
And so the way to do that in a method like that is to not actually create your object but to create little commands or factories or something that will run after a certain amount of time has expired. Then set them free.

What could I use as the delay? The Timer class in the java library? Or is there something else you would recommend?

float time;

That’s your delay.

Again… you need to start thinking about pushing action forward a slice at a time. So a delay looks like this:

public void update( float tpf ) {
    time += tpf;
    if( time > delay ) {
        // Do the thing
    }
}

…in some object. Or you can count down to 0. It’s up to you.

I cant even do something simple like change the material of the cube every second or any time at all…
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;

/**

  • test

  • @author normenhansen
    */
    public class Main extends SimpleApplication {

    int var = 0;
    int timeBetweenReleases = 1000;
    float currentTime;
    Geometry geom;
    Material mat;
    Material mat2;
    public static void main(String[] args) {
    Main app = new Main();
    app.start();
    }

    @Override
    public void simpleInitApp() {
    Box b = new Box(1, 1, 1);
    geom = new Geometry(“Box”, b);

     mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat.setColor("Color", ColorRGBA.Blue);
     geom.setMaterial(mat);
     
     mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat2.setColor("Color", ColorRGBA.Red);
    
     rootNode.attachChild(geom);
    

    }

    @Override
    public void simpleUpdate(float tpf) {
    currentTime+= tpf;
    if(currentTime >= timeBetweenReleases)
    {
    if(var == 0){
    geom.setMaterial(mat);
    var++;
    }
    else{
    geom.setMaterial(mat2);
    var–;
    }
    }
    }

    @Override
    public void simpleRender(RenderManager rm) {
    //TODO: add render code
    }
    }
    Iv’e been at this all day its killing me…
    Please help.
    It doesnt change the cubes color every second instead it just changes it infinitely after the entered time.

You never reset current time so once it is greater than timeBetweenReleases then your code block will run every frame rapidly switching your materials back and forth.

1 Like

THANK YOU! God now I can go to sleep in peace. How the hell did I not see that…