package org.atriaSoft.gameEngine; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.atriaSoft.etk.math.Vector2f; import org.atriaSoft.gale.backend3d.OpenGL; import org.atriaSoft.gale.event.EventEntry; import org.atriaSoft.gale.event.EventInput; import org.atriaSoft.gale.event.EventTime; import org.atriaSoft.gale.key.KeyKeyboard; import org.atriaSoft.gale.key.KeySpecial; import org.atriaSoft.gale.key.KeyStatus; import org.atriaSoft.gale.key.KeyType; import org.atriaSoft.gameEngine.camera.Camera; import org.atriaSoft.gameEngine.engines.EngineRender; import org.atriaSoft.gameEngine.engines.EngineAI; import org.atriaSoft.gameEngine.engines.EngineLight; import org.atriaSoft.gameEngine.engines.EngineParticle; import org.atriaSoft.gameEngine.engines.EnginePhysics; //import org.atriaSoft.gameEngine.resource.Mesh; public class Environement { public Signal signalPlayTimeChange = new Signal(); private GameStatus propertyStatus = GameStatus.gameStop; // !< the display is running (not in pause) public float propertyRatio = 1.0f; // !< Speed ratio protected List engine = new ArrayList(); // !< EGE sub engine interface (like physique, rendering, // audio, ...). private List listEntity = new ArrayList(); // !< List of all entity added in the Game List controls = new ArrayList(); long lastCallTime = 0; // ! list of all camera in the world protected Map listCamera = new HashMap(); protected long gameTime = 0; // !< time of the game running private long startTime; //protected List listMeshToDrawFirst = new ArrayList(); public Environement() { // we add the 4 classical engines (the order is used to the global rendering cycle ... addEngine(new EnginePhysics(this)); addEngine(new EngineAI(this)); addEngine(new EngineRender(this)); addEngine(new EngineParticle(this)); addEngine(new EngineLight(this)); } public void addControlInterface(ControlInterface ref) { controls.add(ref); } public void removeControlInterface(ControlInterface ref) { controls.remove(ref); } public void onPointer(KeySpecial special, KeyType type, int pointerID, Vector2f pos, KeyStatus state) { EventInput event = new EventInput(type, state, pointerID, pos, special); for (ControlInterface elem : controls) { elem.onEventInput(event, pos); } } public void onKeyboard( KeySpecial special, KeyKeyboard type, Character value, KeyStatus state) { EventEntry event = new EventEntry(special, type, state, value); for (ControlInterface elem : controls) { elem.onEventEntry(event); } } public void addEngine(Engine ref) { if (ref == null) { Log.error("try to add an empty Engine"); return; } // check if not exist for (Engine it : engine) { if (it.getType().contains(ref.getType())) { it = ref; return; } } // add it at the end ... engine.add(ref); } public void rmEngine(Engine ref) { engine.remove(ref); } public void rmEngine(String type) { for (Engine it : engine) { if (it.getType().contains(type)) { engine.remove(it); return; } } } public Engine getEngine(String type) { for (Engine it : engine) { if (it.getType().contains(type)) { return it; } } Log.error("try to get an unexisting engine type: '" + type + "'"); return null; } public void engineComponentRemove(Component ref) { for (Engine it: engine) { if (it.getType().contentEquals(ref.getType())) { it.componentRemove(ref); return; } } } public void engineComponentAdd(Component ref) { for (Engine it: engine) { if (it.getType().contentEquals(ref.getType())) { it.componentAdd(ref); return; } } } public void render(long deltaMilli, String cameraName) { // get the correct camera: Camera camera = getCamera(cameraName); if (camera == null) { Log.error("Render: Can not get camera named: '" + cameraName + "'"); return; } OpenGL.setCameraMatrix(camera.getConvertionMatrix()); for (Engine it: engine) { //Log.verbose(" render: " + it.getType()); it.render(deltaMilli, camera); } // for (Engine it: engine) { // if(it == null) { // continue; // } // Log.verbose(" render: " + it.getType()); // it.renderDebug(deltaMilli, camera); // } } /** * @brief Add a camera in the camera pool. * @param[in] name Name of the camera. * @param[in] camera Pointer on the camera to add. */ public void addCamera(String name, Camera camera) { listCamera.put(name, camera); } /** * @brief Get a specific camera. * @param[in] name Name of the camera. * @return A pointer on the camera requested. */ public Camera getCamera(String name) { return listCamera.get(name); } /** * @brief Get List of all camera. * @return All the camera registerred. */ public Map getCameraList() { return listCamera; } /** * @brief Remove all from the current environement */ public void clear() { listEntity.clear(); } private static Map creators = new HashMap(); /** * @brief add a creator entity system * @param[in] type Type of the entity. * @param[in] creator Function pointer that reference the entity creating. */ public static void addCreator(String type, CreatorEntity creator) { if (creator == null) { Log.error("Try to add an empty CREATOR ..."); return; } Log.debug("Add creator: " + type); creators.put(type, creator); Log.debug("Add creator: " + type + " (done)"); } /** * @brief Create an entity on the curent scene. * @param[in] type Type of the entity that might be created. * @param[in] description String that describe the content of the entity * properties. * @param[in] autoAddEntity this permit to add the entity if it is created == > * no more action ... * @return null if an error occured OR the pointer on the entity and it is * already added on the system. * @note Pointer is return in case of setting properties on it... */ public Entity createEntity(String type, Object value, boolean autoAddEntity) { if (creators.containsKey(type) == false) { Log.error("Request creating of an type that is not known '" + type + "'"); return null; } CreatorEntity creatorPointer = creators.get(type); if (creatorPointer == null) { Log.error("null pointer creator == > internal error... '" + type + "'"); return null; } Entity tmpEntity = creatorPointer.create(this, value); if (tmpEntity == null) { Log.error("allocation error '" + type + "'"); return null; } if (autoAddEntity == true) { addEntity(tmpEntity); } return tmpEntity; } public Entity createEntity(String type, boolean autoAddEntity) { return this.createEntity(type, null, autoAddEntity); } /** * @breif get a reference on the curent list of entity games * @return all entity list */ public List getEntity() { return listEntity; }; /** * @brief add an entity on the list availlable. * @param[in] newEntity Entity to add. */ public void addEntity(Entity newEntity) { // prevent memory allocation and un allocation ... if (newEntity == null) { return; } listEntity.add(newEntity); newEntity.dynamicEnable(); } /** * @brief remove an entity on the list availlable. * @param[in] removeEntity Entity to remove. */ public void rmEntity(Entity removeEntity) { if (removeEntity == null) { return; } for (int iii=0; iii usefull for * explosion, or lazer fire ... * @param[in] event event that might be apply ... */ public void generateInteraction(EntityInteraction event) { // inform the entity that an entity has been removed ==> this permit to keep pointer on entitys ... for (int iii=0; iiidecreasePower) { continue; } float inpact = (decreasePower-dist)/decreasePower * power; glistEntity[iii].setFireOn(groupIdSource, type, -inpact, sourcePosition); */ } } // private void onCallbackPeriodicCall(ewol::event::Time event) { // float curentDelta = event.getDeltaCall(); // EGEVERBOSE("periodic call : " + event); // // small hack to change speed ... // curentDelta *= *propertyRatio; // // check if the processing is availlable // if (propertyStatus.get() == gameStop) { // return; // } // // update game time: // int lastGameTime = mgameTime*0.000001f; // mgameTime += curentDelta; // if (lastGameTime != (int)(mgameTime*0.000001f)) { // EGEVERBOSE(" Emit Signal"); // signalPlayTimeChange.emit(mgameTime*0.000001f); // } // // //EWOLDEBUG("Time: mlastCallTime=" + mlastCallTime + " deltaTime=" + deltaTime); // // // update camera positions: // for (auto it : mlistCamera) { // if (it.second != null) { // EGEVERBOSE(" update camera : '" + it.first + "'"); // it.second.periodicCall(curentDelta); // } // } // EGEVERBOSE(" step simulation : " + curentDelta); // for (auto it: mengine) { // if(it == null) { // continue; // } // EGEVERBOSE(" update: " + it.getType()); // it.update(echrono::Duration(double(curentDelta))); // } // // //EGE.debug("stepSimulation (start)"); // ///step the simulation // // TODO : mphysicEngine.update(curentDelta); // // TODO : //optional but useful: debug drawing // // TODO : mphysicEngine.debugDrawWorld(); // // TODO : EGEINFO(" Update particule engine"); // // TODO : mparticuleEngine.update(curentDelta); // // remove all entity that requested it ... // /** // { // int numberEnnemyKilled=0; // int victoryPoint=0; // auto it(mlistEntity.begin()); // while (it != mlistEntity.end()) { // if(*it != null) { // if ((*it).needToRemove() == true) { // if ((*it).getGroup() > 1) { // numberEnnemyKilled++; // victoryPoint++; // } // EGEINFO("[" + (*it).getUID() + "] entity Removing ... " + (*it).getType()); // rmEntity((*it)); // it = mlistEntity.begin(); // } else { // ++it; // } // } else { // ++it; // } // } // if (numberEnnemyKilled != 0) { // //signalKillEnemy.emit(numberEnnemyKilled); // } // } // */ // } // public void addStaticMeshToDraw(Mesh mesh) { // listMeshToDrawFirst.add(mesh); // } // // public List getStaticMeshToDraw() { // return listMeshToDrawFirst; // } public GameStatus getPropertyStatus() { return propertyStatus; } public void setPropertyStatus(GameStatus propertyStatus) { if (this.propertyStatus == propertyStatus) { return; } this.propertyStatus = propertyStatus; // if (propertyStatus == GameStatus.gameStart) { // mperiodicCallConnection = getObjectManager().periodicCall.connect(this, Environement::onCallbackPeriodicCall); // } else { // mperiodicCallConnection.disconnect(); // } } public void periodicCall() { if (lastCallTime == 0 ) { startTime = System.nanoTime()/1000; lastCallTime = startTime; } long lastUpdate = lastCallTime; lastCallTime = System.nanoTime()/1000; EventTime event = new EventTime(lastCallTime, lastCallTime-startTime, lastCallTime-lastUpdate, lastCallTime-lastUpdate); for (ControlInterface elem : controls) { elem.periodicCall(event); } } } /* * void Environement::getEntityNearest( Vector3f sourcePosition, float * distanceMax, List resultList) { * resultList.clear(); Environement::ResultNearestEntity result; result.dist = * 99999999999.0f; result.entity = null; for (int iii=0; iii? " + * distance + " id=" + iii); if (distanceMax>result.dist) { * resultList.pushBack(result); } } } * * void Environement::getEntityNearestFixed( Vector3f sourcePosition, float * distanceMax, List resultList) { * resultList.clear(); Environement::ResultNearestEntity result; result.dist = * 99999999999.0f; result.entity = null; for (int iii=0; iii? " + * distance + " id=" + iii); if (distanceMax <= result.dist) { continue; } // * try to add the entity at the best positions: int jjj; for (jjj=0; * jjjresult.dist) { * resultList.insert(resultList.begin()+jjj, result); break; } } // add entity * at the end : if (jjj >= resultList.size()) { resultList.pushBack(result); } } * } */