Project

General

Profile

Download (14.4 KB) Statistics
| Branch: | Revision:

sokoban / distorted-sokoban / src / main / java / org / distorted / sokoban / SokobanCanvas.java @ 1f6d1786

1
package org.distorted.sokoban;
2

    
3
import android.app.Activity;
4
import android.content.Context;
5
import android.content.Intent;
6
import android.content.pm.PackageInfo;
7
import android.content.pm.PackageManager;
8
import android.content.pm.PackageManager.NameNotFoundException;
9
import android.content.res.Resources;
10
import android.graphics.Canvas;
11
import android.telephony.TelephonyManager;
12
import android.util.DisplayMetrics;
13
import android.util.Log;
14
import android.view.KeyEvent;
15
import android.view.MotionEvent;
16
import android.view.SurfaceHolder;
17
import android.view.SurfaceView;
18

    
19
import android.graphics.Paint;
20
import android.graphics.Paint.Style;
21

    
22
///////////////////////////////////////////////////////////////////
23

    
24
public class SokobanCanvas extends SurfaceView implements SurfaceHolder.Callback
25
{
26
	private static final String TAG_CANVAS = "SokobanCanvas";
27
	private static String strEmail, strName;
28
	
29
	public static final int STATE_MAIN = 1;
30
    public static final int STATE_PLAY = 2;
31
      public static final int STATE_TIME =3;
32
      public static final int STATE_NEWR =4;
33
        public static final int STATE_SUBM = 5;
34
          public static final int STATE_FAIL = 6; 
35
          public static final int STATE_RECO = 7; 
36
          public static final int STATE_EXIS = 8;
37
          public static final int STATE_SECU = 9;
38
        public static final int STATE_NAME = 10;
39
    public static final int STATE_MENU = 11;
40
      public static final int STATE_DOWN = 12;
41
        public static final int STATE_FAID = 13;
42
        public static final int STATE_SUCD = 14;
43
      public static final int STATE_DOWL = 15;
44
        public static final int STATE_FAIE = 16;
45
        public static final int STATE_SUCE = 17;
46
      public static final int STATE_CREA = 18;
47
        public static final int STATE_CRED = 19;
48
          public static final int STATE_CRES = 20;
49
            public static final int STATE_SUBC = 21;
50
              public static final int STATE_FAIC = 22;
51
              public static final int STATE_SUCC = 23;
52
      public static final int STATE_HELP = 24;
53

    
54
  	public  static final int COLOR_BAR   = 0xfffde051;
55
  	public  static final int COLOR_BLACK = 0xff000000;
56
  	public  static final int COLOR_RED   = 0xffff0000;
57
  	public  static final int COLOR_GREY  = 0xff444444;
58
  	public  static final int COLOR_WHITE = 0xffffffff;
59
  	public  static final int COLOR_DIALOG= 0xff447da7;
60

    
61
  	private static final int FRAME_INTERVAL = 70;
62

    
63
    private static int currState = STATE_MAIN;
64
    private static int scrWidth, scrHeight;
65

    
66
    private static SokobanMenu    mMenu;
67
    private static SokobanLevels  mLevels;
68
    private static SokobanRecords mRecords;
69
    private static Activity       mAct;
70
    private static SokobanCanvas  mCanvas;
71
    
72
	private static boolean mDestroy = true;
73
	private static boolean refreshScreen = true;
74
	private static boolean mFinishedBooting=false;  
75
	private GraphicsThread mThread;
76
	public  static String mVersionStr="";
77
	private Paint mPaint = new Paint();
78

    
79
    private class GraphicsThread extends Thread 
80
    {
81
        private SurfaceHolder mSurfaceHolder;
82
        private SokobanCanvas mCanvas;
83
        private boolean mRun = false;
84
     
85
        public GraphicsThread(SurfaceHolder surfaceHolder, SokobanCanvas c) 
86
        {
87
            mSurfaceHolder = surfaceHolder;
88
            mCanvas = c;
89
        }
90
     
91
        public void setRunning(boolean run) 
92
        {
93
            mRun = run;
94
        }
95
     
96
        public void run() 
97
          {	
98
          Canvas c;
99
          long time;
100
        	
101
          while (mRun) 
102
            {
103
            c = null;
104
            time = 0;
105
                
106
            if( refreshScreen && mFinishedBooting )
107
              {
108
              refreshScreen=false;	
109
              time = System.currentTimeMillis();
110
                  
111
              try 
112
                {
113
                c = mSurfaceHolder.lockCanvas(null);
114
                synchronized (mSurfaceHolder) { mCanvas.drawSurface(c); }
115
                } 
116
              finally 
117
                {
118
                if (c != null)  mSurfaceHolder.unlockCanvasAndPost(c);
119
                }
120
              
121
              time = System.currentTimeMillis() -time;
122
              }
123
                
124
            if( time<FRAME_INTERVAL )
125
              {
126
              try { Thread.sleep(FRAME_INTERVAL-time); }
127
              catch(InterruptedException ex) {}
128
              }
129
            }
130
          }
131
    };
132
    
133
///////////////////////////////////////////////////////////////////
134
	
135
	private SokobanCanvas(Context context)
136
	{		
137
		super(context);
138
		  
139
	    try 
140
	      {
141
	      PackageManager pm = context.getPackageManager();   
142
	      PackageInfo pi =  pm.getPackageInfo( "org.distorted.sokoban", 0);
143
	      mVersionStr = pi.versionName;
144
	      } 
145
	    catch (NameNotFoundException e)  { }
146
	    
147
	    mMenu   = new SokobanMenu(context,this);    
148
	    mRecords= new SokobanRecords();
149
	    
150
	    mPaint.setColor(SokobanLevels.COLOR_BLACK);
151
	    mPaint.setStyle(Style.FILL);
152
	    
153
	    getHolder().addCallback(this);
154
        setFocusable(true);
155
        setFocusableInTouchMode(true);
156
	    
157
        strEmail = context.getString(R.string.email);
158
        strName  = context.getString(R.string.app_name);
159
        
160
        mFinishedBooting=true;
161
	}
162
	
163

    
164
///////////////////////////////////////////////////////////////////
165

    
166
	public synchronized void deallocate()
167
	{
168
		stopThread();
169
		
170
	}
171

    
172
///////////////////////////////////////////////////////////////////
173
	
174
	public static void setActivity(Activity act)
175
	{
176
		mAct = act;
177
	}
178

    
179
///////////////////////////////////////////////////////////////////
180

    
181
	public Activity getActivity()
182
	{
183
		return mAct;
184
	}
185
	
186
///////////////////////////////////////////////////////////////////
187
	
188
	public static void init(Activity act)
189
	{
190
		Log.d(TAG_CANVAS, "init");
191
		
192
		Resources res = act.getResources();
193

    
194
	  if( scrWidth<=0 || scrHeight<=0 )
195
		  {
196
		  DisplayMetrics dm = new DisplayMetrics();
197
		  act.getWindowManager().getDefaultDisplay().getMetrics(dm);
198
		  
199
		  scrWidth = Math.min(dm.widthPixels,dm.heightPixels);
200
		  scrHeight= Math.max(dm.widthPixels,dm.heightPixels);
201
		  }
202
		
203
		if( mCanvas==null ) mCanvas = new SokobanCanvas((Context)act);
204
	}
205
	
206
///////////////////////////////////////////////////////////////////
207
	
208
	public static SokobanCanvas getCanvas(Activity act)
209
	{
210
		init(act);
211
		return mCanvas;
212
	}
213
	
214
///////////////////////////////////////////////////////////////////
215

    
216
	public static boolean isCreated()
217
	{
218
		return mCanvas!=null;
219
	}
220
	
221
///////////////////////////////////////////////////////////////////
222

    
223
	public int getScrWidth()
224
	{
225
		return scrWidth;
226
	}
227
	
228
///////////////////////////////////////////////////////////////////
229

    
230
	public int getScrHeight()
231
	{
232
		return scrHeight;
233
	}
234
	
235
///////////////////////////////////////////////////////////////////
236
	
237
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) 
238
    {
239
    	Log.e( TAG_CANVAS, "surfaceChanged: width="+w+" height="+h);   
240
    	
241
    	int width  = Math.min(w,h);
242
    	int height = Math.max(w,h);
243
    	
244
    	if( mMenu  !=null ) mMenu.setScrDimensions(width,height);
245
    	if( mLevels!=null) mLevels.setScrDimensions(width,height);
246
    	
247
    	scrWidth = width;
248
    	scrHeight= height;
249
   	    refreshScreen = true;
250
    }
