/examples/advanced/physics/scenes/AirHockeyScene.java
Java | 587 lines | 418 code | 75 blank | 94 comment | 57 complexity | a4c6b45d0c977b1c66ae38279d713d55 MD5 | raw file
1package advanced.physics.scenes; 2 3import java.awt.event.KeyEvent; 4 5import org.jbox2d.collision.AABB; 6import org.jbox2d.collision.shapes.CircleDef; 7import org.jbox2d.collision.shapes.PolygonDef; 8import org.jbox2d.collision.shapes.Shape; 9import org.jbox2d.common.Vec2; 10import org.jbox2d.dynamics.Body; 11import org.jbox2d.dynamics.BodyDef; 12import org.jbox2d.dynamics.ContactListener; 13import org.jbox2d.dynamics.World; 14import org.jbox2d.dynamics.contacts.ContactPoint; 15import org.jbox2d.dynamics.contacts.ContactResult; 16import org.jbox2d.dynamics.joints.Joint; 17import org.jbox2d.dynamics.joints.JointType; 18import org.jbox2d.dynamics.joints.MouseJoint; 19import org.mt4j.MTApplication; 20import org.mt4j.components.MTComponent; 21import org.mt4j.components.visibleComponents.font.FontManager; 22import org.mt4j.components.visibleComponents.font.IFont; 23import org.mt4j.components.visibleComponents.shapes.MTEllipse; 24import org.mt4j.components.visibleComponents.shapes.MTLine; 25import org.mt4j.components.visibleComponents.shapes.MTRectangle; 26import org.mt4j.components.visibleComponents.widgets.MTTextArea; 27import org.mt4j.input.inputProcessors.IGestureEventListener; 28import org.mt4j.input.inputProcessors.MTGestureEvent; 29import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragEvent; 30import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragProcessor; 31import org.mt4j.input.inputProcessors.globalProcessors.CursorTracer; 32import org.mt4j.sceneManagement.AbstractScene; 33import org.mt4j.util.MTColor; 34import org.mt4j.util.camera.MTCamera; 35import org.mt4j.util.math.ToolsMath; 36import org.mt4j.util.math.Vector3D; 37 38import processing.core.PApplet; 39import processing.core.PImage; 40import advanced.physics.physicsShapes.IPhysicsComponent; 41import advanced.physics.physicsShapes.PhysicsCircle; 42import advanced.physics.physicsShapes.PhysicsRectangle; 43import advanced.physics.util.PhysicsHelper; 44import advanced.physics.util.UpdatePhysicsAction; 45 46public class AirHockeyScene extends AbstractScene { 47 private float timeStep = 1.0f / 60.0f; 48 private int constraintIterations = 10; 49 50 /** THE CANVAS SCALE **/ 51 private float scale = 20; 52 private MTApplication app; 53 private World world; 54 55 private MTComponent physicsContainer; 56 private MTTextArea t1; 57 private MTTextArea t2; 58 59 private int scorePlayer1; 60 private int scorePlayer2; 61 private HockeyBall ball; 62 /* 63 private Minim minim; 64 private AudioSnippet wallHit; 65 private AudioSample paddleBallClash; 66 private AudioSnippet goalHit; 67 private AudioSnippet paddleHit; 68 */ 69 private Paddle redCircle; 70 private Paddle blueCircle; 71 72 private boolean enableSound = true; 73 74 75 //TODO sometimes goal not recognized when shot at fast 76 //TODO after goal reset puck and make 3 second countdown -> dont use physics until countdown up! 77 //TODO get graphics, sounds, effects 78 79// private String imagesPath = System.getProperty("user.dir") + File.separator + "examples" + File.separator +"advanced"+ File.separator + "physics" + File.separator + "data" + File.separator + "images" + File.separator; 80 private String imagesPath = "advanced" + MTApplication.separator + "physics" + MTApplication.separator + "data" + MTApplication.separator + "images" + MTApplication.separator; 81 82 83 public AirHockeyScene(MTApplication mtApplication, String name) { 84 super(mtApplication, name); 85 this.app = mtApplication; 86// this.setClearColor(new MTColor(120,150,150)); 87// this.setClearColor(new MTColor(190, 190, 170, 255)); 88 this.setClearColor(new MTColor(0, 0, 0, 255)); 89// this.setClearColor(new MTColor(40, 40, 40, 255)); 90 this.registerGlobalInputProcessor(new CursorTracer(app, this)); 91 92 this.scorePlayer1 = 0; 93 this.scorePlayer2 = 0; 94 95 float worldOffset = 10; //Make Physics world slightly bigger than screen borders 96 //Physics world dimensions 97 AABB worldAABB = new AABB(new Vec2(-worldOffset, -worldOffset), new Vec2((app.width)/scale + worldOffset, (app.height)/scale + worldOffset)); 98 Vec2 gravity = new Vec2(0, 0); 99 boolean sleep = true; 100 //Create the pyhsics world 101 this.world = new World(worldAABB, gravity, sleep); 102 103 //Update the positions of the components according the the physics simulation each frame 104 this.registerPreDrawAction(new UpdatePhysicsAction(world, timeStep, constraintIterations, scale)); 105 106 physicsContainer = new MTComponent(app); 107 //Scale the physics container. Physics calculations work best when the dimensions are small (about 0.1 - 10 units) 108 //So we make the display of the container bigger and add in turn make our physics object smaller 109 physicsContainer.scale(scale, scale, 1, Vector3D.ZERO_VECTOR); 110 this.getCanvas().addChild(physicsContainer); 111 112 //Create borders around the screen 113 this.createScreenBorders(physicsContainer); 114 115 //Create gamefield marks 116 MTLine line = new MTLine(mtApplication, mtApplication.width/2f/scale, 0, mtApplication.width/2f/scale, mtApplication.height/scale); 117 line.setPickable(false); 118// line.setStrokeColor(new MTColor(0,0,0)); 119 line.setStrokeColor(new MTColor(150,150,150)); 120 line.setStrokeWeight(0.5f); 121 physicsContainer.addChild(line); 122 123 MTEllipse centerCircle = new MTEllipse(mtApplication, new Vector3D(mtApplication.width/2f/scale, mtApplication.height/2f/scale), 80/scale, 80/scale); 124 centerCircle.setPickable(false); 125 centerCircle.setNoFill(true); 126// centerCircle.setStrokeColor(new MTColor(0,0,0)); 127 centerCircle.setStrokeColor(new MTColor(150,150,150)); 128 centerCircle.setStrokeWeight(0.5f); 129 physicsContainer.addChild(centerCircle); 130 131 MTEllipse centerCircleInner = new MTEllipse(mtApplication, new Vector3D(mtApplication.width/2f/scale, mtApplication.height/2f/scale), 10/scale, 10/scale); 132 centerCircleInner.setPickable(false); 133 centerCircleInner.setFillColor(new MTColor(160,160,160)); 134// centerCircleInner.setStrokeColor(new MTColor(150,150,150)); 135// centerCircleInner.setStrokeColor(new MTColor(0,0,0)); 136 centerCircleInner.setStrokeColor(new MTColor(150,150,150)); 137 centerCircleInner.setStrokeWeight(0.5f); 138 physicsContainer.addChild(centerCircleInner); 139 140 //Create the paddles 141 PImage paddleTex = mtApplication.loadImage(imagesPath + "paddle.png"); 142 redCircle = new Paddle(app, new Vector3D(mtApplication.width - 60, mtApplication.height/2f), 50, world, 1.0f, 0.3f, 0.4f, scale); 143 redCircle.setTexture(paddleTex); 144 redCircle.setFillColor(new MTColor(255,50,50)); 145 redCircle.setNoStroke(true); 146 redCircle.setName("red"); 147 redCircle.setPickable(false); 148 physicsContainer.addChild(redCircle); 149 150 blueCircle = new Paddle(app, new Vector3D(80, mtApplication.height/2f), 50, world, 1.0f, 0.3f, 0.4f, scale); 151 blueCircle.setTexture(paddleTex); 152 blueCircle.setFillColor(new MTColor(50,50,255)); 153 blueCircle.setNoStroke(true); 154 blueCircle.setName("blue"); 155 blueCircle.setPickable(false); 156 physicsContainer.addChild(blueCircle); 157 158 //Create the ball 159 ball = new HockeyBall(app, new Vector3D(mtApplication.width/2f, mtApplication.height/2f), 38, world, 0.5f, 0.005f, 0.70f, scale); 160// MTColor ballCol = new MTColor(0,255,0); 161// ball.setFillColor(ballCol); 162 PImage ballTex = mtApplication.loadImage(imagesPath + "puk.png"); 163 ball.setTexture(ballTex); 164// ball.setFillColor(new MTColor(160,160,160,255)); 165 ball.setFillColor(new MTColor(255,255,255,255)); 166 ball.setNoStroke(true); 167 ball.setName("ball"); 168 physicsContainer.addChild(ball); 169 ball.getBody().applyImpulse(new Vec2(ToolsMath.getRandom(-8f, 8),ToolsMath.getRandom(-8, 8)), ball.getBody().getWorldCenter()); 170 171 //Create the GOALS 172 HockeyGoal goal1 = new HockeyGoal(new Vector3D(0, mtApplication.height/2f), 50, mtApplication.height/4f, mtApplication, world, 0.0f, 0.1f, 0.0f, scale); 173 goal1.setName("goal1"); 174 goal1.setFillColor(new MTColor(0,0,255)); 175 goal1.setStrokeColor(new MTColor(0,0,255)); 176 physicsContainer.addChild(goal1); 177 178 HockeyGoal goal2 = new HockeyGoal(new Vector3D(mtApplication.width, mtApplication.height/2f), 50, mtApplication.height/4f, mtApplication, world, 0.0f, 0.1f, 0.0f, scale); 179 goal2.setName("goal2"); 180 goal2.setFillColor(new MTColor(255,0,0)); 181 goal2.setStrokeColor(new MTColor(255,0,0)); 182 physicsContainer.addChild(goal2); 183 184 //Make two components for both game field sides to drag the puks upon 185 MTRectangle leftSide = new MTRectangle( 186 app, PhysicsHelper.scaleDown(0, scale), 187 PhysicsHelper.scaleDown(0, scale), PhysicsHelper.scaleDown(app.width/2f, scale) 188 , PhysicsHelper.scaleDown(app.height, scale)); 189 leftSide.setName("left side"); 190 leftSide.setNoFill(true); //Make it invisible -> only used for dragging 191 leftSide.setNoStroke(true); 192 leftSide.unregisterAllInputProcessors(); 193 leftSide.removeAllGestureEventListeners(DragProcessor.class); 194 leftSide.registerInputProcessor(new DragProcessor(app)); 195 leftSide.addGestureListener(DragProcessor.class, new GameFieldHalfDragListener(blueCircle)); 196 physicsContainer.addChild(0, leftSide); 197 MTRectangle rightSide = new MTRectangle( 198 app, PhysicsHelper.scaleDown(app.width/2f, scale), 199 PhysicsHelper.scaleDown(0, scale), PhysicsHelper.scaleDown(app.width, scale) 200 , PhysicsHelper.scaleDown(app.height, scale)); 201 rightSide.setName("right Side"); 202 rightSide.setNoFill(true); //Make it invisible -> only used for dragging 203 rightSide.setNoStroke(true); 204 rightSide.unregisterAllInputProcessors(); 205 rightSide.removeAllGestureEventListeners(DragProcessor.class); 206 rightSide.registerInputProcessor(new DragProcessor(app)); 207 rightSide.addGestureListener(DragProcessor.class, new GameFieldHalfDragListener(redCircle)); 208 physicsContainer.addChild(0, rightSide); 209 210 //Display Score UI 211 MTComponent uiLayer = new MTComponent(mtApplication, new MTCamera(mtApplication)); 212 uiLayer.setDepthBufferDisabled(true); 213 getCanvas().addChild(uiLayer); 214 IFont font = FontManager.getInstance().createFont(mtApplication, "arial", 50, MTColor.WHITE); 215 216 t1 = new MTTextArea(mtApplication, font); 217 t1.setPickable(false); 218 t1.setNoFill(true); 219 t1.setNoStroke(true); 220 t1.setPositionGlobal(new Vector3D(5,30,0)); 221 uiLayer.addChild(t1); 222 223 t2 = new MTTextArea(mtApplication, font); 224 t2.setPickable(false); 225 t2.setNoFill(true); 226 t2.setNoStroke(true); 227 t2.setPositionGlobal(new Vector3D(mtApplication.width - 65 , 30,0)); 228 uiLayer.addChild(t2); 229 this.updateScores(); 230 231 //Set up check for collisions between objects 232 this.addWorldContactListener(world); 233 234 /* 235 //Sound 236 if (enableSound){ 237 minim = new Minim(mtApplication); 238 wallHit = minim.loadSnippet(MT4jSettings.getInstance().getDataFolderPath() + "sound" + File.separator + "paddleBallHit.wav"); 239// paddleBallClash = minim.loadSample(MT4jSettings.getInstance().getDataFolderPath() + "sound" + File.separator + "paddleBallHit.wav", 2048); 240// goalHit = minim.loadSnippet(MT4jSettings.getInstance().getDataFolderPath() + "sound" + File.separator + "goal.wav"); 241// goalHit.play(); 242 paddleHit = minim.loadSnippet(MT4jSettings.getInstance().getDataFolderPath() + "sound" + File.separator + "wallHit.wav"); 243 } 244 */ 245 } 246 247 248 249 private class GameFieldHalfDragListener implements IGestureEventListener{ 250 private MTComponent comp; 251 252 public GameFieldHalfDragListener(MTComponent dragComp){ 253 this.comp = dragComp; 254 if (comp.getUserData("box2d") == null){ 255 throw new RuntimeException("GameFieldHalfDragListener has to be given a physics object!"); 256 } 257 } 258 259 public boolean processGestureEvent(MTGestureEvent ge) { 260 DragEvent de = (DragEvent)ge; 261 try{ 262 Body body = (Body)comp.getUserData("box2d"); 263 MouseJoint mouseJoint; 264 Vector3D to = new Vector3D(de.getTo()); 265 //Un-scale position from mt4j to box2d 266 PhysicsHelper.scaleDown(to, scale); 267 switch (de.getId()) { 268 case DragEvent.GESTURE_STARTED: 269 comp.sendToFront(); 270 body.wakeUp(); 271 body.setXForm(new Vec2(to.x, to.y), body.getAngle()); 272 mouseJoint = PhysicsHelper.createDragJoint(world, body, to.x, to.y); 273 comp.setUserData(comp.getID(), mouseJoint); 274 break; 275 case DragEvent.GESTURE_UPDATED: 276 mouseJoint = (MouseJoint) comp.getUserData(comp.getID()); 277 if (mouseJoint != null){ 278 boolean onCorrectGameSide = ((MTComponent)de.getTarget()).containsPointGlobal(de.getTo()); 279 //System.out.println(((MTComponent)de.getTargetComponent()).getName() + " Contains " + to + " -> " + contains); 280 if (onCorrectGameSide){ 281 mouseJoint.setTarget(new Vec2(to.x, to.y)); 282 } 283 } 284 break; 285 case DragEvent.GESTURE_ENDED: 286 mouseJoint = (MouseJoint) comp.getUserData(comp.getID()); 287 if (mouseJoint != null){ 288 comp.setUserData(comp.getID(), null); 289 //Only destroy the joint if it isnt already (go through joint list and check) 290 for (Joint joint = world.getJointList(); joint != null; joint = joint.getNext()) { 291 JointType type = joint.getType(); 292 switch (type) { 293 case MOUSE_JOINT: 294 MouseJoint mj = (MouseJoint)joint; 295 if (body.equals(mj.getBody1()) || body.equals(mj.getBody2())){ 296 if (mj.equals(mouseJoint)) { 297 world.destroyJoint(mj); 298 } 299 } 300 break; 301 default: 302 break; 303 } 304 } 305 } 306 mouseJoint = null; 307 break; 308 default: 309 break; 310 } 311 }catch (Exception e) { 312 System.err.println(e.getMessage()); 313 } 314 return false; 315 } 316 } 317 318 319 private class Paddle extends PhysicsCircle{ 320 public Paddle(PApplet applet, Vector3D centerPoint, float radius, 321 World world, float density, float friction, float restitution, float worldScale) { 322 super(applet, centerPoint, radius, world, density, friction, restitution, worldScale); 323 } 324 @Override 325 protected void bodyDefB4CreationCallback(BodyDef def) { 326 super.bodyDefB4CreationCallback(def); 327 def.fixedRotation = true; 328 def.linearDamping = 0.5f; 329 } 330 } 331 332 private class HockeyBall extends PhysicsCircle{ 333 public HockeyBall(PApplet applet, Vector3D centerPoint, float radius, 334 World world, float density, float friction, float restitution, float worldScale) { 335 super(applet, centerPoint, radius, world, density, friction, restitution, worldScale); 336 } 337 338 @Override 339 protected void circleDefB4CreationCallback(CircleDef def) { 340 super.circleDefB4CreationCallback(def); 341 def.radius = def.radius -5/scale; 342 } 343 @Override 344 protected void bodyDefB4CreationCallback(BodyDef def) { 345 super.bodyDefB4CreationCallback(def); 346// def.linearDamping = 0.15f; 347 def.linearDamping = 0.25f; 348 def.isBullet = true; 349 def.angularDamping = 0.9f; 350 351// def.fixedRotation = true; 352 } 353 } 354 355 356 private class HockeyGoal extends PhysicsRectangle { 357 public HockeyGoal(Vector3D centerPosition, float width, float height, 358 PApplet applet, World world, float density, float friction,float restitution, float scale) { 359 super(centerPosition, width, height, applet, world, density, friction,restitution, scale); 360 } 361 362 @Override 363 protected void bodyDefB4CreationCallback(BodyDef def) { 364 def.isBullet = true; 365 super.bodyDefB4CreationCallback(def); 366 } 367 368 @Override 369 protected void polyDefB4CreationCallback(PolygonDef def) { 370 super.polyDefB4CreationCallback(def); 371 def.isSensor = true; //THIS AS SENSOR! 372 } 373 } 374 375 376 377 378 private void addWorldContactListener(World world){ 379 world.setContactListener(new ContactListener() { 380 public void result(ContactResult point) { 381// System.out.println("Result contact"); 382 } 383 //@Override 384 public void remove(ContactPoint point) { 385// System.out.println("remove contact"); 386 } 387 //@Override 388 public void persist(ContactPoint point) { 389// System.out.println("persist contact"); 390 } 391 //@Override 392 public void add(ContactPoint point) { 393// /* 394 Shape shape1 = point.shape1; 395 Shape shape2 = point.shape2; 396 final Body body1 = shape1.getBody(); 397 final Body body2 = shape2.getBody(); 398 Object userData1 = body1.getUserData(); 399 Object userData2 = body2.getUserData(); 400 401 if (userData1 instanceof IPhysicsComponent && userData2 instanceof IPhysicsComponent) { //Check for ball/star collision 402 IPhysicsComponent physObj1 = (IPhysicsComponent) userData1; 403 IPhysicsComponent physObj2 = (IPhysicsComponent) userData2; 404// System.out.println("Collided: " + mt4jObj1 + " with " + mt4jObj2); 405 if (physObj1 instanceof MTComponent && physObj2 instanceof MTComponent) { 406 MTComponent comp1 = (MTComponent) physObj1; 407 MTComponent comp2 = (MTComponent) physObj2; 408 409 //Check if one of the components is the BALL 410 MTComponent ball = isHit("ball", comp1, comp2); 411 final MTComponent theBall = ball; 412 413 //Check if one of the components is the GOAL 414 MTComponent goal1 = isHit("goal1", comp1, comp2); 415 MTComponent goal2 = isHit("goal2", comp1, comp2); 416 417 //Check if a puck was involved 418 MTComponent bluePuck = isHit("blue", comp1, comp2); 419 MTComponent redPuck = isHit("red", comp1, comp2); 420 421 //Check if a border was hit 422 MTComponent border = null; 423 if (comp1.getName() != null && comp1.getName().startsWith("border")){ 424 border = comp1; 425 }else if (comp2.getName() != null && comp2.getName().startsWith("border")){ 426 border = comp2; 427 } 428 429 if (ball != null){ 430 //CHECK IF BALL HIT A PADDLE 431 if (enableSound && (bluePuck != null || redPuck != null)){ 432// System.out.println("PUCK HIT BALL!"); 433 /* 434 triggerSound(paddleHit); 435 */ 436 } 437 438 439 //Check if BALL HIT A GOAL 440 if (goal1 != null || goal2 != null){ 441 //BALL HIT A GOAL 442 if (goal1 != null){ 443 System.out.println("GOAL FOR PLAYER 2!"); 444 scorePlayer2++; 445 }else if (goal2 != null){ 446 System.out.println("GOAL FOR PLAYER 1!"); 447 scorePlayer1++; 448 } 449 450 //Update scores 451 updateScores(); 452 //Play goal sound 453// triggerSound(goalHit); 454 455 if (scorePlayer1 >= 15 || scorePlayer2 >= 15){ 456 reset(); 457 }else{ 458 459 //Reset ball 460 if (theBall.getUserData("resetted") == null){ //To make sure that we call destroy only once 461 theBall.setUserData("resetted", true); 462 app.invokeLater(new Runnable() { 463 public void run() { 464 IPhysicsComponent a = (IPhysicsComponent)theBall; 465 a.getBody().setXForm(new Vec2(getMTApplication().width/2f/scale, getMTApplication().height/2f/scale), a.getBody().getAngle()); 466// a.getBody().setLinearVelocity(new Vec2(0,0)); 467 a.getBody().setLinearVelocity(new Vec2(ToolsMath.getRandom(-8, 8),ToolsMath.getRandom(-8, 8))); 468 a.getBody().setAngularVelocity(0); 469 theBall.setUserData("resetted", null); 470 } 471 }); 472 } 473 } 474 475 } 476 477 //If ball hit border Play sound 478 if (enableSound && border != null){ 479 /* 480 triggerSound(wallHit); 481 */ 482 } 483 } 484 } 485 }else{ //if at lest one if the colliding bodies' userdata is not a physics shape 486 487 } 488// */ 489 } 490 }); 491 } 492 493 /* 494 private void triggerSound(AudioSnippet snippet){ 495 if (!snippet.isPlaying()){ 496 snippet.pause(); 497 snippet.rewind(); 498 snippet.play(); 499 } 500 } 501 */ 502 503 private MTComponent isHit(String componentName, MTComponent comp1, MTComponent comp2){ 504 MTComponent hitComp = null; 505 if (comp1.getName() != null && comp1.getName().equalsIgnoreCase(componentName)){ 506 hitComp = comp1; 507 }else if (comp2.getName() != null && comp2.getName().equalsIgnoreCase(componentName)){ 508 hitComp = comp2; 509 } 510 return hitComp; 511 } 512 513 private void updateScores(){ 514 t1.setText(Integer.toString(scorePlayer1)); 515 t2.setText(Integer.toString(scorePlayer2)); 516 } 517 518 private void reset(){ 519 if (ball.getUserData("resetted") == null){ //To make sure that we call destroy only once 520 ball.setUserData("resetted", true); 521 app.invokeLater(new Runnable() { 522 public void run() { 523 IPhysicsComponent a = (IPhysicsComponent)ball; 524 a.getBody().setXForm(new Vec2(getMTApplication().width/2f/scale, getMTApplication().height/2f/scale), a.getBody().getAngle()); 525// a.getBody().setLinearVelocity(new Vec2(0,0)); 526 a.getBody().setLinearVelocity(new Vec2(ToolsMath.getRandom(-8, 8),ToolsMath.getRandom(-8, 8))); 527 a.getBody().setAngularVelocity(0); 528 ball.setUserData("resetted", null); 529 } 530 }); 531 } 532 this.scorePlayer1 = 0; 533 this.scorePlayer2 = 0; 534 this.updateScores(); 535 } 536 537 538 private void createScreenBorders(MTComponent parent){ 539 //Left border 540 float borderWidth = 50f; 541 float borderHeight = app.height; 542 Vector3D pos = new Vector3D(-(borderWidth/2f) , app.height/2f); 543 PhysicsRectangle borderLeft = new PhysicsRectangle(pos, borderWidth, borderHeight, app, world, 0,0,0, scale); 544 borderLeft.setName("borderLeft"); 545 parent.addChild(borderLeft); 546 //Right border 547 pos = new Vector3D(app.width + (borderWidth/2), app.height/2); 548 PhysicsRectangle borderRight = new PhysicsRectangle(pos, borderWidth, borderHeight, app, world, 0,0,0, scale); 549 borderRight.setName("borderRight"); 550 parent.addChild(borderRight); 551 //Top border 552 borderWidth = app.width; 553 borderHeight = 50f; 554 pos = new Vector3D(app.width/2, -(borderHeight/2)); 555 PhysicsRectangle borderTop = new PhysicsRectangle(pos, borderWidth, borderHeight, app, world, 0,0,0, scale); 556 borderTop.setName("borderTop"); 557 parent.addChild(borderTop); 558 //Bottom border 559 pos = new Vector3D(app.width/2 , app.height + (borderHeight/2)); 560 PhysicsRectangle borderBottom = new PhysicsRectangle(pos, borderWidth, borderHeight, app, world, 0,0,0, scale); 561 borderBottom.setName("borderBottom"); 562 parent.addChild(borderBottom); 563 } 564 565 566 public void onEnter() { 567 getMTApplication().registerKeyEvent(this); 568 } 569 570 public void onLeave() { 571 getMTApplication().unregisterKeyEvent(this); 572 } 573 574 public void keyEvent(KeyEvent e){ 575 int evtID = e.getID(); 576 if (evtID != KeyEvent.KEY_PRESSED) 577 return; 578 switch (e.getKeyCode()){ 579 case KeyEvent.VK_SPACE: 580 this.reset(); 581 break; 582 default: 583 break; 584 } 585 } 586 587}