package com.example.android.planegame;

import android.graphics.Canvas;
import android.graphics.Rect;

/**
 * Created by Administrator on 2016/7/25.
 */
public abstract class BaseDraw {
    /**
     * 绘制
     * */
    abstract void onDraw(Canvas canvas);
    /**
     * 销毁
     * */
    abstract void onDestory();


}
BaseDraw
package com.example.android.planegame;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.util.Log;

/**
 * Created by Administrator on 2016/7/25.
 */
public class DrawBackgound extends BaseDraw {

    private Bitmap backGround = null;
    private Rect rectBp = null;
    private Rect rectBg = null;
    private Rect rectBg2 = null;
    private int screenWidth = 0;
    private int screenHeigth = 0;
    //偏移量
    private int offset = 0;

    public DrawBackgound(Context context) {

        //未获取屏幕的宽高则获取宽高
        if (screenWidth == 0 && screenHeigth == 0) {
            backGround = BitmapFactory.decodeResource(context.getResources(), R.mipmap.bg2);

            Resources resources = context.getResources();
            DisplayMetrics dm = resources.getDisplayMetrics();
            screenWidth = dm.widthPixels;
            screenHeigth = dm.heightPixels;
        }

    }

    @Override
    void onDraw(Canvas canvas) {
        //判断偏移量
        if (offset >= screenHeigth) {
            offset = 0;
        } else {
            offset = offset + 2;
        }
        rectBg = new Rect(0, offset, screenWidth, screenHeigth + offset);
        rectBg2 = new Rect(0, -screenHeigth + offset, screenWidth, offset);
        canvas.drawBitmap(backGround, null, rectBg, null);
        canvas.drawBitmap(backGround, null, rectBg2, null);

    }

    @Override
    void onDestory() {
        backGround.recycle();
    }

}
DrawBackgound
package com.example.android.planegame;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.DisplayMetrics;

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

/**
 * Created by Administrator on 2016/7/27.
 */
public class DrawEnemyPlane extends BaseDraw {
    /**
     * 所有敌机的合集
     */
    private List<ObjectEmemyPlane> listPlanes = new ArrayList<ObjectEmemyPlane>();
    /**
     * 所有敌机的样式
     */
    private List<Bitmap> listBitmap = new ArrayList<Bitmap>();
    /**
     * 敌机的速度
     */
    private int ememySpeed[] = {5, 8, 11};
    /**
     * 敌机能被击中的次数
     */
    private int ememyHitNum[] = {6
            , 4, 2};

    private int screenWidth = 0;
    private int screenHeigth = 0;
    /**
     * 随机数
     */
    private Random random = new Random();
    /**
     * 生产敌机的速度
     */
    private int freshCount = 100;
    private int freshNum = freshCount;
    /**
     * 最多一次性生产几架飞机
     */
    private int maxMake = 4;

    private Canvas canvas;

    public DrawEnemyPlane(Context context) {

        if (screenWidth == 0 && screenHeigth == 0) {
            Bitmap ememyPlane_1 = BitmapFactory.decodeResource(context.getResources(), R.mipmap.boss_plane);
            Bitmap ememyPlane_2 = BitmapFactory.decodeResource(context.getResources(), R.mipmap.f16_23);
            Bitmap ememyPlane_3 = BitmapFactory.decodeResource(context.getResources(), R.mipmap.hy2000_r);

            listBitmap.add(ememyPlane_1);
            listBitmap.add(ememyPlane_2);
            listBitmap.add(ememyPlane_3);

            Resources resources = context.getResources();
            DisplayMetrics dm = resources.getDisplayMetrics();
            screenWidth = dm.widthPixels;
            screenHeigth = dm.heightPixels;

        }

    }

    @Override
    void onDraw(Canvas canvas) {
        this.canvas = canvas;
        if (listPlanes.size() > 0) {
            Iterator<ObjectEmemyPlane> iteror = listPlanes.iterator();

            while (iteror.hasNext()) {
                ObjectEmemyPlane plane = iteror.next();

                if (plane.y > screenHeigth || plane.ifDiead) {
                    iteror.remove();
                } else {
                    plane.y += plane.offsetY;

                    plane.rect = new Rect(plane.x, plane.y,
                            plane.x + plane.bitmap.getWidth(),
                            plane.y + plane.bitmap.getHeight());
                    canvas.drawBitmap(plane.bitmap, null, plane.rect, null);
                }
            }
        }

        if (freshNum == freshCount) {
            addEmemyPlane();
            freshNum--;
        } else {
            freshNum--;
            if (freshNum < 0) {
                freshNum = freshCount;
            }
        }
    }

