mirror of
				https://github.com/Dejvino/roadtrip
				synced 2025-10-31 07:45:22 +00:00 
			
		
		
		
	Map: refactoring of map generation. Added RoadTrip Planner app.
This commit is contained in:
		
							parent
							
								
									f75fdecf07
								
							
						
					
					
						commit
						cbf342cb97
					
				| @ -26,6 +26,12 @@ public abstract class GameApplication extends NotSoSimpleApplication | ||||
|         stateManager.attach(bulletAppState); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void update() { | ||||
|         super.update(); | ||||
|         updateListenerPosition(); | ||||
|     } | ||||
| 
 | ||||
|     protected PhysicsSpace getPhysicsSpace(){ | ||||
|         return bulletAppState.getPhysicsSpace(); | ||||
|     } | ||||
| @ -43,4 +49,10 @@ public abstract class GameApplication extends NotSoSimpleApplication | ||||
|     { | ||||
|         bulletAppState.setEnabled(!paused); | ||||
|     } | ||||
| 
 | ||||
|     protected void updateListenerPosition() | ||||
|     { | ||||
|         listener.setLocation(cam.getLocation()); | ||||
|         listener.setRotation(cam.getRotation()); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -153,6 +153,8 @@ public class RoadTrip extends GameApplication implements ActionListener { | ||||
|         VehicleNode vehicle = new VehicleNode("Car " + vehicleInstance.toString(), vehicleInstance); | ||||
|         vehicle.initialize(assetManager); | ||||
| 
 | ||||
|         vehicle.vehicleControl.setPhysicsLocation(new Vector3f(10f + (float)Math.random() * 40f, 228f, 12f + (float)Math.random() * 40f)); | ||||
| 
 | ||||
|         gameWorldState.vehicles.add(vehicle); | ||||
| 	    getPhysicsSpace().addAll(vehicle); | ||||
|         rootNode.attachChild(vehicle); | ||||
| @ -169,7 +171,7 @@ public class RoadTrip extends GameApplication implements ActionListener { | ||||
|         person.addControl(personControl); | ||||
|         /**/personControl.setJumpForce(new Vector3f(0,5f,0)); | ||||
|         personControl.setGravity(new Vector3f(0,1f,0)); | ||||
|         personControl.warp(new Vector3f(10f + (float)Math.random() * 20f, 30f, 12f + (float)Math.random() * 20f));/**/ | ||||
|         personControl.warp(new Vector3f(10f + (float)Math.random() * 20f, 230f, 12f + (float)Math.random() * 20f));/**/ | ||||
|         //personControl.setPhysicsLocation(new Vector3f(10f, 30f, 12f)); | ||||
|         getPhysicsSpace().add(personControl); | ||||
|         //getPhysicsSpace().addAll(person); | ||||
|  | ||||
							
								
								
									
										77
									
								
								src/roadtrip/RoadTripPlanner.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/roadtrip/RoadTripPlanner.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | ||||
| package roadtrip; | ||||
| 
 | ||||
| import com.jme3.app.SimpleApplication; | ||||
| import com.jme3.audio.AudioNode; | ||||
| import com.jme3.audio.AudioSource.Status; | ||||
| import com.jme3.bullet.BulletAppState; | ||||
| import com.jme3.bullet.PhysicsSpace; | ||||
| import com.jme3.bullet.collision.shapes.*; | ||||
| import com.jme3.bullet.control.BetterCharacterControl; | ||||
| import com.jme3.bullet.control.RigidBodyControl; | ||||
| import com.jme3.bullet.control.VehicleControl; | ||||
| import com.jme3.font.BitmapFont; | ||||
| import com.jme3.font.BitmapText; | ||||
| import com.jme3.font.Rectangle; | ||||
| import com.jme3.input.ChaseCamera; | ||||
| import com.jme3.input.KeyInput; | ||||
| import com.jme3.input.controls.ActionListener; | ||||
| import com.jme3.input.controls.KeyTrigger; | ||||
| import com.jme3.light.AmbientLight; | ||||
| import com.jme3.light.DirectionalLight; | ||||
| import com.jme3.material.Material; | ||||
| import com.jme3.math.*; | ||||
| import com.jme3.renderer.queue.RenderQueue; | ||||
| import com.jme3.scene.Geometry; | ||||
| import com.jme3.scene.Node; | ||||
| import com.jme3.scene.Spatial; | ||||
| import com.jme3.scene.debug.Arrow; | ||||
| import com.jme3.scene.shape.Box; | ||||
| import com.jme3.scene.shape.Cylinder; | ||||
| import com.jme3.terrain.geomipmap.TerrainGrid; | ||||
| import com.jme3.terrain.geomipmap.TerrainGridListener; | ||||
| import com.jme3.terrain.geomipmap.TerrainQuad; | ||||
| import java.util.Random; | ||||
| import roadtrip.model.VehicleInstance; | ||||
| import roadtrip.view.CompassNode; | ||||
| import roadtrip.view.GameMenuNode; | ||||
| import roadtrip.view.GameWorldView; | ||||
| import roadtrip.view.VehicleNode; | ||||
| import roadtrip.view.model.GameWorldState; | ||||
| import roadtrip.view.model.Player; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * @author dejvino | ||||
|  */ | ||||
| public class RoadTripPlanner extends SimpleApplication { | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         RoadTripPlanner app = new RoadTripPlanner(); | ||||
|         app.start(); | ||||
|     } | ||||
| 
 | ||||
|     public static boolean DEBUG = /*false;/*/true;/**/ | ||||
| 
 | ||||
|     protected BulletAppState bulletAppState; | ||||
|     private GameWorldState gameWorldState; | ||||
|     private GameWorldView gameWorldView; | ||||
| 
 | ||||
|     protected PhysicsSpace getPhysicsSpace(){ | ||||
|         return bulletAppState.getPhysicsSpace(); | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
|     public void simpleInitApp() | ||||
|     { | ||||
|         bulletAppState = new BulletAppState(); | ||||
|         stateManager.attach(bulletAppState); | ||||
|          | ||||
|         bulletAppState.setDebugEnabled(DEBUG); | ||||
|          | ||||
|         gameWorldState = new GameWorldState(1L); | ||||
|         gameWorldView = GameWorldView.create(gameWorldState, assetManager, cam, rootNode, getPhysicsSpace()); | ||||
|          | ||||
|         flyCam.setMoveSpeed(300f); | ||||
|         cam.setLocation(new Vector3f(0, 200f, 0)); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										26
									
								
								src/roadtrip/model/MapObjectInstance.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/roadtrip/model/MapObjectInstance.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| package roadtrip.model; | ||||
| 
 | ||||
| import com.jme3.math.Vector3f; | ||||
| 
 | ||||
| /** | ||||
|  * Created by dejvino on 21.01.2017. | ||||
|  */ | ||||
| public class MapObjectInstance | ||||
| { | ||||
| 	private Vector3f position; | ||||
| 
 | ||||
| 	public MapObjectInstance(Vector3f position) | ||||
| 	{ | ||||
| 		this.position = new Vector3f(position); | ||||
| 	} | ||||
| 
 | ||||
| 	public Vector3f getPosition() | ||||
| 	{ | ||||
| 		return new Vector3f(position); | ||||
| 	} | ||||
| 
 | ||||
| 	public void setPosition(Vector3f position) | ||||
| 	{ | ||||
| 		this.position = new Vector3f(position); | ||||
| 	} | ||||
| } | ||||
| @ -1,5 +1,6 @@ | ||||
| package roadtrip.model; | ||||
| 
 | ||||
| import com.jme3.terrain.geomipmap.TerrainQuad; | ||||
| import roadtrip.model.AbstractProceduralBlock; | ||||
| import roadtrip.model.ProceduralMapQuadBlock; | ||||
| 
 | ||||
| @ -13,8 +14,10 @@ public class ProceduralMapBlock extends AbstractProceduralBlock | ||||
| 		super(seed); | ||||
| 	} | ||||
| 
 | ||||
| 	public ProceduralMapQuadBlock getMapQuadBlock(String quadName) | ||||
| 	public ProceduralMapQuadBlock getMapQuadBlock(TerrainQuad terrainQuad) | ||||
| 	{ | ||||
| 		return getSubBlock(quadName, ProceduralMapQuadBlock.class); | ||||
| 		ProceduralMapQuadBlock quadBlock = getSubBlock(terrainQuad.getName(), ProceduralMapQuadBlock.class); | ||||
| 		quadBlock.initialize(terrainQuad); | ||||
| 		return quadBlock; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -1,12 +1,56 @@ | ||||
| package roadtrip.model; | ||||
| 
 | ||||
| import com.jme3.bullet.collision.shapes.ConeCollisionShape; | ||||
| import com.jme3.bullet.control.RigidBodyControl; | ||||
| import com.jme3.math.Vector2f; | ||||
| import com.jme3.math.Vector3f; | ||||
| import com.jme3.scene.Spatial; | ||||
| import com.jme3.terrain.geomipmap.TerrainQuad; | ||||
| 
 | ||||
| import java.util.Collections; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.Random; | ||||
| 
 | ||||
| /** | ||||
|  * Created by dejvino on 21.01.2017. | ||||
|  */ | ||||
| public class ProceduralMapQuadBlock extends AbstractProceduralBlock | ||||
| { | ||||
| 	protected float cellSize = 64 * 2f * 2f; /* terrainGrid.getPatchSize() * terrainGrid.getLocalScale().x * 2f */ | ||||
| 
 | ||||
| 	private List<MapObjectInstance> mapObjects; | ||||
| 
 | ||||
| 	public ProceduralMapQuadBlock(long seed) | ||||
| 	{ | ||||
| 		super(seed); | ||||
| 	} | ||||
| 
 | ||||
| 	public void initialize(TerrainQuad terrainQuad) | ||||
| 	{ | ||||
| 		mapObjects = new LinkedList<>(); | ||||
| 		Random quadRand = getBlockRandom(); | ||||
| 		Vector2f prevPos = null; | ||||
| 		Vector2f quadPos = new Vector2f(terrainQuad.getLocalTranslation().x, terrainQuad.getLocalTranslation().z); | ||||
| 		for (int i = 0; i < quadRand.nextInt(10000); i++) { | ||||
| 			Vector2f pos; | ||||
| 			if (prevPos == null || quadRand.nextFloat() < 0.2f) { | ||||
| 				pos = new Vector2f((quadRand.nextFloat() - 0.5f) * cellSize, (quadRand.nextFloat() - 0.5f) * cellSize) | ||||
| 						.addLocal(quadPos); | ||||
| 			} else { | ||||
| 				pos = new Vector2f((quadRand.nextFloat() - 0.5f) * 20f, (quadRand.nextFloat() - 0.5f) * 20f) | ||||
| 						.addLocal(prevPos); | ||||
| 			} | ||||
| 			prevPos = pos; | ||||
| 			float height = terrainQuad.getHeight(pos); | ||||
| 			Vector3f location = new Vector3f(pos.x, height, pos.y); | ||||
| 			mapObjects.add(new MapObjectInstance(location)); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public Iterable<? extends MapObjectInstance> getMapObjects() | ||||
| 	{ | ||||
| 		if (mapObjects == null) throw new RuntimeException("Call to getMapObjects on an uninitialized block."); | ||||
| 		return mapObjects; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -5,8 +5,10 @@ import com.jme3.bullet.PhysicsSpace; | ||||
| import com.jme3.bullet.collision.shapes.ConeCollisionShape; | ||||
| import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape; | ||||
| import com.jme3.bullet.control.RigidBodyControl; | ||||
| import com.jme3.light.AmbientLight; | ||||
| import com.jme3.light.DirectionalLight; | ||||
| import com.jme3.material.Material; | ||||
| import com.jme3.math.Vector2f; | ||||
| import com.jme3.math.ColorRGBA; | ||||
| import com.jme3.math.Vector3f; | ||||
| import com.jme3.renderer.Camera; | ||||
| import com.jme3.scene.Node; | ||||
| @ -23,12 +25,11 @@ import com.jme3.terrain.noise.filter.SmoothFilter; | ||||
| import com.jme3.terrain.noise.fractal.FractalSum; | ||||
| import com.jme3.terrain.noise.modulator.NoiseModulator; | ||||
| import com.jme3.texture.Texture; | ||||
| import roadtrip.model.MapObjectInstance; | ||||
| import roadtrip.model.ProceduralMapQuadBlock; | ||||
| import roadtrip.model.TerrainDataProvider; | ||||
| import roadtrip.view.model.GameWorldState; | ||||
| 
 | ||||
| import java.util.Random; | ||||
| 
 | ||||
| /** | ||||
|  * Created by dejvino on 14.01.2017. | ||||
|  */ | ||||
| @ -59,6 +60,15 @@ public class GameWorldView { | ||||
| 
 | ||||
|     private void initialize() | ||||
|     { | ||||
|         // Environment | ||||
|         DirectionalLight dl = new DirectionalLight(); | ||||
|         dl.setColor(ColorRGBA.LightGray); | ||||
|         dl.setDirection(new Vector3f(1, -1, 1)); | ||||
|         rootNode.addLight(dl); | ||||
|         AmbientLight al = new AmbientLight(); | ||||
|         al.setColor(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f)); | ||||
|         rootNode.addLight(al); | ||||
|          | ||||
|         // TERRAIN TEXTURE material | ||||
|         terrain.mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md"); | ||||
| 
 | ||||
| @ -133,15 +143,15 @@ public class GameWorldView { | ||||
| 
 | ||||
|         ground.addPreFilter(terrain.terrainDataProvider.iterate); | ||||
| 
 | ||||
|         terrain.terrainGrid = new TerrainGrid("terrain", 64 + 1, 256 + 1, new FractalTileLoader(ground, 300f)); | ||||
|         terrain.terrainGrid = new TerrainGrid("terrain", 16 + 1, 512 + 1, new FractalTileLoader(ground, 300f)); | ||||
| 
 | ||||
|         terrain.terrainGrid.setMaterial(terrain.mat_terrain); | ||||
|         terrain.terrainGrid.setLocalTranslation(0, -200, 0); | ||||
|         terrain.terrainGrid.setLocalScale(2f, 1f, 2f); | ||||
|         //terrain.terrainGrid.setLocalTranslation(0, -200, 0); | ||||
|         //terrain.terrainGrid.setLocalScale(2f, 1f, 2f); | ||||
|         this.rootNode.attachChild(terrain.terrainGrid); | ||||
| 
 | ||||
|         TerrainLodControl control = new TerrainGridLodControl(terrain.terrainGrid, camera); | ||||
|         control.setLodCalculator(new DistanceLodCalculator(64 + 1, 2.7f)); // patch size, and a multiplier | ||||
|         control.setLodCalculator(new DistanceLodCalculator(32 + 1, 2.7f)); // patch size, and a multiplier | ||||
|         terrain.terrainGrid.addControl(control); | ||||
| 
 | ||||
|         final TerrainGrid terrainGrid = terrain.terrainGrid; | ||||
| @ -163,48 +173,33 @@ public class GameWorldView { | ||||
| 
 | ||||
|                 String quadObjectsNodeKey = getQuadObjectsNodeKey(quad); | ||||
|                 Node objects = new Node(quadObjectsNodeKey); | ||||
|                 populateQuadObjectsNode(quad, quadObjectsNodeKey, objects); | ||||
|                 populateQuadObjectsNode(quad, objects); | ||||
|                 rootNode.attachChild(objects); | ||||
|             } | ||||
| 
 | ||||
|             protected void populateQuadObjectsNode(TerrainQuad quad, String quadObjectsNodeKey, Node objects) | ||||
|             protected void populateQuadObjectsNode(TerrainQuad quad, Node objects) | ||||
|             { | ||||
|                 ProceduralMapQuadBlock mapQuadBlock = state.proceduralMap.getMapQuadBlock(quad.getName()); | ||||
|                 ProceduralMapQuadBlock mapQuadBlock = state.proceduralMap.getMapQuadBlock(quad); | ||||
| 
 | ||||
|                 // TODO: move any access to the Random into the ProceduralMapQuadBlock | ||||
|                 Random quadRand = mapQuadBlock.getBlockRandom(); | ||||
| 
 | ||||
|                 // Generate trees | ||||
|                 // Add map objects (for now - trees) | ||||
|                 Spatial treeModel = assetManager.loadModel("Models/tree.j3o"); | ||||
|                 //System.out.println("Grid @ " + terrainGrid.getLocalTranslation() + " s " + terrainGrid.getLocalScale()); | ||||
|                 //System.out.println("Quad " + quad.getName() + " @ " + quad.getLocalTranslation()); | ||||
|                 float cellSize = terrainGrid.getPatchSize() * terrainGrid.getLocalScale().x * 2f; | ||||
|                 Vector2f prevPos = null; | ||||
|                 for (int i = 0; i < quadRand.nextInt(10000); i++) { | ||||
|                     Vector2f pos; | ||||
|                     if (prevPos == null || quadRand.nextFloat() < 0.2f) { | ||||
|                         pos = new Vector2f((quadRand.nextFloat() - 0.5f) * cellSize, (quadRand.nextFloat() - 0.5f) * cellSize) | ||||
|                                 .addLocal(quad.getWorldTranslation().x, quad.getWorldTranslation().z); | ||||
|                     } else { | ||||
|                         pos = new Vector2f((quadRand.nextFloat() - 0.5f) * 20f, (quadRand.nextFloat() - 0.5f) * 20f).addLocal(prevPos); | ||||
|                     } | ||||
|                     prevPos = pos; | ||||
|                     float height = quad.getHeight(pos); | ||||
|                     Vector3f location = new Vector3f(pos.x, height, pos.y) | ||||
|                             .addLocal(terrainGrid.getWorldTranslation()); | ||||
|                     System.out.println("Tree " + i + ": " + location); | ||||
|                     Spatial treeInstance = treeModel.clone(); | ||||
|                     treeInstance.setLocalTranslation(location); | ||||
|                 for (MapObjectInstance mapObject : mapQuadBlock.getMapObjects()) { | ||||
|                     Vector3f pos = mapObject.getPosition(); | ||||
|                     Spatial modelInstance = treeModel.clone(); | ||||
|                     modelInstance.setLocalTranslation(pos); | ||||
|                     // TODO: physics from the model and not hard-coded | ||||
|                     //RigidBodyControl control = treeInstance.getControl(RigidBodyControl.class); | ||||
|                     RigidBodyControl control = new RigidBodyControl(new ConeCollisionShape(1f, 5f), 0f); | ||||
|                     if (control != null) { | ||||
|                         treeInstance.addControl(control); | ||||
|                         control.setPhysicsLocation(location); | ||||
|                         modelInstance.addControl(control); | ||||
|                         control.setPhysicsLocation(pos); | ||||
|                         physicsSpace.add(control); | ||||
|                     } | ||||
|                     objects.attachChild(treeInstance); | ||||
|                     objects.attachChild(modelInstance); | ||||
|                 } | ||||
|                 //objects.setLocalTranslation(terrainGrid.getWorldTranslation()); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|  | ||||
| @ -213,7 +213,6 @@ public class VehicleNode extends Node | ||||
| 		vehicle.attachChild(vehicle.wheelSlipAudio); | ||||
| 
 | ||||
| 		vehicle.addControl(vehicleControl); | ||||
| 		vehicleControl.setPhysicsLocation(new Vector3f(10f + (float)Math.random() * 40f, 28f, 12f + (float)Math.random() * 40f)); | ||||
| 	} | ||||
| 
 | ||||
| 	public void update(float tpf) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user