关于横版我的世界跑酷地图存档类地图处理的问题

穿越黑暗城堡、城市街道,尽可能逃出生天
(责任编辑:snowlian)(人气:)上一篇:
(来源:安卓网)下一篇:
热门产品推荐
分享到其他平台:
推荐理由:《两个罗马士兵 Cato and Macro》是一款在线模拟经营游戏。从这星期日泰晤士报畅销书作者西蒙·斯卡罗带来游戏:两个罗马士兵
推荐理由:《死亡之地:未来世界 Dead Earth: Sci-fi》是一款科幻风格的第一人称射击类游戏。就像电影《终结者》里的经典台词一样,审
推荐理由:《瘦人传说 Origins II》是《瘦长鬼影:起源 Slender Man Origins》的续作。这是一款恐怖冒险游戏。瘦长鬼影——Slender Man 外观是
推荐理由:《炽焰:入侵 Under Fire: Invasion》是一款策略、动作、角色扮演相结合的游戏。世界末日来临,我们的银河系危在旦夕,骚乱和
推荐理由:《重金属风暴 Heavy Metal Thunder》是一款游戏书(gamebook)风格游戏。游戏类似电子书,还是英文的。在每一段故事后,玩家需要做一款单机的苹果手机游戏,横版的,类似跑酷的,但遇到过过河,只要手指在屏幕画个指定图形就会出现船,等_百度知道
一款单机的苹果手机游戏,横版的,类似跑酷的,但遇到过过河,只要手指在屏幕画个指定图形就会出现船,等
等等的!,之前在朋友手机上玩的,画横线会出现长条的方块,横版的,只要手指在屏幕画个指定图形就会出现船,画个三角形!感激不尽,又没那位大大知道名字呀,但遇到过过河,类似跑酷的!,会出现三角形方块,画圆形会出现气球!一款单机的苹果手机游戏
我有更好的答案
按默认排序
是不是这个:麦克斯与魔法标记(Max & the Magic Marker)
其他类似问题
苹果手机的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁求助:一个小鸡横版跑酷类的苹果游戏名称?_百度知道
求助:一个小鸡横版跑酷类的苹果游戏名称?
经玩过苹果游戏一个游戏?,请问这个游戏名是,主角是一只小鸡,横版跑酷类,和太阳赛跑,地图比较单调,日落了就GAME OVER,如果跑不赢太阳,都是波浪型的山丘为主,分每个小关?知道的朋友请告知
提问者采纳
应该是极速滑行
多谢回答,但我上网搜索过不是
提问者评价
找到了,游戏:小鸟学飞Tiny Wings,虽然你答案不正确,还是感谢你的回答,奖励就给最先回答的喔
其他类似问题
苹果游戏的相关知识
按默认排序
其他2条回答
可能是小鸡快跑
多谢回答,但我上网搜索过不是
就是。。。
是极速滑行
多谢回答,但我上网搜索过不是
那就不清楚了
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁卡马克算法(地图重复利用,跑酷类游戏)
http://blog.chinaunix.net/uid-52437-id-2152240.html
-----------------------------下面是理论知识--------------------------
卡马克算法:由约翰·卡马克(John
Carmack)开发的一种游戏地图处理方法,被广泛运用到2D卷轴式游戏和手机游戏中。
约翰·卡马克:id
Software创始人之一,技术总监。享誉世界的著名程序员,以卡马克算法和3D游戏引擎开发而闻名世界,被奉为游戏行业偶像。同时他也是个全面型的技术天才,现在致力于民用航天器开发,是民用航天器开发小组Armadillo
Aerospace的主要创办人和技术骨干。
约翰·卡马克(百度百科):&
约翰·卡马克(维基百科):&
&&&&&地图是游戏中必不可少的一种预算元素,尤其是在RPG、ACT等类型的游戏中作用更为重要,一个漂亮的地图效果和一个流畅的卷动速度会大大增加玩家的游戏体验。而游戏中地图滚动的重绘有多种算法,由于手机性能的限制和开发周期等其他非技术条件,需要根据情况灵活选择所需的技术。本文将主要介绍如何使用OPhone
API来绘制2D游戏中的场景,也即地图的绘制方法。
地图绘制及滚动的常用算法
无缝图片滚动画法&&&&&&&最简单的一种画地图方法,无需使用数组,只需要使用一张无缝的背景图片,在屏幕上绘制两次,以此来实现最简单的地图滚动效果和图片的重复使用以节约资源。
如下图,红色虚线部分为屏幕,使用一个偏移量在屏幕中错开位置贴上两次图片,通过不断改变偏移量的大小来实现动画效果。
&&&&&&&&代码举例:
&&&&//imgBack图片对象&&
&&&&//posX图片在X轴方向上的偏移量&&
canvas.drawBitmap(imgBack, -posX, 0,
canvas.drawBitmap(imgBack, imgBack.getHeight()+posX, 0,
&&&&if(posX==-imgBack.getHeight())&&
&&&&&&&&posX=0;&&&//imgBack图片对象
//posX图片在X轴方向上的偏移量 canvas.drawBitmap(imgBack, -posX, 0, paint);
canvas.drawBitmap(imgBack, imgBack.getHeight()+posX, 0, paint);
if(posX==-imgBack.getHeight()) posX=0;
&&&&&&&优点与局限:此算法非常简单,由于是单张图片反复滚动生成的背景图片,所以对于美术人员的限制较少,利于发挥,而且外观效果好。但因为不是地图Tile组成的,资源复用率不高,只能用于生成不太复杂的地图。而且由于没有Tile的存在,无法针对不同的Tile计算碰撞。最终使得这种画法只能用于绘制简单屏幕背景图片,而无法用在有复杂物理碰撞的地图层。
裁剪区画法
&&&&&&&&我们平时所玩的游戏一般场景都是大于屏幕的尺寸的,也就是说在游戏中的主角移动的时候,后面的地图将会随着主角的位置变化而发生移动,我们称之为地图的卷轴效果。而对诸如RPG,ACT这类地图场景比较大的类型的游戏来说,地图都不是一整张的背景图直接使用,而是采用一种“拼接”的方式,这样做既能节省内存的占用,同时也能使图片资源的利用率达到最大化。下图就是2D游戏常用的图片样式:
&&&&&&&&&从图中我们能够看出,我们可以把整张图片进行分割,并将分割后的图片进行编号,如下所示:
&&&&&&&&&为每块图素编号之后,就可以设计自己的地图了。这里需要使用一种叫做“地图编辑器”的工具软件。我们这里使用“mapwin”进行地图的设计,使用步骤如下图所示:
&&&&&&&&&上面的四个输入框分别代表地图小块的宽度和高度,以及我们要创建的整个场景的水平和垂直的地图块数,输入后点击“OK”如下图所示:
&&&&&&&&&下面需要引入一张图片,引入方法为“File——Import”,选取一张图片并点击确定,随后就能看到如下的图片:
&&&&&&&&&&&剩下的工作想必你就可以想到了,用鼠标在右边区域选取一个图块,然后将其放到左边黑色区域中即可,拼接完的效果如下图:
&&&&&&&&&&&接下来要把地图数据导出,导出放下如下图:
&&&&&&&&&最后我们需要的数据是这样的:
const short ss_map0[10][10] = {
{ 1, 1, 1, 1, 1, 1, 1, 5, 1, 1 },
{ 10, 10, 10, 1, 1, 1, 1, 1, 1, 1 },
{ 8, 8, 8, 1, 1, 1, 1, 1, 1, 1 },
{ 9, 9, 9, 1, 1, 1, 1, 14, 15, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 16, 17, 1 },
{ 1, 1, 1, 6, 11, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 11, 1, 1, 1, 21, 1 },
{ 1, 4, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
&&&&&&&&&实际上就是一个二维数组,数组中的数字即为地图块的索引号。
&&&&&&&&&使用二维数组保存地图信息,另外有一张图片素材,根据地图数组的不同下标,配合public
boolean clipRect(float left, float top, float right, float
bottom,Region.Op op) 裁剪区方法,将对应的Tile显示在正确的位置上。
&&&&&&&&如下图所示,红色虚线部分为屏幕,红色实线为裁剪区,通过读取地图数组,将相应的位置设置为裁剪区,并用将图片素材相对于裁剪区偏移一定x,y位置的方法,使得要绘制的Tile正好对应出现在裁剪区中。
代码举例:
// 绘制切割图片&&
&&&&public
void drawClipImg(int XDest, int YDest, int Width, int
&&&&&&&&&&&&int
XSrc, int YSrc, Bitmap img, Paint g,Canvas
&&&&&&&&canvas.clipRect(XDest,
YDest, XDest + Width, YDest +
&&&&&&&&&&&&&&&&Region.Op.REPLACE);&&
&&&&&&&&canvas.drawBitmap(img,
XDest - XSrc, YDest - YSrc,
&&&&&&&&canvas.clipRect(0,
0, Const.SCREEN_WIDTH,
Const.SCREEN_HEIGHT,&&
&&&&&&&&&&&&&&&&Region.Op.REPLACE);&&
&&&&}&&&&&//
绘制切割图片 public void drawClipImg(int XDest, int YDest, int Width, int
Height, int XSrc, int YSrc, Bitmap img, Paint g,Canvas canvas) {
canvas.clipRect(XDest, YDest, XDest + Width, YDest + Height,
Region.Op.REPLACE); canvas.drawBitmap(img, XDest - XSrc, YDest -
YSrc, g); canvas.clipRect(0, 0, Const.SCREEN_WIDTH,
Const.SCREEN_HEIGHT, Region.Op.REPLACE); }
&&&&&&&相对于前一种画法,图片资源的利用率提高了很多,可以绘制很复杂的地图。由于Tile的存在,可以针对不同的Tile计算碰撞,可以用于地图物理层的绘制。
最常见的地图绘制优化——只绘制当前屏幕&&&&&&&上面的绘制方法都是将整个地图的数据全部画出来的,这样做实际上也存在很大的浪费,因为玩家实际上只能看见屏幕中的一块区域,其他大部分的地图即使被绘制也不能反映到屏幕上,反而因为这个不必要的步骤大大增加了CPU的负担,从而影响了游戏的流畅程度。因此,在实际开发中,常用的优化方法就是只绘制当前屏幕的地图块。代码如下:
&&&&//计算单元格起始位置下标&&
startIndexX =leftTopY/
MAP_TILE_SIZE;&&
startIndexY =leftTopX/
MAP_TILE_SIZE;&&
&&&&//再使用上面得到的数据修改双循环绘制的条件即可,&&
for (int i = startIndexX; i 1;
&&&&&&&&&&&&for
(int j = startIndexY; j 1;
j++)&&&//计算单元格起始位置下标
int startIndexX =leftTopY/ MAP_TILE_SIZE; int startIndexY
=leftTopX/ MAP_TILE_SIZE; //再使用上面得到的数据修改双循环绘制的条件即可, for (int i =
startIndexX; i
卡马克卷轴算法的引入&&&&&&&上面的算法虽然在一定程度上解决了地图绘制的效率问题,但对于某些资源严重不足的手机,或者由于地图块比较小、循环次数过多的情况,仍然会造成画图时屏幕闪烁。因此,在这种情况下,仍然需要对上述算法做进一步的优化。
&&&&&&&&不论采用哪种优化算法,一个基本的思路就是尽量减少绘制的次数,从而减少对系统资源的消耗。卡马克卷轴算法就是这样算法的一个经典例子。
单方向卷轴
&&&&&&&&对于横版游戏来说,如果角色向右侧移动,则地图向左侧滚动。由于角色每次移动若干个步长,因此地图中新画出的区域宽度也为若干个像素,那么如果让系统重绘所有屏幕区域,很明显,大部分区域都是和上一屏幕区域相同的,如此造成成了资源的浪费。而卡马克算法的思路就是——如果上一次绘制过的地图也能够部分重用到本次地图绘制上来就好了。那么很容易想到在内存中建立一个和屏幕一样大或略大的缓冲区即可很好的完成这个设想。
&&&&&&&由上图可以看到,区域B为相同的地图区域,这个区域在下一次屏幕重绘时,可以被重新利用。区域A是在下一次屏幕重绘中不被采用的区域,这区域应当被舍弃,但是如果稍微留意一下的话,不难发现区域A和区域C的面积大小其实居然是一样的。
&&&&&&&那么如果建立一个和屏幕大小相同的缓冲,在其被舍弃掉的绘制区域A中画上新的区域C,再把区域B和区域C拼合到屏幕上,是不是就能达到减少系统资源消耗的目的了呢?卡马克卷轴的基本原理正是如此。
&&&&&&&图显示了卡马克卷轴的最基本原理,首先在内存中建立一块和屏幕一样大小(或略大)的缓冲区。然后在本应由于地图移动而被舍弃掉的区域1上面绘制,由于地图滚动而出现的新地图区域。最后把两个区域按照地图的实际位置拼合到屏幕上。
双轴滚动的卡马克卷轴
&&&&&&&&对于俯视游戏,或者有Y轴卷动的游戏来说,单单一个方向的地图卷动并不够用。那么如果是出现两个方向的卷动会如何呢。不必担心,上面的思路算法一样能适应这种情况。
&&&&&&&&由上图可以看到,区域D为相同的地图区域,这个区域在下一次屏幕重绘时,可以被重新利用。区域ABC是在下一次屏幕重绘中不被采用的区域,可以在这个3个区域上绘制上下一次需要重绘的区域A’B’C’。再将绘制好的四个区域拼合到屏幕的对应位置。
&&&&&&&上图显示了双轴滚动的卡马克卷轴的基本绘制原理,需要特别注意的是:在缓冲区的绘制顺序和在屏幕上拼合的顺序是完全相反的。
卡马克算法的实现卡马克卷轴缓冲画法的一般步骤如下:
1. 初始化所有地图数据,并且全屏绘制初始的地图
2. 若人物移动,则调用摄像机算法,修正地图偏移量
3. 地图偏移量不满足地图的边界条件,就重绘缓冲区
4. 重绘缓冲区
5. 后台缓冲区的四个子区按照顺序画到屏幕上
地图类——Map的设计
//地图数据&&
public byte
mapData[][];&&
//移动缓冲区的当前坐标窗口&&
public int sx,&&
//地图图片&&
private Bitmap
public GameView
public final static int MAP_TILE_SIZE =
private int bufWidth,
private int carTileWidth,
carTileH&&
private int scrWidth,
private int carx,
private int mapOffx,
public Bitmap
private Canvas carGp;&&
private int buffS&&
private int
imageTileW&&
private Bitmap
mapI&&&&&&
Paint paint=new
Paint();&&
private byte
mapArray[][];&&
private int tileS&&
private int tileW,
private int mapLastx,
mapL&&&//地图数据
public byte mapData[][]; //移动缓冲区的当前坐标窗口 public int sx, //地图图片
private Bitmap imgM public GameView m_V //常量 public final
static int MAP_TILE_SIZE = 24; private int bufWidth, bufH
private int carTileWidth, carTileH private int scrWidth,
scrH private int carx, private int mapOffx, mapO
public Bitmap carB private Canvas carGp; private int
buffS private int imageTileW private Bitmap mapI
Paint paint=new Paint(); private byte mapArray[][]; private int
tileS private int tileW, tileH; private int mapLastx,
CarMapBuffer(int, int, int, int)构造器
CarMapBuffer(int, int, int)构造器的代理
setMap(Image, byte[][])设置地图参数
initBuffer()初始化绘制地图
scroll(int, int)卷动地图算法
updateBuffer(int, int)绘制缓冲区
getIndexCarX()获得切割线所在的图块索引X
getIndexCarY()获得切割线所在的图块索引Y
getBufferCarX()获得切割线在Buffer中的X位置
getBufferCarY()获得切割线在Buffer中的Y位置
getIndexBuffLastX()获得缓冲区后面的X索引
getIndexBuffLastY()获得缓冲区后面的Y索引
getTitleHeight()获得当前要绘制的图块高度的数量
getTitelWidth()获得当前要绘制的图块宽度的数量
copyBufferX(int, int, int, int, int) 由于x方向卷动造成的重绘
copyBufferY(int, int, int, int, int) 由于y方向卷动造成的重绘
getMapX(int, int) 获得地图图片的X坐标偏移
getMapY(int, int) 获得地图图片的Y坐标偏移
paint(Graphics, int, int)将缓冲区的内容分成4块依次拼合到屏幕上
drawBuffer(Graphics, int, int)绘制缓冲区方法
drawRegion(Graphics, Image, int, int, int, int, int, int, int,
int)封装的drawRegion()方法
getGraphics()获得缓冲区画笔
getImage()获得缓冲区Image对象
步骤一的实现
初始化所有地图数据,并且全屏绘制初始的地图,代码如下:
&&&&private
void initBuffer()&&
&&&&&&&&int
x, y, cx,&&
&&&&&&&&for
(int i = 0; i
&&&&&&&&{&&
&&&&&&&&&&&&for
(int j = 0; j
&&&&&&&&&&&&{&&
&&&&&&&&&&&&&&&&x
= getMapX(i, j);&&
&&&&&&&&&&&&&&&&y
= getMapY(i, j);&&
&&&&&&&&&&&&&&&&cx
= j * tileS&&
&&&&&&&&&&&&&&&&cy
= i * tileS&&
&&&&&&&&&&&&&&&&m_View.drawClipImg(cx,
cy, tileSize, tileSize, x, y, mapImage, paint,
&&&&&&&&&&&&}&&
&&&&&&&&}&&
}&&&private void
initBuffer() { int x, y, cx, for (int i = 0; i
步骤二、三的实现
若人物移动,则调用摄像机算法,修正地图偏移量,若偏移量在[0,maplast]移动范围内移动,则有可能发生重绘
&&&&private
void scroll(int x, int
&&&&&&&&try&&
&&&&&&&&{&&
&&&&&&&&&&&&x
&&&&&&&&&&&&y
&&&&&&&&&&&&//
*************************************************&&
&&&&&&&&&&&&//
边界检测&&
&&&&&&&&&&&&if
(x 0 || y 0)&&
&&&&&&&&&&&&{&&
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&}&&
&&&&&&&&&&&&if
(x & mapLastx)&&
&&&&&&&&&&&&{&&
&&&&&&&&&&&&&&&&mapOffx
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&}&&
&&&&&&&&&&&&if
(y & mapLasty)&&
&&&&&&&&&&&&{&&
&&&&&&&&&&&&&&&&mapOffy
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&}&&
&&&&&&&&&&&&updateBuffer(x,
&&&&&&&&&&&&//
*************************************************&&
&&&&&&&&}&&
&&&&&&&&catch
(ArrayIndexOutOfBound***ception
&&&&&&&&{&&
&&&&&&&&}&&
&&&&&&&private
void scroll(int x, int y) { try { x += mapO y += mapO //
************************************************* // 边界检测 if
(x&&mapLastx) { mapOffx =
mapL } if (y & mapLasty) { mapOffy = mapL
} updateBuffer(x, y); //
************************************************* } catch
(ArrayIndexOutOfBound***ception e) { } }
步骤四的实现&&&&&&&&重绘缓冲区,地图的x方向卷动会造成列方向上的重绘(调用copyBufferX()方法),地图的y方向上的卷动会造成行方向上的重绘(调用copyBufferY()方法)。updateBuffer()方法用于针对不同的四个方向上的卷动进行copyBuffer()参数的初始化。
&&&&private
void updateBuffer(int x, int
&&&&&&&&mapOffx
&&&&&&&&mapOffy
&&&&&&&&//
&&&&&&&&if
(x & carx +
buffSize)&&
&&&&&&&&{&&
&&&&&&&&&&&&//
while (carx&&
&&&&&&&&&&&&int
indexMapLastX =
getIndexBuffLastX();&&
&&&&&&&&&&&&if
(indexMapLastX
&&&&&&&&&&&&{&&
&&&&&&&&&&&&&&&&copyBufferX(indexMapLastX,
getIndexCarY(),
getTileHeight(),&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&getBufferCarX(),
getBufferCarY());&&
&&&&&&&&&&&&&&&&carx
+= tileS&&
&&&&&&&&&&&&}&&
&&&&&&&&&&&&//
&&&&&&&&}&&
&&&&&&&&//
&&&&&&&&if
&&&&&&&&{&&
&&&&&&&&&&&&//
&&&&&&&&&&&&carx
-= tileS&&
&&&&&&&&&&&&copyBufferX(getIndexCarX(),
getIndexCarY(),
getTileHeight(),&&
&&&&&&&&&&&&&&&&&&&&&&&&getBufferCarX(),
getBufferCarY());&&
&&&&&&&&&&&&//
} while (carx &
mapOffx);&&
&&&&&&&&}&&
&&&&&&&&//
&&&&&&&&if
(y & cary +
buffSize)&&
&&&&&&&&{&&
&&&&&&&&&&&&//
while (cary&&
&&&&&&&&&&&&int
indexMapLastY =
getIndexBuffLastY();&&
&&&&&&&&&&&&if
(indexMapLastY
&&&&&&&&&&&&{&&
&&&&&&&&&&&&&&&&copyBufferY(getIndexCarX(),
indexMapLastY,
getTitelWidth(),&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&getBufferCarX(),
getBufferCarY());&&
&&&&&&&&&&&&&&&&cary
+= tileS&&
&&&&&&&&&&&&}&&
&&&&&&&&&&&&//
&&&&&&&&}&&
&&&&&&&&//
&&&&&&&&if
&&&&&&&&{&&
&&&&&&&&&&&&//
&&&&&&&&&&&&cary
-= tileS&&
&&&&&&&&&&&&copyBufferY(getIndexCarX(),
getIndexCarY(),
getTitelWidth(),&&
&&&&&&&&&&&&&&&&&&&&&&&&getBufferCarX(),
getBufferCarY());&&
&&&&&&&&&&&&//
} while (cary &
mapOffy);&&
&&&&&&&&}&&
&&&&}&&&private
void updateBuffer(int x, int y) { mapOffx = mapOffy = // 右移
if (x & carx + buffSize) { // while
(carx&&mapOffx); } // 下移 if (y
& cary + buffSize) { // while
(cary&&mapOffy); } }
&&&&&&&&重绘缓冲区的具体方法,该方法涉及到大量的坐标运算,而且由于卡马克点的存在经常会分成两个区域分两次进行重绘。见下图:
&&&&&&&&&&&&&&下面以x方向卷动为例举例
private void copyBufferX(int indexMapx, int indexMapy, int
tileHeight,&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&int
destx, int desty)&&
mapImagex, mapImagey,
拷贝地图上面到缓冲的下面&&
timer=0;&&
(int j = 0; j
&&&&&&&&&&mapImagex
= getMapX(indexMapy + j,
indexMapx);&&
&&&&&&&&&&mapImagey
= getMapY(indexMapy + j,
indexMapx);&&
&&&&&&&&&&vy
= j * tileSize +
&&&&&&&&&&m_View.drawClipImg(destx,
vy, tileSize, tileSize, mapImagex, mapImagey, mapImage, paint,
&&&&&&&&&&timer++;&&
拷贝地图下面到缓冲的上面&&
(int k = tileH k
&&&&&&&&&&mapImagex
= getMapX(indexMapy + k,
indexMapx);&&
&&&&&&&&&&mapImagey
= getMapY(indexMapy + k,
indexMapx);&&
&&&&&&&&&&vy
= (k - tileHeight) *
&&&&&&&&&&m_View.drawClipImg(destx,
vy, tileSize, tileSize, mapImagex, mapImagey, mapImage, paint,
&&&&&&&&&&timer++;&&
&&&&&&System.out.println("x:"+timer);&&
&&}&&&private
void copyBufferX(int indexMapx, int indexMapy, int tileHeight, int
destx, int desty) { int mapImagex, mapImagey, // 拷贝地图上面到缓冲的下面
int timer=0; for (int j = 0; j
步骤五的实现
&&&&&&&&将后台缓冲区的四个子区按照顺序画到屏幕上:
public void paint(Canvas g, int x, int
&&&&&&&&//
地图在缓冲中的坐标&&
&&&&&&&&int
tempx = mapOffx %
&&&&&&&&int
tempy = mapOffy %
&&&&&&&&//
切割线右下角的宽与高&&
&&&&&&&&int
rightWidth = bufWidth -
&&&&&&&&int
rightHeight = bufHeight -
&&&&&&&&//
&&&&&&&&drawRegion(g,
carBuffer, tempx, tempy, rightWidth, rightHeight, 0, x,
&&&&&&&&//
&&&&&&&&drawRegion(g,
carBuffer, 0, tempy, scrWidth - rightWidth, rightHeight, 0, x +
rightWidth, y);&&
&&&&&&&&//
&&&&&&&&drawRegion(g,
carBuffer, tempx, 0, rightWidth, scrHeight - rightHeight, 0, x, y +
rightHeight);&&
&&&&&&&&//
&&&&&&&&drawRegion(g,
carBuffer, 0, 0, scrWidth - rightWidth,
scrHeight&&
&&&&&&&&&&&&&&&&&&&-
rightHeight, 0, x + rightWidth, y +
rightHeight);&&
&&&&private
void drawRegion(Canvas g, Bitmap img, int x_src, int
&&&&&&&&&&&&&&&&&&&&&&&&&&&&int
width, int height, int transform, int
&&&&&&&&&&&&&&&&&&&&&&&&&&&&int
&&&&&&&&//
作宽度检测&&
&&&&&&&&if
(width 0 || height 0)&&
&&&&&&&&{&&
&&&&&&&&&&&&&&
&&&&&&&&}&&
&&&&&&&&//
作超屏幕宽度检测&&
&&&&&&&&if
(width & scrWidth)&&
&&&&&&&&{&&
&&&&&&&&&&&&width
&&&&&&&&&&&&//
作超屏幕高度检测&&
&&&&&&&&}&&
&&&&&&&&if
scrHeight)&&
&&&&&&&&{&&
&&&&&&&&&&&&height
&&&&&&&&}&&
&&&&&&&&m_View.drawClipImg(x_dest,
y_dest, width, height, x_src, y_src, img, paint,
}&&public void paint(Canvas g,
int x, int y) { // 地图在缓冲中的坐标 int tempx = mapOffx % bufW int
tempy = mapOffy % bufH // 切割线右下角的宽与高 int rightWidth =
bufWidth - int rightHeight = bufHeight - // 画左上
drawRegion(g, carBuffer, tempx, tempy, rightWidth, rightHeight, 0,
x, y); // 画右上 drawRegion(g, carBuffer, 0, tempy, scrWidth -
rightWidth, rightHeight, 0, x + rightWidth, y); // 画左下
drawRegion(g, carBuffer, tempx, 0, rightWidth, scrHeight -
rightHeight, 0, x, y + rightHeight); // 画右下 drawRegion(g,
carBuffer, 0, 0, scrWidth - rightWidth, scrHeight - rightHeight, 0,
x + rightWidth, y + rightHeight); } private void drawRegion(Canvas
g, Bitmap img, int x_src, int y_src, int width, int height, int
transform, int x_dest, int y_dest) { // 作宽度检测 if
(width&&scrWidth) { width =
scrW // 作超屏幕高度检测 } if (height & scrHeight) { height =
scrH } m_View.drawClipImg(x_dest, y_dest, width, height,
x_src, y_src, img, paint, g); }
&&&&&&&当然,地图的卷动和精灵的移动是分不开的,在本文中我们只阐述了游戏的地图绘制方法,关于精灵的绘制以及地图随精灵的位移而卷动,我们会在另一篇文章中做以介绍。
&&&&&&卡马克算法是在进行2D游戏地图卷动的算法中内存痕迹最小、效率适中的算法之一。其核心的思想就是把地图卷动过程中移出屏幕(不需要在显示的部分)所占用的buffer区域,绘制上新的需要图块,在往屏幕上绘制的时候,通过四次绘制buffer把完整的地图重现。
&&&&&&我们在实际的代码编写中按以下的方式进行。根据上面的基本思想,把地图分为四个块(十字形的将buffer划分为四块),用carx和cary来记录十字分区的中心坐标(相对于buffer的坐标,我把这个点叫卡马克分区点)。
当地图向右移动的时候这时把卡马克分区点的坐标X方向加上一个tile的width,然后在从现在的卡马克分区点的坐标Y开始绘制提取出来的tileID对应的图象,注意是从当前的卡马克分区点的坐标Y开始绘制,当超出carHeight时在从0开始绘制直到结束,这样就完成了在水平方向上的更新。
&&&&&&&还有就是在水平移动卡马克分区点的时候是在buffer中循环的,也就是从0到carWidth的一个循环过程,Y方向上完全一致。最后是绘制过程,也就是将四个分区绘制出来,口诀就是左变右上变下,掌握好卡马克算法对手游开发很有帮助的。
&&&&&&&注:本文参考了网上关于卡马克算法的一些介绍并引用了其中的部分文字和图片。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 mc跑酷地图 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信