Make Box Fall From Top

I’m a computer science student (3rd semester) and a professor gave us a work to do (the points will be added to the final grade) and he specified that he wants the shooting game to be done on JMonkey, the thing is that I never worked on it before and I barely made a game using Eclipse before…I’ve made the ship, the bullet, the enemy (very simple stuff)…the ship moves, shoots the enemy and it disappears, BUT my enemy is static and I need it to fall down towards the ship, but I need a lot of them falling, and since I know only the basics of JMonkey (learned through the week on tutorials) I need someone who might be able to add me, message me or whatever to hel me out. This thing is due tuesday and I’m really desperate. Here goes a video of what the professor wants (he did it, but while teaching he never really introduced us to anything beyond creating boxes and making it move). I can send my code to whoever wants to take a look at it (it’s a mess, I just really want to get it over with it)

[video]http://youtu.be/W9adaNO-R7Y[/video]

Well for this you dont really need more than a box and moving the box.

In short, do you have any concrete problem, wher we can give hints, or do you seek someone who will do your work?
Btw something like this in way better is in the forms/tuorials here somewhere.

The game is nearly ready, I just used the physics stuff I found on tutorials and a book named “JMonkey Engine For Beginners” or something like that, but NOTHING WORKED to make the enemy fall from the top to the bottom, it just stands still in the middle of the top of the screen, the things I tried either had no effect at all OR it didn’t run the program (errors and more errors) I’m not home right now, I left to work, but I will post my messed up code here later and maybe someone can give me a hint of what to do or explain in a more clear way what works how and what works better IN MY CODE AND FOR IT’S STRUCTURE. The only thing I need is to make the enemy to fall. He didn’t ask for player to die/game over or anything like that, but I will do it after I understand for GOOD the physics part. I’m not really into games, my objective is to work with assistive technology (technology for people with disabilities) after I graduate, so I just need to understand this and get thru the semester.

Well for a 2d game i would not use physics at all,

just a update method taht moves the enemy by x pixels every y ms.
Collisions with bullets can be done with simple box checks, eg for each projectile test if X > shipstart and < ship end (and the same for y), this is way simpler and better suited for this.

The bullet collision is done…as I said, I will post the code onde I’m home.

Here’s my code…and no, I didn’t separate it in classes, there’s only the Main class and that’s all, as I said, want to get it over with, still have 40 exercises of statistics to do, 2 papers for digital circuits, 12 exercises of Calculus II a Flowchart and a program to search words in .txt file…

[java]package mygame;

