1. 程式人生 > >Android遊戲開發之地圖編輯器的使用以及繪製地圖

Android遊戲開發之地圖編輯器的使用以及繪製地圖

x
Mappy中文地圖編輯器的使用說明

下載地址:  Mappy地圖編輯器.rar (938.58 KB, 下載次數: 2967)

壓縮包中包含 遊戲地圖編輯器使用指南 與地圖資源圖片 宮院1.png 一張 mapwin.exe 可執行檔案 map.FMP 與map.TXT為使用編輯器生成出來的儲存檔案與地圖陣列。

解壓後開啟地圖編輯器 mapwin.exe.exe 建立一張新的地圖。

由於我用的Android模擬器寬高是320X480
地圖寬的塊數 就是 320 / 32 = 10
地圖高的塊數 就是 480 / 32 = 15

這裡擴充一下 實際在工作開發中因為手機的解析度各式各樣 所以是需要尺寸考慮自適應的 有兩種方法可以拿到當前手機螢幕的寬高

  1.   Display display = getWindowManager().getDefaultDisplay();
  2.   Log.i(“view” , “height:” +display.getHeight());
  3.   Log.i(“view” , “width:” +display.getWidth());
  4.   DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
  5.   Log.i(“view” , “height” +displayMetrics.heightPixels);
  6.   Log.i(“view” , “width” +displayMetrics.widthPixels);

複製程式碼

彈出框後點擊確定

匯入地圖圖塊 編輯器下載地址中包含了一張 地圖圖片 可以選擇使用
因為編輯器是須要美術圖片配合使用的 比如tile的尺寸 圖片的寬高尺寸必需能被整除。

匯入地圖圖塊成功 右側為匯入的地圖資源 接下來就是自己拖動右側地圖塊拼出自己想要的地圖了。

接下來我將填充3個圖層 最底層 實體層 物理層 我會一一介紹他們的作用

圖層0為最底層 繪製地圖先繪製這一層

圖層1為實物層 這一層主要繪製一些actor 繪製完第一層在繪製這一層

圖層2為物理層檢測物理碰撞這一層不用繪製但是玩家每移動一次就須要以玩家當前點在地圖陣列中的角標 和物理層做判斷是否碰撞,它和Actor層的位置一樣。

拼地圖的使用技巧 編輯新圖層的時候可以把上一個塗層開啟進行對比編輯。
這樣子就可以根據0圖層的資訊來編輯圖層1

地圖塊拼完後編輯完成後點選儲存檔案 後在點選儲存文字資料  地圖陣列檔案就生成出來了 檔案命為map.TXT 裡面就存著我們編輯的3個地圖層的地圖資訊。

使用Mappy中文地圖編輯器生成的地圖資訊陣列來繪製遊戲地圖

效果圖如下

程式碼實現

這裡我先說一下游戲視窗的全屏實現方法
第一種

  1.         // 全屏顯示視窗
  2.         requestWindowFeature(Window.FEATURE_NO_TITLE);
  3.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

複製程式碼

第二種 AndroidManifest.xml 中加入

  1.         <activity android:name=”.activity”
  2.                           android:theme=”@android:style/Theme.NoTitleBar.Fullscreen” />

複製程式碼