251
 
252
///////////////////////////////////////////////////////////////////
253

    
254
    public void surfaceCreated(SurfaceHolder holder) 
255
    {
256
    	Log.e( TAG_CANVAS, "surfaceCreated");
257
    	
258
    	mThread = new GraphicsThread(getHolder(), this);
259
    	mThread.setRunning(true);
260
        mThread.start();
261
    }
262

    
263
///////////////////////////////////////////////////////////////////
264
    
265
    public void surfaceDestroyed(SurfaceHolder holder) 
266
    {
267
    	Log.e( TAG_CANVAS, "surfaceDestroyed");
268
    	      
269
        stopThread();
270
        mRecords.setDirty();
271
    }
272

    
273
///////////////////////////////////////////////////////////////////
274

    
275
    private void stopThread()
276
    {
277
        if( mThread!=null )
278
        {
279
        	boolean retry = true;
280
        	mThread.setRunning(false);
281
        
282
        	while (retry) 
283
        	{
284
        		try 
285
        		{
286
        			mThread.join();
287
        			retry = false;
288
        		} 
289
        		catch (InterruptedException e) { Log.e( TAG_CANVAS, "Joining thread interrupted!"); }
290
        	}
291
        	mThread=null;
292
        }
293
    }
294

    
295
///////////////////////////////////////////////////////////////////
296

    
297
    public static void setLevels(SokobanLevels sl)