import com.jme3.collision.CollisionResults;
import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.Trigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsTickListener;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.TimerTask;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Main extends SimpleApplication {

private static final Trigger TRIGGER_MOVE_LEFT = new KeyTrigger(KeyInput.KEY_LEFT);

private static final Trigger TRIGGER_MOVE_RIGHT = new KeyTrigger(KeyInput.KEY_RIGHT);

private static final Trigger TRIGGER_FIRE = new KeyTrigger(KeyInput.KEY_SPACE);

private static final String MAPPING_MOVE_LEFT = "MOVE_LEFT";

private static final String MAPPING_MOVE_RIGHT = "MOVE_RIGHT";

private static final String MAPPING_FIRE = "FIRE";
    
private Geometry ship;

private Geometry target;

private BitmapText scoreText;

private List&lt;Geometry&gt; bullets = new LinkedList&lt;Geometry&gt;();

private AnalogListener moveLeftListener = new LeftListener();

private AnalogListener moveRightListener = new RightListener();

private ActionListener fireListener = new FireListener();

private static Lock lock = new ReentrantLock();

private RigidBodyControl target_phy = new RigidBodyControl();

private BulletAppState bulletAppState;

private Vector3f moveDirection = new Vector3f();

public static void main(String[] args) {
    Main app = new Main();
    app.start();
}
 
@Override
public void simpleInitApp() {
    
    viewPort.setBackgroundColor(ColorRGBA.DarkGray);
    
    bulletAppState = new BulletAppState();
    stateManager.attach(bulletAppState);


    setDisplayStatView(false); 
    setDisplayFps(false); 
    
    inputManager.addMapping(MAPPING_MOVE_LEFT, TRIGGER_MOVE_LEFT);
    inputManager.addListener(moveLeftListener, new String[] {MAPPING_MOVE_LEFT});
    
    inputManager.addMapping(MAPPING_MOVE_RIGHT, TRIGGER_MOVE_RIGHT);
    inputManager.addListener(moveRightListener, new String[] {MAPPING_MOVE_RIGHT});
    
    inputManager.addMapping(MAPPING_FIRE, TRIGGER_FIRE);
    inputManager.addListener(fireListener, MAPPING_FIRE);
    
    flyCam.setEnabled(false);
    
    createShip();
    createTarget();
    createScore();
    
    //Timer auto = new Timer();
    //auto.schedule(new AutoFire(), 1000, 1000);   
}

private void createShip() {
    Box b = new Box(0.9f, 1, 0.5f);
    ship = new Geometry("Ship", b);

    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    mat.setTexture("ColorMap",assetManager.loadTexture("Textures/tardis.png"));
    mat.setColor("Color", ColorRGBA.Blue);
    ship.setMaterial(mat);
    ship.setLocalTranslation(0, -3, 0);
    rootNode.attachChild(ship);
}

private void createTarget() {
    Box b = new Box(0.7f, 0.7f, 0.2f);
    target = new Geometry("Target", b);

    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    mat.setTexture("ColorMap",assetManager.loadTexture("Textures/dalek.png"));
    mat.setColor("Color", ColorRGBA.Red);
    target.setMaterial(mat);
    target.setLocalTranslation(0, 3, 0);
    rootNode.attachChild(target);
}

private void createBullet() {
    Box b = new Box(0.1f, 0.3f, 0.1f);
    Geometry bullet = new Geometry("Bullet", b);

    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    mat.setTexture("ColorMap",assetManager.loadTexture("Textures/sonicscrewdriver.png"));
    mat.setColor("Color", ColorRGBA.Cyan);
    bullet.setMaterial(mat);
    bullet.setLocalTranslation(
            ship.getLocalTranslation().x, 
            ship.getLocalTranslation().y, 
            ship.getLocalTranslation().z);
    rootNode.attachChild(bullet);
    bullets.add(bullet);
}

private void createScore() {
    scoreText = new BitmapText(guiFont, false);          
    scoreText.setSize(guiFont.getCharSet().getRenderedSize());
    scoreText.setColor(ColorRGBA.White);
    scoreText.setText("Score: " + 0);
    scoreText.setLocalTranslation(8, 20, 0);
    guiNode.attachChild(scoreText);
}

@Override
public void simpleUpdate(float tpf) {
    try {
        lock.lock();
        for (Geometry bullet : bullets) {
            bullet.move(0, 0.005f, 0);
        }
    } finally {
        lock.unlock();
    }
    
    CollisionResults resultado = new CollisionResults();
    for (Geometry bullet : bullets) {
        bullet.collideWith(target.getWorldBound(), resultado);
        
        if (resultado.size() &gt; 0) {
            // collision
            rootNode.detachChild(target);
        }
        Random r = new Random(System.currentTimeMillis());
        r.nextFloat();
    }
    
    // remove  bullets that pass thru the top of sreen.
    // rootNode.detachChild(null);
    
    List&lt;Geometry&gt; remover = new LinkedList&lt;Geometry&gt;();
    for (Geometry bullet : bullets) {
        if (bullet.getLocalTranslation().y &gt; 4) {
            remover.add(bullet);
            rootNode.detachChild(bullet);
        }
    }
    bullets.removeAll(remover);
    
}

@Override
public void simpleRender(RenderManager rm) {
}

public class LeftListener implements AnalogListener {

    public void onAnalog(String name, float value, float tpf) {
        ship.move(-0.1f, 0, 0);
    }
    
}

public class RightListener implements AnalogListener {

    public void onAnalog(String name, float value, float tpf) {
        ship.move(0.1f, 0, 0);
    }
    
}

public class FireListener implements ActionListener {

    public void onAction(String name, boolean isPressed, float tpf) {
        if (isPressed) {
            createBullet();
        }
    }
    
}

public class AutoFire extends TimerTask {

    @Override
    public void run() {
       try {
            lock.lock();
            createBullet();
       } finally {
            lock.unlock();
       }    
    }
    
}

}
[/java]

Well if it works good enough, that fine,

One thing thats really unclean is the lock, instead use application.enqueue and spawn the bullets there.

Also i wonder for what you create the random in 166

Yeah, the lock isn’t safe anyway since only the one loop iteration is gated. In general, as a word of advice, if you find yourself using locks like this in update() then there is probably a better way.

…also the TimerTask was probably unnecessary anyway. Firing things off periodically is pretty easy when you’re already called once a frame with the time.

