《飞机大战》安卓游戏开发源码(三)
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
本文章屬于原創(chuàng)性文章,珍惜他人勞動(dòng)成果,轉(zhuǎn)載請(qǐng)注明出處:http://www.pm-road.com/index.php/2014/11/06/161/
?
前言:最 近閑來(lái)無(wú)事,而且也是因?yàn)閯偨佑|安卓不久,所以萌生了以后在開(kāi)發(fā)web 項(xiàng)目的過(guò)程中同樣開(kāi)發(fā)安卓手游,因前一段時(shí)間項(xiàng)目需要獨(dú)立完成了一款功能型手機(jī)app ,該App比較簡(jiǎn)單,全是按鈕操作,也就是Activity之間的相互傳值與過(guò)渡,所以對(duì)安卓的基本知識(shí)有了一定了解,在我的印象當(dāng)中,感覺(jué)安卓手游是比 較困難的,但是有困難就要克服,所以有了開(kāi)發(fā)游戲的念頭。
?
接著上一篇文章,把實(shí)體類(lèi)和線(xiàn)程實(shí)體類(lèi)創(chuàng)建之后,我們把代碼和安卓的xml進(jìn)行整合一下:目前涉及的只有一個(gè)MainActivity.java和一個(gè)MySurfaceView類(lèi),layout 中的xml 目前只一個(gè)activity_main.xml 文件
?
按照安卓開(kāi)發(fā)流程,先把MainActivity.java中的代碼補(bǔ)充一下,首先在這個(gè)activity中應(yīng)該有你控制的飛機(jī)實(shí)體類(lèi),還有 MySurfaceView這個(gè)類(lèi),考慮到可能需要屏幕的高度和寬度,所以還應(yīng)該有兩個(gè)屬性,一個(gè)寬度,一個(gè)高度:,以下是代碼:但是此activity 繼承了一個(gè)BaseActivity(該類(lèi)沒(méi)有做一些具體操作,只是在創(chuàng)建activity的時(shí)候,把屏幕全屏化)
?
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: 基類(lèi)* @author lipeng* @date 2014-11-4 上午10:46:01**/ public class BaseActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 將游戲界面設(shè)置為全屏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: 空中大戰(zhàn)進(jìn)口頁(yè)面* @author lipeng* @date 2014-11-4 上午10:42:51**/ public class MainActivity extends BaseActivity {// private WelcomeView welcomeView;// 歡迎頁(yè)面//這里要解釋一下原因:這里定義了一個(gè)飛機(jī)圖片,和一個(gè)飛機(jī)實(shí)體類(lèi),目的是把飛機(jī)的圖片和實(shí)體類(lèi)進(jìn)行了分離,在界面上移動(dòng)飛機(jī)的時(shí)候//只是移動(dòng) 了該圖片,并未移動(dòng)飛機(jī),只是在移動(dòng)圖片的過(guò)程中,會(huì)把飛機(jī)圖片的xY坐標(biāo)賦值給飛機(jī)實(shí)體類(lèi),(這里的飛機(jī)實(shí)體類(lèi)是不可見(jiàn)///的,只是和圖片進(jìn)行綁定, 獲取坐標(biāo)而已)// 飛機(jī)圖片private ImageButton yourPlanImg;// 控制的飛機(jī)實(shí)體private YourPlane yourPlane;private MySurfaceView surfaceView;// 上下文private Context context;private int windowHeight;private int windowWidth;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);context = this;setContentView(R.layout.activity_main);/** 初始化頁(yè)面 */initView();/** 初始化實(shí)體類(lèi) */initBean();/** 增加事件 */initListener();/** 初始化子視圖類(lèi) */initSubView();}/*** 初始化子視圖*/private void initSubView() {this.addContentView(surfaceView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));Log.i(CommonUtil.TAG, “初始化子視圖”);}/*** 初始化實(shí)體類(lèi)*/private void initBean() {yourPlane = new YourPlane();yourPlane.setLife(CommonUtil.YOUR_PLAN_LIFE);yourPlane.setShot(true);/** 將飛機(jī)的位置設(shè)置和圖標(biāo)相同 */setPlanPosition(yourPlanImg);// 初始化surfaceViewsurfaceView = new MySurfaceView(context);// 將其置頂surfaceView.setZOrderOnTop(true);// 控制的飛機(jī)surfaceView.setYourPlane(yourPlane);surfaceView.setYourPlaneImg(yourPlanImg);Log.i(CommonUtil.TAG, “初始化實(shí)體類(lèi)”);}/*** 設(shè)置飛機(jī)的位置** @param view*/private void setPlanPosition(View view) {yourPlane.setX(view.getX());yourPlane.setY(view.getY());Log.i(CommonUtil.TAG, “控制的飛機(jī)坐標(biāo)X:” + view.getX() + “;Y:” + view.getY());}/*** 初始化綁定事件*/private void initListener() {// 飛機(jī)綁定事件yourPlanImg.setOnTouchListener(new YourPlaneTouch());Log.i(CommonUtil.TAG, “控制的飛機(jī)綁定移動(dòng)事件”);}/*** 初始化View*/private void initView() {// 初始化飛機(jī)圖片,這里涉及一個(gè)飛機(jī)圖片,這個(gè)圖片隨便在網(wǎng)上找一個(gè)類(lèi)似的小飛機(jī)就可以,這里我就不上傳了。yourPlanImg = (ImageButton) findViewById(R.id.yourplane);// 得到屏幕高度windowHeight = getResources().getDisplayMetrics().heightPixels;windowWidth = getResources().getDisplayMetrics().widthPixels;Log.i(CommonUtil.TAG, “初始化view”);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic 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();// 點(diǎn)擊周邊,不關(guān)閉提示框alert.setCanceledOnTouchOutside(false);alert.show();}return super.onKeyDown(keyCode, event);}class ExitListener implements OnClickListener{@Overridepublic void onClick(DialogInterface dialog, int which) {//退出程序之前,將飛機(jī)停止射擊yourPlane.setShot(false);finish();}}/**** @ClassName: YourPlaneTouch* @Description: 飛機(jī)綁定事件* @author liPeng* @date 2014-11-5 上午11:23:25**/class YourPlaneTouch implements OnTouchListener {int lastX, lastY;@Overridepublic 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; //在這里進(jìn)行判斷是防止飛機(jī)在托動(dòng)過(guò)程中超出屏幕的范圍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();/** 將飛機(jī)的位置設(shè)置和圖標(biāo)相同 */setPlanPosition(v);v.postInvalidate();break;case MotionEvent.ACTION_UP:break;}return false;}}}?
以下是surfaceView 的代碼:該代碼做了一個(gè)橋梁的作用,用來(lái)搭建xml 和線(xiàn)程之間的功能 。
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;// 控制的飛機(jī)private YourPlane yourPlane;private ImageButton yourPlaneImg;// 飛機(jī)Runnableprivate PlaneRunnable planeRunnable;// 飛機(jī)線(xiàn)程private Thread shotThread;private SurfaceHolder holder;public MySurfaceView(Context context) {super(context);this.context = context;holder = getHolder();holder.addCallback(this);// 設(shè)置透明度holder.setFormat(PixelFormat.TRANSLUCENT);}/*** 執(zhí)行線(xiàn)程*/private void threadRun() {// 控制飛機(jī)線(xiàn)程planeRunnable = new PlaneRunnable(context,holder);//將控制的飛機(jī)綁定到該線(xiàn)程中planeRunnable.setPlane(yourPlane);planeRunnable.setPlaneImg(yourPlaneImg);shotThread = new Thread(planeRunnable);//控制的飛機(jī) 開(kāi)始射擊shotThread.start();Log.i(CommonUtil.VIEW_TAG, “控制的飛機(jī)射擊”);}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}@Overridepublic void surfaceCreated(SurfaceHolder holder) {/** 啟動(dòng)線(xiàn)程 */threadRun();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {if (shotThread != null && shotThread.isAlive()) {try {// 當(dāng)繪圖線(xiàn)程結(jié)束后自動(dòng)銷(xiāo)毀shotThread.join();Log.i(CommonUtil.VIEW_TAG, “射擊線(xiàn)程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中涉及了一個(gè)Util工具類(lèi):代碼如下:主要用來(lái)定義一些常量package com.pm_road.fireair.common;public class CommonUtil {/** 飛機(jī)生命 */public static final int YOUR_PLAN_LIFE = 5;/** 敵機(jī)生命 */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”;}?
完成以上代碼之后:大概的工作也就差不多了,可以使用真機(jī)或ADT運(yùn)行一下:
?
接下來(lái)我們就是寫(xiě)敵機(jī)和敵機(jī)發(fā)射子彈了 《飛機(jī)大戰(zhàn)》安卓游戲開(kāi)發(fā)源碼(四)
?
在這里我的運(yùn)行效果如下:
?
本文章屬于原創(chuàng)性文章,珍惜他人勞動(dòng)成果,轉(zhuǎn)載請(qǐng)注明出處:http://www.pm-road.com/index.php/2014/11/06/161/
?
飛機(jī)大戰(zhàn)源碼
轉(zhuǎn)載于:https://my.oschina.net/pmroad/blog/357078
總結(jié)
以上是生活随笔為你收集整理的《飞机大战》安卓游戏开发源码(三)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 移动终端测试进化论
- 下一篇: java 类的加载、连接和初始化