这个宠物蛇会跟踪人的手指,并且能随着不断移动而长大。当然如果他得不到锻炼,也会随着时间的推移而不断缩小。其主界面如下:
菜单部分,它实现了根据程序状态显示菜单内容,代码如下:
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Check information state
boolean bOpenInfo = mSnakeView.getInfoState();
// Change info item title.
MenuItem infoItem = menu.findItem(R.id.action_info);
infoItem.setTitle(bOpenInfo ? R.string.action_info_close : R.string.action_info_show);
return super.onPrepareOptionsMenu(menu);
}
宠物蛇活动部分,它会根据移动的方位来确定自己的走向。需要注意的是,蛇的起点也是在Canvas缩放中会改变的。这段代码如下,
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*Redraw snake by call invalidate when the bounds has been changed*/
float scale = getFactor();
//The original coordination will be changed by scale.
int x = (int)(mSnakeCoor.x/scale);
int y = (int)(mSnakeCoor.y/scale);
Matrix matrix = new Matrix();
//Rotate around with the center of image
int degree = 0;
if( mNextCoor.y!=0 || mNextCoor.x !=0){
degree = (int) (Math.atan2(mNextCoor.y, mNextCoor.x) * 180.0 / Math.PI) - 90;
}
matrix.preRotate( degree, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
matrix.postTranslate(x, y);
matrix.postScale(scale, scale);
canvas.drawBitmap(mBitmap, matrix, null);
matrix = null;
}
消息处理部分,它分两部分,一部分是定时移动宠物,另一部分是有按键或触摸是实时处理消息。前者代码为:
class SnakeHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if ( msg.what == SNAKE_MSG ) {
Bundle data = msg.getData();
int x = data.getInt("x");
int y = data.getInt("y");
//If snake is not changed position, don't relay message.
if ( x != 0 || y!= 0) {
//Set snake bounds and redraw it
setSnakeOffset(x, y);
//If snake runs out of view, adjust the step
float factor = getFactor();
//Change direction if need
if ((mSnakeCoor.x + x < 0) && x < 0 ||
(mBitmap.getWidth() * factor + mSnakeCoor.x + x > mScreen.widthPixels) && x > 0) {
data.putInt("x", -x);
}
if ((mSnakeCoor.y + y < 0) && y < 0 ||
(mBitmap.getHeight() * factor + mSnakeCoor.y + y > mScreen.heightPixels) && y > 0) {
data.putInt("y", -y);
}
mSnakeEnergy++;
Message newMsg = Message.obtain();
newMsg.what = SNAKE_MSG;
newMsg.setData(data);
mHandler.sendMessageDelayed(newMsg, 1000);
}
}
}
}
后者如按键处理的代码为:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Bundle data = new Bundle();
Message msg = Message.obtain();
int degree = 0;
int x = 0;
int y = 0;
switch( keyCode ){
case KeyEvent.KEYCODE_DPAD_UP:
Log.i(TAG, "key code:up");
x = 0;
y = -10;
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
Log.i(TAG, "key code:down");
x = 0;
y = 10;
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
Log.i(TAG, "key code:left");
x = -10;
y = 0;
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
Log.i(TAG, "key code:right");
x = 10;
y = 0;
break;
default:
break;
}
if ( x != 0 || y != 0 ) {
msg.what = SNAKE_MSG;
data.putInt("x", x);
data.putInt("y", y);
msg.setData(data);
//Remove message to make sure only one message in the message looper
mHandler.removeMessages(SNAKE_MSG);
mHandler.sendMessage(msg);
}
return true;
}
工程源代码:petsnake.rar