文档章节

《飞机大战》安卓游戏开发源码(四)

p
 pm-road
发布于 2014/12/17 14:21
字数 1462
阅读 17
收藏 0

本文章属于原创性文章,珍惜他人劳动成果,转载请注明出处: http://www.pm-road.com/index.php/2014/11/06/169/

 

前言:最 近闲来无事,而且也是因为刚接触安卓不久,所以萌生了以后在开发web 项目的过程中同样开发安卓手游,因前一段时间项目需要独立完成了一款功能型手机app ,该App比较简单,全是按钮操作,也就是Activity之间的相互传值与过渡,所以对安卓的基本知识有了一定了解,在我的印象当中,感觉安卓手游是比 较困难的,但是有困难就要克服,所以有了开发游戏的念头。

 

安卓游戏开发源码(三)中,已经把控制的飞机显示出来,结果如下:

 

飞机大战

飞机大战

 

接下来,就要把敌人的战机也开发出来,并可以向下发射子弹。

 

在上一次的代码中,找到MainActivity.java文件,在其属性中添加:一个新的属性:

 

// 敌机的图片
    private List<ImageButton> enemyPlanes;

 

 

在initView()方法中,添加一个新的方法,用来初始化敌机

 

//初始化敌机
 initEnemyPlane();

 

 

然后把这个方法声明出来:

/**
     * 初始化敌机
     */
    private void initEnemyPlane(){
        
        // 生成敌机数量,这里在Util中新增了一个方法
        int enemyCount = CommonUtil.getEnemyPlaneCount();
        enemyPlanes = new ArrayList<ImageButton>();
        
        for (int i = 0; i < enemyCount; i++) {
            
            ImageButton enemyPlaneImg = new ImageButton(context);
            enemyPlaneImg.setBackgroundResource(R.drawable.enemyplane);

//敌机的横坐标也是随机的
            int x = new Random().nextInt(windowWidth);
            enemyPlaneImg.setX(x);
            enemyPlaneImg.setY(0);
            this.addContentView(enemyPlaneImg, new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
            enemyPlanes.add(enemyPlaneImg);
            
        }
        
    }

 

在commonUtil.java中增加新的属性和方法,用来随机得到敌机数量

 

/** 出现最大的战机数 */
    public static final int MAX_ENEMY_PLANE = 4;
    
    /**
     * 随机得到飞机的数量
     * @return
     */
    public static final int getEnemyPlaneCount(){
        
        Random random = new Random();
        //随机出现战机的数量
        int enemyPlaneCount = random.nextInt(CommonUtil.MAX_ENEMY_PLANE);
        //如果随机的数量是0 ,则一直循环,直到非0
        while(enemyPlaneCount == 0){
            enemyPlaneCount = random.nextInt(CommonUtil.MAX_ENEMY_PLANE);
        }
        return enemyPlaneCount;
        
    }

 

 

至此,在页面展示出来之后,敌机也一些展示了出来。接下来我们要做的便是使敌机发射子弹。

在MainActivity.java中找到initBean方法,在方法中添加:如下代码,作用就是把敌机的图片set到surfaceView界面中

 

// 所有敌机
        surfaceView.setEnemyPlanes(enemyPlanes);
        
        surfaceView.setWindowHeight(windowHeight);
        surfaceView.setWindowWidth(windowWidth);

 
打开MySurfaceView.java类,在其中添加属性: 为其增加get  set 方法

 

// 敌机的图片
    private List<ImageButton> enemyPlanes;

public List<ImageButton> getEnemyPlanes() {
        return enemyPlanes;
    }

    public void setEnemyPlanes(List<ImageButton> enemyPlanes) {
        this.enemyPlanes = enemyPlanes;
    }

 

在MySurfaceView.java 中的threadRun 方法中新增一个方法:enemyPlaneShot()如:

 

/**
     * 执行线程
     */
    private void threadRun() {

        // 你控制的飞机发射
        planeShot(yourPlane, false,null);
        Log.i(CommonUtil.VIEW_TAG, “控制的飞机射击”);
        // 敌人的飞机开火
        enemyPlaneShot();
    }

 

 

 

 

 

增加enemyPlaneShot ()方法

 

/**
     * 敌人的战机开始
     */
    private void enemyPlaneShot() {

        for (int i = 0,size = enemyPlanes.size(); i < size; i++) {

            EnemyPlane enemyPlane = new EnemyPlane();
            enemyPlane.setShot(true);
            enemyPlane.setLife(CommonUtil.ENEMY_PLAN_LIFE);
            // 敌机的位置随机出现横坐标
            enemyPlane.setX(enemyPlanes.get(i).getX());
            enemyPlane.setY(enemyPlanes.get(i).getY());
            // 敌机图片
            enemyPlane.setSrcPic(R.drawable.myplane);
            // 敌人的飞机发射  ,该方法原来不是这样的,已经新增了参数
            planeShot(enemyPlane, true,enemyPlanes.get(i));
            
        }
    }

 

 

 

更改以后的planeShot 方法:

 

/**
     * 飞机发射
     *
     * @param plane
     * @param imageButton 敌机的图片
     */
    private void planeShot(Plane plane, boolean isEnemyPlane, ImageButton enemyPlanImg) {
        // 控制飞机线程
        planeRunnable = new PlaneRunnable(context, holder);
        // 将控制的飞机绑定到该线程中
        planeRunnable.setPlane(plane);
        // 屏幕高度
        planeRunnable.setWindowHeight(windowHeight);
        planeRunnable.setWindowWidth(windowWidth);
        planeRunnable
                .setPlaneImg(getResources().getDrawable(plane.getSrcPic()));

        planeRunnable.setEnemyPlanes(enemyPlanImg);
        
        planeRunnable.setHandler(handler);
        // 是否为敌机
        planeRunnable.setEnemyPlane(isEnemyPlane);
        shotThread = new Thread(planeRunnable);
        // 控制的飞机 开始射击
        shotThread.start();
    }

 

 

到现在,PlaneRunnable 中也要增加其它的方法和变量,否则程序一直是报错状态

打开PlaneRunnable.java,在里面加入新的属性:

 

private boolean enemyPlane = false;// 是否为敌机

    // 窗口的大小
    private int windowHeight;
    private int windowWidth;

    // 敌机的图片
    private ImageButton enemyPlaneImg;
private Handler handler;

 

 

 

然后将run方法重新判断,使敌机和你控制的飞机区分开来:

 

@Override
    public void run() {

        Canvas canvas = null;
        while (plane.isShot()) {

            canvas = holder.lockCanvas();
            canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);

            Paint paint = new Paint();
            paint.setColor(Color.BLUE);

            // 如果为敌机,则这架飞机应该往下走,把敌机画出
            if (isEnemyPlane()) {

                canvas.drawText(CommonUtil.BULLET, plane.getX()
                        + planeHalfWidth, plane.getY()+planeImg.getIntrinsicHeight(), paint);
                plane.setY(plane.getY() + 10);
                // 这里这么直接写会报错,线程非安全,原因是不能在子线程中直接更新UI
                // enemyPlaneImg.setY(plane.getY());
                Message msg = handler.obtainMessage();
                msg.arg1 = 1;
                msg.obj = enemyPlaneImg;
                msg.arg2 = (int) plane.getY();
                handler.sendMessage(msg);
            } else {
                canvas.drawText(CommonUtil.BULLET, plane.getX()
                        + planeHalfWidth, plane.getY(), paint);
            }

            holder.unlockCanvasAndPost(canvas);
            // 发射子弹
            shotOneBullet();

            // 如果敌机飞到了最下面,那该线程停止射击
            if (plane.getY() >= windowHeight) {
                plane.setShot(false);
                break;
            }
             try {
             Thread.sleep(300);
             } catch (InterruptedException e) {
             e.printStackTrace();
             }
        }
        Log.i(CommonUtil.THREAD_TAG, “plane停止射击”);
    }

 

 

 

在BulletRunnable.java中,也要增加相应的属性:

 

  

private boolean enemyBullet = false;

    // 窗口的大小
    private int windowHeight;
    private int windowWidth;

 

 

 

 

然后修改run方法,这样做的目的只是为了方便区分敌机和你控制的飞机,以及它们发射的子弹:

 

