贪吃蛇 android版 里面自己实现了简单的事件系统



游戏预览





游戏是用SurfaceView开发的 流畅 和体验还是挺好



CanvasState 游戏的主要业务类

package bill;

import java.util.ArrayList;
import java.util.Collections;
import java.util.EventListener;
import java.util.EventListenerProxy;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;

import model.BtnGameRect;
import model.Direction;
import model.GameRect;
import model.GameRectId;
import model.GameRectType;
import model.SNake;
import model.SnakeNode;

import helper.CollisionHelper;
import helper.ScreenHelper;

import com.shanghongshen.tsnake.R;

import event.CheckEvent;
import event.TouchClick;

import android.R.id;
import android.R.integer;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.RectF;
import android.view.SurfaceHolder;
import android.widget.Toast;

public class CanvasState {

    public HashMap<String, GameRect> GameRects = new HashMap<String, GameRect>();
    public ArrayList<BtnGameRect> btns = new ArrayList<BtnGameRect>();
    public ArrayList<SNake> snakes = new ArrayList<SNake>();
    public ArrayList<GameRect> foods = new ArrayList<GameRect>();
    public SNake mainSnake;

    private CanvasState() {
    }

    public static CanvasState getInstance() {
        if (thisObj == null) {
            thisObj = new CanvasState();
        }
        return thisObj;
    }

    static CanvasState thisObj;
    int FrameRate = 15;
    SurfaceHolder holder;
    Context context;
    int ScreenWidth;
    int ScreenHeight;
    int eachWidth;
    int eachHeight;
    int eachMap;
    int mapOther;
    boolean loadGameRect;
    int maxFood = 5;
    int maxSnakeSize = 5;
    int mapWidth = 18;
    int mapHeight = 18;
    CollisionHelper collisionHelper = new CollisionHelper();

    public void Restart() {
        thisObj = new CanvasState();
    }

