Creating Asha Games: Game Pausing, Orientation, Sensors and Gestures

910 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
910
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Creating Asha Games: Game Pausing, Orientation, Sensors and Gestures

  1. 1. Crea%ng  Asha  Games:   Game  Pausing,  Device  Orienta%on,  Sensors,  Gestures   Jussi  Pohjolainen   Tampere  University  of  Applied  Sciences  
  2. 2. GAME  PAUSING  
  3. 3. About  Game  Pausing   •  Pause  game  when   –  Phone  rings   –  Back  –  buHon  is  pressed   •  Remember  that  MIDlet's  pauseApp  –  method   is  never  called!   •  In  GameCanvas,  implement  following   –  public void showNotify() // resume –  public void hideNotify() // pause
  4. 4. About  Gameloop  and  Threading   •  Gameloop  is  implemented  using  Threading   –  Thread thread = new Thread(Runnable x); –  thread.start(); // calls run() •  Gameloop  usually:   –  while(gameIsOn) { …. Thread.sleep(ticks); } •  How  to  pause  the  current  thread  in  midp?  
  5. 5. Synchroniza%on   •  Let's  first  look  at  synchroniza5on.   •  There  might  be  a  problem,  if  two  threads  accesses  the  same   data   –  Two  people  each  have  a  ATM  cards  that  are  linked  to  only  one  account   –  What  happens  when  these  two  people  accesses  the  account  at  the   same  %me?   •  Withdrawal  is  two-­‐step  process   –  Check  the  balance   –  If  there's  enough  money  int  the  account,  make  the  withdrawal   •  What  happens  if  1  and  2  are  separated?  
  6. 6. Locks   •  We  must  guarantee  that  the  two  steps  are   never  split  apart.  Use  synchronized  keyword   •  Synchroniza%on  works  with  locks.  Every   object  has  a  lock.  If  one  thread  has  picked  up   the  lock,  no  other  thread  can  use  the   synchronized  code.  
  7. 7. Examples   •  Let's  look  at  some  synchroniza%on  examples   –  https://dl.dropboxusercontent.com/u/ 874087/game-programming/examples/ threading/Synchronized1.java •  See  also   –  Synchronized2.java -> Synchronized5.java
  8. 8. wait()   •  Object  class  holds  a  method  wait()   –  Causes  the  current  thread  to  wait  un%l  another   thread  invokes  the  no%fy()  method  for  this  object   •  So  when  calling  wait()  it  pauses  the  current   thread  and  waits  that  some  other  thread  calls   no%fy()  or  no%fyAll()!  
  9. 9. // NOTICE! This example does not work, all exception handling and synchronized blocks // are missing class MyApp { public static void main(String [] args) { new MyApp(); } public MyApp() { MyThread mythread; Thread thread = new Thread(mythread = new MyThread()); thread.start(); System.out.println("Sleeping"); Thread.sleep(2000); // Resume from wait! Calls notify from the object that is in wait… mythread.notify(); } } class MyThread implements Runnable { public void run() { // Let's wait until someone calls notify wait(); System.out.println("Resumed!"); } }
  10. 10. wait()   •  When  calling  wait  and  no%fy,  it  must  be  inside   synchronized  block.     synchronized(this) { // Before calling notify, the thread calling this must // own a lock. notify(); } synchronized(this) { wait(); }  
  11. 11. Game  Pausing  in  MIDlet   •  In  GameCanvas,  following  methods  are  called   when  phone  rings.               // Phone rings public void hideNotify()  {   pause(); // pause game – my own method }     // Phone ends public void showNotify()  {   resume(); // resume game – my own method }
  12. 12. pause() and  resume() public void resume() { isPause = false; synchronized(this) { notify(); // Notify that waiting thread can // continue. } } public void pause() { isPause = true; }
  13. 13. Game  Loop   public void run() { int i = 0; while(true) { checkIfPause(); checkCollisions(); moveSprites(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } private void checkIfPause() { synchronized(this) { while(isPause) { // while, just in case try { wait(); // Wait in current thread } catch (InterruptedException e) { e.printStackTrace(); } } } }
  14. 14. Back  BuHon  to  Game  Canvas   Command backCommand = new Command("Back", Command.BACK, 0); addCommand(backCommand); setCommandListener(this); // and the listener method public void commandAction(Command c, Displayable d) { if(isPause) { midlet.notifyDestroyed(); } else { pause(); } }
  15. 15. DEVICE  ORIENTATION  
  16. 16. Adjus%ng  Device's  Orienta%on   •  MIDlets  can  use  Orienta5on  API  to   –  Change  their  UI  orienta%on   –  Determine  their  current  UI  orienta%on   –  Determine  the  current  display  orienta%on   –  Receive  a  no%fica%on  whenever  the  display   orienta%on  changes   •  When  MIDlet  changes  it's  UI  orienta%on,  it  has   to  redraw  the  low-­‐level  components  that  it   uses.  
  17. 17. Supported  Orienta%ons   •  •  •  •  ORIENTATION_LANDSCAPE ORIENTATION_LANDSCAPE_180 ORIENTATION_PORTRAIT ORIENTATION_PORTRAIT_180
  18. 18. Se^ng  UI  Orienta%on   •  Add  following  to  JAD  file:   –  Nokia-MIDlet-App-Orientation: manual •  Now  it  supports  both  portrait  and  landscape   modes   •  Add  orienta%on  listener   –  Orientation.addOrientationListener(orientationListener);
  19. 19. Orienta%on  Listener  Callback   /** Orientation listener callback */ public void displayOrientationChanged( int newDisplayOrientation ){ /** Check display orientation */ switch( newDisplayOrientation ){ case Orientation.ORIENTATION_PORTRAIT: case Orientation.ORIENTATION_PORTRAIT_180: /** Change MIDlet UI orientation to portrait */ Orientation.setAppOrientation(Orientation.ORIENTATION_PORTRAIT); break; case Orientation.ORIENTATION_LANDSCAPE: case Orientation.ORIENTATION_LANDSCAPE_180: /** Change MIDlet UI orientation to landscape */ Orientation.setAppOrientation(Orientation.ORIENTATION_LANDSCAPE); break; } }
  20. 20. sizeChanged() •  When  UI  Orienta%on  changes:     /** Java platform will call this when UI orientation has been changed */ protected void sizeChanged( int w, int h ){ /** Acquiring new Graphics Object since old is not valid anymore */ g = getGraphics( ); canDraw = true; }
  21. 21. MOBILE  SENSOR  API  
  22. 22. Mobile  Sensors   •  Mobile  Sensor  API  allows  MIDlets  to  fetch   data  from  the  sensors  of  the  mobile  device   •  Sensor  consists  of  one  or  more  channels,  in   accelerometer  you  will  get  data  from  three   channels  (x,  y  and  z)   •  Sensors  have  common  proper%es:     –  accuracy   –  max  and  min  value  
  23. 23. Available  Sensors  in  Asha  50X   •  Accelera5on  sensor     –  measures  accelera%on  in  SI  units  for  x,  y  and  z  -­‐  axis.   •  Orienta5on  sensor   –  provides  informa%on  of  devices  current  orienta%on  posi%on.   •  Rota5on  sensor     –  provides  informa%on  of  devices  current  rota%on  degree.   •  Double  tapping  sensor     –  provides  informa%on  of  double  taps  occurred  on  the  phone  sides.   •  Proximity  sensor     –  indicates  if  an  obstacle  is  right  in  front  of  it   •  BaLery  sensor     –  shows  baHery  charge  level  in  percentage.  Sensor  is  always  on.   •  Charger  sensor   –  shows  whether  charger  is  connected.  Sensor  is  always  on.   •  Signal  strength  sensor   –  shows  strength  of  network  connec%on  in  percentage.  Sensor  is  always  on.  
  24. 24. Using  Sensors  
  25. 25. Finding  and  Iden%fying  a  Sensor   // Find all sensors SensorInfo[] sensorInfos = SensorManager.findSensors(null, null); for(int i=0; i<sensorInfos.length; i++) { SensorInfo si = sensorInfos[i]; System.out.println(si.getUrl()); }
  26. 26. Finding  and  Iden%fying  a  Sensor   // Sensor type (quantity): // acceleration // orientation // rotation // double_tap // proximity // battery_charge // charger_state // network_field_intensity // null String type = "acceleration"; // Sensor Context type // ambient // device // user // vehicle // null String contextType = "user"; // Fetch all sensors with given information, should find only one. SensorInfo[] si = SensorManager.findSensors(type, contextType); // Retrieve the sensor url. String sensorURL = si[0].getUrl();
  27. 27. Opening  a  sensor  connec%on   { try { // This may not be a good idea, fetch the URL from sensorinfo using sensor quantity and // context type String sensorURL = "sensor:acceleration;contextType=user;model=Nokia;location=NoLoc"; // How fast data is sent to listener! final int BUFFER_SIZE = 1; SensorConnection sensorConnection = (SensorConnection)Connector.open(sensorURL); // this = any object that implements DataListener sensorConnection.setDataListener(this, BUFFER_SIZE); } catch (IOException e) { e.printStackTrace(); } } // Datalistener interface method public void dataReceived(SensorConnection sensor, Data[] data, boolean isDataLost) { System.out.println("Here!"); }
  28. 28. Case:  Accelera%on  listening   public void dataReceived(SensorConnection sensor, Data[] data, boolean isDataLost) { // We have three channels. System.out.println("Channel amount: " + data.length); // Channel is Data object Data x = data[0]; // Each channel may hold several values. In this case // only one. double [] values = x.getDoubleValues(); System.out.println("Number of values " + values.length); // And the value is: System.out.println("x = " + values[0]); // Let's fetch the rest (y and z) in just on line System.out.println("y = " + data[1].getDoubleValues()[0]); System.out.println("z = " + data[2].getDoubleValues()[0]); }
  29. 29. Case:  Accelera%on  listening   public void dataReceived(SensorConnection sensor, Data[] data, boolean isDataLost) { System.out.println("x = " + data[0].getDoubleValues()[0]); System.out.println("y = " + data[1].getDoubleValues()[0]); System.out.println("z = " + data[2].getDoubleValues()[0]); }
  30. 30. Closing  connec%on   •  Remember  to  close  the  connec%on  if  not   needed!   –  sensorConnection.close();
  31. 31. GESTURES  API  
  32. 32. Really  Easy  to  Use   // STEP 1: Defines a GestureInteractiveZone for the // whole screen and all Gesture types. GestureInteractiveZone giz = new GestureInteractiveZone( GestureInteractiveZone.GESTURE_ALL ); // STEP 2: Register the GestureInteractiveZones for the // GameCanvas object this. GestureRegistrationManager.register( this, giz ); // STEP 3: Set the listener, source is this gamecanvas // and listener is this also GestureRegistrationManager.setListener(this, this);
  33. 33. Listener   public void gestureAction(Object container, GestureInteractiveZone gestureInteractiveZone, GestureEvent gestureEvent) { switch(gestureEvent.getType()) { case GestureInteractiveZone.GESTURE_TAP: Debug.printInfo("MyGameCanvas", "gestureAction", "TAP", 2); break; ... case GestureInteractiveZone.GESTURE_LONG_PRESS: Debug.printInfo("MyGameCanvas", "gestureAction", "LONG PRESS", 2); break; } }
  34. 34. Listener   public void gestureAction(Object container, GestureInteractiveZone gestureInteractiveZone, GestureEvent gestureEvent) { switch(gestureEvent.getType()) { ... case GestureInteractiveZone.GESTURE_FLICK: Debug.printInfo("MyGameCanvas", "gestureAction", "FLICK", 2); Debug.printInfo("MyGameCanvas", "gestureAction", "flick speed = " + gestureEvent.getFlickSpeed(), 2); Debug.printInfo("MyGameCanvas", "gestureAction", "flick direction = " + gestureEvent.getFlickDirection(), 2); break; } }

×