Jul 11, 2017 4:31:02 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
java.lang.IllegalStateException: Scene graph is not properly updated for rendering.
State was changed after rootNode.updateGeometricState() call.
Make sure you do not modify the scene from another thread!
Problem spatial name: Root Node
- Have scene model
- And players slots (multiplayer)
Logic:
-
Load 3d scene
-
Load players and add to list
-
Update players in cycle
/*
- To change this template, choose Tools | Templates
- and open the template in the editor.
*/
package game;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.plugins.ZipLocator;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
import com.jme3.system.AppSettings;
import config.JConfig;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import message.JInMessages;
import message.JOutMessages;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import static windows.Interface.updateUseArea;/**
*-
@author nn
*/
public class GameLevel extends SimpleApplication implements ActionListener {
public static GameLevel gameLevel;
public String state = “start”;
/**
- Archive of game leve
*/
public String levelName;
/**
- Players array
*/
public static Map<String, Player> players = new HashMap<String, Player>();
/*
- Player command, numbers - slot, latter - command
- 1,2,3 command A
- 4,5,6 command B
*/
/**
- Model paramiters
*/
private Spatial sceneModel;
/**
* Local player
*/
Player player;private BulletAppState bulletAppState;
private RigidBodyControl landscape;private boolean left = false, right = false, up = false, down = false,lclick = false,sit = false;
//Temporary vectors used on each frame.
//They here to avoid instanciating new vectors on each frame
private Vector3f camDir = new Vector3f();
private Vector3f camLeft = new Vector3f();private Vector3f camOld;
private String levelId;
private static String localPlayerId;
public GameLevel(String levelJson){
//asdasd
try {
gameLevel = this;JSONParser parser = new JSONParser(); JSONObject result = (JSONObject) parser.parse(levelJson); GameLevel.gameLevel.levelName = (String) result.get("model"); GameLevel.gameLevel.levelId = (String) result.get("leveId"); GameLevel.gameLevel.localPlayerId = JConfig.user_id; //levelDescription = (String) result.get("points"); // fallSpeed = (int) result.get("fallSpeed"); GameLevel.gameLevel.levelName = levelName; setShowSettings(false); AppSettings settings = new AppSettings(true); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int width = (int) screenSize.getWidth(); int height = (int) screenSize.getHeight(); settings.setResolution(width, height); settings.setBitsPerPixel(32); setSettings(settings); GameLevel.gameLevel.state = "init"; } catch (ParseException ex) { Logger.getLogger(GameLevel.class.getName()).log(Level.SEVERE, null, ex); }
}
public void simpleInitApp() {
//cam.set GameLevel.gameLevel.camOld = cam.getLeft(); /** Set up Physics */ GameLevel.gameLevel.bulletAppState = new BulletAppState(); GameLevel.gameLevel.stateManager.attach(bulletAppState); //bulletAppState.getPhysicsSpace().enableDebug(assetManager); // We re-use the flyby camera for rotation, while positioning is handled by physics GameLevel.gameLevel.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); GameLevel.gameLevel.flyCam.setMoveSpeed(0.2f); setUpKeys(); setUpLight(); // We load the scene from the zip file and adjust its size. //assetManager.registerLocator("Models/" + levelName + ".zip", ZipLocator.class); // sceneModel = assetManager.loadModel(levelName+".scene"); GameLevel.gameLevel.sceneModel = assetManager.loadModel("Models/" + levelName + "/" + levelName + ".scene"); GameLevel.gameLevel.sceneModel.setLocalScale(2f); // We set up collision detection for the scene by creating a // compound collision shape and a static RigidBodyControl with mass zero. com.jme3.bullet.collision.shapes.CollisionShape sceneShape = CollisionShapeFactory.createMeshShape(GameLevel.gameLevel.sceneModel); GameLevel.gameLevel.landscape = new RigidBodyControl(sceneShape, 0); GameLevel.gameLevel.sceneModel.addControl(landscape); GameLevel.gameLevel.rootNode.attachChild(sceneModel); //get Start position GameLevel.gameLevel.bulletAppState.getPhysicsSpace().add(landscape); state = "sync"; synchronization(); //rootNode.attachChild(characterModel); // bulletAppState.getPhysicsSpace().add(player);
}
private void synchronization(){
String outMessage = "{\"task\":\"JGameTask\",\"user_id\":\""+ JConfig.user_id +"\",\"auth_token\":\""+JConfig.token +"\",\"scenario\":\"load_players\",\"data\":\""+ levelId +"\"}"; JOutMessages outMessages = new JOutMessages(JConfig.server_ip,outMessage); outMessages.insert();
}
public static void initPlayers(JInMessages in){
if(in.json.get("error") == null){ JSONObject players = (JSONObject)in.json.get("players"); Set<?> playersDataSet = players.keySet(); Iterator<?> playerDataIterator = playersDataSet.iterator(); while (playerDataIterator.hasNext()) { String playerDataKey = (String) playerDataIterator.next(); JSONObject playerJson = (JSONObject) players.get(playerDataKey); // System.out.println(playerJson); addPlayer(playerJson,playerDataKey); } //System.out.println(in.json.get("players")); }
}
public static void connectPlayer(JInMessages in){
if(in.json.get(“error”) == null){
JSONObject player = (JSONObject)in.json.get(“player”);
String id = (String) player.get(“id”);// System.out.print("add player " + id); addPlayer(player,id); }
}
private static void addPlayer(JSONObject playerJson,String key) {
//
//System.out.println("");
System.out.println("add player: " + playerJson.toJSONString());Player player = new Player(); player.assetManager = GameLevel.gameLevel.assetManager; player.camLeft = GameLevel.gameLevel.camLeft; player.id = key; player.setJsonKeys(playerJson); player.levelId = GameLevel.gameLevel.levelId; // player.startLocation = gameLevel.startPosition.get(player.slot); player.init(); GameLevel.gameLevel.players.put(player.id, player); GameLevel.gameLevel.rootNode.attachChild(player.characterModel); GameLevel.gameLevel.bulletAppState.getPhysicsSpace().add(player.characterControl);
}
private void setUpLight() {
// We add light so we see the scene
AmbientLight al = new AmbientLight();
al.setColor(ColorRGBA.White.mult(0.8f));
GameLevel.gameLevel.rootNode.addLight(al);DirectionalLight dl = new DirectionalLight(); dl.setColor(ColorRGBA.White); dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal()); GameLevel.gameLevel.rootNode.addLight(dl);
}
/** We over-write some navigational key mappings here, so we can
* add physics-controlled walking and jumping: */
private void setUpKeys() {
GameLevel.gameLevel.inputManager.addMapping(“Left”, new KeyTrigger(KeyInput.KEY_A));
GameLevel.gameLevel.inputManager.addMapping(“Right”, new KeyTrigger(KeyInput.KEY_D));
GameLevel.gameLevel.inputManager.addMapping(“Up”, new KeyTrigger(KeyInput.KEY_W));
GameLevel.gameLevel.inputManager.addMapping(“Down”, new KeyTrigger(KeyInput.KEY_S));
GameLevel.gameLevel.inputManager.addMapping(“Jump”, new KeyTrigger(KeyInput.KEY_SPACE));GameLevel.gameLevel.inputManager.addMapping("LClick",new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); GameLevel.gameLevel.inputManager.addMapping("Ctrl", new KeyTrigger(KeyInput.KEY_LCONTROL)); //sit GameLevel.gameLevel.inputManager.addListener(this, "Left"); GameLevel.gameLevel.inputManager.addListener(this, "Right"); GameLevel.gameLevel.inputManager.addListener(this, "Up"); GameLevel.gameLevel.inputManager.addListener(this, "Down"); GameLevel.gameLevel.inputManager.addListener(this, "Jump"); GameLevel.gameLevel.inputManager.addListener(this, "LClick"); GameLevel.gameLevel.inputManager.addListener(this, "Ctrl");
}
/** These are our custom actions triggered by key presses.
* We do not walk yet, we just keep track of the direction the user pressed. */
public void onAction(String binding, boolean isPressed, float tpf) {if (binding.equals("Left")) { GameLevel.gameLevel.left = isPressed; if(isPressed){ jsonPackKeys("Left",true,false); }else{ jsonPackKeys("Left",false,false); jsonPackKeys("LeftRelease",true,false); } } else if (binding.equals("Right")) { GameLevel.gameLevel.right= isPressed; if(isPressed){ jsonPackKeys("Right",true,false); }else{ jsonPackKeys("Right",false,false); jsonPackKeys("RightRelease",true,false); } } else if (binding.equals("Up")) { GameLevel.gameLevel.up = isPressed; if(isPressed){ jsonPackKeys("Up",true,false); }else{ jsonPackKeys("Up",false,false); jsonPackKeys("UpRelease",true,false); } } else if (binding.equals("Down")) { GameLevel.gameLevel.down = isPressed; if(isPressed){ jsonPackKeys("Down",true,false); }else{ jsonPackKeys("Down",false,false); jsonPackKeys("DownRelease",true,false); } } else if (binding.equals("Jump")) { if (isPressed) { jsonPackKeys("Jump",true,false); }else{ jsonPackKeys("Jump",false,false); jsonPackKeys("JumpRelease",true,false); } } else if (binding.equals("LClick")){ if(isPressed){ jsonPackKeys("LClick",true,false); }else{ jsonPackKeys("LClick",false,false); jsonPackKeys("LClickRelease",true,false); } } else if(binding.equals("Ctrl")){ if(isPressed){ jsonPackKeys("Ctrl",true,false); }else{ jsonPackKeys("Ctrl",false,false); jsonPackKeys("CtrlRelease",true,false); } }
}
/**
* This is the main event loop–walking happens here.
* We check in which direction the player is walking by interpreting
* the camera direction forward (camDir) and to the side (camLeft).
* The setWalkDirection() command is what lets aed player walk.
* We also make sure here that the camera moves with physics-controllplayer.
*/
@Override
public void simpleUpdate(float tpf) {
if(GameLevel.gameLevel.players.size() > 0){GameLevel.gameLevel.camDir.set(cam.getDirection()).multLocal(0.3f); GameLevel.gameLevel.camLeft.set(cam.getLeft()).multLocal(0.2f); Quaternion camRotation = cam.getRotation(); jsonPackKeys("camRotationX",camRotation.getX(),false); jsonPackKeys("camRotationY",camRotation.getY(),false); jsonPackKeys("camRotationZ",camRotation.getZ(),false); jsonPackKeys("camRotationW",camRotation.getW(),false); jsonPackKeys("camDirectionX",GameLevel.gameLevel.camDir.getX(),false); jsonPackKeys("camDirectionY",GameLevel.gameLevel.camDir.getY(),false); jsonPackKeys("camDirectionZ",GameLevel.gameLevel.camDir.getZ(),false); jsonPackKeys("camLeftX",GameLevel.gameLevel.camLeft.getX(),false); jsonPackKeys("camLeftY",GameLevel.gameLevel.camLeft.getY(),false); jsonPackKeys("camLeftZ",GameLevel.gameLevel.camLeft.getZ(),true); try { JSONParser parser = new JSONParser(); Object obj = parser.parse(GameLevel.gameLevel.keyString); JSONObject jsonObj = (JSONObject) obj; JSONObject keysObject = (JSONObject) jsonObj.get("keys"); GameLevel.gameLevel.players.get(GameLevel.gameLevel.localPlayerId).setJsonKeys(keysObject); } catch (ParseException ex) { Logger.getLogger(GameLevel.class.getName()).log(Level.SEVERE, null, ex); } // System.out.println(keyString); GameLevel.gameLevel.keyString = "{\"keys\" : {"; GameLevel.gameLevel.cam.setLocation(GameLevel.gameLevel.players.get(GameLevel.gameLevel.localPlayerId).characterControl.getPhysicsLocation()); for(String key : GameLevel.gameLevel.players.keySet()){ GameLevel.gameLevel.players.get(key).update(tpf); GameLevel.gameLevel.players.get(key).tpfUpdate(); } } } // public static void updatePlayerPosition(JInMessages in){ if(in.json.get("error") == null){ JSONObject player = (JSONObject)in.json.get("player"); String id = (String) player.get("id"); System.out.println("game level update localID " + GameLevel.gameLevel.localPlayerId + " update id " + id); GameLevel.gameLevel.players.get(id).setJsonKeys(player); } } /** * Packe keys to json string */ String keyString = "{\"keys\": {"; public void jsonPackKeys(String key,float value,boolean endflag){ GameLevel.gameLevel.keyString += "\"" +key + "\"" + ":" + value; if(endflag){ GameLevel.gameLevel.keyString += "}}"; }else { GameLevel.gameLevel.keyString += ","; } } public void jsonPackKeys(String key,boolean value,boolean endflag){ GameLevel.gameLevel.keyString += "\"" +key + "\"" + ":" + value; if(endflag){ GameLevel.gameLevel.keyString += "}}"; }else { GameLevel.gameLevel.keyString += ","; } }
}