《飞机大战》安卓游戏开发源码(三)
本文章属于原创性文章,珍惜他人劳动成果,转载请注明出处:http://www.pm-road.com/index.php/2014/11/06/161/
前言:最 近闲来无事,而且也是因为刚接触安卓不久,所以萌生了以后在开发web 项目的过程中同样开发安卓手游,因前一段时间项目需要独立完成了一款功能型手机app ,该App比较简单,全是按钮操作,也就是Activity之间的相互传值与过渡,所以对安卓的基本知识有了一定了解,在我的印象当中,感觉安卓手游是比 较困难的,但是有困难就要克服,所以有了开发游戏的念头。
接着上一篇文章,把实体类和线程实体类创建之后,我们把代码和安卓的xml进行整合一下:目前涉及的只有一个MainActivity.java和一个MySurfaceView类,layout 中的xml 目前只一个activity_main.xml 文件
按照安卓开发流程,先把MainActivity.java中的代码补充一下,首先在这个activity中应该有你控制的飞机实体类,还有 MySurfaceView这个类,考虑到可能需要屏幕的高度和宽度,所以还应该有两个属性,一个宽度,一个高度:,以下是代码:但是此activity 继承了一个BaseActivity(该类没有做一些具体操作,只是在创建activity的时候,把屏幕全屏化)
package com.pm_road.fireair.base; import android.app.Activity; import android.os.Bundle; import android.view.Window; import android.view.WindowManager.LayoutParams; /** * * @ClassName: BaseActivity * @Description: 基类 * @author lipeng * @date 2014-11-4 上午10:46:01 * */ public class BaseActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 将游戏界面设置为全屏 requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(LayoutParams.FLAG_FULLSCREEN, LayoutParams.FLAG_FULLSCREEN); } }
以下是主界面代码:
package com.pm_road.fireair; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.view.Menu; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup.LayoutParams; import android.widget.ImageButton; import com.pm_road.fireair.base.BaseActivity; import com.pm_road.fireair.bean.YourPlane; import com.pm_road.fireair.common.CommonUtil; import com.pm_road.fireair.view.MySurfaceView; /** * * @ClassName: MainActivity * @Description: 空中大战进口页面 * @author lipeng * @date 2014-11-4 上午10:42:51 * */ public class MainActivity extends BaseActivity { // private WelcomeView welcomeView;// 欢迎页面 //这里要解释一下原因:这里定义了一个飞机图片,和一个飞机实体类,目的是把飞机的图片和实体类进行了分离,在界面上移动飞机的时候//只是移动 了该图片,并未移动飞机,只是在移动图片的过程中,会把飞机图片的xY坐标赋值给飞机实体类,(这里的飞机实体类是不可见///的,只是和图片进行绑定, 获取坐标而已) // 飞机图片 private ImageButton yourPlanImg; // 控制的飞机实体 private YourPlane yourPlane; private MySurfaceView surfaceView; // 上下文 private Context context; private int windowHeight; private int windowWidth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); context = this; setContentView(R.layout.activity_main); /** 初始化页面 */ initView(); /** 初始化实体类 */ initBean(); /** 增加事件 */ initListener(); /** 初始化子视图类 */ initSubView(); } /** * 初始化子视图 */ private void initSubView() { this.addContentView(surfaceView, new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); Log.i(CommonUtil.TAG, “初始化子视图”); } /** * 初始化实体类 */ private void initBean() { yourPlane = new YourPlane(); yourPlane.setLife(CommonUtil.YOUR_PLAN_LIFE); yourPlane.setShot(true); /** 将飞机的位置设置和图标相同 */ setPlanPosition(yourPlanImg); // 初始化surfaceView surfaceView = new MySurfaceView(context); // 将其置顶 surfaceView.setZOrderOnTop(true); // 控制的飞机 surfaceView.setYourPlane(yourPlane); surfaceView.setYourPlaneImg(yourPlanImg); Log.i(CommonUtil.TAG, “初始化实体类”); } /** * 设置飞机的位置 * * @param view */ private void setPlanPosition(View view) { yourPlane.setX(view.getX()); yourPlane.setY(view.getY()); Log.i(CommonUtil.TAG, “控制的飞机坐标X:” + view.getX() + “;Y:” + view.getY()); } /** * 初始化绑定事件 */ private void initListener() { // 飞机绑定事件 yourPlanImg.setOnTouchListener(new YourPlaneTouch()); Log.i(CommonUtil.TAG, “控制的飞机绑定移动事件”); } /** * 初始化View */ private void initView() { // 初始化飞机图片,这里涉及一个飞机图片,这个图片随便在网上找一个类似的小飞机就可以,这里我就不上传了。 yourPlanImg = (ImageButton) findViewById(R.id.yourplane); // 得到屏幕高度 windowHeight = getResources().getDisplayMetrics().heightPixels; windowWidth = getResources().getDisplayMetrics().widthPixels; Log.i(CommonUtil.TAG, “初始化view”); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { //退出按钮 if ((keyCode == KeyEvent.KEYCODE_BACK)) { Dialog alert = new AlertDialog.Builder(context).setTitle(R.string.exit) .setMessage(R.string.sureexit).setPositiveButton(R.string.sure,new ExitListener()) .setNeutralButton(R.string.cancel, null).create(); // 点击周边,不关闭提示框 alert.setCanceledOnTouchOutside(false); alert.show(); } return super.onKeyDown(keyCode, event); } class ExitListener implements OnClickListener{ @Override public void onClick(DialogInterface dialog, int which) { //退出程序之前,将飞机停止射击 yourPlane.setShot(false); finish(); } } /** * * @ClassName: YourPlaneTouch * @Description: 飞机绑定事件 * @author liPeng * @date 2014-11-5 上午11:23:25 * */ class YourPlaneTouch implements OnTouchListener { int lastX, lastY; @Override public boolean onTouch(View v, MotionEvent event) { int eventAction = event.getAction(); switch (eventAction) { case MotionEvent.ACTION_DOWN: lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); break; case MotionEvent.ACTION_MOVE: int dx = (int) event.getRawX() – lastX; int dy = (int) event.getRawY() – lastY; int left = v.getLeft() + dx; int top = v.getTop() + dy; int right = v.getRight() + dx; int bottom = v.getBottom() + dy; //在这里进行判断是防止飞机在托动过程中超出屏幕的范围 if (left < 0) { left = 0; right = left + v.getWidth(); } if (right > windowWidth) { right = windowWidth; left = right – v.getWidth(); } if (top < 0) { top = 0; bottom = top + v.getHeight(); } if (bottom > windowHeight) { bottom = windowHeight; top = bottom – v.getHeight(); } v.layout(left, top, right, bottom); lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); /** 将飞机的位置设置和图标相同 */ setPlanPosition(v); v.postInvalidate(); break; case MotionEvent.ACTION_UP: break; } return false; } } }
以下是surfaceView 的代码:该代码做了一个桥梁的作用,用来搭建xml 和线程之间的功能 。
package com.pm_road.fireair.view; import android.content.Context; import android.graphics.PixelFormat; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; import android.widget.ImageButton; import com.pm_road.fireair.bean.YourPlane; import com.pm_road.fireair.common.CommonUtil; import com.pm_road.fireair.thread.PlaneRunnable; public class MySurfaceView extends SurfaceView implements Callback { // 上下文 private Context context; // 控制的飞机 private YourPlane yourPlane; private ImageButton yourPlaneImg; // 飞机Runnable private PlaneRunnable planeRunnable; // 飞机线程 private Thread shotThread; private SurfaceHolder holder; public MySurfaceView(Context context) { super(context); this.context = context; holder = getHolder(); holder.addCallback(this); // 设置透明度 holder.setFormat(PixelFormat.TRANSLUCENT); } /** * 执行线程 */ private void threadRun() { // 控制飞机线程 planeRunnable = new PlaneRunnable(context,holder); //将控制的飞机绑定到该线程中 planeRunnable.setPlane(yourPlane); planeRunnable.setPlaneImg(yourPlaneImg); shotThread = new Thread(planeRunnable); //控制的飞机 开始射击 shotThread.start(); Log.i(CommonUtil.VIEW_TAG, “控制的飞机射击”); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { /** 启动线程 */ threadRun(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { if (shotThread != null && shotThread.isAlive()) { try { // 当绘图线程结束后自动销毁 shotThread.join(); Log.i(CommonUtil.VIEW_TAG, “射击线程destroy”); } catch (InterruptedException e) { e.printStackTrace(); } } } public YourPlane getYourPlane() { return yourPlane; } public void setYourPlane(YourPlane yourPlane) { this.yourPlane = yourPlane; } public ImageButton getYourPlaneImg() { return yourPlaneImg; } public void setYourPlaneImg(ImageButton yourPlaneImg) { this.yourPlaneImg = yourPlaneImg; } } 在activity中涉及了一个Util工具类:代码如下:主要用来定义一些常量 package com.pm_road.fireair.common; public class CommonUtil { /** 飞机生命 */ public static final int YOUR_PLAN_LIFE = 5; /** 敌机生命 */ public static final int ENEMY_PLAN_LIFE = 5; public static final String TAG = “com.pm_road.fireair.mainActivity”; public static final String VIEW_TAG = “com.pm_road.fireair.view”; public static final String THREAD_TAG = “com.pm_road.fireair.thread”; public static final String BULLET = “o”; }
完成以上代码之后:大概的工作也就差不多了,可以使用真机或ADT运行一下:
接下来我们就是写敌机和敌机发射子弹了 《飞机大战》安卓游戏开发源码(四)
在这里我的运行效果如下:
本文章属于原创性文章,珍惜他人劳动成果,转载请注明出处:http://www.pm-road.com/index.php/2014/11/06/161/