    /**
     * 注册所有的矩阵块
     */
    void loadGameRect() {

        ScreenWidth = ScreenHelper.getScreenWidth(context);
        ScreenHeight = ScreenHelper.getScreenHeight(context);
        eachHeight = ScreenHeight / 12;
        eachWidth = ScreenWidth / 6;

        // 背景
        GameRect gameRect = new GameRect(GameRectId.background,
                GameRectType.background, BitmapFactory.decodeResource(
                        context.getResources(), R.drawable.background),
                new RectF(0, 0, ScreenWidth, ScreenHeight));
        GameRects.put(GameRectId.background, gameRect);

        // 地图
        gameRect = new GameRect(GameRectId.map, GameRectType.map,
                BitmapFactory.decodeResource(context.getResources(),
                        R.drawable.map), new RectF(50, eachHeight * 2,
                        ScreenWidth - 50,
                        (float) (ScreenWidth - 100 + eachHeight * 2)));
        GameRects.put(GameRectId.map, gameRect);
        eachMap = (int) ((int) (ScreenWidth - 100) / 18.5);
        mapOther = eachMap / 4;

        // 蓝色的食物
        gameRect = new GameRect(GameRectId.foodBlue, GameRectType.food,
                BitmapFactory.decodeResource(context.getResources(),
                        R.drawable.blue), new RectF(0, 0, 0, 0));
        GameRects.put(GameRectId.foodBlue, gameRect);
        // 红色的食物
        gameRect = new GameRect(GameRectId.foodRed, GameRectType.food,
                BitmapFactory.decodeResource(context.getResources(),
                        R.drawable.red), new RectF(0, 0, 0, 0));
        GameRects.put(GameRectId.foodRed, gameRect);
        // 绿色的食物
        gameRect = new GameRect(GameRectId.foodGreen, GameRectType.food,
                BitmapFactory.decodeResource(context.getResources(),
                        R.drawable.green), new RectF(0, 0, 0, 0));
        GameRects.put(GameRectId.foodGreen, gameRect);

        // 按钮背景
        gameRect = new GameRect(GameRectId.btnFameGreen,
                GameRectType.background, BitmapFactory.decodeResource(
                        context.getResources(), R.drawable.frame_green),
                new RectF(0, eachHeight * 9, ScreenWidth, ScreenHeight));
        GameRects.put(GameRectId.btnFameGreen, gameRect);

        // 按钮右
        BtnGameRect gameRectBtn = new BtnGameRect(GameRectId.btnRight,
                GameRectType.button, BitmapFactory.decodeResource(
                        context.getResources(), R.drawable.right),
                BitmapFactory.decodeResource(context.getResources(),
                        R.drawable.rightblue),
                new RectF((float) (eachWidth * 3.5),
                        (float) (eachHeight * 9.8), (float) (eachWidth * 5.5),
                        (float) (eachHeight * 11.2)), true);
        gameRectBtn.onClick = new TouchClick() {
            @Override
            public void OnClick() {
                RightClick();
            }
        };
        GameRects.put(GameRectId.btnRight, gameRectBtn);
        btns.add(gameRectBtn);
        CheckEvent.getInstance().RegisterEventGameRects.add(gameRectBtn);
        // 按钮左
        gameRectBtn = new BtnGameRect(GameRectId.btnLeft, GameRectType.button,
                BitmapFactory.decodeResource(context.getResources(),
                        R.drawable.left), BitmapFactory.decodeResource(
                        context.getResources(), R.drawable.leftblue),
                new RectF((float) (eachWidth * 0.5),
                        (float) (eachHeight * 9.8), (float) (eachWidth * 2.5),
                        (float) (eachHeight * 11.2)), true);
        gameRectBtn.onClick = new TouchClick() {
            @Override
            public void OnClick() {
                LeftClick();
            }
        };
        GameRects.put(GameRectId.btnLeft, gameRectBtn);
        btns.add(gameRectBtn);
        CheckEvent.getInstance().RegisterEventGameRects.add(gameRectBtn);
        // 按钮上
        gameRectBtn = new BtnGameRect(GameRectId.btnUp, GameRectType.button,
                BitmapFactory.decodeResource(context.getResources(),
                        R.drawable.up), BitmapFactory.decodeResource(
                        context.getResources(), R.drawable.upblue), new RectF(
                        (float) (eachWidth * 2), (float) (eachHeight * 9.2),
                        (float) (eachWidth * 4), (float) (eachHeight * 10.5)),
                true);
        gameRectBtn.onClick = new TouchClick() {
            @Override
            public void OnClick() {
                UpClick();
            }
        };
        GameRects.put(GameRectId.btnUp, gameRectBtn);
        btns.add(gameRectBtn);
        CheckEvent.getInstance().RegisterEventGameRects.add(gameRectBtn);
        // 按钮下
        gameRectBtn = new BtnGameRect(GameRectId.btnDown, GameRectType.button,
                BitmapFactory.decodeResource(context.getResources(),
                        R.drawable.down), BitmapFactory.decodeResource(
                        context.getResources(), R.drawable.downblue),
                new RectF((float) (eachWidth * 2), (float) (eachHeight * 10.5),
                        (float) (eachWidth * 4), (float) (eachHeight * 11.8)),
                true);
        gameRectBtn.onClick = new TouchClick() {
            @Override
            public void OnClick() {
                DownClick();
            }
        };
        GameRects.put(GameRectId.btnDown, gameRectBtn);
        btns.add(gameRectBtn);
        CheckEvent.getInstance().RegisterEventGameRects.add(gameRectBtn);
        // 按钮on
        gameRectBtn = new BtnGameRect(GameRectId.btnOn, GameRectType.button,
                BitmapFactory.decodeResource(context.getResources(),
                        R.drawable.on_blue), BitmapFactory.decodeResource(
                        context.getResources(), R.drawable.on_red), new RectF(
                        (float) (eachWidth * 4), (float) (eachHeight * 0.5),
                        (float) (eachWidth * 5.7), (float) (eachHeight * 1.5)),
                true);
        gameRectBtn.onClick = new TouchClick() {
            @Override
            public void OnClick() {
                BtnGameRect btnOn = (BtnGameRect) GameRects
                        .get(GameRectId.btnOn);
                BtnGameRect btnOff = (BtnGameRect) GameRects
                        .get(GameRectId.btnOff);
                btnOn.ShowState = false;
                btnOff.ShowState = true;
                setIsSuspend(false);
            }
        };
        GameRects.put(GameRectId.btnOn, gameRectBtn);
        btns.add(gameRectBtn);
        CheckEvent.getInstance().RegisterEventGameRects.add(gameRectBtn);
        // 按钮off
        gameRectBtn = new BtnGameRect(GameRectId.btnOff, GameRectType.button,
                BitmapFactory.decodeResource(context.getResources(),
                        R.drawable.off_blue), BitmapFactory.decodeResource(
                        context.getResources(), R.drawable.off_red), new RectF(
                        (float) (eachWidth * 4), (float) (eachHeight * 0.5),
                        (float) (eachWidth * 5.7), (float) (eachHeight * 1.5)),
                true);
        gameRectBtn.onClick = new TouchClick() {
            @Override
            public void OnClick() {
                BtnGameRect btnOn = (BtnGameRect) GameRects
                        .get(GameRectId.btnOn);
                BtnGameRect btnOff = (BtnGameRect) GameRects
                        .get(GameRectId.btnOff);
                btnOn.ShowState = true;
                btnOff.ShowState = false;
                setIsSuspend(true);

            }
        };
        GameRects.put(GameRectId.btnOff, gameRectBtn);
        gameRectBtn.ShowState = false;
        btns.add(gameRectBtn);
        CheckEvent.getInstance().RegisterEventGameRects.add(gameRectBtn);

        // 加载snake 资源
        SnakeNode snakeNode = new SnakeNode(GameRectId.snakeHeadTop,
                GameRectType.snakeNode, BitmapFactory.decodeResource(
                        context.getResources(), R.drawable.head_n), new RectF(
                        0, 0, 0, 0));
        GameRects.put(GameRectId.snakeHeadTop, snakeNode);
        snakeNode = new SnakeNode(GameRectId.snakeHeadDown,
                GameRectType.snakeNode, BitmapFactory.decodeResource(
                        context.getResources(), R.drawable.head_s), new RectF(
                        0, 0, 0, 0));
        GameRects.put(GameRectId.snakeHeadDown, snakeNode);
        snakeNode = new SnakeNode(GameRectId.snakeHeadLeft,
                GameRectType.snakeNode, BitmapFactory.decodeResource(
                        context.getResources(), R.drawable.head_w), new RectF(
                        0, 0, 0, 0));
        GameRects.put(GameRectId.snakeHeadLeft, snakeNode);
        snakeNode = new SnakeNode(GameRectId.snakeHeadRight,
                GameRectType.snakeNode, BitmapFactory.decodeResource(
                        context.getResources(), R.drawable.head_e), new RectF(
                        0, 0, 0, 0));
        GameRects.put(GameRectId.snakeHeadRight, snakeNode);
        snakeNode = new SnakeNode(GameRectId.snakeNode, GameRectType.snakeNode,
                BitmapFactory.decodeResource(context.getResources(),
                        R.drawable.snake), new RectF(0, 0, 0, 0));
        GameRects.put(GameRectId.snakeNode, snakeNode);

        mainSnake = getSnake(3, GameRectId.snakeHeadLeft);
        mainSnake.SetSpeed(1000);
        mainSnake.IsPause(true);
        snakes.add(mainSnake);

        // OpenAutoCreateSnake();
        OpenAutoCreateFood();
    }

