android 贪吃蛇简易实现

这篇博客分享了作者闲暇时编写的Android版贪吃蛇游戏的实现过程,虽然代码网上有很多,但作者还是提供了自己的实现。文中提到代码可能存在瑕疵,如数组集合转换的效率优化和蛇长度计算的冗余,以及未实现的碰撞检测功能,鼓励读者自行完善。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

其实关于贪吃蛇的代码在网上实在是一搜一大堆,我也是闲着无聊随便写写 有瑕疵  数组集合转换部分应该有更快的算法,蛇的长度计算其实设计时没考虑充分有多余代码 ,碰撞检测部分没写 大家自己发挥吧     直接上代码


/**
 * Created by Administrator on 2017/8/10.
 */

public class SnakeView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    private Paint mPaint;
    private Thread mThread;
    private SurfaceHolder mHolder;
    private int screenWidth;
    private int screenHeight;
    private static MyLinkList list;
    private int sX1;
    private int sY1;
    private int sX2;
    private int sY2;
    private int foodX;
    private int foodY;
    private int headX;
    private int headY;
    private int foodRadiu;

    private void initView() {
        screenWidth = getResources().getDisplayMetrics().widthPixels;
        screenHeight = getResources().getDisplayMetrics().heightPixels;
        mPaint = new Paint();
        foodRadiu=10;
        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(15);
        list = new MyLinkList();
        mHolder = this.getHolder();
        mHolder.addCallback(this);
        mThread = new Thread(this);
        list.add(new CustomStructure(0, 30, 500, 30, Direction.RIGHT, 500, true, true, new LenghtListener() {
            @Override
            public void lengehCheanger(int lenght, CustomStructure customStructure) {

                if (list.size() == 1) {
                    customStructure.setPositionX1(customStructure.getPositionX1() + 1);

                    customStructure.setPositionX2(customStructure.getPositionX2() + 1);
                } else {
                    customStructure.setPositionX1(customStructure.getPositionX1() + 1);
                }
            }
        }));
    }

    private void snakeRun() {
        list.get(0).setLenght(list.get(0).getLenght());


    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                sX1 = list.get(list.size() - 1).getPositionX1();
                sY1 = list.get(list.size() - 1).getPositionY1();

                sX2 = list.get(list.size() - 1).getPositionX2();
                sY2 = list.get(list.size() - 1).getPositionY2();
                list.get(list.size() - 1).setStart(false);
                if (event.getRawX() > sX1 && (list.get(list.size() - 1).getmDirection() == Direction.UP || list.get(list.size() - 1).getmDirection() == Direction.DOWN)) {
                    if (list.get(list.size() - 1).getmDirection() == Direction.UP) {
                        list.add(new CustomStructure(sX1, sY1, sX1, sY1, Direction.RIGHT, 0, true, false, new LenghtListener() {
                            @Override
                            public void lengehCheanger(int lenght, CustomStructure customStructure) {
                                if (list.size() == 1) {
                                    customStructure.setPositionX1(customStructure.getPositionX1() + 1);
                                    customStructure.setPositionX2(customStructure.getPositionX2() + 1);
                                } else if (customStructure.isEnd()) {
                                    customStructure.setPositionX1(customStructure.getPositionX1() + 1);
                                } else if (customStructure.isStart()) {
                                    customStructure.setPositionX2(customStructure.getPositionX2() + 1);
                                }
                            }
                        }));
                    } else {
                        list.add(new CustomStructure(sX2, sY2, sX2, sY2, Direction.RIGHT, 0, true, false, new LenghtListener() {
                            @Override
                            public void lengehCheanger(int lenght, CustomStructure customStructure) {
                                if (list.size() == 1) {
                                    customStructure.setPositionX1(customStructure.getPositionX1() + 1);
                                    customStructure.setPositionX2(customStructure.getPositionX2() + 1);
                                } else if (customStructure.isEnd()) {
                                    customStructure.setPositionX1(customStructure.getPositionX1() + 1);
                                } else if (customStructure.isStart()) {
                                    customStructure.setPositionX2(customStructure.getPositionX2() + 1);
                                }
                            }
                        }));
                    }
                } else if (event.getRawX() < sX1 && (list.get(list.size() - 1).getmDirection() == Direction.UP || list.get(list.size() - 1).getmDirection() == Direction.DOWN)) {
                    if (list.get(list.size() - 1).getmDirection() == Direction.UP) {
                        list.add(new CustomStructure(sX1, sY1, sX1, sY1, Direction.LEFT, 0, true, false, new LenghtListener() {
                            @Override
                            public void lengehCheanger(int lenght, CustomStructure customStructure) {
                                if (list.size() == 1) {
                                    customStructure.setPositionX1(customStructure.getPositionX1() - 1);
                                    customStructure.setPositionX2(customStructure.getPositionX2() - 1);
                                } else if (customStructure.isEnd()) {
                                    customStructure.setPositionX2(customStructure.getPositionX2() - 1);
                                } else if (customStructure.isStart()) {
                                    customStructure.setPositionX1(customStructure.getPositionX1() - 1);
                                }
                            }
                        }));
                    } else {
                        list.add(new CustomStructure(sX2, sY2, sX2, sY2, Direction.LEFT, 0, true, false, new LenghtListener() {
                            @Override
                            public void lengehCheanger(int lenght, CustomStructure customStructure) {
                                if (list.size() == 1) {
                                    customStructure.setPositionX1(customStructure.getPositionX1() - 1);
                                    customStructure.setPositionX2(customStructure.getPositionX2() - 1);
                                } else if (customStructure.isEnd()) {
                                    customStructure.setPositionX2(customStructure.getPositionX2() - 1);
                                } else if (customStructure.isStart()) {
                                    customStructure.setPositionX1(customStructure.getPositionX1() - 1);
                                }
                            }
                        }));
                    }
                } else if (event.getRawY() > sY1 && (list.get(list.size() - 1).getmDirection() == Direction.LEFT || list.get(list.size() - 1).getmDirection() == Direction.RIGHT)) {
                    if (list.get(list.size() - 1).getmDirection() == Direction.LEFT) {
                        list.add(new CustomStructure(sX1, sY1, sX1, sY1, Direction.DOWN, 0, true, false, new LenghtListener() {
                            @Override
                            public void lengehCheanger(int lenght, CustomStructure customStructure) {
                                if (list.size() == 1) {
                                    customStructure.setPositionY1(customStructure.getPositionY1() + 1);
                                    customStructure.setPositionY2(customStructure.getPositionY2() + 1);
                                } else if (customStructure.isEnd()) {
                                    customStructure.setPositionY1(customStructure.getPositionY1() + 1);
                                } else if (customStructure.isStart()) {
                                    customStructure.setPositionY2(customStructure.getPositionY2() + 1);
                                }
                            }
                        }));
                    } else {
                        list.add(new CustomStructure(sX2, sY2, sX2, sY2, Direction.DOWN, 0, true, false, new LenghtListener() {
                            @Override
                            public void lengehCheanger(int lenght, CustomStructure customStructure) {
                                if (list.size() == 1) {
                                    customStructure.setPositionY1(customStructure.getPositionY1() + 1);
                                    customStructure.setPositionY2(customStructure.getPositionY2() + 1);
                                } else if (customStructure.isEnd()) {
                                    customStructure.setPositionY1(customStructure.getPositionY1() + 1);
                                } else if (customStructure.isStart()) {
                                    customStructure.setPositionY2(customStructure.getPositionY2() + 1);
                                }
                            }
                        }));
                    }
                } else if (event.getRawY() < sY1 && (list.get(list.size() - 1).getmDirection() == Direction.LEFT || list.get(list.size() - 1).getmDirection() == Direction.RIGHT)) {
                    if (list.get(list.size() - 1).getmDirection() == Direction.LEFT) {
                        list.add(new CustomStructure(sX1, sY1, sX1, sY1, Direction.UP, 0, true, false, new LenghtListener() {
                            @Override
                            public void lengehCheanger(int lenght, CustomStructure customStructure) {
                                if (list.size() == 1) {
                                    customStructure.setPositionY1(customStructure.getPositionY1() - 1);
                                    customStructure.setPositionY2(customStructure.getPositionY2() - 1);
                                } else if (customStructure.isEnd()) {
                                    customStructure.setPositionY2(customStructure.getPositionY2() - 1);
                                } else if (customStructure.isStart()) {
                                    customStructure.setPositionY1(customStructure.getPositionY1() - 1);
                                }
                            }
                        }));
                    } else {
                        list.add(new CustomStructure(sX2, sY2, sX2, sY2, Direction.UP, 0, true, false, new LenghtListener() {
                            @Override
                            public void lengehCheanger(int lenght, CustomStructure customStructure) {
                                if (list.size() == 1) {
                                    customStructure.setPositionY1(customStructure.getPositionY1() - 1);
                                    customStructure.setPositionY2(customStructure.getPositionY2() - 1);
                                } else if (customStructure.isEnd()) {
                                    customStructure.setPositionY2(customStructure.getPositionY2() - 1);
                                } else if (customStructure.isStart()) {
                                    customStructure.setPositionY1(customStructure.getPositionY1() - 1);
                                }
                            }
                        }));
                    }
                }
                break;
        }
        return true;
    }

    public SnakeView(Context context) {
        super(context);
        initView();
    }

    public SnakeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }
    private void initFoodPosition(){
        foodX = new Random().nextInt(screenWidth + 1);
        foodY = new Random().nextInt(screenHeight + 1);
    }

    public SnakeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        initFoodPosition();

        mThread.start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mThread.interrupt();
    }

    @Override
    public void run() {


        while (true) {
            Canvas mCanvas = null;

            try {
                synchronized (mHolder) {
                    mCanvas = mHolder.lockCanvas();
                    mCanvas.drawColor(Color.WHITE);

                    if (list.size() == 1) {
                        list.get(0).setLenght(list.get(0).getLenght());

                    } else {
                        list.get(list.size() - 1).setLenght(list.get(list.size() - 1).getLenght() + 1);
                        list.get(0).setLenght(list.get(0).getLenght() - 1);
                        if (list.get(0).getLenght() == 0) {
                            list.remove(0);
                            list.get(0).setEnd(true);
                        }
                    }

                    Log.e("snakasd", list.toString());

                    mCanvas.drawLines(list.toFloatArray(), 0, list.size() * 4, mPaint);
//                    mCanvas.drawCircle(foodX, foodY, foodRadiu, mPaint);

                    Thread.sleep(10);
                }

            } catch (Exception e) {

            } finally {
                if (mCanvas != null) {
                    mHolder.unlockCanvasAndPost(mCanvas);
                }
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int width;
        int height;

        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {
            int desired = getPaddingLeft() + screenWidth + getPaddingRight();
            width = desired;
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else {
            int desired = getPaddingTop() + screenHeight + getPaddingBottom();
            height = desired;
        }
        setMeasuredDimension(width, height);


    }

    interface LenghtListener {
        void lengehCheanger(int lenght, CustomStructure customStructure);
    }

    class CustomStructure {
        private LenghtListener lenghtListener;

        public int getPositionX1() {
            return positionX1;
        }

        public void setPositionX1(int positionX1) {
            this.positionX1 = positionX1;
        }

        public int getPositionY1() {
            return positionY1;
        }

        public void setPositionY1(int positionY1) {
            this.positionY1 = positionY1;
        }

        public int getPositionX2() {
            return positionX2;
        }

        public void setPositionX2(int positionX2) {
            this.positionX2 = positionX2;
        }

        public int getPositionY2() {
            return positionY2;
        }

        public void setPositionY2(int positionY2) {
            this.positionY2 = positionY2;
        }

        public Direction getmDirection() {
            return mDirection;
        }

        public void setmDirection(Direction mDirection) {
            this.mDirection = mDirection;
        }

        public int getLenght() {
            return lenght;
        }

        public void setLenght(int lenght) {
            this.lenght = lenght;
            lenghtListener.lengehCheanger(lenght, CustomStructure.this);
        }


        private int positionX1;
        private int positionY1;
        private int positionX2;
        private int positionY2;
        private Direction mDirection;
        private int lenght;
        private boolean isEnd;
        private boolean isStart;

        public CustomStructure(int positionX1, int positionY1, int positionX2, int positionY2, Direction mDirection, int lenght, boolean isStart, boolean isEnd, LenghtListener lenghtListener) {
            this.positionX1 = positionX1;
            this.positionY1 = positionY1;
            this.positionX2 = positionX2;
            this.positionY2 = positionY2;
            this.mDirection = mDirection;
            this.lenght = lenght;
            this.isEnd = isEnd;
            this.isStart = isStart;
            this.lenghtListener = lenghtListener;
        }


        public boolean isEnd() {
            return isEnd;
        }

        public void setEnd(boolean end) {
            isEnd = end;
        }

        public boolean isStart() {
            return isStart;
        }

        public void setStart(boolean start) {
            isStart = start;
        }

        @Override
        public String toString() {
            return "CustomStructure{" +
                    "lenghtListener=" + lenghtListener +
                    ", positionX1=" + positionX1 +
                    ", positionY1=" + positionY1 +
                    ", positionX2=" + positionX2 +
                    ", positionY2=" + positionY2 +
                    ", mDirection=" + mDirection +
                    ", lenght=" + lenght +
                    ", isEnd=" + isEnd +
                    ", isStart=" + isStart +
                    '}';
        }
    }

    enum Direction {
        UP, DOWN, LEFT, RIGHT
    }

    class MyLinkList extends LinkedList<CustomStructure> {
        float a[];

        public float[] toFloatArray() {
            a = new float[this.size() * 4];
            for (int i = 0; i < this.size(); i++) {
                a[4 * i] = this.get(i).getPositionX1();
                a[4 * i + 1] = this.get(i).getPositionY1();
                a[4 * i + 2] = this.get(i).getPositionX2();
                a[4 * i + 3] = this.get(i).getPositionY2();
            }
            return a;
        }
    }
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值