首页 >Android频道 >【Android研究院之游戏开发】 > Android研究院之游戏开发地图编辑器(一)
2012
04-27

Android研究院之游戏开发地图编辑器(一)

Android研究院之游戏开发地图编辑器(一) - 雨松MOMO程序研究院 - 1

Mappy中文地图编辑器的使用说明

下载地址:http://download.csdn.net/source/3452259

        压缩包中包含 游戏地图编辑器使用指南 与地图资源图片 宫院1.png 一张 mapwin.exe 可执行文件 map.FMP 与map.TXT为使用编辑器生成出来的保存文件与地图数组。

Android研究院之游戏开发地图编辑器(一) - 雨松MOMO程序研究院 - 2

解压后打开地图编辑器 mapwin.exe.exe 创建一张新的地图。

Android研究院之游戏开发地图编辑器(一) - 雨松MOMO程序研究院 - 3

由于我用的Android模拟器宽高是320X480

地图宽的块数 就是 320 / 32 = 10

地图高的块数 就是 480 / 32 = 15

Android研究院之游戏开发地图编辑器(一) - 雨松MOMO程序研究院 - 4

这里扩充一下 实际在工作开发中因为手机的分辨率各式各样 所以是需要尺寸考虑自适应的 有两种方法可以拿到当前手机屏幕的宽高

  Display display = getWindowManager().getDefaultDisplay();
  Log.i("view" , "height:" +display.getHeight());
  Log.i("view" , "width:" +display.getWidth());
  DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
  Log.i("view" , "height" +displayMetrics.heightPixels);
  Log.i("view" , "width" +displayMetrics.widthPixels);

 

弹出框后点击确定

 

导入地图图块 编辑器下载地址中包含了一张 地图图片 可以选择使用

因为编辑器是须要美术图片配合使用的 比如tile的尺寸 图片的宽高尺寸必需能被整除。

Android研究院之游戏开发地图编辑器(一) - 雨松MOMO程序研究院 - 5导入地图图块成功 右侧为导入的地图资源 接下来就是自己拖动右侧地图块拼出自己想要的地图了。

Android研究院之游戏开发地图编辑器(一) - 雨松MOMO程序研究院 - 6接下来我将填充3个图层 最底层 实体层 物理层 我会一一介绍他们的作用

图层0为最底层 绘制地图先绘制这一层

Android研究院之游戏开发地图编辑器(一) - 雨松MOMO程序研究院 - 7图层1为实物层 这一层主要绘制一些actor 绘制完第一层在绘制这一层

 

Android研究院之游戏开发地图编辑器(一) - 雨松MOMO程序研究院 - 8图层2为物理层检测物理碰撞这一层不用绘制但是玩家每移动一次就须要以玩家当前点在地图数组中的角标 和物理层做判断是否碰撞,它和Actor层的位置一样。

Android研究院之游戏开发地图编辑器(一) - 雨松MOMO程序研究院 - 9

拼地图的使用技巧 编辑新图层的时候可以把上一个涂层打开进行对比编辑。 

这样子就可以根据0图层的信息来编辑图层1

Android研究院之游戏开发地图编辑器(一) - 雨松MOMO程序研究院 - 10

       地图块拼完后编辑完成后点击保存文件 后在点击保存文本数据  地图数组文件就生成出来了 文件命为map.TXT 里面就存着我们编辑的3个地图层的地图信息。

Android研究院之游戏开发地图编辑器(一) - 雨松MOMO程序研究院 - 11

 

使用Mappy中文地图编辑器生成的地图信息数组来绘制游戏地图

效果图如下

Android研究院之游戏开发地图编辑器(一) - 雨松MOMO程序研究院 - 12

代码实现

这里我先说一下游戏窗口的全屏实现方法  
第一种

	// 全屏显示窗口
	requestWindowFeature(Window.FEATURE_NO_TITLE);
	getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

 第二种 AndroidManifest.xml 中加入

	<activity android:name=".activity"
			  android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />

       

