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.input.combomoves; 34 35 import com.jme3.app.SimpleApplication; 36 import com.jme3.font.BitmapText; 37 import com.jme3.input.KeyInput; 38 import com.jme3.input.controls.ActionListener; 39 import com.jme3.input.controls.KeyTrigger; 40 import com.jme3.math.ColorRGBA; 41 import com.jme3.scene.Spatial.CullHint; 42 import java.util.ArrayList; 43 import java.util.HashSet; 44 import java.util.List; 45 46 public class TestComboMoves extends SimpleApplication implements ActionListener { 47 48 private HashSet<String> pressedMappings = new HashSet<String>(); 49 50 private ComboMove fireball; 51 private ComboMoveExecution fireballExec; 52 private BitmapText fireballText; 53 54 private ComboMove shuriken; 55 private ComboMoveExecution shurikenExec; 56 private BitmapText shurikenText; 57 58 private ComboMove jab; 59 private ComboMoveExecution jabExec; 60 private BitmapText jabText; 61 62 private ComboMove punch; 63 private ComboMoveExecution punchExec; 64 private BitmapText punchText; 65 66 private ComboMove currentMove = null; 67 private float currentMoveCastTime = 0; 68 private float time = 0; 69 70 public static void main(String[] args){ 71 TestComboMoves app = new TestComboMoves(); 72 app.start(); 73 } 74 75 @Override 76 public void simpleInitApp() { 77 setDisplayFps(false); 78 setDisplayStatView(false); 79 80 // Create debug text 81 BitmapText helpText = new BitmapText(guiFont); 82 helpText.setLocalTranslation(0, settings.getHeight(), 0); 83 helpText.setText("Moves:\n" + 84 "Fireball: Down, Down+Right, Right\n"+ 85 "Shuriken: Left, Down, Attack1(Z)\n"+ 86 "Jab: Attack1(Z)\n"+ 87 "Punch: Attack1(Z), Attack1(Z)\n"); 88 guiNode.attachChild(helpText); 89 90 fireballText = new BitmapText(guiFont); 91 fireballText.setColor(ColorRGBA.Orange); 92 fireballText.setLocalTranslation(0, fireballText.getLineHeight(), 0); 93 guiNode.attachChild(fireballText); 94 95 shurikenText = new BitmapText(guiFont); 96 shurikenText.setColor(ColorRGBA.Cyan); 97 shurikenText.setLocalTranslation(0, shurikenText.getLineHeight()*2f, 0); 98 guiNode.attachChild(shurikenText); 99 100 jabText = new BitmapText(guiFont); 101 jabText.setColor(ColorRGBA.Red); 102 jabText.setLocalTranslation(0, jabText.getLineHeight()*3f, 0); 103 guiNode.attachChild(jabText); 104 105 punchText = new BitmapText(guiFont); 106 punchText.setColor(ColorRGBA.Green); 107 punchText.setLocalTranslation(0, punchText.getLineHeight()*4f, 0); 108 guiNode.attachChild(punchText); 109 110 inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_LEFT)); 111 inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_RIGHT)); 112 inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_UP)); 113 inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_DOWN)); 114 inputManager.addMapping("Attack1", new KeyTrigger(KeyInput.KEY_Z)); 115 inputManager.addListener(this, "Left", "Right", "Up", "Down", "Attack1"); 116 117 fireball = new ComboMove("Fireball"); 118 fireball.press("Down").notPress("Right").done(); 119 fireball.press("Right", "Down").done(); 120 fireball.press("Right").notPress("Down").done(); 121 fireball.notPress("Right", "Down").done(); 122 fireball.setUseFinalState(false); // no waiting on final state 123 124 shuriken = new ComboMove("Shuriken"); 125 shuriken.press("Left").notPress("Down", "Attack1").done(); 126 shuriken.press("Down").notPress("Attack1").timeElapsed(0.11f).done(); 127 shuriken.press("Attack1").notPress("Left").timeElapsed(0.11f).done(); 128 shuriken.notPress("Left", "Down", "Attack1").done(); 129 130 jab = new ComboMove("Jab"); 131 jab.setPriority(0.5f); // make jab less important than other moves 132 jab.press("Attack1").done(); 133 134 punch = new ComboMove("Punch"); 135 punch.press("Attack1").done(); 136 punch.notPress("Attack1").done(); 137 punch.press("Attack1").done(); 138 139 fireballExec = new ComboMoveExecution(fireball); 140 shurikenExec = new ComboMoveExecution(shuriken); 141 jabExec = new ComboMoveExecution(jab); 142 punchExec = new ComboMoveExecution(punch); 143 } 144 145 @Override 146 public void simpleUpdate(float tpf){ 147 time += tpf; 148 149 // check every frame if any executions are expired 150 shurikenExec.updateExpiration(time); 151 shurikenText.setText("Shuriken Exec: " + shurikenExec.getDebugString()); 152 153 fireballExec.updateExpiration(time); 154 fireballText.setText("Fireball Exec: " + fireballExec.getDebugString()); 155 156 jabExec.updateExpiration(time); 157 jabText.setText("Jab Exec: " + jabExec.getDebugString()); 158 159 punchExec.updateExpiration(time); 160 punchText.setText("Punch Exec: " + punchExec.getDebugString()); 161 162 if (currentMove != null){ 163 currentMoveCastTime -= tpf; 164 if (currentMoveCastTime <= 0){ 165 System.out.println("DONE CASTING " + currentMove.getMoveName()); 166 currentMoveCastTime = 0; 167 currentMove = null; 168 } 169 } 170 } 171 172 public void onAction(String name, boolean isPressed, float tpf) { 173 if (isPressed){ 174 pressedMappings.add(name); 175 }else{ 176 pressedMappings.remove(name); 177 } 178 179 // the pressed mappings was changed. update combo executions 180 List<ComboMove> invokedMoves = new ArrayList<ComboMove>(); 181 if (shurikenExec.updateState(pressedMappings, time)){ 182 invokedMoves.add(shuriken); 183 } 184 185 if (fireballExec.updateState(pressedMappings, time)){ 186 invokedMoves.add(fireball); 187 } 188 189 if (jabExec.updateState(pressedMappings, time)){ 190 invokedMoves.add(jab); 191 } 192 193 if (punchExec.updateState(pressedMappings, time)){ 194 invokedMoves.add(punch); 195 } 196 197 if (invokedMoves.size() > 0){ 198 // choose move with highest priority 199 float priority = 0; 200 ComboMove toExec = null; 201 for (ComboMove move : invokedMoves){ 202 if (move.getPriority() > priority){ 203 priority = move.getPriority(); 204 toExec = move; 205 } 206 } 207 if (currentMove != null && currentMove.getPriority() > toExec.getPriority()){ 208 return; 209 } 210 211 currentMove = toExec; 212 currentMoveCastTime = currentMove.getCastTime(); 213 //System.out.println("CASTING " + currentMove.getMoveName()); 214 } 215 } 216 217 } 218