仿一个小鸟过柱子的游戏

学习时做个一个小游戏,界面有些简陋,部分碰撞计算不是很精准。哭

话不多说直接上代码了,比较简单

package com.example.administrator.bluebird;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Created by Administrator on 2017/6/6.
 */

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

    private boolean isDrawing;
    private Paint pillarPaint;
    /**
     * surface持有者
     */
    private SurfaceHolder mHolder;
    /**
     * 当前画布
     */
    private Canvas mCanvas;

    /**
     * x轴的单位
     */
    private int mXUnit = dp2px(100);

    /**
     * 柱子宽度
     */
    private int pillarWidth = dp2px(30);

    /**
     * 柱子空隙高度
     */
    private int spaceHeight = dp2px(60);

    /**
     * 画布宽度
     */
    private int BG_width;

    /**
     * 画布高度
     */
    private int BG_height;

    /**
     * 柱子集合
     */
    private List<Integer> mPillars;

    /**
     * 柱子偏移量
     */
    private int mOffset;

    /**
     * 主角偏移量
     */
    private int birdOffset;

    /**
     * 主角每次跳高的高度
     */
    private int jump = dp2px(30);

    /**
     * 游戏主角
     */
    private Bitmap bird;

    /**
     * 主角尺寸
     */
    private int bird_width;
    private int bird_height;

    private int DEFAULT_WIDTH = 300;
    private int DEFAULT_HEIGHT = 200;

    public GameBackGround(Context context) {
        this(context, null);
    }

    public GameBackGround(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public GameBackGround(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    /**
     * 初始化
     */
    private void init() {
        mHolder = getHolder();
        mHolder.addCallback(this);
        // 设置可以获取焦点
        setFocusable(true);
        // 进入触摸输入模式后,该控件是否还有获得焦点的能力
        setFocusableInTouchMode(true);
        // 是否保持屏幕常亮
        this.setKeepScreenOn(true);

        //初始化几根柱子
        mPillars = new ArrayList<>();
        mPillars.add(new Random().nextInt(200) + 100);
        mPillars.add(new Random().nextInt(200) + 100);
        mPillars.add(new Random().nextInt(200) + 100);
        mPillars.add(new Random().nextInt(200) + 100);
        mPillars.add(new Random().nextInt(200) + 100);

        //初始化画笔
        pillarPaint = new Paint();
        pillarPaint.setAntiAlias(true);
        pillarPaint.setStrokeWidth(pillarWidth);

        //初始化主角图片
        bird = BitmapFactory.decodeResource(getContext().getResources(), R.mipmap.ic_launcher);
        bird_width = bird.getWidth();
        bird_height = bird.getHeight();
    }

    /**
     * 计算画布大小
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthMode == MeasureSpec.AT_MOST) {
            BG_width = dp2px(DEFAULT_WIDTH);
        } else {
            BG_width = Math.max(widthSize, dp2px(DEFAULT_WIDTH));
        }
        if (heightMode == MeasureSpec.AT_MOST) {
            BG_height = dp2px(DEFAULT_HEIGHT);
        } else {
            BG_height = Math.max(heightSize, dp2px(DEFAULT_HEIGHT));
        }
        setMeasuredDimension(BG_width, BG_height);

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // 开始绘画
        isDrawing = true;
        // 启动绘画线程
        new Thread(this).start();
    }

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

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isDrawing = false;
    }

    @Override
    public void run() {
        while (isDrawing) {
            try {
                draw();
                Thread.sleep(10);
                birdOffset++;
                mOffset++;
                if (mOffset == BG_width + mXUnit) {
                    mOffset = BG_width;
                    mPillars.remove(0);
                    mPillars.add(new Random().nextInt(100) + 100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 绘制方法
     */
    private void draw() {
        // 获取并锁定画布
        mCanvas = mHolder.lockCanvas();

        if (mCanvas != null) {
            // 设置画布背景为白色
            mCanvas.drawColor(0xffffffff);

            //绘制移动的柱子
            drawPillar();

            //绘制游戏主角
            drawBird();

            // 保证每次都将绘制的内容提交到服务器
            mHolder.unlockCanvasAndPost(mCanvas);
        }

    }

    /**
     * 画柱子
     */
    private void drawPillar() {
        mCanvas.save();
        for (int i = 0; i < mPillars.size(); i++) {
            crashEvent(BG_width + mXUnit * i - mOffset, BG_width + mXUnit * i - mOffset, BG_height - dp2px(mPillars.get(i)));
            mCanvas.drawLine(BG_width + mXUnit * i - mOffset, BG_height - dp2px(mPillars.get(i)), BG_width + mXUnit * i - mOffset, BG_height, pillarPaint);
            mCanvas.drawLine(BG_width + mXUnit * i - mOffset, 0, BG_width + mXUnit * i - mOffset, BG_height - dp2px(mPillars.get(i)) - spaceHeight, pillarPaint);
        }
    }

    /**
     * 绘制鸟
     */
    private void drawBird() {
        mCanvas.save();
        mCanvas.drawBitmap(bird, BG_width / 2, BG_height / 2 + birdOffset, pillarPaint);
    }

    /**
     * 碰撞处理
     */
    private void crashEvent(int x, int y_up, int y_down) {
        //此时碰撞发生
        if (x <= BG_width / 2 + bird_width && x >= BG_width / 2 - pillarWidth) {
            if (BG_height / 2 + birdOffset < y_up || BG_height / 2 + bird_height + birdOffset > y_down) {
                isDrawing = false;
            }
        }
        if (birdOffset == BG_height / 2) {
            isDrawing = false;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            //点击事件
            case MotionEvent.ACTION_DOWN:
                if (birdOffset > -BG_height / 2) {
                    birdOffset -= jump;
                }
                break;
        }
        return true;
    }

    /**
     * dp转化为px工具
     */
    private int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
                getContext().getResources().getDisplayMetrics());
    }
}
MainActivity只设置了一个屏幕禁止横屏

package com.example.administrator.bluebird;

import android.content.pm.ActivityInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //禁止横屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        setContentView(R.layout.activity_main);
    }
}
布局文件activity_main.xml直接使用自定义的view

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.administrator.bluebird.GameBackGround
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>
好了,其他业务处理可以发挥脑洞了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值