    public void OpenAutoCreateSnake() {
        if (this.snakes.size() < this.maxSnakeSize) {
            int c = this.maxSnakeSize - this.snakes.size() + 1;
            for (int i = 0; i < c; i++) {
                SNake sk = getSnake(4, GameRectId.snakeHeadRight);
                sk.SetSpeed(2000);
                sk.setAutoDirection(true);
                snakes.add(sk);
            }
        }
    }

    public void OpenAutoCreateFood() {

        int needSize = maxFood - foods.size();
        LinkedList bankMap = GetAllBankIndex();
        GameRect mapRect = GameRects.get(GameRectId.map);

        for (int i = 0; i < needSize; i++) {
            int ran = (int) (Math.random() * 3);
            int ranLocation = (int) bankMap.get((int) (Math.random() * bankMap
                    .size()));

            RectF tempRect = new RectF();
            tempRect.top = mapRect.rectF.top + this.mapOther + ranLocation
                    / this.mapWidth * this.eachMap;
            tempRect.bottom = tempRect.top + this.eachMap;
            tempRect.left = mapRect.rectF.left + this.mapOther + ranLocation
                    % this.mapWidth * this.eachMap;
            tempRect.right = tempRect.left + this.eachMap;
            switch (ran) {
            case 0:
                GameRect old1 = GameRects.get(GameRectId.foodRed);
                GameRect gr1 = new GameRect(old1.Id, old1.gameRectType,
                        old1.bitmap, tempRect);
                foods.add(gr1);
                break;
            case 1:
                GameRect old2 = GameRects.get(GameRectId.foodBlue);
                GameRect gr2 = new GameRect(old2.Id, old2.gameRectType,
                        old2.bitmap, tempRect);
                foods.add(gr2);
                break;
            case 2:
                GameRect old3 = GameRects.get(GameRectId.foodGreen);
                GameRect gr3 = new GameRect(old3.Id, old3.gameRectType,
                        old3.bitmap, tempRect);
                foods.add(gr3);
                break;
            default:
                OpenAutoCreateFood();
                break;
            }
        }

    }

