@@ -23,26 +23,30 @@ A game about a journey involving vehicles and obstacles. | |||||
* Car engine | * Car engine | ||||
* Wheel rolling | * Wheel rolling | ||||
* Wheel slips | * Wheel slips | ||||
* Camera | |||||
* Graphics | |||||
* themeless | |||||
* 3rd person view (following the player) | * 3rd person view (following the player) | ||||
* depth-of-field filter | |||||
* distance-based hiding of objects | |||||
* Input | * Input | ||||
* Keyboard | * Keyboard | ||||
* Game menu | * Game menu | ||||
### TODO | ### TODO | ||||
#### Stage 0 :: Prototype | #### Stage 0 :: Prototype | ||||
* done | |||||
* DONE | |||||
#### Stage 1 :: Core Game | #### Stage 1 :: Core Game | ||||
* Joystick controls | * Joystick controls | ||||
* FPV camera | * FPV camera | ||||
* Main Menu | * Main Menu | ||||
* Winning condition (location) | * Winning condition (location) | ||||
* Loading screen | |||||
* Health indicator | * Health indicator | ||||
* Persistent content on terrain blocks | |||||
* NPC AI | * NPC AI | ||||
* Enemy objects - mines | |||||
* Enemy NPCs - punching, shooting | * Enemy NPCs - punching, shooting | ||||
* Interacting with the environment | |||||
* Interacting with the environment - opening of gates | |||||
#### Stage 2 :: Filled Game | #### Stage 2 :: Filled Game | ||||
* Roadblocks | * Roadblocks | ||||
@@ -50,8 +54,11 @@ A game about a journey involving vehicles and obstacles. | |||||
* Car models | * Car models | ||||
* Scenery models | * Scenery models | ||||
* Intro, Outro | * Intro, Outro | ||||
* Dialogs | |||||
* Fuel | |||||
#### Stage 3 :: Overflowing Game | #### Stage 3 :: Overflowing Game | ||||
* Stealth | * Stealth | ||||
* Clothing | * Clothing | ||||
* Car customization | * Car customization | ||||
* Destructable environment |
@@ -44,13 +44,35 @@ public class ProceduralMapQuadBlock extends AbstractProceduralBlock | |||||
float height = terrainQuad.getHeight(pos); | float height = terrainQuad.getHeight(pos); | ||||
String type; | String type; | ||||
if (quadRand.nextInt(10) == 0) { | if (quadRand.nextInt(10) == 0) { | ||||
type = "house"; | |||||
type = "rock"; | |||||
} else { | } else { | ||||
type = "tree"; | type = "tree"; | ||||
} | } | ||||
Vector3f location = new Vector3f(pos.x, height, pos.y); | Vector3f location = new Vector3f(pos.x, height, pos.y); | ||||
mapObjects.add(new MapObjectInstance(type, location)); | mapObjects.add(new MapObjectInstance(type, location)); | ||||
} | } | ||||
// walls | |||||
if (quadRand.nextInt(3) == 0) { | |||||
int dir = quadRand.nextInt(4); | |||||
for (int i = 0; i < quadRand.nextInt(terrainQuad.getPatchSize() * (10 + quadRand.nextInt(100))); i++) { | |||||
Vector2f pos; | |||||
if (prevPos == null || quadRand.nextFloat() < 0.1f) { | |||||
pos = new Vector2f((quadRand.nextFloat() - 0.5f) * cellSize, (quadRand.nextFloat() - 0.5f) * cellSize) | |||||
.addLocal(quadPos); | |||||
} else { | |||||
if (quadRand.nextInt(10) == 0) { | |||||
dir = (dir + quadRand.nextInt(2) * 2 - 1) % 4; | |||||
} | |||||
pos = new Vector2f(dir == 1 ? 1 : (dir == 3 ? -1 : 0), dir == 0 ? 1 : (dir == 2 ? -1 : 0)).addLocal(prevPos); | |||||
} | |||||
prevPos = pos; | |||||
float height = terrainQuad.getHeight(pos); | |||||
String type = "wall"; | |||||
Vector3f location = new Vector3f(pos.x, height, pos.y); | |||||
mapObjects.add(new MapObjectInstance(type, location)); | |||||
} | |||||
} | |||||
} | } | ||||
public Iterable<? extends MapObjectInstance> getMapObjects() | public Iterable<? extends MapObjectInstance> getMapObjects() | ||||
@@ -182,6 +182,7 @@ public class GameWorldView { | |||||
terrain.terrainGrid.addControl(lodControl); | terrain.terrainGrid.addControl(lodControl); | ||||
final Node treeModel = createTree(); | final Node treeModel = createTree(); | ||||
final Node blockModel = createBlock(); | |||||
final Node rockModel = createRock(); | final Node rockModel = createRock(); | ||||
final FineTerrainGrid terrainGrid = terrain.terrainGrid; | final FineTerrainGrid terrainGrid = terrain.terrainGrid; | ||||
@@ -238,12 +239,19 @@ public class GameWorldView { | |||||
boxHalf = new Vector3f(s * 0.2f, s * 3f, s * 0.2f); | boxHalf = new Vector3f(s * 0.2f, s * 3f, s * 0.2f); | ||||
modelPhysics = new RigidBodyControl(new BoxCollisionShape(boxHalf), 0f); | modelPhysics = new RigidBodyControl(new BoxCollisionShape(boxHalf), 0f); | ||||
break; | break; | ||||
/*case "house": | |||||
modelInstance = houseModel.clone(); | |||||
boxHalf = new Vector3f(2f + rand.nextFloat() * 10f, 2f + rand.nextFloat() * 10f, 2f + rand.nextFloat() * 10f); | |||||
scale = boxHalf; | |||||
case "rock": | |||||
modelInstance = blockModel.clone(); | |||||
boxHalf = new Vector3f(0.5f, 0.5f, 0.5f); | |||||
pos.y += 0.2f; | |||||
modelPhysics = new RigidBodyControl(new BoxCollisionShape(boxHalf), 0f); | modelPhysics = new RigidBodyControl(new BoxCollisionShape(boxHalf), 0f); | ||||
break;*/ | |||||
break; | |||||
case "wall": | |||||
modelInstance = blockModel.clone(); | |||||
scale = new Vector3f(1f, 2f, 1f); | |||||
boxHalf = new Vector3f(0.5f, 1f, 0.5f); | |||||
pos.y += 0.5f; | |||||
modelPhysics = new RigidBodyControl(new BoxCollisionShape(boxHalf), 0f); | |||||
break; | |||||
default: | default: | ||||
throw new RuntimeException("Unhandled object type: " + mapObject.getType()); | throw new RuntimeException("Unhandled object type: " + mapObject.getType()); | ||||
} | } | ||||
@@ -362,5 +370,19 @@ public class GameWorldView { | |||||
return rockModel; | return rockModel; | ||||
} | } | ||||
private Node createBlock() { | |||||
Material rockMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); | |||||
rockMat.setColor("Color", ColorRGBA.Gray); | |||||
rockMat.getAdditionalRenderState().setWireframe(true); | |||||
Geometry rockGeom = new Geometry("rock", new Box(0.5f, 0.5f, 0.5f)); | |||||
rockGeom.setMaterial(rockMat); | |||||
Node rockModel = new Node("rockNode"); | |||||
rockModel.attachChild(rockGeom); | |||||
return rockModel; | |||||
} | |||||
} | } |