1
0
mirror of https://github.com/Dejvino/roadtrip synced 2024-12-22 11:48:49 +00:00

Map: refactoring of map generation. Added RoadTrip Planner app.

This commit is contained in:
Dejvino 2017-01-22 18:28:05 +01:00
parent f75fdecf07
commit cbf342cb97
8 changed files with 196 additions and 38 deletions

View File

@ -26,6 +26,12 @@ public abstract class GameApplication extends NotSoSimpleApplication
stateManager.attach(bulletAppState); stateManager.attach(bulletAppState);
} }
@Override
public void update() {
super.update();
updateListenerPosition();
}
protected PhysicsSpace getPhysicsSpace(){ protected PhysicsSpace getPhysicsSpace(){
return bulletAppState.getPhysicsSpace(); return bulletAppState.getPhysicsSpace();
} }
@ -43,4 +49,10 @@ public abstract class GameApplication extends NotSoSimpleApplication
{ {
bulletAppState.setEnabled(!paused); bulletAppState.setEnabled(!paused);
} }
protected void updateListenerPosition()
{
listener.setLocation(cam.getLocation());
listener.setRotation(cam.getRotation());
}
} }

View File

@ -153,6 +153,8 @@ public class RoadTrip extends GameApplication implements ActionListener {
VehicleNode vehicle = new VehicleNode("Car " + vehicleInstance.toString(), vehicleInstance); VehicleNode vehicle = new VehicleNode("Car " + vehicleInstance.toString(), vehicleInstance);
vehicle.initialize(assetManager); vehicle.initialize(assetManager);
vehicle.vehicleControl.setPhysicsLocation(new Vector3f(10f + (float)Math.random() * 40f, 228f, 12f + (float)Math.random() * 40f));
gameWorldState.vehicles.add(vehicle); gameWorldState.vehicles.add(vehicle);
getPhysicsSpace().addAll(vehicle); getPhysicsSpace().addAll(vehicle);
rootNode.attachChild(vehicle); rootNode.attachChild(vehicle);
@ -169,7 +171,7 @@ public class RoadTrip extends GameApplication implements ActionListener {
person.addControl(personControl); person.addControl(personControl);
/**/personControl.setJumpForce(new Vector3f(0,5f,0)); /**/personControl.setJumpForce(new Vector3f(0,5f,0));
personControl.setGravity(new Vector3f(0,1f,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)); //personControl.setPhysicsLocation(new Vector3f(10f, 30f, 12f));
getPhysicsSpace().add(personControl); getPhysicsSpace().add(personControl);
//getPhysicsSpace().addAll(person); //getPhysicsSpace().addAll(person);

View 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));
}
}

View 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);
}
}

View File

@ -1,5 +1,6 @@
package roadtrip.model; package roadtrip.model;
import com.jme3.terrain.geomipmap.TerrainQuad;
import roadtrip.model.AbstractProceduralBlock; import roadtrip.model.AbstractProceduralBlock;
import roadtrip.model.ProceduralMapQuadBlock; import roadtrip.model.ProceduralMapQuadBlock;
@ -13,8 +14,10 @@ public class ProceduralMapBlock extends AbstractProceduralBlock
super(seed); 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;
} }
} }

View File

@ -1,12 +1,56 @@
package roadtrip.model; 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. * Created by dejvino on 21.01.2017.
*/ */
public class ProceduralMapQuadBlock extends AbstractProceduralBlock 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) public ProceduralMapQuadBlock(long seed)
{ {
super(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;
}
} }

View File

