Maybe somone can help me figure out performance issue with provided code?

Hi guys, this is a big favour to ask, but as my first time developing some sort of game I have made this code:



Main:



[java]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.Spatial;

import com.jme3.scene.shape.Box;

import org.lwjgl.opengl.Display;





public class Main extends SimpleApplication {



Player player;

Enemy enemies[];



//gamestate (1 = menu; 2 = game; 3 = exiting)

int gameState;



public static void main(String[] args) {

Main app = new Main();

app.start();

}



//initialize the game

public void simpleInitApp() {



//setting up the display


Display.setTitle("Zach's Invaders");
flyCam.setEnabled(false);
statsView.setCullHint(Spatial.CullHint.Always);
//fpsText.setCullHint(Spatial.CullHint.Always);
cam.setLocation(new Vector3f(0f,0f,50f));
//

gameState = 2;

player = new Player(this);

}

//update the game
public void simpleUpdate(float tpf) {
//if the game is in the menu
if(gameState == 1){

}

//or if the game is running
else if(gameState == 2){

player.update(tpf);

}

//or if the game is exiting
else if (gameState == 3){

}
}

//DOES NOTHING ATM
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}
[/java]

Player:

[java]package mygame;

import com.jme3.input.KeyInput;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import java.util.*;



public class Player{
//player fields
private Geometry pGeom;
private Box pShip;
public int score;
private Material mat;
private Main gamePointer;

//a dynamic array to hold bullets
public List bullets = new ArrayList();

//constants
private float SPEED = 20;

public Player(Main game){
gamePointer = game;
pShip = new Box(Vector3f.ZERO, 1, 1, 1);
pGeom = new Geometry("Box", pShip);
mat = new Material(gamePointer.getAssetManager(), "Common/MatDefs/Misc/SolidColor.j3md");
mat.setColor("m_Color", ColorRGBA.Blue);
pGeom.setMaterial(mat);
gamePointer.getRootNode().attachChild(pGeom);
//set the player's initial position
initPosition();
//set up the keyboard
initKeys();
}

//this is just a simple wrapper for the move function to move the player paddle
public void shipMove(float x, float y, float z){
pGeom.move(x,y,z);
}
//this will reset the player's paddle at the initial position
public void initPosition(){
pGeom.setLocalTranslation(0f, -15f, 0f);
}

//this will add a point to the player's score
public void score(){
score++;
}

//fires a bullet from the ship
public void fire(){

bullets.add(new Bullet(gamePointer));

}

//updates the ship
public void update(float tpf){
//update each of the bullets
if(bullets.size()>0){
for(int i=1; i<bullets.size();i++){
bullets.get(i).update(tpf);
}
}
}

/** Custom Keybinding: Map named actions to inputs. */
private void initKeys() {
gamePointer.getInputManager().addMapping("Left", new KeyTrigger(KeyInput.KEY_LEFT));
gamePointer.getInputManager().addMapping("Right", new KeyTrigger(KeyInput.KEY_RIGHT));
gamePointer.getInputManager().addMapping("Shoot", new KeyTrigger(KeyInput.KEY_SPACE));
// Add the names to the action listener.
gamePointer.getInputManager().addListener(movementListener, new String[]{"Left","Right"});
gamePointer.getInputManager().addListener(fireListener, new String[]{"Shoot"});
}
//inner class for player movement
private AnalogListener movementListener = new AnalogListener() {
public void onAnalog(String name, float value, float tpf) {
if(name.equals("Right")){
//if the pgeom is not outside boudaries move
if(pGeom.getLocalTranslation().x <= 15)
shipMove(SPEED * tpf, 0f ,0f);
}
else if(name.equals("Left")){
if(pGeom.getLocalTranslation().x >= -15)
shipMove(-(SPEED * tpf), 0f ,0f);
}
}
};

//inner class for player firing
private AnalogListener fireListener = new AnalogListener() {
public void onAnalog(String name, float value, float tpf) {
//if the user is holding the spacebar, fire a bullet
if(name.equals("Shoot")){
fire();
}
}
};

}



[/java]

Bullet:

[java]package mygame;

import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;


public class Bullet {

private Main gamePointer;

//bullet fields
private Geometry geom;
private Box bullet;
private Material mat;

public Bullet(Main game){
gamePointer = game;
bullet = new Box(Vector3f.ZERO, 1, 1, 1);
geom = new Geometry("Box", bullet);
mat = new Material(gamePointer.getAssetManager(), "Common/MatDefs/Misc/SolidColor.j3md");
mat.setColor("m_Color", ColorRGBA.Red);
geom.setMaterial(mat);
gamePointer.getRootNode().attachChild(geom);
//set the player's initial position
initPosition();
}

//initial positioning
public void initPosition(){
geom.setLocalTranslation(0f, 0f, 0f);
}

//move the bullet, check if it should be killed, and also check for collision
public void update(float tpf){
geom.move(.01f * tpf,0,0);
}
}
[/java]


Now I made this with no prior experience in game loops and such. I do know java but I have only developed static applications. What the code above will do, is create a player which youy can move left to right with the arrow keys. Or fire a bullet (dosent seem to move yet but thats not the issue). Before i added the bullet code the player would move fine with around 2500 fps. But the bullet update code seems to make the player movement lag a bit so it dosent move smoothly. My computer is fairly new so there is an obvious problem with the code. If anyone can see it I would really appreciate the suggestions! I realize this is a lot to ask for.

Thanks,
Zach

You should look at the TestWalkingChar example in the test package, it’s basically what you want to do.

Whenever you shoot a bullet you create a new Mesh, only create it once (Singletone or static) and reuse that for every Geometry you create



Same goes for the Material, that way you can probably reduce the short lags whenever you shoot.

Also try instead of geom.move

to just setlocalTranslation(getlocaltranslation.add(direction*speed) * tpf)

(direction and speed could already be calculated in the constructor if they do not change)

Thanks for telling me that meshes only need to be created once. I also found that when i pressed the spacebar thousands of bullets were bewing created a second. This caused the slight lag. The lag at first wasnt even that bad (it was still 80fps) but just a little jumpy. Thanks for the advice!

Would making the mesh a static class variable work well?

it should work, meshs are (mostly) only collections of points, the whole transformation amterial ect stuff is in the geometry. So you can share them without any problems (exceptions are animations, since the point data changes then, but I assume that is still a bit into the future)