本文章屬於原創性文章,珍惜他人勞動成果,轉載請註明出處: 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/