    /**
     * 获取所有的空白场地的索引
     */
    public LinkedList GetAllBankIndex() {
        LinkedList rst = new LinkedList();
        int mapAll = mapWidth * mapHeight;
        for (int i = 0; i < mapAll; i++) {
            rst.add(i);
        }
        GameRect mapRect = GameRects.get(GameRectId.map);
        // 排除所有的snake
        for (SNake snake : snakes) {
            if (snake.SnakeState) {
                for (SnakeNode node : snake.SnakeNodes) {
                    OutRect(mapRect.rectF, node.rectF, rst);
                }
            }
        }
        // 排除所有的食物
        for (GameRect food : foods) {
            OutRect(mapRect.rectF, food.rectF, rst);
        }
        return rst;
    }

    void OutRect(RectF mapRect, RectF neetOutRect, LinkedList rst) {
        int left = (int) ((neetOutRect.left - mapRect.left - this.mapOther) / this.eachMap);
        int top = (int) ((neetOutRect.top - mapRect.top - this.mapOther) / this.eachMap);
        int index = rst.indexOf(left + top * this.mapWidth - 1);
        if (index == -1) {
            return;
        }
        rst.remove(index);
    }

    void CheckDie(SNake snake) {
        SnakeNode head = snake.HeadNode;
        for (int i = 1; i < snake.SnakeNodes.size(); i++) {
            SnakeNode node = snake.SnakeNodes.get(i);
            if (head.rectF.left == node.rectF.left&&head.rectF.top == node.rectF.top) {
                snake.IsLive = false;
                break;
            }
        }
    }

    /**
     * 碰撞检测
     */
    public void CheckCollision() {
        for (int i = 0; i < snakes.size(); i++) {
            SNake item = snakes.get(i);
            CheckDie(item);
            // 蛇和蛇碰撞
            // if (item!=mainSnake&&mainSnake.SnakeState) {
            // SnakeNode mainSnakeHead = mainSnake.SnakeNodes.get(0);
            // for (int j = 0; j < item.SnakeNodes.size(); j++) {
            // boolean rst =
            // collisionHelper.IsRectCollision(mainSnakeHead.rectF,item.SnakeNodes.get(j).rectF);
            // if (rst) {
            // //mainSnake.Stop();
            // OpenAutoCreateSnake();
            // return;
            // }
            // }
            // }
            // 蛇和食物碰撞
            int foodSize = foods.size();
            for (int j = 0; j < foodSize; j++) {
                if (foods.size() == j) {
                    break;
                }
                GameRect sHead = item.SnakeNodes.get(0);
                GameRect nowFood = foods.get(j);
                boolean rst = collisionHelper.IsRectCollision(sHead.rectF,
                        nowFood.rectF);
                if (rst) {
                    // 移除食物
                    foods.remove(j);
                    // 增加蛇节
                    SnakeNode last = item.SnakeNodes
                            .get(item.SnakeNodes.size() - 1);
                    RectF newRf = new RectF(last.rectF.left, last.rectF.top,
                            last.rectF.right, last.rectF.bottom);
                    switch (last.direction) {
                    case Top:
                        newRf.top += eachMap;
                        newRf.bottom += eachMap;
                        break;
                    case Down:
                        newRf.top -= eachMap;
                        newRf.bottom -= eachMap;
                        break;
                    case Left:
                        newRf.left += eachMap;
                        newRf.right += eachMap;
                        break;
                    case Right:
                        newRf.left -= eachMap;
                        newRf.right -= eachMap;
                        break;
                    }
                    SnakeNode sn = new SnakeNode(last.Id, last.gameRectType,
                            last.bitmap, newRf);
                    item.SnakeNodes.add(sn);

                    OpenAutoCreateFood();
                }
            }

        }
    }

