• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2010 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17  *   may be used to endorse or promote products derived from this software
18  *   without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 package jme3test.games;
34 
35 import com.jme3.app.SimpleApplication;
36 import com.jme3.bounding.BoundingVolume;
37 import com.jme3.font.BitmapFont;
38 import com.jme3.font.BitmapText;
39 import com.jme3.input.KeyInput;
40 import com.jme3.input.controls.AnalogListener;
41 import com.jme3.input.controls.KeyTrigger;
42 import com.jme3.material.Material;
43 import com.jme3.math.ColorRGBA;
44 import com.jme3.math.FastMath;
45 import com.jme3.math.Quaternion;
46 import com.jme3.math.Vector3f;
47 import com.jme3.scene.Geometry;
48 import com.jme3.scene.Node;
49 import com.jme3.scene.Spatial.CullHint;
50 import com.jme3.scene.shape.Box;
51 import com.jme3.scene.shape.Dome;
52 import java.util.ArrayList;
53 import java.util.logging.Level;
54 import java.util.logging.Logger;
55 
56 /**
57  * @author Kyle "bonechilla" Williams
58  */
59 public class CubeField extends SimpleApplication implements AnalogListener {
60 
main(String[] args)61     public static void main(String[] args) {
62         CubeField app = new CubeField();
63         app.start();
64     }
65 
66     private BitmapFont defaultFont;
67 
68     private boolean START;
69     private int difficulty, Score, colorInt, highCap, lowCap,diffHelp;
70     private Node player;
71     private Geometry fcube;
72     private ArrayList<Geometry> cubeField;
73     private ArrayList<ColorRGBA> obstacleColors;
74     private float speed, coreTime,coreTime2;
75     private float camAngle = 0;
76     private BitmapText fpsScoreText, pressStart;
77 
78     private boolean solidBox = true;
79     private Material playerMaterial;
80     private Material floorMaterial;
81 
82     private float fpsRate = 1000f / 1f;
83 
84     /**
85      * Initializes game
86      */
87     @Override
simpleInitApp()88     public void simpleInitApp() {
89         Logger.getLogger("com.jme3").setLevel(Level.WARNING);
90 
91         flyCam.setEnabled(false);
92         setDisplayStatView(false);
93 
94         Keys();
95 
96         defaultFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
97         pressStart = new BitmapText(defaultFont, false);
98         fpsScoreText = new BitmapText(defaultFont, false);
99 
100         loadText(fpsScoreText, "Current Score: 0", defaultFont, 0, 2, 0);
101         loadText(pressStart, "PRESS ENTER", defaultFont, 0, 5, 0);
102 
103         player = createPlayer();
104         rootNode.attachChild(player);
105         cubeField = new ArrayList<Geometry>();
106         obstacleColors = new ArrayList<ColorRGBA>();
107 
108         gameReset();
109     }
110     /**
111      * Used to reset cubeField
112      */
gameReset()113     private void gameReset(){
114         Score = 0;
115         lowCap = 10;
116         colorInt = 0;
117         highCap = 40;
118         difficulty = highCap;
119 
120         for (Geometry cube : cubeField){
121             cube.removeFromParent();
122         }
123         cubeField.clear();
124 
125         if (fcube != null){
126             fcube.removeFromParent();
127         }
128         fcube = createFirstCube();
129 
130         obstacleColors.clear();
131         obstacleColors.add(ColorRGBA.Orange);
132         obstacleColors.add(ColorRGBA.Red);
133         obstacleColors.add(ColorRGBA.Yellow);
134         renderer.setBackgroundColor(ColorRGBA.White);
135         speed = lowCap / 400f;
136         coreTime = 20.0f;
137         coreTime2 = 10.0f;
138         diffHelp=lowCap;
139         player.setLocalTranslation(0,0,0);
140     }
141 
142     @Override
simpleUpdate(float tpf)143     public void simpleUpdate(float tpf) {
144         camTakeOver(tpf);
145         if (START){
146             gameLogic(tpf);
147         }
148         colorLogic();
149     }
150     /**
151      * Forcefully takes over Camera adding functionality and placing it behind the character
152      * @param tpf Tickes Per Frame
153      */
camTakeOver(float tpf)154     private void camTakeOver(float tpf) {
155         cam.setLocation(player.getLocalTranslation().add(-8, 2, 0));
156         cam.lookAt(player.getLocalTranslation(), Vector3f.UNIT_Y);
157 
158         Quaternion rot = new Quaternion();
159         rot.fromAngleNormalAxis(camAngle, Vector3f.UNIT_Z);
160         cam.setRotation(cam.getRotation().mult(rot));
161         camAngle *= FastMath.pow(.99f, fpsRate * tpf);
162     }
163 
164     @Override
requestClose(boolean esc)165     public void requestClose(boolean esc) {
166         if (!esc){
167             System.out.println("The game was quit.");
168         }else{
169             System.out.println("Player has Collided. Final Score is " + Score);
170         }
171         context.destroy(false);
172     }
173     /**
174      * Randomly Places a cube on the map between 30 and 90 paces away from player
175      */
randomizeCube()176     private void randomizeCube() {
177         Geometry cube = fcube.clone();
178         int playerX = (int) player.getLocalTranslation().getX();
179         int playerZ = (int) player.getLocalTranslation().getZ();
180 //        float x = FastMath.nextRandomInt(playerX + difficulty + 10, playerX + difficulty + 150);
181         float x = FastMath.nextRandomInt(playerX + difficulty + 30, playerX + difficulty + 90);
182         float z = FastMath.nextRandomInt(playerZ - difficulty - 50, playerZ + difficulty + 50);
183         cube.getLocalTranslation().set(x, 0, z);
184 
185 //        playerX+difficulty+30,playerX+difficulty+90
186 
187         Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
188         if (!solidBox){
189             mat.getAdditionalRenderState().setWireframe(true);
190         }
191         mat.setColor("Color", obstacleColors.get(FastMath.nextRandomInt(0, obstacleColors.size() - 1)));
192         cube.setMaterial(mat);
193 
194         rootNode.attachChild(cube);
195         cubeField.add(cube);
196     }
197 
createFirstCube()198     private Geometry createFirstCube() {
199         Vector3f loc = player.getLocalTranslation();
200         loc.addLocal(4, 0, 0);
201         Box b = new Box(loc, 1, 1, 1);
202 
203         Geometry geom = new Geometry("Box", b);
204         Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
205         mat.setColor("Color", ColorRGBA.Blue);
206         geom.setMaterial(mat);
207 
208         return geom;
209     }
210 
createPlayer()211     private Node createPlayer() {
212         Dome b = new Dome(Vector3f.ZERO, 10, 100, 1);
213         Geometry playerMesh = new Geometry("Box", b);
214 
215         playerMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
216         playerMaterial.setColor("Color", ColorRGBA.Red);
217         playerMesh.setMaterial(playerMaterial);
218         playerMesh.setName("player");
219 
220         Box floor = new Box(Vector3f.ZERO.add(playerMesh.getLocalTranslation().getX(),
221                 playerMesh.getLocalTranslation().getY() - 1, 0), 100, 0, 100);
222         Geometry floorMesh = new Geometry("Box", floor);
223 
224         floorMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
225         floorMaterial.setColor("Color", ColorRGBA.LightGray);
226         floorMesh.setMaterial(floorMaterial);
227         floorMesh.setName("floor");
228 
229         Node playerNode = new Node();
230         playerNode.attachChild(playerMesh);
231         playerNode.attachChild(floorMesh);
232 
233         return playerNode;
234     }
235 
236     /**
237      * If Game is Lost display Score and Reset the Game
238      */
gameLost()239     private void gameLost(){
240         START = false;
241         loadText(pressStart, "You lost! Press enter to try again.", defaultFont, 0, 5, 0);
242         gameReset();
243     }
244 
245     /**
246      * Core Game Logic
247      */
gameLogic(float tpf)248     private void gameLogic(float tpf){
249     	//Subtract difficulty level in accordance to speed every 10 seconds
250     	if(timer.getTimeInSeconds()>=coreTime2){
251 			coreTime2=timer.getTimeInSeconds()+10;
252 			if(difficulty<=lowCap){
253 				difficulty=lowCap;
254 			}
255 			else if(difficulty>lowCap){
256 				difficulty-=5;
257 				diffHelp+=1;
258 			}
259 		}
260 
261         if(speed<.1f){
262             speed+=.000001f*tpf*fpsRate;
263         }
264 
265         player.move(speed * tpf * fpsRate, 0, 0);
266         if (cubeField.size() > difficulty){
267             cubeField.remove(0);
268         }else if (cubeField.size() != difficulty){
269             randomizeCube();
270         }
271 
272         if (cubeField.isEmpty()){
273             requestClose(false);
274         }else{
275             for (int i = 0; i < cubeField.size(); i++){
276 
277             	//better way to check collision
278                 Geometry playerModel = (Geometry) player.getChild(0);
279                 Geometry cubeModel = cubeField.get(i);
280                 cubeModel.updateGeometricState();
281 
282                 BoundingVolume pVol = playerModel.getWorldBound();
283                 BoundingVolume vVol = cubeModel.getWorldBound();
284 
285                 if (pVol.intersects(vVol)){
286                     gameLost();
287                     return;
288                 }
289                 //Remove cube if 10 world units behind player
290                 if (cubeField.get(i).getLocalTranslation().getX() + 10 < player.getLocalTranslation().getX()){
291                     cubeField.get(i).removeFromParent();
292                     cubeField.remove(cubeField.get(i));
293                 }
294 
295             }
296         }
297 
298         Score += fpsRate * tpf;
299         fpsScoreText.setText("Current Score: "+Score);
300     }
301     /**
302      * Sets up the keyboard bindings
303      */
Keys()304     private void Keys() {
305         inputManager.addMapping("START", new KeyTrigger(KeyInput.KEY_RETURN));
306         inputManager.addMapping("Left",  new KeyTrigger(KeyInput.KEY_LEFT));
307         inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_RIGHT));
308         inputManager.addListener(this, "START", "Left", "Right");
309     }
310 
onAnalog(String binding, float value, float tpf)311     public void onAnalog(String binding, float value, float tpf) {
312         if (binding.equals("START") && !START){
313             START = true;
314             guiNode.detachChild(pressStart);
315             System.out.println("START");
316         }else if (START == true && binding.equals("Left")){
317             player.move(0, 0, -(speed / 2f) * value * fpsRate);
318             camAngle -= value*tpf;
319         }else if (START == true && binding.equals("Right")){
320             player.move(0, 0, (speed / 2f) * value * fpsRate);
321             camAngle += value*tpf;
322         }
323     }
324 
325     /**
326      * Determines the colors of the player, floor, obstacle and background
327      */
colorLogic()328     private void colorLogic() {
329     	if (timer.getTimeInSeconds() >= coreTime){
330 
331         	colorInt++;
332             coreTime = timer.getTimeInSeconds() + 20;
333 
334 
335 	        switch (colorInt){
336 	            case 1:
337 	                obstacleColors.clear();
338 	                solidBox = false;
339 	                obstacleColors.add(ColorRGBA.Green);
340 	                renderer.setBackgroundColor(ColorRGBA.Black);
341 	                playerMaterial.setColor("Color", ColorRGBA.White);
342 			floorMaterial.setColor("Color", ColorRGBA.Black);
343 	                break;
344 	            case 2:
345 	                obstacleColors.set(0, ColorRGBA.Black);
346 	                solidBox = true;
347 	                renderer.setBackgroundColor(ColorRGBA.White);
348 	                playerMaterial.setColor("Color", ColorRGBA.Gray);
349                         floorMaterial.setColor("Color", ColorRGBA.LightGray);
350 	                break;
351 	            case 3:
352 	                obstacleColors.set(0, ColorRGBA.Pink);
353 	                break;
354 	            case 4:
355 	                obstacleColors.set(0, ColorRGBA.Cyan);
356 	                obstacleColors.add(ColorRGBA.Magenta);
357 	                renderer.setBackgroundColor(ColorRGBA.Gray);
358                         floorMaterial.setColor("Color", ColorRGBA.Gray);
359 	                playerMaterial.setColor("Color", ColorRGBA.White);
360 	                break;
361 	            case 5:
362 	                obstacleColors.remove(0);
363 	                renderer.setBackgroundColor(ColorRGBA.Pink);
364 	                solidBox = false;
365 	                playerMaterial.setColor("Color", ColorRGBA.White);
366 	                break;
367 	            case 6:
368 	                obstacleColors.set(0, ColorRGBA.White);
369 	                solidBox = true;
370 	                renderer.setBackgroundColor(ColorRGBA.Black);
371 	                playerMaterial.setColor("Color", ColorRGBA.Gray);
372                         floorMaterial.setColor("Color", ColorRGBA.LightGray);
373 	                break;
374 	            case 7:
375 	                obstacleColors.set(0, ColorRGBA.Green);
376 	                renderer.setBackgroundColor(ColorRGBA.Gray);
377 	                playerMaterial.setColor("Color", ColorRGBA.Black);
378                         floorMaterial.setColor("Color", ColorRGBA.Orange);
379 	                break;
380 	            case 8:
381 	                obstacleColors.set(0, ColorRGBA.Red);
382                         floorMaterial.setColor("Color", ColorRGBA.Pink);
383 	                break;
384 	            case 9:
385 	                obstacleColors.set(0, ColorRGBA.Orange);
386 	                obstacleColors.add(ColorRGBA.Red);
387 	                obstacleColors.add(ColorRGBA.Yellow);
388 	                renderer.setBackgroundColor(ColorRGBA.White);
389 	                playerMaterial.setColor("Color", ColorRGBA.Red);
390 	                floorMaterial.setColor("Color", ColorRGBA.Gray);
391 	                colorInt=0;
392 	                break;
393 	            default:
394 	                break;
395 	        }
396         }
397     }
398     /**
399      * Sets up a BitmapText to be displayed
400      * @param txt the Bitmap Text
401      * @param text the
402      * @param font the font of the text
403      * @param x
404      * @param y
405      * @param z
406      */
loadText(BitmapText txt, String text, BitmapFont font, float x, float y, float z)407     private void loadText(BitmapText txt, String text, BitmapFont font, float x, float y, float z) {
408         txt.setSize(font.getCharSet().getRenderedSize());
409         txt.setLocalTranslation(txt.getLineWidth() * x, txt.getLineHeight() * y, z);
410         txt.setText(text);
411         guiNode.attachChild(txt);
412     }
413 }