/examples/advanced/physics/scenes/AirHockeyScene.java

http://mt4j.googlecode.com/ · Java · 587 lines · 418 code · 75 blank · 94 comment · 57 complexity · a4c6b45d0c977b1c66ae38279d713d55 MD5 · raw file

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