1.GameActivity代码如下:
package com.dogstudio.popstart;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import com.dogstudio.popstart.view.GamePanel;
public class GameActivity extends Activity implements View.OnClickListener {
private ImageView mIvPause;
private ImageView mIvChange;
private ImageView mIvClickOne;
private GamePanel mGamepanel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
mIvPause = (ImageView) findViewById(R.id.iv_pause);
mIvChange = (ImageView) findViewById(R.id.iv_change);
mIvClickOne = (ImageView) findViewById(R.id.iv_click);
mGamepanel = (GamePanel) findViewById(R.id.game_panel);
mIvPause.setOnClickListener(this);
mIvChange.setOnClickListener(this);
mIvClickOne.setOnClickListener(this);
initData();
}
private void initData() {
mGamepanel.startGame();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.iv_pause:
break;
case R.id.iv_change:
break;
case R.id.iv_click:
break;
}
}
}
2.StartView,代表一个星星的View
public class StartView extends View {
private int type;
private boolean isSelect = false;
private Point mPoint;
private int mSize;
private Bitmap normalBitmap;
private Bitmap selBgBitmap;
private Paint mPaint;
private Matrix matrixNor;
private Matrix matrixSel;
public StartView(Context context) {
super(context);
init();
}
public StartView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
type = AppUtils.getRandom();
normalBitmap = LruLoader.get().getBitmapByType(type);
selBgBitmap = LruLoader.get().getSelBitmap();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mSize = AppUtils.getStartSize();
matrixNor = AppUtils.getScaleMatrix(normalBitmap.getWidth(), mSize);
matrixSel = AppUtils.getScaleMatrix(selBgBitmap.getWidth(), mSize);
}
public void setSelectState(boolean b) {
isSelect = b;
invalidate();
}
public int getType() {
return type;
}
public void setPosition(Point p) {
mPoint = p;
}
public Point getPosition() {
return mPoint;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(mSize, mSize);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(normalBitmap, matrixNor, mPaint);
if (isSelect) {
canvas.drawBitmap(selBgBitmap, matrixSel, mPaint);
}
}
@Override
public String toString() {
return "StartView{" +
"type=" + type +
", isSelect=" + isSelect +
", mPoint=" + mPoint +
'}';
}
}
3.GamePanel,存放一个10X10的StartView数组,处理触摸手势,消除星星,自动向下,向左合并。
public class GamePanel extends ViewGroup {
private StartView[][] mGroup;
private int block;
private boolean isSelected = false;
private ArrayList<StartView> selectedArea;
private StartView mCurrentView;
private OnScoreListener mListener;
public GamePanel(Context context) {
super(context);
init();
}
public GamePanel(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
block = Config.SCREEN_WIDTH / Config.SIZE;
selectedArea = new ArrayList<StartView>();
}
public void setOnScoreListener(OnScoreListener l) {
mListener = l;
}
public void startGame() {
mGroup = new StartView[Config.SIZE][Config.SIZE];
for (int i = 0; i < Config.SIZE; i++) {
for (int j = 0; j < Config.SIZE; j++) {
mGroup[i][j] = new StartView(getContext());
addView(mGroup[i][j]);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mGroup != null) {
for (int i = 0; i < Config.SIZE; i++) {
for (int j = 0; j < Config.SIZE; j++) {
if (mGroup[i][j] != null) {
mGroup[i][j].measure(widthMeasureSpec, heightMeasureSpec);
}
}
}
}
setMeasuredDimension(Config.SCREEN_WIDTH, Config.SCREEN_WIDTH);
}
@Override
protected void onLayout(boolean isChange, int left, int top, int right, int bottom) {
if (mGroup != null) {
int mLeft = 0;
for (int j = 0; j < Config.SIZE; j++) {
int mTop = Config.SCREEN_WIDTH - block;
for (int i = Config.SIZE - 1; i >= 0; i--) {
if (mGroup[i][j] != null) {
mGroup[i][j].setPosition(new Point(i, j));
mGroup[i][j].layout(mLeft, mTop, mLeft + block, mTop + block);
mTop -= block;
}
}
mLeft += block;
}
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (isSelected && mCurrentView == calInStartRenge(x, y)) {
mergeGroup();
} else {
isSelected = false;
cancelSelectedItems();
mCurrentView = calInStartRenge(x, y);
if (mCurrentView != null) {
getAreaStart(mCurrentView);
}
}
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
private void cancelSelectedItems() {
if (selectedArea.size() > 0) {
for (StartView item : selectedArea) {
item.setSelectState(false);
}
selectedArea.clear();
}
}
private boolean isValiadNum(int num) {
return num >= 0 && num < Config.SIZE;
}
/**
* 计算触摸区域所在的StartView
*/
private StartView calInStartRenge(float x, float y) {
int j = (int) (x / block);
int i = (int) (y / block);
if (isValiadNum(i) && isValiadNum(j)) {
return mGroup[i][j];
} else {
return null;
}
}
/**
* 计算出触摸区域关联的星星,如果个数大于两个则显示选中状态,否则没有
*/
private void getAreaStart(StartView view) {
addSelectedItem(view);
if (selectedArea.size() > 1) {
for (StartView item : selectedArea) {
item.setSelectState(true);
}
isSelected = true;
}
}
private void addSelectedItem(StartView view) {
if (selectedArea.contains(view)) {
return;
}
selectedArea.add(view);
Point p = view.getPosition();
int type = view.getType();
int i = p.x;
int j = p.y;
LogUtils.e("addSelectedItem:i=" + i + ", j=" + j);
// 获取在左边的item
getSide(i, j - 1, type);
// 获取在上边的item
getSide(i - 1, j, type);
// 获取在右边的item
getSide(i, j + 1, type);
// 获取在下边的item
getSide(i + 1, j, type);
}
private void getSide(int i, int j, int type) {
if (isValiadNum(i) && isValiadNum(j) && mGroup[i][j] != null && mGroup[i][j].getType() == type) {
addSelectedItem(mGroup[i][j]);
}
}
/**
* 消除星星,合并星星,向左向、下移动
*/
private void mergeGroup() {
isSelected = false;
//消除星星
if (mListener != null) {
mListener.onScore(selectedArea.size());
}
for (StartView item : selectedArea) {
Point p = item.getPosition();
removeView(mGroup[p.x][p.y]);
mGroup[p.x][p.y] = null;
}
// 执行合并操作 向下合并
ArrayList<Integer> list = new ArrayList<Integer>();
for (int j = 0; j < Config.SIZE; j++) {
int size = Config.SIZE;
for (int i = 0; i < Config.SIZE; i++) {
if (mGroup[i][j] == null) {
size--;
for (int z = i; z > 0; z--) {
mGroup[z][j] = mGroup[z - 1][j];
mGroup[z - 1][j] = null;
}
}
}
if (size == 0) {
list.add(j);
}
}
// 执行合并操作 向左合并
if (list.size() > 0) {
for (int j = Config.SIZE; j > 0; j--) {
if (list.contains(j)) {
for (int i = 0; i < Config.SIZE; i++) {
for (int z = j; z < Config.SIZE - 1; z++) {
mGroup[i][z] = mGroup[i][z + 1];
mGroup[i][z + 1] = null;
}
}
}
}
}
requestLayout();
}
public interface OnScoreListener {
void onScore(int size);
void onSuccess();
void onFailure();
}
}
该项目已经放在码云(开源中国git)上,有兴趣的可以去看看POP-START