@ -5,8 +5,10 @@ import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.ConeCollisionShape; import com.jme3.bullet.collision.shapes.ConeCollisionShape;
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape; import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
import com.jme3.bullet.control.RigidBodyControl; import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.Vector2f; import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera; import com.jme3.renderer.Camera;
import com.jme3.scene.Node; 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.fractal.FractalSum;
import com.jme3.terrain.noise.modulator.NoiseModulator; import com.jme3.terrain.noise.modulator.NoiseModulator;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import roadtrip.model.MapObjectInstance;
import roadtrip.model.ProceduralMapQuadBlock; import roadtrip.model.ProceduralMapQuadBlock;
import roadtrip.model.TerrainDataProvider; import roadtrip.model.TerrainDataProvider;
import roadtrip.view.model.GameWorldState; import roadtrip.view.model.GameWorldState;
import java.util.Random;
/** /**
* Created by dejvino on 14.01.2017. * Created by dejvino on 14.01.2017.
*/ */
@ -59,6 +60,15 @@ public class GameWorldView {
private void initialize() 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 TEXTURE material
terrain.mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md"); terrain.mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");
@ -133,15 +143,15 @@ public class GameWorldView {
ground.addPreFilter(terrain.terrainDataProvider.iterate); 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.setMaterial(terrain.mat_terrain);
terrain.terrainGrid.setLocalTranslation(0, -200, 0); //terrain.terrainGrid.setLocalTranslation(0, -200, 0);
terrain.terrainGrid.setLocalScale(2f, 1f, 2f); //terrain.terrainGrid.setLocalScale(2f, 1f, 2f);
this.rootNode.attachChild(terrain.terrainGrid); this.rootNode.attachChild(terrain.terrainGrid);
TerrainLodControl control = new TerrainGridLodControl(terrain.terrainGrid, camera); 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); terrain.terrainGrid.addControl(control);
final TerrainGrid terrainGrid = terrain.terrainGrid; final TerrainGrid terrainGrid = terrain.terrainGrid;
@ -163,48 +173,33 @@ public class GameWorldView {
String quadObjectsNodeKey = getQuadObjectsNodeKey(quad); String quadObjectsNodeKey = getQuadObjectsNodeKey(quad);
Node objects = new Node(quadObjectsNodeKey); Node objects = new Node(quadObjectsNodeKey);
populateQuadObjectsNode(quad, quadObjectsNodeKey, objects); populateQuadObjectsNode(quad, objects);
rootNode.attachChild(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 // Add map objects (for now - trees)
Random quadRand = mapQuadBlock.getBlockRandom();
// Generate trees
Spatial treeModel = assetManager.loadModel("Models/tree.j3o"); Spatial treeModel = assetManager.loadModel("Models/tree.j3o");
//System.out.println("Grid @ " + terrainGrid.getLocalTranslation() + " s " + terrainGrid.getLocalScale()); //System.out.println("Grid @ " + terrainGrid.getLocalTranslation() + " s " + terrainGrid.getLocalScale());
//System.out.println("Quad " + quad.getName() + " @ " + quad.getLocalTranslation()); //System.out.println("Quad " + quad.getName() + " @ " + quad.getLocalTranslation());
float cellSize = terrainGrid.getPatchSize() * terrainGrid.getLocalScale().x * 2f; for (MapObjectInstance mapObject : mapQuadBlock.getMapObjects()) {
Vector2f prevPos = null; Vector3f pos = mapObject.getPosition();
for (int i = 0; i < quadRand.nextInt(10000); i++) { Spatial modelInstance = treeModel.clone();
Vector2f pos; modelInstance.setLocalTranslation(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);
// TODO: physics from the model and not hard-coded // TODO: physics from the model and not hard-coded
//RigidBodyControl control = treeInstance.getControl(RigidBodyControl.class); //RigidBodyControl control = treeInstance.getControl(RigidBodyControl.class);
RigidBodyControl control = new RigidBodyControl(new ConeCollisionShape(1f, 5f), 0f); RigidBodyControl control = new RigidBodyControl(new ConeCollisionShape(1f, 5f), 0f);
if (control != null) { if (control != null) {
treeInstance.addControl(control); modelInstance.addControl(control);
control.setPhysicsLocation(location); control.setPhysicsLocation(pos);
physicsSpace.add(control); physicsSpace.add(control);
} }
objects.attachChild(treeInstance); objects.attachChild(modelInstance);
} }
//objects.setLocalTranslation(terrainGrid.getWorldTranslation());
} }
@Override @Override

View File

@ -213,7 +213,6 @@ public class VehicleNode extends Node
vehicle.attachChild(vehicle.wheelSlipAudio); vehicle.attachChild(vehicle.wheelSlipAudio);
vehicle.addControl(vehicleControl); vehicle.addControl(vehicleControl);
vehicleControl.setPhysicsLocation(new Vector3f(10f + (float)Math.random() * 40f, 28f, 12f + (float)Math.random() * 40f));
} }
public void update(float tpf) public void update(float tpf)