Jypeli  5
The simple game programming library
TouchPanel.cs
Siirry tämän tiedoston dokumentaatioon.
1 #region MIT License
2 /*
3  * Copyright (c) 2009-2011 University of Jyväskylä, Department of Mathematical
4  * Information Technology.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #endregion
25 
26 
27 using System;
28 using System.Collections.Generic;
29 using System.Diagnostics;
30 using Microsoft.Xna.Framework;
31 
32 #if WINDOWS_PHONE
33 using Microsoft.Xna.Framework.Input.Touch;
34 
35 using XnaTouchPanel = Microsoft.Xna.Framework.Input.Touch.TouchPanel;
36 using XnaGestureType = Microsoft.Xna.Framework.Input.Touch.GestureType;
37 #endif
38 
39 using Jypeli.Controls;
40 using System.Linq;
41 
42 
43 namespace Jypeli.WP7
44 {
48  public class TouchPanel : Controller<TouchPanelState>, PointingDevice
49  {
50  private ListenContext _snipContext = null;
51  private ListenContext _pinchContext = null;
52  private ListenContext _keyEmulationContext = null;
53 
57  public int ActiveChannels
58  {
59  get { return newState.ActiveTouches.Count + newState.ActiveGestures.Count; }
60  }
61 
65  public int NumTouches
66  {
67  get { return newState.ActiveTouches.Count; }
68  }
69 
73  public int NumGestures
74  {
75  get { return newState.ActiveGestures.Count; }
76  }
77 
78  internal override bool IsBufferEmpty()
79  {
80  return true;
81  }
82 
86  public bool FollowSnipping
87  {
88  get { return _snipContext != null; }
89  set
90  {
91  TouchHandler handler = delegate( Touch t ) { Game.Instance.Camera.Position -= t.MovementOnWorld; };
92  ContextHandler op = delegate( ListenContext ctx ) { Listen( ButtonState.Down, handler, "Move around" ).InContext( ctx ); };
93  setContext( ref _snipContext, value, op );
94  }
95  }
96 
100  public bool FollowPinching
101  {
102  get { return _pinchContext != null; }
103  set
104  {
105  TouchHandler handler = delegate( Touch t )
106  {
107  Gesture g = (Gesture)t;
109  };
110  ContextHandler op = delegate( ListenContext ctx ) { ListenGesture( GestureType.Pinch, handler, "Zoom" ); };
111  setContext( ref _pinchContext, value, op );
112  }
113  }
114 
119  public bool EmulateKeyboard
120  {
121  get { return _keyEmulationContext != null; }
122  set
123  {
124  ContextHandler op = delegate( ListenContext ctx ) { Listen( ButtonState.Down, DoEmulateKeyboard, null ).InContext( ctx ); };
125  setContext( ref _keyEmulationContext, value, op );
126  }
127  }
128 
129  delegate void ContextHandler( ListenContext ctx );
130 
131  private void setContext( ref ListenContext context, bool enable, ContextHandler operation )
132  {
133  if ( ( context != null ) == enable ) return;
134  if ( enable )
135  {
137  context.Active = true;
138  operation( context );
139  }
140  else
141  {
142  context.Destroy();
143  context = null;
144  }
145  }
146 
147  public override void Clear()
148  {
149  bool pinch = this.FollowPinching;
150  bool snip = this.FollowSnipping;
151  bool kbem = this.EmulateKeyboard;
152 
153  this.FollowPinching = false;
154  this.FollowSnipping = false;
155  this.EmulateKeyboard = false;
156 
157  base.Clear();
158 
159  this.FollowPinching = pinch;
160  this.FollowSnipping = snip;
161  this.EmulateKeyboard = kbem;
162  }
163 
168  public void Enable( ButtonState state )
169  {
170  base.Enable( listener => ( listener.State == state ) );
171  }
172 
177  public void Disable( ButtonState state )
178  {
179  base.Disable( listener => ( listener.State == state ) );
180  }
181 
182  internal override string GetControlText( Listener listener )
183  {
184  if ( listener.Type != ListeningType.Touch && listener.Type != ListeningType.TouchGesture )
185  Debug.Assert( false, "Bad listener type for touch panel" );
186  return "Touch panel";
187  }
188 
189  internal override TouchPanelState GetCurrentState()
190  {
191 #if WINDOWS_PHONE
192  List<GestureSample> samples = new List<GestureSample>();
193  if ( XnaTouchPanel.EnabledGestures != XnaGestureType.None )
194  {
195  while ( XnaTouchPanel.IsGestureAvailable )
196  samples.Add( XnaTouchPanel.ReadGesture() );
197 
198  }
199 
200  return new TouchPanelState( XnaTouchPanel.GetState(), samples, newState );
201 #else
202  return new TouchPanelState();
203 #endif
204  }
205 
206  public bool IsTriggeredOnChannel( int channel, Listener listener )
207  {
208 #if WINDOWS_PHONE
209  Debug.Assert( ( listener.Type == ListeningType.Touch ) || ( listener.Type == ListeningType.TouchGesture ) );
210 
211  if ( !listener.Context.Active )
212  return false;
213 
214  if ( listener.gestureType == null )
215  {
216  // Normal touch
217  if ( newState.ActiveTouches.Count <= channel )
218  return false;
219 
220  if ( listener.GameObject != null )
221  {
222  Vector touchOnScreen = newState.ActiveTouches[channel].PositionOnScreen;
223  Vector touchOnWorld = Game.Instance.Camera.ScreenToWorld( touchOnScreen, listener.GameObject.Layer );
224 
225  if ( !listener.GameObject.IsInside( touchOnWorld ) )
226  return false;
227  }
228 
229  switch ( newState.ActiveTouches[channel].State )
230  {
231  case TouchLocationState.Moved:
232  return listener.State == ButtonState.Down;
233 
234  case TouchLocationState.Pressed:
235  return listener.State == ButtonState.Pressed;
236 
237  case TouchLocationState.Released:
238  return listener.State == ButtonState.Released;
239  }
240  }
241  else
242  {
243  // Gesture
244  int gIndex = channel - newState.ActiveTouches.Count;
245  if ( gIndex < 0 || newState.ActiveGestures.Count <= gIndex )
246  return false;
247 
248  if ( listener.GameObject != null && !listener.GameObject.IsInside( newState.ActiveGestures[gIndex].PositionOnWorld ) )
249  return false;
250 
251  return newState.samples.Any( s => s.GestureType == (XnaGestureType)listener.gestureType.Value );
252  }
253 #endif
254 
255  return false;
256  }
257 
258  private void DoEmulateKeyboard( Touch touch )
259  {
260  if ( Game.Instance == null ) return;
261 
262  if ( touch.PositionOnScreen.X > Game.Screen.Width / 4 )
263  {
264  // Right
265  Game.Controls.Keyboard.listeners.FindAll( l => l.Key == Key.Right ).ForEach( Listener.Invoke );
266  }
267 
268  else if ( touch.PositionOnScreen.X < -Game.Screen.Width / 4 )
269  {
270  // Left
271  Game.Controls.Keyboard.listeners.FindAll( l => l.Key == Key.Left ).ForEach( Listener.Invoke );
272  }
273 
274  if ( touch.PositionOnScreen.Y > Game.Screen.Height / 4 )
275  {
276  // Up
277  Game.Controls.Keyboard.listeners.FindAll( l => l.Key == Key.Up ).ForEach( Listener.Invoke );
278  }
279 
280  else if ( touch.PositionOnScreen.Y < -Game.Screen.Height / 4 )
281  {
282  // Down
283  Game.Controls.Keyboard.listeners.FindAll( l => l.Key == Key.Down ).ForEach( Listener.Invoke );
284  }
285 
286  else if ( touch.PositionOnScreen.Magnitude < 150 )
287  {
288  // Space
289  Game.Controls.Keyboard.listeners.FindAll( l => l.Key == Key.Space ).ForEach( Listener.Invoke );
290  }
291  }
292 
293  #region Listen with no parameters
294 
295  public Listener Listen( ButtonState state, TouchHandler handler, string helpText )
296  {
297 #if WINDOWS_PHONE
298  Listener l = new TouchListener( this, ListeningType.Touch, helpText, handler );
299  l.State = state;
300  Add( l );
301  return l;
302 #else
303  return Listener.Null;
304 #endif
305  }
306 
307  public Listener ListenGesture( GestureType type, TouchHandler handler, string helpText )
308  {
309 #if WINDOWS_PHONE
310  Listener l = new TouchListener( this, ListeningType.TouchGesture, helpText, handler );
311  l.gestureType = type;
312  Add( l );
313  XnaTouchPanel.EnabledGestures |= (XnaGestureType)type;
314  return l;
315 #else
316  return Listener.Null;
317 #endif
318  }
319 
320  public Listener ListenGestureOn( GameObject o, GestureType type, TouchHandler handler, string helpText )
321  {
322 #if WINDOWS_PHONE
323  Listener l = new TouchListener( this, ListeningType.TouchGesture, helpText, handler );
324  l.GameObject = o;
325  l.gestureType = type;
326  Add( l );
327  XnaTouchPanel.EnabledGestures |= (XnaGestureType)type;
328  return l;
329 #else
330  return Listener.Null;
331 #endif
332  }
333 
334  public Listener ListenOn( IGameObject o, ButtonState state, TouchHandler handler, String helpText )
335  {
336 #if WINDOWS_PHONE
337  Listener l = new TouchListener( this, ListeningType.Touch, helpText, handler );
338  l.State = state;
339  l.GameObject = o;
340  Add( l );
341  return l;
342 #else
343  return Listener.Null;
344 #endif
345  }
346 
347  #endregion
348 
349  #region Listen with 1 parameter
350 
351  public Listener Listen<T1>( ButtonState state, TouchHandler<T1> handler, string helpText, T1 p1 )
352  {
353 #if WINDOWS_PHONE
354  Listener l = new TouchListener<T1>( this, ListeningType.Touch, helpText, handler, p1 );
355  l.State = state;
356  Add( l );
357  return l;
358 #else
359  return Listener.Null;
360 #endif
361  }
362 
363  public Listener ListenGesture<T1>( GestureType type, TouchHandler<T1> handler, string helpText, T1 p1 )
364  {
365 #if WINDOWS_PHONE
366  Listener l = new TouchListener<T1>( this, ListeningType.TouchGesture, helpText, handler, p1 );
367  l.gestureType = type;
368  Add( l );
369  XnaTouchPanel.EnabledGestures |= (XnaGestureType)type;
370  return l;
371 #else
372  return Listener.Null;
373 #endif
374  }
375 
376  public Listener ListenGestureOn<T1>( GameObject o, GestureType type, TouchHandler<T1> handler, string helpText, T1 p1 )
377  {
378 #if WINDOWS_PHONE
379  Listener l = new TouchListener<T1>( this, ListeningType.TouchGesture, helpText, handler, p1 );
380  l.GameObject = o;
381  l.gestureType = type;
382  Add( l );
383  XnaTouchPanel.EnabledGestures |= (XnaGestureType)type;
384  return l;
385 #else
386  return Listener.Null;
387 #endif
388  }
389 
390  public Listener ListenOn<T1>( IGameObject o, ButtonState state, TouchHandler<T1> handler, String helpText, T1 p1 )
391  {
392 #if WINDOWS_PHONE
393  Listener l = new TouchListener<T1>( this, ListeningType.Touch, helpText, handler, p1 );
394  l.State = state;
395  l.GameObject = o;
396  Add( l );
397  return l;
398 #else
399  return Listener.Null;
400 #endif
401  }
402 
403  #endregion
404 
405  #region Listen with 2 parameters
406 
407  public Listener Listen<T1, T2>( ButtonState state, TouchHandler<T1, T2> handler, string helpText, T1 p1, T2 p2 )
408  {
409 #if WINDOWS_PHONE
410  Listener l = new TouchListener<T1, T2>( this, ListeningType.Touch, helpText, handler, p1, p2 );
411  l.State = state;
412  Add( l );
413  return l;
414 #else
415  return Listener.Null;
416 #endif
417  }
418 
419  public Listener ListenGesture<T1, T2>( GestureType type, TouchHandler<T1, T2> handler, string helpText, T1 p1, T2 p2 )
420  {
421 #if WINDOWS_PHONE
422  Listener l = new TouchListener<T1, T2>( this, ListeningType.TouchGesture, helpText, handler, p1, p2 );
423  l.gestureType = type;
424  Add( l );
425  XnaTouchPanel.EnabledGestures |= (XnaGestureType)type;
426  return l;
427 #else
428  return Listener.Null;
429 #endif
430  }
431 
432  public Listener ListenGestureOn<T1, T2>( GameObject o, GestureType type, TouchHandler<T1, T2> handler, string helpText, T1 p1, T2 p2 )
433  {
434 #if WINDOWS_PHONE
435  Listener l = new TouchListener<T1, T2>( this, ListeningType.TouchGesture, helpText, handler, p1, p2 );
436  l.GameObject = o;
437  l.gestureType = type;
438  Add( l );
439  XnaTouchPanel.EnabledGestures |= (XnaGestureType)type;
440  return l;
441 #else
442  return Listener.Null;
443 #endif
444  }
445 
446  public Listener ListenOn<T1, T2>( IGameObject o, ButtonState state, TouchHandler<T1, T2> handler, String helpText, T1 p1, T2 p2 )
447  {
448 #if WINDOWS_PHONE
449  Listener l = new TouchListener<T1, T2>( this, ListeningType.Touch, helpText, handler, p1, p2 );
450  l.State = state;
451  l.GameObject = o;
452  Add( l );
453  return l;
454 #else
455  return Listener.Null;
456 #endif
457  }
458 
459  #endregion
460 
461  #region Listen with 3 parameters
462 
463  public Listener Listen<T1, T2, T3>( ButtonState state, TouchHandler<T1, T2, T3> handler, string helpText, T1 p1, T2 p2, T3 p3 )
464  {
465 #if WINDOWS_PHONE
466  Listener l = new TouchListener<T1, T2, T3>( this, ListeningType.Touch, helpText, handler, p1, p2, p3 );
467  l.State = state;
468  Add( l );
469  return l;
470 #else
471  return Listener.Null;
472 #endif
473  }
474 
475  public Listener ListenGesture<T1, T2, T3>( GestureType type, TouchHandler<T1, T2, T3> handler, string helpText, T1 p1, T2 p2, T3 p3 )
476  {
477 #if WINDOWS_PHONE
478  Listener l = new TouchListener<T1, T2, T3>( this, ListeningType.TouchGesture, helpText, handler, p1, p2, p3 );
479  l.gestureType = type;
480  Add( l );
481  XnaTouchPanel.EnabledGestures |= (XnaGestureType)type;
482  return l;
483 #else
484  return Listener.Null;
485 #endif
486  }
487 
488  public Listener ListenGestureOn<T1, T2, T3>( GameObject o, GestureType type, TouchHandler<T1, T2, T3> handler, string helpText, T1 p1, T2 p2, T3 p3 )
489  {
490 #if WINDOWS_PHONE
491  Listener l = new TouchListener<T1, T2, T3>( this, ListeningType.TouchGesture, helpText, handler, p1, p2, p3 );
492  l.GameObject = o;
493  l.gestureType = type;
494  Add( l );
495  XnaTouchPanel.EnabledGestures |= (XnaGestureType)type;
496  return l;
497 #else
498  return Listener.Null;
499 #endif
500  }
501 
502  public Listener ListenOn<T1, T2, T3>( IGameObject o, ButtonState state, TouchHandler<T1, T2, T3> handler, String helpText, T1 p1, T2 p2, T3 p3 )
503  {
504 #if WINDOWS_PHONE
505  Listener l = new TouchListener<T1, T2, T3>( this, ListeningType.Touch, helpText, handler, p1, p2, p3 );
506  l.State = state;
507  l.GameObject = o;
508  Add( l );
509  return l;
510 #else
511  return Listener.Null;
512 #endif
513  }
514 
515  #endregion
516 
517  #region Listen with 4 parameters
518 
519  public Listener Listen<T1, T2, T3, T4>( ButtonState state, TouchHandler<T1, T2, T3, T4> handler, string helpText, T1 p1, T2 p2, T3 p3, T4 p4 )
520  {
521 #if WINDOWS_PHONE
522  Listener l = new TouchListener<T1, T2, T3, T4>( this, ListeningType.Touch, helpText, handler, p1, p2, p3, p4 );
523  l.State = state;
524  Add( l );
525  return l;
526 #else
527  return Listener.Null;
528 #endif
529  }
530 
531  public Listener ListenGesture<T1, T2, T3, T4>( GestureType type, TouchHandler<T1, T2, T3, T4> handler, string helpText, T1 p1, T2 p2, T3 p3, T4 p4 )
532  {
533 #if WINDOWS_PHONE
534  Listener l = new TouchListener<T1, T2, T3, T4>( this, ListeningType.TouchGesture, helpText, handler, p1, p2, p3, p4 );
535  l.gestureType = type;
536  Add( l );
537  XnaTouchPanel.EnabledGestures |= (XnaGestureType)type;
538  return l;
539 #else
540  return Listener.Null;
541 #endif
542  }
543 
544  public Listener ListenGestureOn<T1, T2, T3, T4>( GameObject o, GestureType type, TouchHandler<T1, T2, T3, T4> handler, string helpText, T1 p1, T2 p2, T3 p3, T4 p4 )
545  {
546 #if WINDOWS_PHONE
547  Listener l = new TouchListener<T1, T2, T3, T4>( this, ListeningType.TouchGesture, helpText, handler, p1, p2, p3, p4 );
548  l.GameObject = o;
549  l.gestureType = type;
550  Add( l );
551  XnaTouchPanel.EnabledGestures |= (XnaGestureType)type;
552  return l;
553 #else
554  return Listener.Null;
555 #endif
556  }
557 
558  public Listener ListenOn<T1, T2, T3, T4>( IGameObject o, ButtonState state, TouchHandler<T1, T2, T3, T4> handler, String helpText, T1 p1, T2 p2, T3 p3, T4 p4 )
559  {
560 #if WINDOWS_PHONE
561  Listener l = new TouchListener<T1, T2, T3, T4>( this, ListeningType.Touch, helpText, handler, p1, p2, p3, p4 );
562  l.State = state;
563  l.GameObject = o;
564  Add( l );
565  return l;
566 #else
567  return Listener.Null;
568 #endif
569  }
570 
571  #endregion
572  }
573 }
Vector PositionOnScreen
Kosketuksen paikka ruudulla.
Definition: Touch.cs:31
delegate void TouchHandler< T1, T2, T3 >(Touch touch, T1 p1, T2 p2, T3 p3)
Ohjaintapahtumankäsittelijä kolmella parametrilla.
ListenContext CreateSubcontext()
double Magnitude
Vektorin pituus.
Definition: Vector.cs:281
bool IsTriggeredOnChannel(int channel, Listener listener)
Definition: TouchPanel.cs:206
Listener ListenOn(IGameObject o, ButtonState state, TouchHandler handler, String helpText)
Definition: TouchPanel.cs:334
void Enable(ButtonState state)
Ottaa käytöstä poistetun kosketuskontrollin k takaisin käyttöön.
Definition: TouchPanel.cs:168
Kosketuspaneelin kosketus.
Definition: Touch.cs:16
static Jypeli.Controls.Controls Controls
Pelin kontrollit.
Definition: Game.cs:207
Vector WorldDistanceAfter
Sormien etäisyysvektori maailmassa eleen lopussa.
Definition: Gesture.cs:74
delegate void TouchHandler< T1 >(Touch touch, T1 p1)
Ohjaintapahtumankäsittelijä yhdellä parametrilla.
Kosketuspaneeli.
Definition: TouchPanel.cs:48
ButtonState
Napin (minkä tahansa) asento.
Definition: ButtonState.cs:37
static Game Instance
Definition: Game.cs:149
void Zoom(double zoom)
Zoomaa.
Definition: Camera.cs:225
double Height
Näytön korkeus y-suunnassa.
Definition: View.cs:74
static ScreenView Screen
Näytön dimensiot, eli koko ja reunat.
Definition: Game.cs:194
Vector Position
Kameran sijainti.
Definition: Camera.cs:56
void Disable(ButtonState state)
Poistaa kosketuskontrollin k käytöstä.
Definition: TouchPanel.cs:177
double Y
Definition: Vector.cs:275
Peliluokka reaaliaikaisille peleille.
Definition: DebugScreen.cs:10
delegate void TouchHandler< T1, T2 >(Touch touch, T1 p1, T2 p2)
Ohjaintapahtumankäsittelijä kahdella parametrilla.
Listener ListenGestureOn(GameObject o, GestureType type, TouchHandler handler, string helpText)
Definition: TouchPanel.cs:320
Listener Listen(ButtonState state, TouchHandler handler, string helpText)
Definition: TouchPanel.cs:295
GestureType
Kosketuseleen tyyppi.
Definition: GestureType.cs:10
Vector WorldDistanceBefore
Sormien etäisyysvektori maailmassa eleen alussa.
Definition: Gesture.cs:63
ListenContext ControlContext
Pelin pääohjainkonteksti.
Definition: Game.cs:217
double X
Definition: Vector.cs:274
delegate void TouchHandler(Touch touch)
Ohjaintapahtumankäsittelijä ilman parametreja.
Listener ListenGesture(GestureType type, TouchHandler handler, string helpText)
Definition: TouchPanel.cs:307
Vector MovementOnWorld
Kosketuksen liike pelimaailmassa.
Definition: Touch.cs:64
Yhteinen rajapinta kaikille peliolioille.
Definition: IGameObject.cs:14
bool IsInside(Vector point)
Camera Camera
Kamera, joka näyttää ruudulla näkyvän osan kentästä. Kameraa voidaan siirtää, zoomata tai asettaa seu...
Definition: Game.cs:166
Key
Näppäimistön näppäin.
Definition: Key.cs:37
2D-vektori.
Definition: Vector.cs:56
delegate void TouchHandler< T1, T2, T3, T4 >(Touch touch, T1 p1, T2 p2, T3 p3, T4 p4)
Ohjaintapahtumankäsittelijä neljällä parametrilla.
double Width
Näytön leveys x-suunnassa.
Definition: View.cs:66
Pelialueella liikkuva olio. Käytä fysiikkapeleissä PhysicsObject-olioita.
Definition: __GameObject.cs:54
Vector ScreenToWorld(Vector point)
Muuntaa annetun pisteen ruutukoordinaateista maailmankoordinaatteihin.
Definition: Camera.cs:168
override void Clear()
Definition: TouchPanel.cs:147
Keyboard Keyboard
Näppäimistö.
Definition: Controls.cs:153
Yleinen peliohjainluokka.
Definition: Controller.cs:40