    /**
     * 生产敌机
     */
    private void addEmemyPlane() {
        //随机出此次要生产敌机的数量
        int makeNum = random.nextInt(maxMake) + 1;
        //循环生产飞机
        for (int i = 0; i < makeNum; i++) {
            //随机出此敌机的样式
            int choiceNum = random.nextInt(listBitmap.size());
            Bitmap bimapPlane = listBitmap.get(choiceNum);

            //创建一架飞机并随机出它的创建位置
            ObjectEmemyPlane plane = new ObjectEmemyPlane();
            plane.y = -bimapPlane.getHeight();
            plane.x = random.nextInt(screenWidth - bimapPlane.getWidth());
            plane.offsetY = ememySpeed[choiceNum];
            plane.hitNum = ememyHitNum[choiceNum];
            plane.bitmap = bimapPlane;


            listPlanes.add(plane);

        }
    }

    public List<ObjectEmemyPlane> getEmemyPlaneList() {
        return listPlanes;
    }

    @Override
    void onDestory() {

        for (Bitmap bitmap : listBitmap) {
            bitmap.recycle();
        }
    }

}
DrawEnemyPlane
package com.example.android.planegame;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.DisplayMetrics;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by Administrator on 2016/7/26.
 */
public class DrawMasterBullet extends BaseDraw {

    /**
     * 爆炸火花合集
     */
    private List<ObjectFire> listFire = new ArrayList<ObjectFire>();

    /**
     * 爆炸火花图片合集
     */
    private List<Bitmap> fireBitmaps = new ArrayList<Bitmap>();
    /**
     * 子弹合集
     */
    private List<ObjectMasterBullet> listBullets = new ArrayList<ObjectMasterBullet>();
    /**
     * 生产子弹的速度
     */
    private int freshCount = 8;
    private int freshNum = freshCount;
    /**
     * 控制子弹移动的速度4
     */
    private int bulletSpeed = 30;

    private Bitmap bitMapBullet = null;
    private int screenWidth = 0;
    private int screenHeigth = 0;
    private Canvas canvas;
    private Rect planeRect;
    private DrawEnemyPlane drawEnemyPlane;
    private int score = 0;

    public DrawMasterBullet(Context context) {

        if (screenWidth == 0 && screenHeigth == 0) {
            bitMapBullet = BitmapFactory.decodeResource(context.getResources(), R.mipmap.bullet_1);

            Bitmap bitmap0 = BitmapFactory.decodeResource(context.getResources(), R.mipmap.fire0);
            Bitmap bitmap1 = BitmapFactory.decodeResource(context.getResources(), R.mipmap.fire1);
            Bitmap bitmap2 = BitmapFactory.decodeResource(context.getResources(), R.mipmap.fire2);
            Bitmap bitmap3 = BitmapFactory.decodeResource(context.getResources(), R.mipmap.fire3);
            Bitmap bitmap4 = BitmapFactory.decodeResource(context.getResources(), R.mipmap.fire4);
            Bitmap bitmap5 = BitmapFactory.decodeResource(context.getResources(), R.mipmap.fire5);
            Bitmap bitmap6 = BitmapFactory.decodeResource(context.getResources(), R.mipmap.fire6);
            Bitmap bitmap7 = BitmapFactory.decodeResource(context.getResources(), R.mipmap.fire7);

            fireBitmaps.add(bitmap0);
            fireBitmaps.add(bitmap1);
            fireBitmaps.add(bitmap2);
            fireBitmaps.add(bitmap3);
            fireBitmaps.add(bitmap4);
            fireBitmaps.add(bitmap5);
            fireBitmaps.add(bitmap6);
            fireBitmaps.add(bitmap7);

            Resources resources = context.getResources();
            DisplayMetrics dm = resources.getDisplayMetrics();
            screenWidth = dm.widthPixels;
            screenHeigth = dm.heightPixels;

        }
    }

    @Override
    void onDraw(Canvas canvas) {

    }

    @Override
    void onDestory() {
        bitMapBullet.recycle();
    }