@Override
    public void run() {

        Canvas canvas = null;
        while (bullet.isFly()) {

            canvas = holder.lockCanvas();
            canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);

            Paint paint = new Paint();
            paint.setColor(Color.BLUE);
            // 判断是敌机还是我方战机
            if (!isEnemyBullet()) {
                // 我方战机子弹往上走
                canvas.drawText(CommonUtil.BULLET, bullet.getX(),
                        bullet.getY() – 70, paint);
            } else {
                // 敌方战机子弹往下走
                canvas.drawText(CommonUtil.BULLET, bullet.getX(),
                        bullet.getY() + 30, paint);
            }

            holder.unlockCanvasAndPost(canvas);

            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (!isEnemyBullet()) {
                bullet.setY(bullet.getY() – 70);
            } else {
                bullet.setY(bullet.getY() + 30);
            }
            if (bullet.getY() <= 0) {
                // 如果当前线程的Y超过了屏幕,则将该线程回收
                bullet.setFly(false);
                // 爆炸效果
                boom();
                break;
            }
            if (bullet.getY() >= windowHeight) {
                // 如果子弹的Y超过了屏幕底部,则将该线程回收
                bullet.setFly(false);
                break;
            }

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.i(CommonUtil.THREAD_TAG, “子弹飞行中”);
        }
        Log.i(CommonUtil.THREAD_TAG, “子弹线程结束”);
    }

 

 

到目前为止,程序已经可以有敌机、你控制的飞机,所有的飞机都在发射子弹(只不过子弹碰到飞机之后,不会爆炸,而且敌机的移动不是很流畅,还有很多问题需要修改,下次游戏代码:《飞机大战》安卓游戏开发源码(终)),现在效果图如下:

 

本文章属于原创性文章,珍惜他人劳动成果,转载请注明出处: http://www.pm-road.com/index.php/2014/11/06/169/

 

飞机大战游戏源码

飞机大战游戏源码

 

飞机大战游戏源码

飞机大战游戏源码

本文转载自:http://rqlipeng.iteye.com/blog/2160730

p
粉丝 6
博文 69
码字总数 638
作品 0
海淀
私信 提问
libgdx 环境搭建

一、 开发包下载 1) libgdx 开发包下载: google code(最新 libgdx-0.9.7.zip 2012.11.12) 2) libgdx 主干源码下载: github tags 二、 环境搭建 1) 添加开发jar包 libgdx的android开发...

长平狐
2013/01/06
1K
0
Android源码50例汇总,欢迎各位下载

下载中心好资料很多,藏在各个角落,小弟在此帮大家做了一个整理,做了一个下载目录,方便大家选择性下载。 源码实例如下: 《Android应用开发揭秘》源代码推荐 http://down.51cto.com/data...

程序袁_绪龙
2015/01/23
1K
0
寻android开发工作

本人现居深圳,12年软件工程毕业,热爱android移动开发,自学android,由于现公司android开发项目少,android开发交流人员少,希望可以找到一个android交流学习、深入系统源码、android架构的...

Sassoon
2013/03/29
537
7
开发H5游戏平台的网站

【业务需求】 一、项目描述 开发和设计H5游戏网站平台。包括首页,个人主页,游戏界面(支持H5游戏) 【业务需求】 一、功能描述 开发和设计H5游戏网站平台。 包括网页首页,登录(微信、QQ、...

she2862902
2016/04/08
104
3
Android进阶二部曲第二部《Android进阶解密》已出版

Android进阶二部曲第一部《Android进阶之光》介绍 :点击这里 本书源码地址:https://github.com/henrymorgen/android-advanced-decode 为什么写这本书 Android进阶二部曲包括《Android进阶之...

刘望舒
2018/10/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Mybatis Plus删除

/** @author beth @data 2019-10-17 00:30 */ @RunWith(SpringRunner.class) @SpringBootTest public class DeleteTest { @Autowired private UserInfoMapper userInfoMapper; /** 根据id删除......

一个yuanbeth
32分钟前
4
0
总结

一、设计模式 简单工厂:一个简单而且比较杂的工厂,可以创建任何对象给你 复杂工厂:先创建一种基础类型的工厂接口,然后各自集成实现这个接口,但是每个工厂都是这个基础类的扩展分类,spr...

BobwithB
今天
4
0
java内存模型

前言 Java作为一种面向对象的,跨平台语言,其对象、内存等一直是比较难的知识点。而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚。比如本文我们要讨论的JVM内存结构、Java内存模...

ls_cherish
今天
4
0
友元函数强制转换

友元函数强制转换 p522

天王盖地虎626
昨天
5
0
js中实现页面跳转(返回前一页、后一页)

本文转载于:专业的前端网站➸js中实现页面跳转(返回前一页、后一页) 一:JS 重载页面,本地刷新,返回上一页 复制代码代码如下: <a href="javascript:history.go(-1)">返回上一页</a> <a h...

前端老手
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部