這裡我詳細說一下編輯器生成出來的陣列怎麼用?就拿生成出來的ID 137為例  假設 tile的寬高為32 137表示從圖片的左上角從左到右從上到下 數到第137個tile 就是我們須要繪製的tile
繪製方面利用 clipRect方法來剪裁圖片 實現繪製 下一章我講遊戲中的攝像頭機制 會詳細介紹這一點。

  1. public class mapAcitvity extends Activity {
  2.     @Override
  3.     public void onCreate(Bundle savedInstanceState) {
  4.         super.onCreate(savedInstanceState);
  5.         // 全屏顯示視窗
  6.         requestWindowFeature(Window.FEATURE_NO_TITLE);
  7.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
  8.         //顯示自定義的遊戲View
  9.         setContentView(new MapView(this));
  10.     }
  11.     public class MapView extends View{
  12.         //tile塊的寬高
  13.         public final static int TILE_WIDTH = 32;
  14.         public final static int TILE_HEIGHT = 32;
  15.         //tile塊的寬高的數量
  16.         public final static int TILE_WIDTH_COUNT = 10;
  17.         public final static int TILE_HEIGHT_COUNT = 15;
  18.         //陣列元素為0則什麼都不畫
  19.         public final static int TILE_NULL = 0;
  20.         //第一層遊戲View地圖陣列
  21.         public int [][]mMapView = {
  22.                 { 1, 1, 1, 1, 137, 137, 137, 1, 1, 1 },
  23.                 { 1, 1, 1, 1, 137, 137, 137, 1, 1, 1 },
  24.                 { 1, 1, 1, 1, 137, 137, 137, 1, 1, 1 },
  25.                 { 137, 137, 137, 137, 137, 137, 137, 137, 137, 137 },
  26.                 { 137, 137, 137, 137, 137, 137, 137, 137, 137, 137 },
  27.                 { 1, 1, 1, 1, 1, 1, 1, 1, 137, 137 },
  28.                 { 1, 1, 1, 1, 1, 1, 1, 1, 137, 137 },
  29.                 { 1, 1, 1, 1, 1, 1, 1, 1, 137, 137 },
  30.                 { 1, 1, 1, 1, 1, 1, 1, 1, 137, 137 },
  31.                 { 1, 1, 1, 1, 1, 1, 1, 1, 137, 137 },
  32.                 { 1, 1, 1, 1, 1, 1, 1, 1, 137, 137 },
  33.                 { 137, 137, 137, 137, 137, 137, 137, 137, 137, 137 },
  34.                 { 137, 137, 137, 137, 137, 137, 137, 137, 137, 137 },
  35.                 { 1, 1, 1, 1, 1, 137, 137, 137, 1, 1 },
  36.                 { 1, 1, 1, 1, 1, 137, 137, 137, 1, 1 }
  37.                 };
  38.         //第二層遊戲實體actor陣列
  39.         public int [][]mMapAcotor  = {
  40.                 { 102, 103, 103, 104, 0, 0, 0, 165, 166, 167 },
  41.                 { 110, 111, 111, 112, 0, 0, 0, 173, 174, 175 },
  42.                 { 126, 127, 127, 128, 0, 0, 0, 181, 182, 183 },
  43.                 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  44.                 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  45.                 { 41, 42, 43, 44, 0, 0, 0, 0, 0, 0 },
  46.                 { 49, 50, 51, 52, 0, 0, 0, 0, 0, 0 },
  47.                 { 57, 58, 59, 60, 229, 230, 231, 232, 0, 0 },
  48.                 { 65, 66, 67, 68, 237, 238, 239, 240, 0, 0 },
  49.                 { 0, 0, 0, 0, 245, 246, 247, 248, 0, 0 },
  50.                 { 0, 0, 0, 0, 0, 254, 255, 0, 0, 0 },
  51.                 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  52.                 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  53.                 { 102, 103, 103, 103, 104, 0, 0, 0, 143, 144 },
  54.                 { 110, 111, 111, 111, 112, 0, 0, 0, 143, 144 }
  55.                 };
  56.         //第三層遊戲碰撞物理層陣列
  57.         //下一章介紹
  58.         //………………..
  59.         //遊戲地圖資源
  60.         Bitmap mBitmap = null;
  61.         //資原始檔
  62.         Resources mResources = null;
  63.         //遊戲畫筆
  64.         Paint mPaint = null;
  65.         //橫向縱向tile塊的數量
  66.         int mWidthTileCount = 0;
  67.         int mHeightTileCount = 0;
  68.         //橫向縱向tile塊的數量
  69.         int mBitMapWidth = 0;
  70.         int mBitMapHeight = 0;
  71.         /**
  72.          * 構造方法
  73.          * @param context
  74.          */
  75.         public MapView(Context context) {
  76.             super(context);
  77.             mPaint = new Paint();
  78.             mBitmap = ReadBitMap(context, R.drawable.map);
  79.             mBitMapWidth = mBitmap.getWidth();
  80.             mBitMapHeight = mBitmap.getHeight();
  81.             mWidthTileCount = mBitMapWidth / TILE_WIDTH;
  82.             mHeightTileCount = mBitMapHeight / TILE_HEIGHT;
  83.         }
  84.         @Override
  85.         protected void onDraw(Canvas canvas) {
  86.             DrawMap(canvas,mPaint,mBitmap);
  87.             super.onDraw(canvas);
  88.         }
  89.         private void DrawMap(Canvas canvas,Paint paint ,Bitmap bitmap) {
  90.             int i,j;
  91.             for(i = 0; i< TILE_HEIGHT_COUNT; i++) {
  92.                 for(j = 0; j<TILE_WIDTH_COUNT;j++) {
  93.                     int ViewID =  mMapView[i][j];
  94.                     int ActorID = mMapAcotor[i][j];
  95.                     //繪製地圖第一層
  96.                     if(ViewID > TILE_NULL) {
  97.                          DrawMapTile(ViewID,canvas,paint,bitmap, j * TILE_WIDTH , i * TILE_HEIGHT);
  98.                     }
  99.                     //繪製地圖第二層
  100.                     if(ActorID > TILE_NULL) {
  101.                         DrawMapTile(ActorID,canvas,paint,bitmap, j * TILE_WIDTH , i * TILE_HEIGHT);
  102.                     }
  103.                 }
  104.             }
  105.         }
  106.         /**
  107.          * 根據ID繪製一個tile塊
  108.          * @param id
  109.          * @param canvas
  110.          * @param paint
  111.          * @param bitmap
  112.          */
  113.         private void DrawMapTile(int id,Canvas canvas,Paint paint ,Bitmap bitmap,int x, int y) {
  114.             //根據陣列中的ID算出在地圖資源中的XY 座標
  115.             //因為編輯器預設0 所以第一張tile的ID不是0而是1 所以這裡 -1
  116.             id–;
  117.             int count = id /mWidthTileCount;
  118.             int bitmapX = (id – (count * mWidthTileCount)) * TILE_WIDTH;
  119.             int bitmapY = count * TILE_HEIGHT;
  120.             DrawClipImage(canvas,paint,bitmap,x,y,bitmapX,bitmapY,TILE_WIDTH,TILE_HEIGHT);
  121.         }
  122.         /**
  123.          * 讀取本地資源的圖片
  124.          * @param context
  125.          * @param resId
  126.          * @return
  127.          */
  128.         public Bitmap ReadBitMap(Context context, int resId){
  129.             BitmapFactory.Options opt = new BitmapFactory.Options();
  130.             opt.inPreferredConfig = Bitmap.Config.RGB_565;
  131.             opt.inPurgeable = true;
  132.             opt.inInputShareable = true;
  133.             //獲取資源圖片
  134.             InputStream is = context.getResources().openRawResource(resId);
  135.                 return BitmapFactory.decodeStream(is,null,opt);
  136.         }
  137.         /**
  138.          * 繪製圖片中的一部分圖片
  139.          * @param canvas
  140.          * @param paint
  141.          * @param bitmap
  142.          * @param x
  143.          * @param y
  144.          * @param src_x
  145.          * @param src_y
  146.          * @param src_width
  147.          * @param src_Height
  148.          */
  149.         private void DrawClipImage(Canvas canvas,Paint paint ,Bitmap bitmap, int x, int y, int src_x, int src_y, int src_xp, int src_yp) {
  150.             canvas.save();
  151.             canvas.clipRect(x, y, x + src_xp, y + src_yp);
  152.             canvas.drawBitmap(bitmap, x – src_x, y – src_y,paint);
  153.             canvas.restore();
  154.         }
  155.     }
  156. }

複製程式碼