package com.andorid.link;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
public class GameView extends View{
private static final String TAG = "GameView";
Main app;
private static final Random random = new Random();
private RefreshHandler mRedrawHandler = new RefreshHandler();
class RefreshHandler extends Handler {
@Override
public void handleMessage(Message msg) {
GameView.this.updateView();
GameView.this.invalidate();
}
public void sleep(long delayMillis) {
this.removeMessages(0);
sendMessageDelayed(obtainMessage(0), delayMillis);
}
};
private int iconWidth = 32;
private int iconHeight = 32;
private static final int iconsCount = 27;
private int margin = iconWidth > iconHeight ? iconWidth : iconHeight;
private Bitmap[] icons = new Bitmap[iconsCount];;
private int[][] map;
private final Paint p = new Paint();
private final Paint pFont = new Paint();
private int countX, countY, offsetX, offsetY;
private boolean mCurDown;
private int curX, curY;
private int lastX, lastY;
private int count;
private List<Point> path = new ArrayList<Point>();
private String message;
private int help;
private static final int MILLIS_PER_TICK = 100;
long startTime, lastTime;
long time, remain;
private int drawState;
private static final int STATE_NORMAL = 0;
private static final int STATE_MARCHED = 1;
private static final int STATE_LINK = 2;
private boolean deadcheck;
public GameView(Context context) {
super(context);
app = (Main)context;
setFocusable(true);
loadIcons();
p.setARGB(255, 60, 60, 200);
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(2);
pFont.setARGB(255, 60, 60, 200);
pFont.setTextSize(16);
}
private void loadIcons() {
Resources r = this.getContext().getResources();
for (int i = 0; i < iconsCount; i++) {
icons[i] = ((BitmapDrawable)r.getDrawable(R.drawable.i1 + i)).getBitmap();
}
message = r.getText(R.string.help).toString();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
// TODO Auto-generated method stub
super.onLayout(changed, left, top, right, bottom);
if(Main.gameState == Main.STATE_START)
init(right-left, bottom-top);
startTime = System.currentTimeMillis();
}
private void init(int w, int h) {
curX = -1;
curY = -1;
lastX = -1;
lastY = -1;
count = 0;
countX = (int) Math.floor((w - margin * 2) / iconWidth);
countY = (int) Math.floor((h - margin * 2) / iconHeight);
if (countY % 2 != 0)
countY -= 1;
offsetX = ((w - (iconWidth * countX)) / 2);
offsetY = ((h - (iconHeight * countY)) / 2);
reset();
time = countX * countY * 2;
drawState = STATE_NORMAL;
help = 3;
}
private void reset() {
int i=0;
map = new int[countX][countY];
for (int x = 0; x < countX; x += 1) {
for (int y = 0; y < countY; y += 2) {
map[x][y] = map[x][y+1] = i++;
if(i == iconsCount)
i = 0;
}
}
shuffle();
}
private void shuffle() {
int tmpV, tmpX, tmpY;
for (int y = 0; y < countY; y++) {
for (int x = 0; x < countX; x++) {
tmpV = map[x][y];
tmpX = random.nextInt(countX);
tmpY = random.nextInt(countY);
map[x][y] = map[tmpX][tmpY];
map[tmpX][tmpY] = tmpV;
}
}
if(die()) {
shuffle();
}
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Log.v(TAG, "onDraw");
updateView();
for (int x = 0; x < countX; x += 1) {
for (int y = 0; y < countY; y += 1) {
if (map[x][y] > -1) {
Rect rDst = new Rect(offsetX + x * iconWidth,
offsetY + y * iconHeight, offsetX + (x+1) * iconWidth,
offsetY + (y+1) * iconHeight);
canvas.drawBitmap(icons[map[x][y]], null, rDst, p);
}
}
}
message = "帮助:" + help + "次 剩余时间:" + remain + "秒";
canvas.drawText(message, 0, message.length(), 15, 15, pFont);
if (curX > -1 && curY > -1 && map[curX][curY] > -1) {
canvas.drawRect(offsetX + iconWidth * curX, offsetY + iconHeight
* curY, offsetX + iconWidth * (curX + 1), offsetY
+ iconHeight * (curY + 1), p);
}
if(drawState != STATE_NORMAL) {
canvas.drawRect(sx(-1), sy(-1), sx(-1) + iconWidth, sy(-1) + iconHeight, p);
canvas.drawRect(sx(-2), sy(-2), sx(-2) + iconWidth, sy(-2) + iconHeight, p);
if(path.size() == 2) {
canvas.drawLine(sx(0) + iconWidth/2,
sy(0) + iconHeight/2,
sx(1) + iconWidth/2,
sy(1) + iconHeight/2, p);
}else if(path.size() == 3) {
canvas.drawLine(sx(0) + iconWidth/2,
sy(0) + iconHeight/2,
sx(1) + iconWidth/2,
sy(1) + iconHeight/2, p);
canvas.drawLine(sx(0) + iconWidth/2,
sy(0) + iconHeight/2,
sx(2) + iconWidth/2,
sy(2) + iconHeight/2, p);
}else if(path.size() == 4) {
canvas.drawLine(sx(0) + iconWidth/2,
sy(0) + iconHeight/2,
sx(1) + iconWidth/2,
sy(1) + iconHeight/2, p);
canvas.drawLine(sx(1) + iconWidth/2,
sy(1) + iconHeight/2,
sx(2) + iconWidth/2,
sy(2) + iconHeight/2, p);
canvas.drawLine(sx(3) + iconWidth/2,
sy(3) + iconHeight/2,
sx(0) + iconWidth/2,
sy(0) + iconHeight/2, p);
}
}
// invalidate();
}
// get screen x from listPath by index
int sx(int i) {
if(i<0)
return ((Point)path.get(path.size() + i)).x * iconWidth + offsetX;
else
return ((Point)path.get(i)).x * iconWidth + offsetX;
}
int sy(int i) {
if(i<0)
return ((Point)path.get(path.size() + i)).y * iconHeight + offsetY;
else
return ((Point)path.get(i)).y * iconHeight + offsetY;
}
private void updateView() {
if(Main.gameState == Main.STATE_START) {
if(System.currentTimeMillis() - lastTime < MILLIS_PER_TICK) {
return;
}
remain = time - (System.currentTimeMillis()-startTime)/1000;
if(remain<=0) {
Main.gameState = Main.STATE_LOST;
app.showMenu();
return;
}
if(drawState == STATE_MARCHED) {
drawState = STATE_LINK;
} else if(drawState == STATE_LINK) {
drawState = STATE_NORMAL;
path.clear();
if(die())
shuffle();
}
lastTime = System.currentTimeMillis();
mRedrawHandler.sleep(MILLIS_PER_TICK);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
mCurDown = action == MotionEvent.ACTION_DOWN;
if (mCurDown && drawState == STATE_NORMAL) {
// Log.v(TAG, "Checking start ********");
curX = curX2iconX((int) event.getX());
curY = curY2iconY((int) event.getY());
deadcheck = false;
if (lastX > -1 && lastY > -1 && curX > -1 && curY > -1
&& (lastX != curX || lastY != curY)
&& map[curX][curY] != -1
&& map[curX][curY] == map[lastX][lastY]
&& link(curX, curY, lastX, lastY)) {
// Log.v(TAG, "OK --------------");
drawState = STATE_MARCHED;
line(lastX, lastY);
line(curX, curY);
map[curX][curY] = -1;
map[lastX][lastY] = -1;
curX = lastX = -1;
curY = lastY = -1;
count += 2;
if (count == countX * countY) {
Main.gameState = Main.STATE_WIN;
app.score = remain + help * 3 + countX * countY /10;
app.showMenu();
}
} else {
lastX = curX;
lastY = curY;
}
// Log.v(TAG, "Checkin