最近在做一个Android小游戏,使用SurfaceView实现,在为游戏加过关动画的时候遇到了麻烦,记录于此,供大家参考。在SurfaceView中,加动画有两种方式,一种是在Canvas上画出图形,然后对图形的位置、大小等参数进行改变来实现动画效果;另一种是使用Animation类。
对于在SurfaeView上实现第二种方式的动画,有很多值得注意的地方,当然网上有一种将View和SurfaceView同时显示,利用View去实现动画的方法 ,虽然可以,但感觉太麻烦。开始入题:
首先,提醒大家,在SurfaceView中,只能对整个Canvas播放动画,而不能对某个画出来的图形播放动画;
其次,要想看到动画效果,必须先为SurfaceView设置背景,setBackgroundXXX(),有三个可用方法,可任意选用,视情况而定
最后,在播放玩动画后,你会发现原来画的东西看不到了,只能看到背景,这时候要去掉这个背景,调用SurfaceView的setBackgroundResource(0)方法,参数0表示去掉背景。
来一段实例
private MessageHandler messageHandler;
public GameView(Context context) {
......
Looper looper = Looper.getMainLooper();
messageHandler = new MessageHandler(looper);
......
}
//播放过关动画
private void playAnimation() {
//收缩
ScaleAnimation mScaleAnimation = new ScaleAnimation(1.0f, 0f,
1.0f, 0f, Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
mScaleAnimation.setDuration(3000);
//旋转
RotateAnimation mRotateAnimation = new RotateAnimation(0.0f, 1000.0f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
mRotateAnimation.setDuration(3000);
//更新背景必须在主线程中调用,所以使用了MessageHandler
GameView.this.setBackgroundResource(ResourceUtil.nextLevelImage);
AnimationSet animationSet = new AnimationSet(true);
animationSet.addAnimation(mRotateAnimation);
animationSet.addAnimation(mScaleAnimation);
GameView.this.setAnimation(animationSet);
animationSet.startNow();
//这里使用Timer在动画播放后将背景去掉,注意控制时间
Timer tempTimer = new Timer();
tempTimer.schedule(new TimerTask() {
@Override
public void run() {
GameView.this.setBackgroundResource(0);
}
}, 3000);
}
class MessageHandler extends Handler {
public MessageHandler (Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
if(msg.what == Play_Animation_Message)
playAnimation();
}
}
在要播放动画的地方加入以下代码
Message msg = new Message();
msg.what = Play_Animation_Message; //构造Message对象
messageHandler.sendMessage(msg); //发送Message,将由MessageHandler来处理
以下是效果截图:
大家有什么更好的方法,欢迎分享交流!