298
    {
299
    	mLevels = sl;    
300
    }
301

    
302
///////////////////////////////////////////////////////////////////
303

    
304
    public SokobanRecords getRecords()
305
    {
306
    	return mRecords;
307
    }
308

    
309
///////////////////////////////////////////////////////////////////
310
    
311
	protected void onDraw(Canvas c)
312
	{
313
	drawSurface(c);
314
	}
315

    
316
///////////////////////////////////////////////////////////////////
317

    
318
  private void drawSurface(Canvas c)
319
		{
320
	  if( c!=null )
321
		  {
322
			if( mLevels!=null ) mLevels.render(currState,c);
323
			if( mMenu  !=null ) mMenu.render(currState,c);
324
		  }
325
		}
326

    
327
///////////////////////////////////////////////////////////////////
328

    
329
    public static void setRepaint()
330
    {
331
    	refreshScreen=true;
332
    }
333
   
334
///////////////////////////////////////////////////////////////////
335

    
336
	public boolean onKeyDown( int keyCode, KeyEvent event)
337
	{
338
		if( mMenu==null || mLevels==null ) return false;
339
	         
340
		switch(keyCode)
341
		{
342
		case KeyEvent.KEYCODE_MENU: mMenu.setPointerState(currState,  scrWidth/4,scrHeight,true);
343
			 					    refreshScreen = true;
344
			  					    break;
345
		case KeyEvent.KEYCODE_BACK: mMenu.setPointerState(currState,3*scrWidth/4,scrHeight,true);	
346
		  		                    refreshScreen = true;
347
		                            break;                     
348
		}
349
		  
350
		if( currState==STATE_PLAY || currState==STATE_CREA || currState==STATE_CRES )
351
		{
352
			switch(keyCode)
353
			{
354
			case KeyEvent.KEYCODE_DPAD_UP   : mLevels.keyboardMovePlayer(currState,1);
355
			  		                          refreshScreen = true; 
356
			  		                          break;
357
			case KeyEvent.KEYCODE_DPAD_DOWN : mLevels.keyboardMovePlayer(currState,3);
358
			                                  refreshScreen = true; 
359
			                                  break;
360
			case KeyEvent.KEYCODE_DPAD_LEFT : mLevels.keyboardMovePlayer(currState,4);
361
			                                  refreshScreen = true; 
362
			                                  break;
363
			case KeyEvent.KEYCODE_DPAD_RIGHT: mLevels.keyboardMovePlayer(currState,2);
364
			                                  refreshScreen = true; 
365
			                                  break;
366
			}
367
		}
368
		  
369
		return true;
370
	}
371

    
372
///////////////////////////////////////////////////////////////////
373

    
374
	  public boolean onKeyUp( int keyCode, KeyEvent event)
375
	  {
376
		  if( mMenu==null ) return false;
377
		  
378
		  switch(keyCode)
379
		  {
380
		  case KeyEvent.KEYCODE_MENU: mMenu.tryPress(currState,  scrWidth/4,scrHeight);
381
								      refreshScreen = true;
382
				  					  break;
383
		  case KeyEvent.KEYCODE_BACK: mMenu.tryPress(currState,3*scrWidth/4,scrHeight);
384
			  		                  refreshScreen = true;
385
			                          break;                     
386
		  }
387
		  
388
		  return true;
389
	  }
390
	  
