本文通过重写RelativeLayout实现消消乐逻辑以及动画效果。
地图信息:
Info类用来存储ImageView信息,除了图片坐标信息存储在ImageView的Tag中,其他关于图片的信息均存储在对应下表的Info对象中。
动画实现:
每一个图片都是一个ImageView,根据其位置设置一个Point对象的Tag,用来标记该ImageView的位置。在需要生成动画时,将需要产生动画的ImageView隐藏,然后在原布局上面使用一个动画层(RelativeLayout)进行动画,动画完毕之后,将动画层的View全部移除,再将原布局的ImageView显现,并设置对应的图片。动画全部使用平移动动画TranslateAnimation即可,主要需要实现动画位置的处理。
逻辑实现:
消除逻辑,判断该点上下左右相邻区域是否存在超过2个相同的type(图片种类的标识)。消除后上面的图片需要掉落几个位置的计数:从左到右,从下到上遍历整个图,如果遇到能够消除的,那么该列上面所有Info.downTime++,downTime即为该点需要下落的位置数。
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
public class GameBack extends RelativeLayout implements View.OnClickListener {
private ImageView[][] mImageItems;
private Bitmap[] mAllBitmaps;
private Info[][] mInfos;
//相关布局参数
private int mWidth;
private int maxLine = 9;
private int mPadding = 3;
private int mMargin = 3;
//第一次调用OnMeasuer
private boolean once = true;
private int mItemWidth;
//动画正在进行
private boolean isAnimation = false;
//动画层
private RelativeLayout mAnimationLayout;
//handler使用到的参数
private static final int DROP_TIME = 1000;
private static final int CHANGE_TIME = 300;
private static final int MESSAGE_TIME = 100;
private static final int BEGIN_TIME = 500;
public GameBack(Context context) {
this(context, null);
}
public GameBack(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public GameBack(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAllBitmaps();
initAnimationLayout();
handler.sendEmptyMessageDelayed(START_MESSAGE, BEGIN_TIME);
}
//初始化动画布局
private void initAnimationLayout() {
mAnimationLayout = new RelativeLayout(getContext());
//重要!! RelativeLayout 默认包裹内容
RelativeLayout.LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
addView(mAnimationLayout, lp);
}
private static final int START_MESSAGE = 0x00;
private static final int RESET_IMAGE = 0x01;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case START_MESSAGE:
if (checkAllImageView()) {
isAnimation = true;
setChangeTempImage();
} else {
isAnimation = false;
}
break;
case RESET_IMAGE:
setVisiable();
break;
}
}
};
//log信息
private void test() {
for (int i = 0; i < maxLine; i++) {
Log.i("shxy - state = ", mInfos[i][0].imageType + " " + mInfos[i][1].imageType + " " + mIn