Project

General

Profile

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

sokoban / distorted-sokoban / src / main / java / org / distorted / sokoban / SokobanCanvas.java @ 839651ce

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

    
165
///////////////////////////////////////////////////////////////////
166

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

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

    
180
///////////////////////////////////////////////////////////////////
181

    
182
	public Activity getActivity()
183
	{
184
		return mAct;
185
	}
186
	
187
///////////////////////////////////////////////////////////////////
188
	
189
	public static void init(Activity act)
190
	{
191
		Log.d(TAG_CANVAS, "init");
192
		
193
		Resources res = act.getResources();
194
		isKorean = res.getInteger(R.integer.is_korean);
195
		
196
	    if( scrWidth<=0 || scrHeight<=0 )
197
		  {
198
		  DisplayMetrics dm = new DisplayMetrics();
199
		  act.getWindowManager().getDefaultDisplay().getMetrics(dm);
200
		  
201
		  scrWidth = Math.min(dm.widthPixels,dm.heightPixels);
202
		  scrHeight= Math.max(dm.widthPixels,dm.heightPixels);
203
		  }
204
		
205
		if( mCanvas==null ) mCanvas = new SokobanCanvas((Context)act);
206
	}
207
	
208
///////////////////////////////////////////////////////////////////
209
	
210
	public static SokobanCanvas getCanvas(Activity act)
211
	{
212
		init(act);
213
		return mCanvas;
214
	}
215
	
216
///////////////////////////////////////////////////////////////////
217

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

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

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

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

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

    
275
///////////////////////////////////////////////////////////////////
276

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

    
297
///////////////////////////////////////////////////////////////////
298

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

    
304
///////////////////////////////////////////////////////////////////
305

    
306
    public SokobanRecords getRecords()
307
    {
308
    	return mRecords;
309
    }
310

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

    
318
///////////////////////////////////////////////////////////////////
319

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

    
329
///////////////////////////////////////////////////////////////////
330

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

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

    
374
///////////////////////////////////////////////////////////////////
375

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

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

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

    
409
		  return true;
410
	  }
411

    
412
///////////////////////////////////////////////////////////////////
413

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

    
422
		refreshScreen = true;
423
	}
424
	
425
///////////////////////////////////////////////////////////////////
426

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

    
435
		refreshScreen = true;
436
	}
437
	
438
///////////////////////////////////////////////////////////////////
439

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

    
448
		refreshScreen= true;
449
	}
450
	
451
///////////////////////////////////////////////////////////////////
452

    
453
	  
454
	public static String getIso()
455
	{
456
		if( isKorean==1 )
457
		  {
458
		  return "kr";
459
		  }
460
		else
461
		  {
462
          String ret="";
463
		
464
		  TelephonyManager tM =((TelephonyManager) mAct.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE));
465
		
466
		  if( tM!=null )
467
	        {
468
		    ret = tM.getSimCountryIso();
469
		  
470
		    if( ret==null || ret.length()<=1 )
471
		      {
472
			  ret = tM.getNetworkCountryIso();  
473
		      }
474
		    }
475
		
476
		  return ret;
477
		  }		
478
	}
479
	
480
///////////////////////////////////////////////////////////////////
481

    
482
	public static void setDestroy(boolean d)
483
	{
484
		mDestroy = d;
485
	}
486
	
487
///////////////////////////////////////////////////////////////////
488

    
489
	public static boolean getDestroy()
490
	{
491
		return mDestroy;
492
	}
493
		   
494

    
495
///////////////////////////////////////////////////////////////////
496

    
497
	public void sendMail()
498
	{
499
		try
500
		  {
501
		  mDestroy = false;	
502
		  final Intent email = new Intent(android.content.Intent.ACTION_SEND);
503
		  email.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
504
		  email.setType("message/rfc822");
505
		  email.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{strEmail});
506
		  email.putExtra(android.content.Intent.EXTRA_SUBJECT, strName+" v."+mVersionStr);
507
		  mAct.startActivity(Intent.createChooser(email, "Send mail..."));
508
		  }
509
		catch( Exception ex )
510
		  {
511
		  Log.e( TAG_CANVAS, "No email application!");		
512
		  }
513
	}
514

    
515
///////////////////////////////////////////////////////////////////
516

    
517
	public static void setState(int state)
518
	{
519
		currState = state;
520
	}
521

    
522
///////////////////////////////////////////////////////////////////
523

    
524
	public static int getState()
525
	{
526
		return currState;
527
	}
528

    
529
///////////////////////////////////////////////////////////////////
530

    
531
	public static SokobanMenu getMenu()
532
	{
533
		return mMenu;
534
	}
535

    
536
///////////////////////////////////////////////////////////////////
537
// end of SokobanCanvas
538
}
(2-2/14)