public class mapAcitvity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
	// 全屏显示窗口
	requestWindowFeature(Window.FEATURE_NO_TITLE);
	getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
	//显示自定义的游戏View
	setContentView(new MapView(this));
    }

    public class MapView extends View{

        //tile块的宽高
	public final static int TILE_WIDTH = 32;
	public final static int TILE_HEIGHT = 32;

        //tile块的宽高的数量
	public final static int TILE_WIDTH_COUNT = 10;
	public final static int TILE_HEIGHT_COUNT = 15;

	//数组元素为0则什么都不画
	public final static int TILE_NULL = 0;
	//第一层游戏View地图数组
	public int [][]mMapView = {
		{ 1, 1, 1, 1, 137, 137, 137, 1, 1, 1 },
		{ 1, 1, 1, 1, 137, 137, 137, 1, 1, 1 },
		{ 1, 1, 1, 1, 137, 137, 137, 1, 1, 1 },
		{ 137, 137, 137, 137, 137, 137, 137, 137, 137, 137 },
		{ 137, 137, 137, 137, 137, 137, 137, 137, 137, 137 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 137, 137 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 137, 137 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 137, 137 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 137, 137 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 137, 137 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 137, 137 },
		{ 137, 137, 137, 137, 137, 137, 137, 137, 137, 137 },
		{ 137, 137, 137, 137, 137, 137, 137, 137, 137, 137 },
		{ 1, 1, 1, 1, 1, 137, 137, 137, 1, 1 },
		{ 1, 1, 1, 1, 1, 137, 137, 137, 1, 1 }
		};

	//第二层游戏实体actor数组
	public int [][]mMapAcotor  = {
		{ 102, 103, 103, 104, 0, 0, 0, 165, 166, 167 },
		{ 110, 111, 111, 112, 0, 0, 0, 173, 174, 175 },
		{ 126, 127, 127, 128, 0, 0, 0, 181, 182, 183 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 41, 42, 43, 44, 0, 0, 0, 0, 0, 0 },
		{ 49, 50, 51, 52, 0, 0, 0, 0, 0, 0 },
		{ 57, 58, 59, 60, 229, 230, 231, 232, 0, 0 },
		{ 65, 66, 67, 68, 237, 238, 239, 240, 0, 0 },
		{ 0, 0, 0, 0, 245, 246, 247, 248, 0, 0 },
		{ 0, 0, 0, 0, 0, 254, 255, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 102, 103, 103, 103, 104, 0, 0, 0, 143, 144 },
		{ 110, 111, 111, 111, 112, 0, 0, 0, 143, 144 }
		};

	//第三层游戏碰撞物理层数组
	//下一章介绍
	//....................

	//游戏地图资源
	Bitmap mBitmap = null;

	//资源文件
	Resources mResources = null;

	//游戏画笔
	Paint mPaint = null;

	//横向纵向tile块的数量
	int mWidthTileCount = 0;
	int mHeightTileCount = 0;

	//横向纵向tile块的数量
	int mBitMapWidth = 0;
	int mBitMapHeight = 0;

	/**
	 * 构造方法
	 * @param context
	 */
	public MapView(Context context) {
	    super(context);

	    mPaint = new Paint();
	    mBitmap = ReadBitMap(context, R.drawable.map);
	    mBitMapWidth = mBitmap.getWidth();
	    mBitMapHeight = mBitmap.getHeight();
	    mWidthTileCount = mBitMapWidth / TILE_WIDTH;
	    mHeightTileCount = mBitMapHeight / TILE_HEIGHT;
	}

        @Override
        protected void onDraw(Canvas canvas) {
            DrawMap(canvas,mPaint,mBitmap);
            super.onDraw(canvas);

        }

        private void DrawMap(Canvas canvas,Paint paint ,Bitmap bitmap) {
            int i,j;
            for(i = 0; i< TILE_HEIGHT_COUNT; i++) {
        	for(j = 0; j<TILE_WIDTH_COUNT;j++) {
        	    int ViewID =  mMapView[i][j];
        	    int ActorID = mMapAcotor[i][j];
        	    //绘制地图第一层
        	    if(ViewID > TILE_NULL) {
        		 DrawMapTile(ViewID,canvas,paint,bitmap, j * TILE_WIDTH , i * TILE_HEIGHT);
        	    }

        	    //绘制地图第二层
        	    if(ActorID > TILE_NULL) {
        		DrawMapTile(ActorID,canvas,paint,bitmap, j * TILE_WIDTH , i * TILE_HEIGHT);
        	    }
        	}
            }
        }

        /**
         * 根据ID绘制一个tile块
         * @param id
         * @param canvas
         * @param paint
         * @param bitmap
         */
        private void DrawMapTile(int id,Canvas canvas,Paint paint ,Bitmap bitmap,int x, int y) {
            //根据数组中的ID算出在地图资源中的XY 坐标
            //因为编辑器默认0 所以第一张tile的ID不是0而是1 所以这里 -1
            id--;
            int count = id /mWidthTileCount;
            int bitmapX = (id - (count * mWidthTileCount)) * TILE_WIDTH;
            int bitmapY = count * TILE_HEIGHT;
            DrawClipImage(canvas,paint,bitmap,x,y,bitmapX,bitmapY,TILE_WIDTH,TILE_HEIGHT);
        }

        /**
         * 读取本地资源的图片
         * @param context
         * @param resId
         * @return
         */
        public Bitmap ReadBitMap(Context context, int resId){
            BitmapFactory.Options opt = new BitmapFactory.Options();
            opt.inPreferredConfig = Bitmap.Config.RGB_565;
            opt.inPurgeable = true;
            opt.inInputShareable = true;
            //获取资源图片
            InputStream is = context.getResources().openRawResource(resId);
                return BitmapFactory.decodeStream(is,null,opt);
        }  

        /**
	 * 绘制图片中的一部分图片
	 * @param canvas
	 * @param paint
	 * @param bitmap
	 * @param x
	 * @param y
	 * @param src_x
	 * @param src_y
	 * @param src_width
	 * @param src_Height
	 */
	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) {
	    canvas.save();
	    canvas.clipRect(x, y, x + src_xp, y + src_yp);
	    canvas.drawBitmap(bitmap, x - src_x, y - src_y,paint);
	    canvas.restore();
	}
    }
}

