Home | History | Annotate | Download | only in games
      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 
     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
     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      */
    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
    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      */
    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
    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      */
    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 
    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 
    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      */
    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      */
    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      */
    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 
    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      */
    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      */
    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 }