    public void onDraw(Canvas canvas, Rect planeRect, DrawEnemyPlane drawEnemyPlane) {

        this.canvas = canvas;
        this.planeRect = planeRect;
        this.drawEnemyPlane = drawEnemyPlane;

        //绘制子弹
        drawBullet();

        //绘制爆炸火花
        drawFires();

        //判断敌机是否与子弹相遇
        ifBulletWithPlane();
    }

    /**
     * 绘制子弹
     */
    private void drawBullet() {
        if (listBullets.size() > 0) {
            Iterator<ObjectMasterBullet> iter = listBullets.iterator();

            while (iter.hasNext()) {
                ObjectMasterBullet bullet = iter.next();
                if (bullet.y < 0 || bullet.ifDiead) {
                    //移除屏幕之外的子弹
                    iter.remove();

                } else {
                    Rect rect = new Rect(bullet.x, bullet.y,
                            bullet.x + bitMapBullet.getWidth(),
                            bullet.y + bitMapBullet.getHeight());

                    canvas.drawBitmap(bitMapBullet, null, rect, null);

                    bullet.y = bullet.y - bulletSpeed;
                }
            }

        }

        if (freshNum == freshCount) {
            addOneBullet();
            freshNum--;
        } else {
            freshNum--;
            if (freshNum < 0) {
                freshNum = freshCount;
            }
        }
    }


    private int fireFreshCoutn = 0;
    private int fireFreshNum = fireFreshCoutn;

    /**
     * 绘制爆炸火花
     */
    private void drawFires() {
        if (listFire.size() > 0) {
            if (fireFreshNum == fireFreshCoutn) {
                fireFreshNum--;
                Iterator<ObjectFire> iterator = listFire.iterator();
                while (iterator.hasNext()) {
                    ObjectFire fire = iterator.next();
                    if (fire.picFlag < fireBitmaps.size()) {

                        Bitmap bitmapFire = fireBitmaps.get(fire.picFlag);
                        Rect rect = new Rect(fire.centerX - bitmapFire.getWidth() / 2
                                , fire.centerY - bitmapFire.getHeight() / 2
                                , fire.centerX + bitmapFire.getWidth() / 2
                                , fire.centerY + bitmapFire.getHeight() / 2);

                        canvas.drawBitmap(bitmapFire, null, rect, null);

                        fire.picFlag += 1;

                    } else {
                        iterator.remove();
                    }
                }
            } else {
                fireFreshNum--;
                if (fireFreshNum < 0) {
                    fireFreshNum = fireFreshCoutn;
                }
            }
        }
    }

    /**
     * 判断子弹是否击中了敌机
     */
    private void ifBulletWithPlane() {

        List<ObjectEmemyPlane> listEmemy = drawEnemyPlane.getEmemyPlaneList();

        for (int i = 0; i < listBullets.size(); i++) {
            ObjectMasterBullet bullet = listBullets.get(i);
            for (int j = 0; j < listEmemy.size(); j++) {
                ObjectEmemyPlane ememy = listEmemy.get(j);

                if (null != ememy.rect && ememy.rect.contains(bullet.x, bullet.y)) {
                    bullet.ifDiead = true;
                    if (ememy.hitNum < 1) {
                        ememy.ifDiead = true;
                        //新增一个爆炸火花
                        addFireBragound(ememy.rect.centerX(), ememy.rect.centerY());

                        score += 100;
                    } else {
                        ememy.hitNum--;
                    }
                }
            }
        }
    }

    /**
     * 新增一个爆炸火花
     */
    private void addFireBragound(int x, int y) {

        ObjectFire fire = new ObjectFire();
        fire.centerX = x;
        fire.centerY = y;

        listFire.add(fire);
    }

    /**
     * 新增一个子弹
     */
    private void addOneBullet() {

        ObjectMasterBullet bullet = new ObjectMasterBullet();
        bullet.x = planeRect.centerX() - planeRect.width() / 12;
        bullet.y = planeRect.top - bitMapBullet.getHeight();

        Rect rect = new Rect(bullet.x, bullet.y,
                bullet.x + bitMapBullet.getWidth(), bullet.y + bitMapBullet.getHeight());

        canvas.drawBitmap(bitMapBullet, null, rect, null);

        listBullets.add(bullet);

    }

    /**
     * 返回分数
     */
    public int getScore() {

        if(score>100){

        }

        return score;
    }
}
DrawMasterBullet
package com.example.android.planegame;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.MotionEvent;

/**
 * Created by Administrator on 2016/7/26.
 */