    /**
     * 暂停恢复
     *
     * @param suspend
     */
    public void setIsSuspend(boolean suspend) {
        if (suspend) {
            mainSnake.IsPause(true);
        } else {
            mainSnake.IsPause(false);
        }
    }

    void Draw(Canvas cv) {
        if (!loadGameRect) {
            loadGameRect();
            loadGameRect = true;
        }
        // 画背景
        DrawBackground(cv);
        // 碰撞检测
        CheckCollision();
        CheckGameState();
        // 画蛇
        DrawSnake(cv);
        // 画食物
        DrawFood(cv);
    }

    public void CheckGameState(){
        if (!this.mainSnake.IsLive) {
            //游戏结束
            foods.clear();
            snakes.clear();
            mainSnake = getSnake(3, GameRectId.snakeHeadLeft);
            mainSnake.SetSpeed(1000);
            mainSnake.IsPause(true);
            snakes.add(mainSnake);
            OpenAutoCreateFood();
            BtnGameRect btnOn = (BtnGameRect) GameRects
                    .get(GameRectId.btnOn);
            BtnGameRect btnOff = (BtnGameRect) GameRects
                    .get(GameRectId.btnOff);
            btnOn.ShowState = true;
            btnOff.ShowState = false;
            setIsSuspend(true);
        }
    }

    private void DrawFood(Canvas cv) {
        for (GameRect item : foods) {
            cv.drawBitmap(item.bitmap, null, item.rectF, null);
        }
    }

    private void DrawSnake(Canvas cv) {
        for (SNake temp : snakes) {
            if (temp.SnakeState) {
                for (SnakeNode item : temp.SnakeNodes) {
                    if (item.ShowState) {
                        cv.drawBitmap(item.bitmap, null, item.rectF, null);
                    }
                }
            }
        }
    }

    private void DrawBackground(Canvas cv) {
        cv.drawColor(Color.WHITE);
        DrawGameRect(GameRectId.background, cv);
        DrawGameRect(GameRectId.map, cv);
        DrawGameRect(GameRectId.btnFameGreen, cv);
        DrawGameRect(GameRectId.btnLeft, cv);
        DrawGameRect(GameRectId.btnRight, cv);
        DrawGameRect(GameRectId.btnUp, cv);
        DrawGameRect(GameRectId.btnDown, cv);
        DrawGameRect(GameRectId.btnOn, cv);
        DrawGameRect(GameRectId.btnOff, cv);
    }

    void DrawGameRect(String id, Canvas cv) {
        GameRect rect = GameRects.get(id);
        if (rect != null && rect.ShowState) {
            cv.drawBitmap(rect.bitmap, null, rect.rectF, null);
        }
    }

    /*
     * 获取一条蛇
     */
    public SNake getSnake(int size, String headId) {
        SnakeNode head = (SnakeNode) this.GameRects.get(headId);
        SnakeNode node = (SnakeNode) this.GameRects.get(GameRectId.snakeNode);
        SnakeNode headNode = new SnakeNode(head.Id, head.gameRectType,
                head.bitmap, getRectFRandom(null, headId));
        SetDirection(headId, headNode);
        SNake sk = new SNake(this.GameRects.get(GameRectId.map), eachMap,
                mapOther, headNode, GameRects);
        if (head != null) {
            sk.SnakeNodes.add(headNode);
        }
        for (int i = 0; i < size - 1; i++) {
            if (node != null) {
                RectF tempR = getRectFRandom(sk.SnakeNodes.get(i).rectF, headId);
                SnakeNode snakeNode = new SnakeNode(GameRectId.snakeNode,
                        GameRectType.snakeNode, node.bitmap, tempR);
                SetDirection(headId, snakeNode);
                sk.SnakeNodes.add(snakeNode);
            }
        }
        return sk;
    }