Guys, thanks for the help, I’ve used lock and TimerTask, it was a hell of work because it would be easier if I didn’t use, but when I didn’t use the game froze for a couple seconds (for TimerTask) or the bullets got stuck (lock), I don’t kjnow why because I didn’t find any similar problem here. I’ve organized my game a little bit and it’s working perfectly. The tardis moves around and shoots, the daleks are falling from the top on random positions and when the bullets collide with the daleks they “die” and the score is updated, now I have a question (the last one, I promise)…
To remove the bullets and daleks I used a LinkedList. The professor didn’t ask for it, but I would like to remove the tardis when the dalek touchs it…since there was more there’s only ONE ship, what’s the best way of doing it? Here’s the code now

[java] package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.collision.CollisionResults;
import com.jme3.font.BitmapText;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.Trigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**

  • test

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

    private Geometry tardis;
    private Geometry bullet;
    private Geometry dalek;
    private static final Trigger TRIGGER_LEFT = new KeyTrigger(KeyInput.KEY_LEFT);
    private static final Trigger TRIGGER_RIGHT = new KeyTrigger(KeyInput.KEY_RIGHT);
    private static final Trigger TRIGGER_FIRE = new KeyTrigger(KeyInput.KEY_SPACE);
    private static final String MAPPING_LEFT = “LEFT”;
    private static final String MAPPING_RIGHT = “RIGHT”;
    private static final String MAPPING_FIRE = “FIRE”;
    private AnalogListener leftListener = new LeftListener();
    private AnalogListener rightListener = new RightListener();
    private ActionListener fireListener = new FireListener();
    private static Lock lock = new ReentrantLock();
    private List<Geometry> bullets = new LinkedList<Geometry>();
    private List<Geometry> daleks = new LinkedList<Geometry>();
    private BitmapText scoreText;
    private int points = 0;

    public static void main(String[] args) {
    Main app = new Main();
    app.start();
    }

    @Override
    public void simpleInitApp() {

      viewPort.setBackgroundColor(ColorRGBA.DarkGray);
    
     Timer enemySpawn = new Timer();
     enemySpawn.schedule(new AutoTarget(), 500, 750);
     
     setDisplayStatView(false);
     setDisplayFps(false);
     
     flyCam.setEnabled(false);
     
     inputManager.addMapping(MAPPING_LEFT, TRIGGER_LEFT);
     inputManager.addListener(leftListener, new String[] {MAPPING_LEFT});
     
     inputManager.addMapping(MAPPING_RIGHT, TRIGGER_RIGHT);
     inputManager.addListener(rightListener, new String[] {MAPPING_RIGHT});
     
     inputManager.addMapping(MAPPING_FIRE, TRIGGER_FIRE);
     inputManager.addListener(fireListener, new String[] {MAPPING_FIRE});
     
     /*cam.setLocation(new Vector3f(0, 0, -50f));
     cam.setRotation(new Quaternion().fromAngles(0, 270.2f, 0));*/
     
     createTardis();
     
     createScore();
    

    }

    public class LeftListener implements AnalogListener {

     public void onAnalog(String name, float value, float tpf) {
         if(tardis.getLocalTranslation().x&gt;-6){
             tardis.move(-0.005f, 0, 0);
         }
     }
    

    }

    public class RightListener implements AnalogListener {

     public void onAnalog(String name, float value, float tpf) {
         if(tardis.getLocalTranslation().x&lt;6){
             tardis.move(0.005f, 0, 0);
         }
     }
    

    }

    public class FireListener implements ActionListener {

     public void onAction(String name, boolean isPressed, float tpf) {
         if(isPressed) {
             createBullet();
         }
     }
    

    }

    public void createTardis(){

     Box b = new Box(0.7f, 0.7f, 0.7f);
     tardis = new Geometry("Tardis", b);
    
     Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat.setTexture("ColorMap",assetManager.loadTexture("Textures/tardis.png"));
     mat.setColor("Color", ColorRGBA.Blue);
     
     
     tardis.setMaterial(mat);
     tardis.setLocalTranslation(0f,-3f,0f);
     rootNode.attachChild(tardis);
    

    }

    public void createBullet(){

     Box b = new Box(0.1f, 0.3f, 0.1f);
     Geometry bullet = new Geometry("Bullet", b);
    
     Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat.setTexture("ColorMap",assetManager.loadTexture("Textures/sonicscrewdriver.png"));
     mat.setColor("Color", ColorRGBA.Cyan);
     bullet.setMaterial(mat);
     bullet.setLocalTranslation(tardis.getLocalTranslation().x,
                              tardis.getLocalTranslation().y,
                              tardis.getLocalTranslation().z);
     rootNode.attachChild(bullet);
     bullets.add(bullet);
    

    }

    public void createDalek(){
    Box b = new Box(0.5f, 0.5f, 0.5f);
    dalek = new Geometry("Dalek ", b);

     Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat.setTexture("ColorMap",assetManager.loadTexture("Textures/dalek.png"));
     mat.setColor("Color", ColorRGBA.Red);
     dalek.setMaterial(mat);
     dalek.setLocalTranslation((float) Math.random() * 12 - 5f, 3.5f, 0f);
     rootNode.attachChild(dalek);
     daleks.add(dalek);
    

    }

    public class AutoTarget extends TimerTask {

     @Override
     public void run() {
         try {
             lock.lock();
             createDalek();
         }
         finally {
             lock.unlock();
         }
     }
    

    }

    private void createScore () {
    scoreText = new BitmapText(guiFont, false);
    scoreText.setSize(guiFont.getCharSet().getRenderedSize());
    scoreText.setColor(ColorRGBA.White);
    scoreText.setText("Score: " + 0);
    scoreText.setLocalTranslation(8, 20, 0);
    guiNode.attachChild(scoreText);
    }

    private void updateScore(int pts) {
    scoreText.setText("Score: " + pts);
    }

    @Override
    public void simpleUpdate(float tpf) {

     try {
         lock.lock();
         for(Geometry bullet : bullets) {
             if(bullet != null) {
                 bullet.move(0, 0.01f, 0);
             }
         }
     }
     finally {
         lock.unlock();
     }
     
     for(Geometry dalk : daleks) {
         dalk.move(0, -0.001f, 0);
     }
     
     List&lt;Geometry&gt; removerDaleks = new LinkedList&lt;Geometry&gt;();
     List&lt;Geometry&gt; removerBullets = new LinkedList&lt;Geometry&gt;();
         for (Geometry dalek : daleks) {
         for (Geometry bullet : bullets) {
             CollisionResults resultado = new CollisionResults();
             bullet.collideWith(dalek.getWorldBound(), resultado);
             if(resultado.size() &gt; 0) {
                 //Colisão
                 points++;
                 removerDaleks.add(dalek);
                 removerBullets.add(bullet);
                 rootNode.detachChild(dalek);
                 rootNode.detachChild(bullet);
             }
             if(dalek.getLocalTranslation().y&lt;-3f){
                 removerDaleks.add(dalek);
                 rootNode.detachChild(dalek);
             }
             if(bullet.getLocalTranslation().y&gt;4.5f){
                 removerBullets.add(bullet);
                 rootNode.detachChild(bullet);
             }
                        }
     }
     
     daleks.removeAll(removerDaleks);
     bullets.removeAll(removerBullets);
     
     updateScore(points);
    

    }

    @Override
    public void simpleRender(RenderManager rm) {
    //TODO: add render code
    }
    }
    [/java]

