package de.cwde.freeshisen;
+import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
+import android.app.AlertDialog;
import android.content.Context;
+import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Typeface;
import android.os.Handler;
import android.os.Message;
+import android.preference.PreferenceManager;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
class ShisenShoView extends SurfaceView implements SurfaceHolder.Callback {
+ private static final String INVALID_TIME = "9:99:99";
private static final String COLOR_TEXT = "#FFFFFF";
private static final String COLOR_TEXT_SHADOW = "#000000";
private static final String COLOR_HINT = "#F0C000";
private int tileWidth;
private Bitmap bg;
private Bitmap tile[];
- private Point selection1 = new Point(0,0);
- private Point selection2 = new Point(0,0);
- private List<Point> path=null;
- private List<Line> pairs=null;
+ private Point selection1 = new Point(0, 0);
+ private Point selection2 = new Point(0, 0);
+ private List<Point> path = null;
+ private List<Line> pairs = null;
private long startTime;
private long playTime;
private long baseTime;
private Timer timer;
- private static Handler timerHandler;
- private boolean timerRegistered=false;
+ static class hHandler extends Handler {
+ private final WeakReference<ShisenShoView> mTarget;
+
+ hHandler(ShisenShoView target) {
+ mTarget = new WeakReference<ShisenShoView>(target);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ ShisenShoView target = mTarget.get();
+ if (target != null)
+ target.onUpdateTime();
+ }
+ }
+
+ private Handler timerHandler = new hHandler(this);
+
+ private boolean timerRegistered = false;
private ShisenSho app;
private StatePlay cstate;
private StatePaint pstate;
private Canvas canvas = null;
private SurfaceHolder surfaceHolder = null;
+ private String time = INVALID_TIME;
public ShisenShoView(ShisenSho shishenSho) {
super((Context) shishenSho);
}
public ShisenShoView(Context ctx) {
- super((Context) ctx);
- // silence lint?
+ super(ctx);
+ this.app = (ShisenSho) ctx;
+ cstate = StatePlay.UNINITIALIZED;
+ surfaceHolder = getHolder();
+ surfaceHolder.addCallback(this);
}
private void paint(StatePaint pstate) {
}
private void registerTimer() {
- if (timer!=null) return; // Already registered
- timerHandler = new Handler() {
- public void handleMessage(Message msg) {
- onUpdateTime();
- }
- };
- timer=new Timer();
+ if (timer != null)
+ return; // Already registered
+ timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
timerHandler.sendEmptyMessage(Activity.RESULT_OK);
}
}, 0, 1000);
- timerRegistered=true;
+ timerRegistered = true;
}
private void unregisterTimer() {
- if (timer==null) return; // Already unregistered
+ if (timer == null)
+ return; // Already unregistered
timer.cancel();
timer = null;
- timerHandler = null;
- timerRegistered=false;
+ timerRegistered = false;
}
public void pauseTime() {
startTime=System.currentTimeMillis();
playTime=0;
baseTime=0;
- if (app.timeCounter && !timerRegistered) {
+ if (!timerRegistered) {
registerTimer();
}
pairs=app.board.getPairs(1);
private void onUndoActivate() {
if (app.board.getCanUndo()) {
- if (cstate==StatePlay.GAMEOVER && app.timeCounter && !timerRegistered) {
+ if (cstate==StatePlay.GAMEOVER && !timerRegistered) {
// Reprogram the time update that had been
// deactivated with the game over status
registerTimer();
}
public void onTimeCounterActivate() {
- if (app.timeCounter && cstate!=StatePlay.GAMEOVER && !timerRegistered) {
+ if (cstate!=StatePlay.GAMEOVER && !timerRegistered) {
// Reprogram the time update that had been
// deactivated with the time_counter=false
registerTimer();
private void onUpdateTime() {
paint(pstate);
- if (!(app.timeCounter && cstate!=StatePlay.GAMEOVER)) {
+ if (cstate==StatePlay.GAMEOVER) {
unregisterTimer();
}
}
protected void doDraw(Canvas canvas) {
try {
- // Double buffering
- // Bitmap buffer = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
- //Canvas cbuffer = new Canvas(buffer);
- Canvas cbuffer = canvas;
if (canvas == null) return;
- //super.onDraw(canvas);
-
// Board upper left corner on screen
int x0=0;
int y0=0;
int selectcolor = Color.parseColor(COLOR_SELECTED);
int hintcolor = Color.parseColor(COLOR_HINT);
- Paint paint = new Paint();
- paint.setFlags(Paint.ANTI_ALIAS_FLAG);
// Background & board painting
switch (pstate) {
int bgHeight = bg.getHeight();
for (int i=0; i<screenHeight/bgHeight+1; i++) {
for (int j=0; j<screenWidth/bgWidth+1; j++) {
- cbuffer.drawBitmap(bg, j*bgWidth, i*bgHeight, paint);
+ canvas.drawBitmap(bg, j*bgWidth, i*bgHeight, null);
}
}
// Tiles are 56px height, 40px width each
char piece=app.board.board[i][j];
if (piece!=0) {
- cbuffer.drawBitmap(tile[piece], x0+j*tileWidth, y0+i*tileHeight, paint);
+ canvas.drawBitmap(tile[piece], x0+j*tileWidth, y0+i*tileHeight, null);
}
}
}
break;
}
- // Red rectangle for selection 1
+ // rectangle for selection 1
switch (pstate) {
case SELECTED1:
case SELECTED2:
case MATCHED:
- highlightTile(cbuffer, x0, y0, selection1, selectcolor);
+ highlightTile(canvas, x0, y0, selection1, selectcolor);
break;
}
- // Red rectangle for selection 2
+ // rectangle for selection 2
switch (pstate) {
case SELECTED2:
case MATCHED:
- highlightTile(cbuffer, x0, y0, selection2, selectcolor);
+ highlightTile(canvas, x0, y0, selection2, selectcolor);
break;
}
// Matching path
switch (pstate) {
case MATCHED:
- paint.setColor(selectcolor);
- paint.setStyle(Style.STROKE);
- paint.setStrokeCap(Cap.ROUND);
- paint.setStrokeJoin(Join.ROUND);
- paint.setStrokeWidth(3);
-
if (path!=null) {
Point p0=null;
for (Point p1 : path) {
if (p0!=null) {
- drawLine(cbuffer, x0, y0, p0, p1, paint);
+ drawLine(canvas, x0, y0, p0, p1, selectcolor);
}
p0=p1;
}
break;
}
- // Orange hint rectangles
+ // hint rectangles
switch (pstate) {
case HINT:
if (pairs != null && pairs.size() > 0) {
Point a = pair.a;
Point b = pair.b;
path = app.board.getPath(a, b);
- paint.setColor(hintcolor);
- paint.setStyle(Style.STROKE);
- paint.setStrokeCap(Cap.ROUND);
- paint.setStrokeJoin(Join.ROUND);
- paint.setStrokeWidth(3);
- highlightTile(cbuffer, x0, y0, a, hintcolor);
+ highlightTile(canvas, x0, y0, a, hintcolor);
if (path != null) {
Point p0 = null;
for (Point p1 : path) {
if (p0 != null) {
- drawLine(cbuffer, x0, y0, p0, p1, paint);
+ drawLine(canvas, x0, y0, p0, p1, hintcolor);
}
p0 = p1;
}
path = null;
}
- highlightTile(cbuffer, x0, y0, b, hintcolor);
+ highlightTile(canvas, x0, y0, b, hintcolor);
}
break;
}
// Win & loose notifications
switch (pstate) {
case WIN:
- drawMessage(cbuffer, screenWidth / 2, screenHeight / 2, true,
+ drawMessage(canvas, screenWidth / 2, screenHeight / 2, true,
"You Win!", 100);
break;
case LOSE:
- drawMessage(cbuffer, screenWidth / 2, screenHeight / 2, true,
+ drawMessage(canvas, screenWidth / 2, screenHeight / 2, true,
"Game Over", 100);
break;
}
- if (app.timeCounter) switch (pstate) {
+ switch (pstate) {
case BOARD:
case SELECTED1:
case SELECTED2:
int hours = (int) (playTime / (60 * 60));
int minutes = (int) ((playTime / 60) % 60);
int seconds = (int) (playTime % 60);
- String time = String.format(Locale.US, "%01d:%02d:%02d",
- hours, minutes, seconds);
+ if (hours < 10) {
+ time = String.format(Locale.US, "%01d:%02d:%02d",
+ hours, minutes, seconds);
+ } else {
+ time = INVALID_TIME;
+ }
int timePosX=screenWidth-120;
int timePosY=screenHeight-10;
-
- drawMessage(cbuffer, timePosX, timePosY, false, time, 30);
- break;
- }
-
- // Debug messages
- /*
- debugMessage="StatePlay: "+cstate+"\n"+"StatePaint: "+pstate;
- if (debugMessage!=null && debugMessage.length()>0) {
- int l = 20;
- String lines[] = debugMessage.split("\n");
- for (int i=0; i<lines.length; i++) {
- drawMessage(cbuffer,1,l,false,lines[i],"#FFFF00",30);
- l+=30;
+
+ if (app.timeCounter) {
+ drawMessage(canvas, timePosX, timePosY, false, time, 30);
}
+ break;
}
- */
-
- // Double buffer dumping
- // canvas.drawBitmap(buffer, 0, 0, null);
} catch (Exception e) {
e.printStackTrace();
}
- private void drawLine(Canvas cbuffer, int x0, int y0, Point p0, Point p1,
- Paint paint) {
- cbuffer.drawLine(
+ private void drawLine(Canvas canvas, int x0, int y0, Point p0, Point p1, int color) {
+ Paint paint = new Paint();
+ paint.setFlags(Paint.ANTI_ALIAS_FLAG);
+ paint.setColor(color);
+ paint.setStyle(Style.STROKE);
+ paint.setStrokeCap(Cap.ROUND);
+ paint.setStrokeJoin(Join.ROUND);
+ paint.setStrokeWidth(3);
+ canvas.drawLine(
x0 + p0.j * tileWidth - 2 + (tileWidth / 2),
y0 + p0.i * tileHeight - 2 + (tileHeight / 2),
x0 + p1.j * tileWidth - 2 + (tileWidth / 2),
y0 + p1.i * tileHeight - 2 + (tileHeight / 2), paint);
}
- private void highlightTile(Canvas cbuffer, int x0, int y0, Point p, int color) {
+ private void highlightTile(Canvas canvas, int x0, int y0, Point p, int color) {
Paint paint = new Paint();
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setColor(color);
Rect r = new Rect(
x0 + p.j * tileWidth - 2,
y0 + p.i * tileHeight - 2,
- x0 + p.j * tileWidth * 2 + 2,
- y0 + p.i * tileHeight * 2 + 2);
- cbuffer.drawRect(r, paint);
+ x0 + p.j * tileWidth + tileWidth + 2,
+ y0 + p.i * tileHeight + tileHeight + 2);
+ canvas.drawRect(r, paint);
}
@Override
if (pairs.size() == 0) {
if (app.board.getNumPieces() == 0) {
paint(StatePaint.WIN);
+ checkforhiscore();
} else {
paint(StatePaint.LOSE);
}
}
}
+ private void checkforhiscore() {
+ if (timerRegistered) {
+ unregisterTimer();
+ }
+ final String[] sizes = { "S", "M", "L" };
+ final String[] diffs = { "E", "H" };
+ String prefname1 = "hiscore_" + diffs[app.difficulty-1] + sizes[app.size-1] + "1";
+ String prefname2 = "hiscore_" + diffs[app.difficulty-1] + sizes[app.size-1] + "2";
+ // get hiscores for current size/difficulty
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(app);
+ String besttime1 = sp.getString(prefname1, INVALID_TIME);
+ String besttime2 = sp.getString(prefname2, INVALID_TIME);
+ // did we win something?
+ if (time.compareTo(besttime2) < 0) {
+ // score!
+ new AlertDialog.Builder(app.activity)
+ .setTitle("Hiscore!")
+ .setCancelable(true)
+ .setIcon(R.drawable.icon)
+ .setPositiveButton(app.getString(android.R.string.ok), null)
+ .setMessage("You've made the highscore list!").create() // FIXME: hardcoded string
+ .show();
+
+ SharedPreferences.Editor editor = sp.edit();
+ if (time.compareTo(besttime1) < 0) {
+ editor.putString(prefname1, time);
+ editor.putString(prefname2, besttime1);
+ } else {
+ editor.putString(prefname2, time);
+ }
+ editor.commit();
+ }
+ }
+
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
surfaceHolder = holder;
- if (cstate!=StatePlay.GAMEOVER && app.timeCounter && !timerRegistered) {
+ if (cstate!=StatePlay.GAMEOVER && !timerRegistered) {
registerTimer();
}
repaint();