    void SetDirection(String headId, SnakeNode node) {
        if (node == null)
            return;
        switch (headId) {
        // 上
        case GameRectId.snakeHeadTop:
            node.direction = Direction.Top;
            break;
        // 下
        case GameRectId.snakeHeadDown:
            node.direction = Direction.Down;
            break;
        // 左
        case GameRectId.snakeHeadLeft:
            node.direction = Direction.Left;
            break;
        // 右
        case GameRectId.snakeHeadRight:
            node.direction = Direction.Right;
            break;
        }
    }

    RectF getRectFRandom(RectF lastRect, String headId) {
        RectF temp = new RectF();
        GameRect rect = GameRects.get(GameRectId.map);
        if (lastRect == null) {
            int randNumLeft = (int) (Math.random() * (13 - 7) + 7);
            int randNumTop = (int) (Math.random() * (13 - 7) + 7);
            temp.left = eachMap * randNumLeft + mapOther + rect.rectF.left;
            temp.right = eachMap * randNumLeft + mapOther + rect.rectF.left
                    + eachMap;
            temp.top = eachMap * randNumTop + mapOther + rect.rectF.top;
            temp.bottom = eachMap * randNumTop + mapOther + rect.rectF.top
                    + eachMap;

        } else if (headId == null) {
            int randNumLeft = (int) (Math.random() * 18);
            int randNumTop = (int) (Math.random() * 18);
            temp.left = eachMap * randNumLeft + mapOther + rect.rectF.left;
            temp.right = eachMap * randNumLeft + mapOther + rect.rectF.left
                    + eachMap;
            temp.top = eachMap * randNumTop + mapOther + rect.rectF.top;
            temp.bottom = eachMap * randNumTop + mapOther + rect.rectF.top
                    + eachMap;
        } else {
            switch (headId) {
            // 上
            case GameRectId.snakeHeadTop:
                temp.top = lastRect.top - eachMap;
                temp.bottom = lastRect.bottom - eachMap;
                temp.right = lastRect.right;
                temp.left = lastRect.left;
                break;
            // 下
            case GameRectId.snakeHeadDown:
                temp.top = lastRect.top + eachMap;
                temp.bottom = lastRect.bottom + eachMap;
                temp.right = lastRect.right;
                temp.left = lastRect.left;
                break;
            // 左
            case GameRectId.snakeHeadLeft:
                temp.top = lastRect.top;
                temp.bottom = lastRect.bottom;
                temp.right = lastRect.right + eachMap;
                temp.left = lastRect.left + eachMap;
                break;
            // 右
            case GameRectId.snakeHeadRight:
                temp.top = lastRect.top;
                temp.bottom = lastRect.bottom;
                temp.right = lastRect.right - eachMap;
                temp.left = lastRect.left - eachMap;
                break;
            }
        }
        return temp;
    }

    void UpClick() {
        if (!mainSnake.IsPause)
            mainSnake.Run(Direction.Top);

    }

    void DownClick() {
        if (!mainSnake.IsPause)
            mainSnake.Run(Direction.Down);
    }

    void RightClick() {
        if (!mainSnake.IsPause)
            mainSnake.Run(Direction.Right);
    }

    void LeftClick() {
        if (!mainSnake.IsPause)
            mainSnake.Run(Direction.Left);
    }
}


游戏碰撞检测类



package helper;

import android.graphics.Rect;

import android.graphics.RectF;

/**

* 游戏碰撞检测类

*

* @author poolo

* @version 1.00

*/

public class CollisionHelper {

/**
 * 矩形碰撞检测 参数为x,y,width,height
 *
 * @param x1
 *            第一个矩形的x
 * @param y1
 *            第一个矩形的y
 * @param w1
 *            第一个矩形的w
 * @param h1
 *            第一个矩形的h
 * @param x2
 *            第二个矩形的x
 * @param y2
 *            第二个矩形的y
 * @param w2
 *            第二个矩形的w
 * @param h2
 *            第二个矩形的h
 * @return 是否碰撞
 */
public boolean IsRectCollision(float x1, float y1, float w1, float h1, float x2,
        float y2, float w2, float h2) {
    if (x2 > x1 && x2 > x1 + w1) {
        return false;
    } else if (x2 < x1 && x2 < x1 - w2) {
        return false;
    } else if (y2 > y1 && y2 > y1 + h1) {
        return false;
    } else if (y2 < y1 && y2 < y1 - h2) {
        return false;
    } else {
        return true;
    }
}   

/**
 * 矩形碰撞检测 参数为Rect对象
 *
 * @param r1
 *            第一个Rect对象
 * @param r2
 *            第二个Rect对象
 * @return 是否碰撞
 */
public boolean IsRectCollision(RectF r1, RectF r2) {
    if (r1.left==r2.left&&r1.right==r2.right&&r1.top==r2.top&&r1.bottom==r2.bottom) {
        return true;
    }else {
        return false;
    }
} 

/**
 * 圆形碰撞检测
 *
 * @param x1
 *            第一个圆的圆心x
 * @param y1
 *            第一个圆的圆心y
 * @param r1
 *            第一个圆的半径
 * @param x2
 *            第二个圆的圆心x
 * @param y2
 *            第二个圆的圆心y
 * @param r2
 *            第二个圆的半径
 * @return 是否碰撞
 */
public boolean IsCircleCollision(int x1, int y1, int r1, int x2, int y2,
        int r2) {
    // 两点距大于 2圆形半径距离
    if (Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) > r1 + r2) {
        return false;
    }
    return true;
}   

