轉載 : http://cwq.yfjhh.com/2009/05/android.html
該遊戲對象移動,以view的背景作動畫,假設開始的位置是父View座標的(0,0)
遊戲角色view的事件監聽應該在父view中監聽。
同時注意,AnimationDrawable.start()不能在Activity.onCreate事件未執行完就調用,
但可以用在比如點擊按紐後就調用等。
public class Dog extends View implements OnKeyListener, Runnable {
// 左右移動對應不同的背景動畫,用這個記下當前的背景動畫
private AnimationDrawable nowAnim;
// 左移動對應的背景動畫
private AnimationDrawable animLeft;
// 右移動對應的背景動畫
private AnimationDrawable animRight;
private View parent;
// 記下view的座標位置,用於移動後重畫該地區。該座標是相對於父View的。
// 同時要注意,如果父View是有padding的,要算上,因為是以父Vew的左上方點為原點的
// padding最好為每次位移量的正倍數。l,t,r,b為即時的座標位置,step為每次位移量
private int l=0,t=0,r=22,b=20,step=3;
public Dog(Context context, View parent) {
super(context);
// TODO Auto-generated constructor stub
this.parent = parent;
// 記下父容器,即父View
l += parent.getPaddingLeft(); t += parent.getPaddingTop();
r += parent.getPaddingRight(); b += parent.getPaddingBottom();
// 如果父view有padding,要算上,因為view的座標是以父view的左上方為原點的
// 產生左和右移動對應的背景動畫,其實只是一個png,有對象移動時是的幾個圖片,將其分拆成移動的動畫
animLeft = AndroidUtils.animationFromSplitImage(
context, R.drawable.woniu, 22, 20, 200);
// 只需一個移動方向的png就行了,該animationFromSplitImage函數是將映像水來翻轉。
animRight = AndroidUtils.animationFromSplitImage(
AndroidUtils.imageFlipHorizintal(context, R.drawable.woniu), 22, 20, 200);
setAnimationDrawable( animRight );
//this.setOnKeyListener( this );
}
private void setAnimationDrawable(AnimationDrawable anim) {
if( nowAnim != null ) {
nowAnim.stop();
// 必須要先stop才行,不然會影響到下一個動畫的情況
nowAnim = null;
}
nowAnim = anim;
this.setBackgroundDrawable(nowAnim);
}
// 返回當前的動畫,用於在其它地方控制停止等。
public AnimationDrawable getBgAnimationDrawable() {
return nowAnim;
}
public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if( event.getAction() == KeyEvent.ACTION_DOWN )
{
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_LEFT: {
if( getLeft()>parent.getPaddingLeft() ) {
// 左或右位移量,是相對當前View的座標
offsetLeftAndRight(-1*step);
// 記下當前的座標值,用於在父view中重畫經過的地區。
l -= step;
}
if( animLeft != nowAnim ) {
setAnimationDrawable( animLeft );
nowAnim.start();
}
break ;
}
case KeyEvent.KEYCODE_DPAD_RIGHT: {
if( getRight()<(parent.getWidth() - parent.getPaddingRight()) ) {
offsetLeftAndRight(step);
r += step;
}
if( animRight != nowAnim ) {
setAnimationDrawable( animRight );
nowAnim.start();
}
break ;
}
case KeyEvent.KEYCODE_DPAD_UP: {
if( getTop()>parent.getPaddingTop() ) {
offsetTopAndBottom(-1*step);
t -= step;
}
break ;
}
case KeyEvent.KEYCODE_DPAD_DOWN: {
if( getBottom()<(parent.getHeight() - parent.getPaddingBottom()) ) {
offsetTopAndBottom(step);
b += step;
}
break ;
}
case KeyEvent.KEYCODE_DPAD_CENTER: {
break ;
}
default: {}
}
repaint();
}
return true;
}
public void run() {
// TODO Auto-generated method stub
// 每次位移後,都重畫位移前的地區的內容
parent.invalidate(l,t,r,b);
}
public void repaint() {
this.post(this);
}
}