上一篇講過游戲背景圖的加載以及場景運動效果,如果還需要了解的請<a href="http://www.lxweimin.com/p/a87a9ed6a8b2">移駕這里</a>
今天要研究的是游戲主角戰機的運動以及邏輯的實現。
1.創建一個主角的類DrawPlayer。
package com.tangyx.game.holder;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import com.tangyx.game.R;
import com.tangyx.game.util.BitmapUtils;
import com.tangyx.game.util.ScreenUtils;
import com.tangyx.game.util.SizeUtils;
/**
* Created by tangyx on 2016/12/22.
*
*/
public class DrawPlayer extends DrawGame {
/**
* 主角
*/
private Bitmap mPlayer;
private float mPlayerX;
private float mPlayerY;
/**
* 主角的控制位置
*/
private Bitmap mCollect;
private float mCollectX;
private float mCollectY;
private int mCollectCount;
private Paint mCollectPaint;
/**
* 尾氣噴氣
*/
private Bitmap mPlayerBlow;
private float mSpeedAngle=0.05f;
private float mBlowAngle = 1;
private Matrix mBlowMatrix;
public DrawPlayer(Context context,int player) {
super(context,player);
}
@Override
void initialize(Object... objects) {
mPlayer = BitmapUtils.ReadBitMap(getContext(), (Integer) objects[0]);
int wh = SizeUtils.dp2px(getContext(),20);
mPlayer = BitmapUtils.getBitmap(mPlayer,wh,wh);
mPlayerBlow = BitmapUtils.ReadBitMap(getContext(), R.drawable.playblow0);
mPlayerBlow = BitmapUtils.getBitmap(mPlayerBlow,wh,wh);
mCollect = BitmapUtils.ReadBitMap(getContext(),R.drawable.collect);
wh = SizeUtils.dp2px(getContext(),30);
mCollect = BitmapUtils.getBitmap(mCollect,wh,wh);
int screenW = ScreenUtils.getScreenWidth(getContext());
int screenH = ScreenUtils.getScreenHeight(getContext());
//初始化戰機的位置
mPlayerX = screenW/2-mPlayer.getWidth()/2;
mPlayerY = screenH-mPlayer.getHeight()-screenH/10;
mCollectX = screenW/2-mCollect.getWidth()/2;
mCollectY = mPlayerY+mPlayer.getHeight()+mCollect.getHeight()/2;
mBlowMatrix = new Matrix();
mCollectPaint = new Paint();
mCollectPaint.setAntiAlias(true);
}
@Override
void onDraw(Canvas canvas) {
mPaint.setAlpha(255);
canvas.drawBitmap(mPlayer,mPlayerX,mPlayerY,mPaint);
canvas.drawBitmap(getBlowAnimation(), (mPlayerX-mPlayerBlow.getWidth()/4),mPlayerY+mPlayerBlow.getHeight()/1.5f,mPaint);
}
/**
* 尾氣噴氣動畫
*/
private Bitmap getBlowAnimation(){
mBlowAngle += mSpeedAngle;
float sx =1.5f;
float sy = mBlowAngle;
mBlowMatrix.reset();
mBlowMatrix.postScale(sx,sy);
if(mBlowAngle>=1.2||mBlowAngle<1){
mSpeedAngle=-mSpeedAngle;
}
return Bitmap.createBitmap(mPlayerBlow,0,0,mPlayerBlow.getWidth(),mPlayerBlow.getHeight(),mBlowMatrix,true);
}
/**
* 繪制操作的位置按鈕
*/
public void onDrawCollect(Canvas canvas,String text){
if(mCollectCount==(Integer.MAX_VALUE-1)){
mCollectCount=0;
}
mCollectPaint.setTextSize(20f);
mCollectCount++;
if(mCollectCount%2==0){
mCollectPaint.setAlpha(0);
}else{
mCollectPaint.setAlpha(255);
}
mCollectX = mPlayerX-(mCollect.getWidth()-mPlayer.getWidth())/2;
mCollectY = mPlayerY+mPlayer.getHeight()+mCollect.getHeight()/2;
canvas.drawBitmap(mCollect,mCollectX,mCollectY,mCollectPaint);
String fire = getContext().getString(R.string.fire);
Rect rect = getTextRect(fire,mCollectPaint);
float tx = mCollectX+(mCollect.getWidth()-rect.width())/2;
float ty = mCollectY+mCollect.getHeight()/2+rect.height()/2;
//點擊這個地方游戲繼續
canvas.drawText(fire, tx, ty, mCollectPaint);
int w = ScreenUtils.getScreenWidth(getContext());
int h = ScreenUtils.getScreenHeight(getContext());
mPaint.setTextSize(SizeUtils.sp2px(getContext(),20));
//游戲暫停提示語
rect = getTextRect(text,mPaint);
canvas.drawText(text,(w-rect.width())/2 ,h/3, mPaint);
}
@Override
void updateGame() {
}
public void setPlayerX(float mPlayerX) {
this.mPlayerX = mPlayerX-mPlayer.getWidth()/1.5f;
}
public void setPlayerY(float mPlayerY) {
this.mPlayerY = mPlayerY-mPlayer.getHeight() * 2.5f;
}
public float getCollectX() {
return mCollectX;
}
public float getCollectY() {
return mCollectY;
}
public Bitmap getCollect() {
return mCollect;
}
}
主角戰機組成部分:飛機+尾部噴氣+手指操作按鈕。
1.戰機部分就跟簡單,默認開始坐標在屏幕底部中心位置。
canvas.drawBitmap(mPlayer,mPlayerX,mPlayerY,mPaint);
2.因為是戰機,肯定需要尾部火焰噴氣效果嘛,不然不夠炫。
火焰的位置就是位于戰機的尾部,所以前面繪制完成戰機以后,通過得到戰機的x,y計算出噴氣的位置。
canvas.drawBitmap(getBlowAnimation(), (mPlayerX-mPlayerBlow.getWidth()/4),mPlayerY+mPlayerBlow.getHeight()/1.5f,mPaint);
其中有一個getBlowAnimation的方法,通過它實時更改火焰圖片的高度來給人一種噴射的感覺。
其中主要是通過Matrix類來完成一些特效,這個類也是非常非常非常的重要,在<a >官網</a>有詳細的介紹,可自行查看。
3.戰機是通過我們用手按住屏幕來移動,所以我們需要提供一個可操控的位置,操控的位置也是一張圖片,它的位置一直緊隨著噴氣的底部,而噴氣是緊隨戰機,所以操作動作就是去移動戰機在屏幕的位置。
操作按鈕中心就是一個FIRE的字體,字體和按鈕通過<a >Paint</a>設置透明度的變化產生一個閃爍的效果,并且手離開屏幕的時候操作按鈕就會出現,并且提示游戲狀態以及下一步操作,手按下屏幕的時候就按鈕就會消失并且游戲繼續。
---------我是分割線----------
這里只是把戰機繪制出來,那怎么讓戰機跟隨我的手指運動呢?
回到<b>GameView</b>類,既然是手勢操作,你想到的是什么?我想到就是實現onTouchEvent。
1.暫時給游戲定義三個狀態
2.默認是游戲加載到可操作狀態READY。
當游戲可以操作的時候,這時候把手放到操作按鈕的位置(上圖的白色圓圈),就可以變更游戲狀態為ING。點擊其他位置不做任何變化。
3.手指移動變更戰機的位置x,y。
4.手離開屏幕,游戲進入暫停狀態。
5.在GameView的onGameDraw方法中調用主角繪制。
/**
* 繪制內容以及更新內容
*/
private void onGameDraw(){
if(mCanvas==null)return;
mCanvas.drawColor(Color.WHITE);
//背景
mDrawBackground.onDraw(mCanvas);
mDrawBackground.updateGame();
//主角
mPlayer.onDraw(mCanvas);
mPlayer.updateGame();
//判斷當前游戲狀態
switch (GAME_STATE){
case ING:
break;
case READY:
mPlayer.onDrawCollect(mCanvas,getContext().getString(R.string.reading));
break;
case PAUSE:
mPlayer.onDrawCollect(mCanvas,getContext().getString(R.string.conution));
break;
}
}```

主角戰機的核心思路就是以上部分,最后是提供持續更新的源碼。
<a >源碼傳送門</a>
<a href="http://www.lxweimin.com/p/a87a9ed6a8b2">上一篇</a> <a href="http://www.lxweimin.com/p/966a3e9d8bdf">下一篇</a>