/**
 * 圆形与矩形碰撞检测
 *
 * @param x1
 *            第一个矩形的x
 * @param y1
 *            第一个矩形的y
 * @param w1
 *            第一个矩形的宽
 * @param h1
 *            第一个矩形的高
 * @param x2
 *            圆的圆心x
 * @param y2
 *            圆的圆心y
 * @param r2
 *            圆的半径r
 * @return 是否碰撞
 */
public boolean IsC2RCollision(int x1, int y1, int w1, int h1, int x2,
        int y2, int r2) {
    if ((Math.abs(x2 - (x1 + w1 / 2)) > w1 / 2 + r2)
            || Math.abs(y2 - (y1 + h1 / 2)) > h1 / 2 + r2) {
        return false;
    }
    return true;
}   

/**
 * 多矩形碰撞
 *
 * @param rArray1
 * @param rArray2
 * @return 是否碰撞
 */
public boolean IsRectsCollision(RectF[] rArray1, RectF[] rArray2) {
    for (RectF rt1 : rArray1) {
        for (RectF rt2 : rArray2) {
            if (IsRectCollision(rt1, rt2)) {
                return true;
            }   

        }
    }
    return false;
}

}



事件管理和分发类

package event;

import java.util.ArrayList;

import model.BtnGameRect;
import model.GameRect;

public class CheckEvent {
    public ArrayList<BtnGameRect> RegisterEventGameRects = new ArrayList<BtnGameRect>();
    static CheckEvent thisObj;

    private CheckEvent() {

    }

    public static CheckEvent getInstance() {
        if (thisObj == null) {
            thisObj = new CheckEvent();
        }
        return thisObj;
    }

    public void Restart() {
        thisObj = new CheckEvent();
    }

    public void CheckDown(float x, float y) {
        for (int i = 0; i < RegisterEventGameRects.size(); i++) {
            BtnGameRect item = RegisterEventGameRects.get(i);
            if (item.rectF.left < x && item.rectF.right > x
                    && item.rectF.top < y && item.rectF.bottom > y
                    && item.ShowState) {
                if (item.onDown != null) {
                    item.onDown.OnDown();
                }

                break;
            }
        }
    }

    public void CheckUp(float x, float y) {
        for (int i = 0; i < RegisterEventGameRects.size(); i++) {
            BtnGameRect item = RegisterEventGameRects.get(i);
            //if (item.rectF.left < x && item.rectF.right > x
            //      && item.rectF.top < y && item.rectF.bottom > y
            //      && item.ShowState) {
            if (item.DownState) {
                if (item.onUp != null) {
                    item.onUp.OnUp();
                }
                if (item.onClick != null) {
                    item.onClick.OnClick();
                }
            }
            //}
        }
    }

}


其他详细见源码

注:源码里的图片资源是破解的,请不要用作商业用途,否则后果自负

http://pan.baidu.com/s/1ntw25Hv

版权声明:欢迎装载,原文链接http://blog.csdn.net/shanghongshen/article/

时间: 2024-10-11 01:44:22

贪吃蛇 android版 里面自己实现了简单的事件系统的相关文章

原生js写的贪吃蛇网页版游戏

<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>原生js写的贪吃蛇网页版游戏</title> </head> <body><div><A href="http://www.999jiujiu.com/">h

c/c++ 贪吃蛇控制台版