最后如果你还是觉得我写的不够详细 看的不够爽 不要紧我把源代码的下载地址贴出来 欢迎大家一起讨论学习
雨松MOMO希望可以和大家一起进步。

下载地址:http://vdisk.weibo.com/s/aa81p

 这里我详细说一下编辑器生成出来的数组怎么用?就拿生成出来的ID 137为例  假设 tile的宽高为32 137表示从图片的左上角从左到右从上到下 数到第137个tile 就是我们须要绘制的tile   
绘制方面利用 clipRect方法来剪裁图片 实现绘制 下一章我讲游戏中的摄像头机制 会详细介绍这一点。

 

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

Android研究院之游戏开发地图编辑器(一)》有 18 条评论

  1. 怪毛说:

    请问上方图层图片的白色部分会覆盖在下方图层上导致白色部分不透明,不显示背景,该怎么解决呢?

  2. untiy 里面可以使用吗, 可以编辑 45 度 地图吗, 或者有什么好的地图插件吗

  3. 朱凯说:

    请问怎样才能适应不同的屏幕,想要显示全屏,new mapView(getBasecontext).setLayout(LayoutParam) 貌似不起作用

  4. 请问做游戏的时候,这些图片资源都会暴露在外面(apk解压),有没有文章有这方面的说明,谢谢!!!

  5. 风一体说:

    生成出来的ID 137为例不是很懂

  6. 请问Mapwin可以多选tile吗? 不然绘制一个图是不是要一个一个选 然后一个一个的点在屏幕上

  7. Alwaystiys说:

    用那个Mappy制作的地图 放到模拟器 它是不是会放大?

  8. Alwaystiys说:

    博主 我想问一下我的Android模拟器是480*800的然后我按照你里面的代码 自制了一张地图并且模仿你的代码 新建了一个类 但是运行后,显示的地图是完整的,但是显示的内容跟我原来的地图不一样然后我 就直接在你的代码里改,地图显示正确,但是只显示了一部分。我弄了很久都没弄对,所以来麻烦你了

  9. jerry1331说:

    大力支持!太好了,正需要呢! [给力]

  10. 大玩家说:

    请允许我尊称你为老师,我是个游戏爱好着,想通过学习也做做程序,今天有幸看到你的网站,今后我会经常进来学习,您愿意指导我吗?谢谢!!!

留下一个回复

你的email不会被公开。 必填项已用 * 标注。