public class DrawMasterPlane extends BaseDraw {
    private int screenWidth = 0;
    private int screenHeigth = 0;
    /**
     * 主机
     */
    private Bitmap bitmapPlane = null;

    private int planeDist = 0;
    private Rect planeRect = null;
    /**
     * 手指移动偏移量
     */
    private int offsetX = 0;
    private int offsetY = 0;

    public DrawMasterPlane(Context context) {

        if (screenWidth == 0 && screenHeigth == 0) {
            bitmapPlane = BitmapFactory.decodeResource(context.getResources(), R.mipmap.plane_y);

            Resources resources = context.getResources();
            DisplayMetrics dm = resources.getDisplayMetrics();
            screenWidth = dm.widthPixels;
            screenHeigth = dm.heightPixels;

            planeDist = screenWidth / 5;
        }

    }

    @Override
    void onDraw(Canvas canvas) {

        planeRect = new Rect(
                (((screenWidth - planeDist) / 2) + offsetX) > 0 ? Math.min((((screenWidth - planeDist) / 2) + offsetX), screenWidth - bitmapPlane.getWidth()) : 0
                , (screenHeigth - planeDist * 2 + offsetY) > 0 ? Math.min((screenHeigth - planeDist * 2 + offsetY), screenHeigth - bitmapPlane.getHeight()) : 0
                , ((screenWidth + planeDist) / 2 + offsetX) > bitmapPlane.getWidth() ? Math.min((screenWidth + planeDist) / 2 + offsetX, screenWidth) : bitmapPlane.getWidth()
                , (screenHeigth - planeDist + offsetY) > bitmapPlane.getHeight() ? Math.min((screenHeigth - planeDist + offsetY), screenHeigth) : bitmapPlane.getHeight()
        );

        canvas.drawBitmap(bitmapPlane, null, planeRect, null);

    }

    /**
     * 返回飞机的矩形
     */
    public Rect getPlaneRect() {
        return planeRect;
    }

    boolean canMove = false;
    int downX = 0;
    int downY = 0;

    /**
     * 用户手指移动飞机
     */
    public void onTouch(MotionEvent event) {

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

                downX = (int) event.getX();
                downY = (int) event.getY();
                //判断手指按下的点不在飞机上面  重置
                if (planeRect.contains(downX, downY)) {
                    canMove = true;
                } else {
                    canMove = false;
                }
                break;
            case MotionEvent.ACTION_MOVE:

                int moveX = (int) event.getX();
                int moveY = (int) event.getY();

                if (canMove) {

                    offsetX = offsetX + (moveX - downX);
                    offsetY = offsetY + (moveY - downY);

                }

                downX = moveX;
                downY = moveY;

                break;
            case MotionEvent.ACTION_UP:

                canMove = false;
                break;
        }

    }

    @Override
    void onDestory() {

        bitmapPlane.recycle();
    }
}
DrawMasterPlane
package com.example.android.planegame;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private PlaneView surfaceView;
    private TextView textScore;
    private int Score = 0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        surfaceView = (PlaneView) findViewById(R.id.surfaceView);
        textScore = (TextView) findViewById(R.id.textScore);

        handler.sendEmptyMessage(0);
    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            textScore.setText("Score:" + surfaceView.getScore());
            handler.sendEmptyMessage(0);
        }
    };
}
MainActivity
package com.example.android.planegame;

import android.graphics.Bitmap;
import android.graphics.Rect;

/**
 * Created by Administrator on 2016/7/27.
 */
public class ObjectEmemyPlane {
    /**
     * 子弹的坐标
     */
    public int x, y;
    /**
     * 飞机飞行速度
     */
    public int offsetY = 0;
    /**
     * 飞机的样式
     */
    public Bitmap bitmap;
    /**
     * 飞机的矩形
     */
    public Rect rect;
    /**
     * 飞机是否死亡
     */
    public boolean ifDiead = false;
    /**
     * 飞机能被击中几次
     */
    public int hitNum = 0;
}
ObjectEmemyPlane
package com.example.android.planegame;

/**
 * Created by Administrator on 2016/7/27.
 */
public class ObjectFire {

    public int centerX, centerY;
    //已绘制到第几张图片
    public int picFlag = 0;

