贪吃蛇初探

自定义view控件

package snake.dg.com.tanchishe;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Collections;

public class Tanchishe extends View {

    private float screenHeight;
    private float screenWidth;

    private int WIDTH_MAX_LINE = 20;
    private int HEIGHT_MAX_LINE = 33;

    private float lineWidth;
    private float lineHeight;

    private Bitmap snakeBitmap;
    private Bitmap foodBitmap;

    private ArrayList<Point> snakeArray = new ArrayList<Point>();
    private ArrayList<Point> foodArray = new ArrayList<Point>();

    private final int MOVE_RIGHT = 1;
    private final int MOVE_LEFT = 2;
    private final int MOVE_UP = 3;
    private final int MOVE_DOWN = 4;

    private int Deirector = MOVE_RIGHT;
    private int grade = 0, i = 0;//得分
    private int delayTime = 300;//发送消息的延迟时间
    private final int movelength = 100;//控制灵敏度

    private float downX = 0, downY = 0, upX = 0, upY = 0;

    //调出振动器
    private Vibrator vibrator;
    //处理各个方向
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (Deirector) {
                case MOVE_RIGHT:
                    moveRight();
                    break;
                case MOVE_LEFT:
                    moveLeft();
                    break;
                case MOVE_UP:
                    moveUp();
                    break;
                case MOVE_DOWN:
                    moveDown();
                    break;
            }
        }
    };
    //重玩
    public void restartGame() {
        snakeArray.clear();
        foodArray.clear();
        snakeArray.add(new Point(2, 2));
        snakeArray.add(new Point(3, 2));
        snakeArray.add(new Point(4, 2));
        foodArray.add(new Point(0, 0));
        setFood();
        Deirector = MOVE_RIGHT;
        grade = 0;
        i = 0;
        delayTime = 300;
        handler.sendEmptyMessageDelayed(MOVE_RIGHT, delayTime);
        Toast.makeText(getContext(), "重新开局", Toast.LENGTH_SHORT).show();
        invalidate();
    }
    //游戏结束弹出对话框
    private void popWindow(String text) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
        builder.setTitle("得分情况:");
        int fenshu = Integer.parseInt(text);
        if (fenshu <= 2500) {
            text = "好low啊," + fenshu + "分,菜鸟一只!";
        } else if (fenshu > 2500 && fenshu <= 6000) {
            text = "成绩不错," + fenshu + "分,继续加油!";
        } else {
            text = "牛掰哦," + fenshu + "分,好羡慕!";
        }
        builder.setMessage(text);
        builder.setPositiveButton("再来一局", new android.content.DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                restartGame();
                dialog.dismiss();
            }

        });
        builder.setNegativeButton("退出游戏", new android.content.DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                System.exit(0);
            }
        });
        //让对话框显示出来
        builder.show();
    }

    private void gameOver() {
        //震动0.5秒
        invalidate();
        vibrator.vibrate(500);
        popWindow(String.valueOf(grade));
    }

    //自己撞到自己
    private boolean me2me() {
        int count = Collections.frequency(snakeArray, snakeArray.get(snakeArray.size() - 1));
        if (count == 2) {
            gameOver();
            return true;
        }
        return false;
    }

    //蛇右移
    private void moveRight() {
        snakeArray.remove(0);
        Point point = snakeArray.get(snakeArray.size() - 1);
        Point p = new Point(point.x + 1, point.y);
        snakeArray.add(p);
        invalidate();
        if (isEat()) {
            snakeArray.add(new Point(p.x + 1, p.y));
        }
        if (me2me())
            return;
        if (p.x == WIDTH_MAX_LINE) {//靠右边墙,游戏结束
            snakeArray.add(new Point(snakeArray.get(0).x - 1, snakeArray.get(0).y));
            gameOver();
            return;
        }
        handler.sendEmptyMessageDelayed(Deirector, delayTime);
    }

    //蛇左移
    private void moveLeft() {
        snakeArray.remove(0);
        Point point = snakeArray.get(snakeArray.size() - 1);
        Point p = new Point(point.x - 1, point.y);
        snakeArray.add(p);
        invalidate();
        if (isEat()) {
            snakeArray.add(new Point(p.x - 1, p.y));
        }
        if (me2me())
            return;
        if (p.x + 1 == 0) {//靠左边墙,游戏结束
            snakeArray.add(new Point(snakeArray.get(0).x + 1, snakeArray.get(0).y));
            gameOver();
            return;
        }
        handler.sendEmptyMessageDelayed(Deirector, delayTime);
    }

    //蛇上移
    private void moveUp() {
        snakeArray.remove(0);
        Point point = snakeArray.get(snakeArray.size() - 1);
        Point p = new Point(point.x, point.y - 1);
        snakeArray.add(p);
        invalidate();
        if (isEat()) {
            snakeArray.add(new Point(p.x, p.y - 1));
        }
        if (me2me())
            return;
        if (p.y + 1 == 0) {//靠上边墙,游戏结束
            snakeArray.add(new Point(snakeArray.get(0).x, snakeArray.get(0).y + 1));
            gameOver();
            return;
        }
        handler.sendEmptyMessageDelayed(Deirector, delayTime);
    }

    //蛇下移
    private void moveDown() {
        snakeArray.remove(0);
        Point point = snakeArray.get(snakeArray.size() - 1);
        Point p = new Point(point.x, point.y + 1);
        snakeArray.add(p);
        invalidate();
        if (isEat()) {
            snakeArray.add(new Point(p.x, p.y + 1));
        }
        if (me2me())
            return;
        if (p.y == HEIGHT_MAX_LINE) {//靠下边墙,游戏结束
            snakeArray.add(new Point(snakeArray.get(0).x, snakeArray.get(0).y - 1));
            gameOver();
            return;
        }
        handler.sendEmptyMessageDelayed(Deirector, delayTime);
    }

    private boolean isEat() {
        //头撞到食物
        if (snakeArray.get(snakeArray.size() - 1).equals(foodArray.get(0))) {
            setFood();
            return true;
        }
        return false;
    }

    //让食物随机出现,不能出现在蛇身上
    private void setFood() {
        int randomX = (int) (Math.random() * WIDTH_MAX_LINE);
        int randomY = (int) (Math.random() * HEIGHT_MAX_LINE);
        foodArray.set(0, new Point(randomX, randomY));
        if (delayTime>=70)
            delayTime -= 8;
        grade = grade + 10 * i;
        i++;
    }

    public Tanchishe(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    //初始化蛇和食物,以及振动器
    private void init() {
        snakeArray.add(new Point(2, 2));
        snakeArray.add(new Point(3, 2));
        snakeArray.add(new Point(4, 2));

        foodArray.add(new Point(0, 0));
        setFood();

        snakeBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bird);
        foodBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.cz);
        handler.sendEmptyMessageDelayed(MOVE_RIGHT, delayTime);
        //初始化振动器对象
        vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
    }

    //测量view大小
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(widthSize, heightSize);
    }
    //确定蛇和食物的大小
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        screenWidth = w * 1.0f;
        screenHeight = h * 1.0f;
        lineWidth = screenWidth / WIDTH_MAX_LINE;
        lineHeight = screenHeight / HEIGHT_MAX_LINE;

        snakeBitmap = Bitmap.createScaledBitmap(snakeBitmap, (int) lineWidth, (int) lineHeight, false);
        foodBitmap = Bitmap.createScaledBitmap(foodBitmap, (int) lineWidth, (int) lineHeight, false);
    }
    //画蛇画食物
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawSnake(canvas);
        drawFood(canvas);
    }

    //画蛇
    private void drawSnake(Canvas canvas) {
        for (int i = 0, n = snakeArray.size(); i < n; i++) {
            Point snakePoint = snakeArray.get(i);
            canvas.drawBitmap(snakeBitmap,
                    (snakePoint.x) * lineWidth,
                    (snakePoint.y) * lineHeight, null);
        }
    }

    //画食物
    private void drawFood(Canvas canvas) {
        canvas.drawBitmap(foodBitmap, foodArray.get(0).x * lineWidth, foodArray.get(0).y * lineHeight, null);
    }
    //处理滑动事件
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();

        if (action == MotionEvent.ACTION_DOWN) {
            downX = event.getX();
            downY = event.getY();
        }
        if (action == MotionEvent.ACTION_UP) {
            upX = event.getX();
            upY = event.getY();
            float x_x = upX - downX;
            float y_y = upY - downY;
            switch (Deirector) {
                case MOVE_RIGHT:
                case MOVE_LEFT: {
                    if (y_y > movelength) {
                        Deirector = MOVE_DOWN;
                    } else if (y_y < -movelength) {
                        Deirector = MOVE_UP;
                    }
                    break;
                }
                case MOVE_UP:
                case MOVE_DOWN: {
                    if (x_x > movelength) {
                        Deirector = MOVE_RIGHT;
                    } else if (x_x < -movelength) {
                        Deirector = MOVE_LEFT;
                    }
                    break;
                }
            }
        }
        return true;
    }
}

MainActivity

package snake.dg.com.tanchishe;

import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.WindowManager;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private MediaPlayer mediaPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //去掉状态栏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        //播放背景音乐,音乐可以放在res下面的raw资源文件下面
        mediaPlayer = null;
        mediaPlayer = MediaPlayer.create(this, R.raw.bgm);
        mediaPlayer.start();

        //设置循环播放
        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                mediaPlayer.start();
                mediaPlayer.setLooping(true);
            }
        });
    }


    //实现再按一次退出程序
    private long exitTime = 0;

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
                exitTime = System.currentTimeMillis();
            } else {
                finish();
                System.exit(0);
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/wg"
    tools:context="snake.dg.com.tanchishe.MainActivity">

    <snake.dg.com.tanchishe.Tanchishe
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="snake.dg.com.tanchishe">
    <!--获取振动器需要配置的权限-->
    <uses-permission android:name="android.permission.VIBRATE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/title"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar"><!--去掉头部-->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值