391
///////////////////////////////////////////////////////////////////
392

    
393
	  public boolean onTouchEvent(MotionEvent event)
394
	  {
395
		  int action = event.getAction();
396

    
397
		  switch(action)
398
		  {
399
		  case MotionEvent.ACTION_DOWN: pointerPressed( (int)event.getX(), (int)event.getY() );
400
		  								break;
401
		  case MotionEvent.ACTION_UP  : pointerReleased((int)event.getX(), (int)event.getY() );
402
		  								break;
403
		  case MotionEvent.ACTION_MOVE: pointerDragged( (int)event.getX(), (int)event.getY() );
404
		  								break;
405
		  }
406

    
407
		  return true;
408
	  }
409

    
410
///////////////////////////////////////////////////////////////////
411

    
412
	private void pointerPressed(int x, int y)
413
	{
414
		if( mLevels==null || mMenu==null ) return;    
415
         
416
		mMenu.setPointerState(currState,x,y,true);
417
		if( currState==STATE_PLAY || currState==STATE_MAIN || currState==STATE_SUCD || currState==STATE_CREA || currState==STATE_CRES )
418
			mLevels.click(currState,x,y);
419

    
420
		refreshScreen = true;
421
	}
422
	
423
///////////////////////////////////////////////////////////////////
424

    
425
	private void pointerReleased(int x, int y)
426
	{
427
		if( mLevels==null || mMenu==null ) return;    
428
         
429
		mMenu.tryPress(currState,x,y);
430
		if( currState==STATE_PLAY || currState==STATE_MAIN || currState==STATE_SUCD || currState==STATE_CREA || currState==STATE_CRES )
431
			mLevels.unclick(currState,x,y);
432

    
433
		refreshScreen = true;
434
	}
435
	
436
///////////////////////////////////////////////////////////////////
437

    
438
	private void pointerDragged(int x, int y)
439
	{
440
		if( mLevels==null || mMenu==null ) return;    
441
	        
442
		mMenu.setPointerState(currState,x,y,false);
443
		if( currState==STATE_PLAY || currState==STATE_MAIN || currState==STATE_SUCD || currState==STATE_CREA || currState==STATE_CRES )
444
			mLevels.drag(currState,x,y);
445

    
446
		refreshScreen= true;
447
	}
448
	
449
///////////////////////////////////////////////////////////////////
450

    
451
	  
452
	public static String getIso()
453
	{
454
     String ret="";
455
		
456
		  TelephonyManager tM =((TelephonyManager) mAct.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE));
457
		
458
		  if( tM!=null )
459
	        {
460
		    ret = tM.getSimCountryIso();
461
		  
462
		    if( ret==null || ret.length()<=1 )
463
		      {
464
			  ret = tM.getNetworkCountryIso();  
465
		      }
466
		    }
467
		
468
		  return ret;
469
	}
470
	
471
///////////////////////////////////////////////////////////////////
472

    
473
	public static void setDestroy(boolean d)
474
	{
475
		mDestroy = d;
476
	}
477
	
478
///////////////////////////////////////////////////////////////////
479

    
480
	public static boolean getDestroy()
481
	{
482
		return mDestroy;
483
	}
484
		   
485

    
486
///////////////////////////////////////////////////////////////////
487

    
488
	public void sendMail()
489
	{
490
		try
491
		  {
492
		  mDestroy = false;	
493
		  final Intent email = new Intent(android.content.Intent.ACTION_SEND);
494
		  email.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
495
		  email.setType("message/rfc822");
496
		  email.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{strEmail});
497
		  email.putExtra(android.content.Intent.EXTRA_SUBJECT, strName+" v."+mVersionStr);
498
		  mAct.startActivity(Intent.createChooser(email, "Send mail..."));
499
		  }
500
		catch( Exception ex )
501
		  {
502
		  Log.e( TAG_CANVAS, "No email application!");		
503
		  }
504
	}
505

    
506
///////////////////////////////////////////////////////////////////
507

    
508
	public static void setState(int state)
509
	{
510
		currState = state;
511
	}
512

    
513
///////////////////////////////////////////////////////////////////
514

    
515
	public static int getState()
516
	{
517
		return currState;
518
	}
519

    
520
///////////////////////////////////////////////////////////////////
521

    
522
	public static SokobanMenu getMenu()
523
	{
524
		return mMenu;
525
	}
526

    
527
///////////////////////////////////////////////////////////////////
528
// end of SokobanCanvas
529
}
(2-2/12)