Well, your locking is all over the place now and not even protecting the things it’s supposed to be protecting. When possible, it’s better to avoid multithreading if you don’t understand.

And in this case the timer task is completely unnecessary. You could have simply added up some time in simpleUpdate().
[java]
time += tpf;
if( time > makeAnotherDalek ) {
time = 0;
createDalek();
}
[/java]

I do understand, but the thing is, when not using the lock, I had a stack on bullets and daleks on the top of each other, I have no idea why…I’m just using the engine because the professor required…and true, for the dalek I could have used the makeAnotherDalek as you said, but when not using TimerTask, the game freezes for about 10 seconds, unfreezes and I’m able to play for a minute or so and then it freezes again…I tried different things and figured only when returning the TimeTask I would get it working properly. I thought it was my PC before, but then I used my MAC and tested and it was the same thing.

@diefani said: I do understand, but the thing is, when not using the lock, I had a stack on bullets and daleks on the top of each other, I have no idea why...I'm just using the engine because the professor required...and true, for the dalek I could have used the makeAnotherDalek as you said, but when not using TimerTask, the game freezes for about 10 seconds, unfreezes and I'm able to play for a minute or so and then it freezes again...I tried different things and figured only when returning the TimeTask I would get it working properly. I thought it was my PC before, but then I used my MAC and tested and it was the same thing.

Well, I’m glad what you have is working for you but the lock is protecting one list in one case and a different in another. So it’s kind of held together with tape at the moment because nothing is thread safe.

…probably would have been better to figure out what was wrong with the right way. There had to have been something because this is just about the most basic code ever and shouldn’t be freezing for 10 seconds.

When you have time to look at it again you should do it the right way as I suggested and then post that code… we could then show what else is wrong.