    /**
     * 返回火花图片的ID
     */
    public int getPicID() {
        if (picFlag == 0) {
            return R.mipmap.fire0;
        } else if (picFlag == 1) {
            return R.mipmap.fire1;
        } else if (picFlag == 2) {
            return R.mipmap.fire2;
        } else if (picFlag == 3) {
            return R.mipmap.fire3;
        } else if (picFlag == 4) {
            return R.mipmap.fire4;
        } else if (picFlag == 5) {
            return R.mipmap.fire5;
        } else if (picFlag == 6) {
            return R.mipmap.fire6;
        } else if (picFlag == 7) {
            return R.mipmap.fire7;
        }
        return -1;
    }
}
ObjectFire
package com.example.android.planegame;

/**
 * Created by Administrator on 2016/7/26.
 */
public class ObjectMasterBullet {

    /**
     * 子弹的坐标
     */
    public int x, y;

    public int offsetY = 0;

    public boolean ifDiead = false;

}
ObjectMasterBullet
package com.example.android.planegame;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

/**
 * Created by Administrator on 2016/7/25.
 */
public class PlaneView extends SurfaceView implements SurfaceHolder.Callback, Runnable, View.OnTouchListener {

    /**
     * 游戏是否继续
     */
    private boolean ifStop = false;
    /**
     * 游戏是否暂停
     */
    private boolean ifPause = false;

    private SurfaceHolder holder = null;
    /**
     * 画笔
     */
    private Canvas canvas = null;
    /**
     * 绘制背景用的类
     */
    private DrawBackgound drawBackgound = null;
    /**
     * 绘制飞机用的类
     */
    private DrawMasterPlane drawMasterPlane = null;

    /**
     * 绘制飞机的子弹
     */
    private DrawMasterBullet drawMasterBullet = null;
    /**
     * 绘制敌方飞机
     */
    private DrawEnemyPlane drawEnemyPlane = null;


    public PlaneView(Context context, AttributeSet attrs) {
        super(context, attrs);

        holder = this.getHolder();
        holder.addCallback(this);
        // 让整个界面透明
        holder.setFormat(PixelFormat.TRANSPARENT);
        setZOrderOnTop(true);

        drawBackgound = new DrawBackgound(context);
        drawMasterPlane = new DrawMasterPlane(context);
        drawMasterBullet = new DrawMasterBullet(context);
        drawEnemyPlane = new DrawEnemyPlane(context);

        this.setOnTouchListener(this);

        setZOrderOnTop(true);
        setZOrderMediaOverlay(true);
    }

    public PlaneView(Context context) {
        super(context);

        holder = this.getHolder();
        holder.addCallback(this);
        // 让整个界面透明
        holder.setFormat(PixelFormat.TRANSPARENT);
        setZOrderOnTop(true);

        drawBackgound = new DrawBackgound(context);
        drawMasterPlane = new DrawMasterPlane(context);
        drawMasterBullet = new DrawMasterBullet(context);
        drawEnemyPlane = new DrawEnemyPlane(context);

        this.setOnTouchListener(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        ifPause = false;
        ifStop = false;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        //启动线程 开始绘制
        new Thread(this).start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

        ifPause = true;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        ifPause = false;
        ifStop = true;

        drawBackgound.onDestory();
        drawMasterPlane.onDestory();
        drawMasterBullet.onDestory();
        drawEnemyPlane.onDestory();

    }

    @Override
    public void run() {

        while (!ifStop) {

            if (!ifPause) {
                //锁定画布
                canvas = holder.lockCanvas();
                if (null != canvas) {
                    //绘制背景
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    drawBackgound.onDraw(canvas);

                    drawEnemyPlane.onDraw(canvas);

                    drawMasterPlane.onDraw(canvas);

                    drawMasterBullet.onDraw(canvas, drawMasterPlane.getPlaneRect(),
                            drawEnemyPlane);
                    //解锁画布并提交改变
                    holder.unlockCanvasAndPost(canvas);
                }
            }
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        drawMasterPlane.onTouch(event);

        return true;
    }

    private Handler handler;

    public int getScore() {

        return drawMasterBullet.getScore();
    }

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

    <com.example.android.planegame.PlaneView
        android:id="@+id/surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TextView
        android:id="@+id/textScore"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#66000000"
        android:gravity="center"
        android:padding="10dp"
        android:text="Game Start"
        android:textColor="#fff"
        android:textSize="16sp" />
</FrameLayout>
activity_main.xml

 

posted on 2016-07-27 21:00  青年程序猿  阅读(956)  评论(0)    收藏  举报