贪吃蛇控制台版(操作系统win7 64位:编译环境gcc, vs2017通过,其它环境未测试 不保证一定通过) 运行效果: #include <iomanip> #include <windows.h> #include <conio.h> using namespace std; HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//全局句柄 class snake; void Init_Console();//控制台初始化

Android快乐贪吃蛇游戏实战项目开发教程-01项目概述

一.项目简介贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏.我已经将做好的案例上传到了应用宝,大家可以下载下来把玩一下.为了和其它的贪吃蛇区别开来,我取名叫“快乐贪吃蛇”.应用宝链接:http://sj.qq.com/myapp/detail.htm?apkName=net.chengyujia.happysnake这里上两张截图先睹为快,哈哈.怎么玩大家应该都知道,不过我还是要多提一下.通过屏幕上的方向键控制蛇的前进方向.蛇每吃到一个食物身体会

Java版贪吃蛇(比较完善的版本)

很认真的写的一个java版的贪吃蛇游戏,图形界面,支持菜单操作,键盘监听,可加速,减速,统计得分,设定运动速度,设定游戏背景颜色等!应该没有Bug了,因为全被我修改没了.哈哈. 下面是项目各包及类的层次关系: 游戏的主要运行界面截图如下: 下面是部分代码,详细源码见此链接:http://pan.baidu.com/s/1bnubnzh //Snake类: package com.huowolf.entities; import java.awt.Color; import java.awt.Gr

Qt版贪吃蛇游戏

Qt版贪吃蛇游戏 转载请标明出处:牟尼的专栏 http://blog.csdn.net/u012027907 最近在学习Qt,用了一个多月的时间掌握了Qt中最基本的知识,也完成了<Qt版音乐播放器>.<Qt版贪吃蛇游戏>.<Qt版双人俄罗斯方块>以及<Qt版科学计算器>等,之前在VC下写过这些程序,所以在Qt下只是改变了显示等语句,我写过<C++版贪吃蛇游戏>.<VC版贪吃蛇游戏>,当时将与显示等无关的东西封装起来,在Qt下直接用,只

Java版贪吃蛇小游戏的实现

使用的IDE eclipse JDK版本 1.6 辅助类 Coordinate.java package com.nn.util; /** *坐标点 */ public class Coordinate { public int x; public int y; public Coordinate(int newX, int newY) { x = newX; y = newY; } public boolean equals(Coordinate other) { if (x == other

控制台小游戏-贪吃蛇,c++和c#版

说是c++版,其实只是用到了c++的cout和cin而已.这是我做的第二个控制台游戏,基本上每一行代码都加上了注释. 游戏嘛,我觉得重要的是了解他的思想,所以后期学了面向对象之后这个游戏的代码我也没有重新封装. 下面请看图 代码如下:我是用dev c++写的 1 //注释. ---星辰 2 3 #include <iostream> 4 #include<Windows.h> 5 #include<ctime> 6 #include<cstdlib> 7 #

OC版贪吃蛇

昨天写了一个js版贪吃蛇,今天突然想写一个OC版的,来对比一下两种语言的区别 oc版功能,适配所有尺寸iphone,可暂停,可设置地图和蛇的比例,可加速 对比一下会发现js版的相对OC版的会简单一些,有想看js版的可以看我上一篇随笔 程序中没用到任何素材,效果图如下: github源码地址:https://github.com/masterChunlinHan/snake_OC 下面开始,跟js版一样,为了方便学习,所有代码都写在一个controller中,所以头文件中什么也不用写 #impor

假期休闲,来发贪吃蛇!(Win32控制台版)

假期无事,整理电脑文件的时候发现了以前大二时做的坦克小游戏,心血来潮,决定再来一发贪吃蛇. 游戏玩法不必多说,主要是算法实现和绘制过程. 首先,利用一个二维数组 mp[][] 来存储地图信息,其中的值表示: 0:空 1:被蛇覆盖 2:食物 有了这个地图数组,生成随机食物的时候就可以避免生成到蛇身上. 那蛇的身体如何存储呢?也很简单,用队列(存储每一个小格的坐标信息). 队列的头尾方向与蛇的头尾方向正好相反. 蛇每走一步,在蛇头方向的下一位置画一个小方格,同时把该位置放置到队列尾端.取出队列第一个