J2ME实践之地图篇

最近三个星期利用业余时间开发了一款J2ME横向滚轴的2D FPS游戏,自我感觉项目不是很成功,最主要的原因是图片太多。但是通过实践,还是收获不少。下面就地图处理发表一点浅见。

javax.microedition.lcdui.game.TiledLayer是一个保存和绘制地图的好工具,通过脚本的方式可以将地图信息转化为数字信息保存在TiledLayer对象中(实际上TiledLayer内部采用是数组的方式来保存地图的数字化信息)。

上面这张地图中每一个地图元素的尺寸为32×32,为此我们可以对其进行编号:

这样,一个编号对应的就是一个地图元,显然下面这些数字:

00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00
00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00
00|00|00|00|00|00|00|00|00|00|04|05|06|07|00|00|00|00|00|00
00|00|00|00|00|04|05|06|07|00|14|15|16|17|00|00|00|00|00|00
34|35|35|36|00|14|15|16|17|00|00|00|00|00|34|35|35|35|35|36
37|38|38|39|00|00|00|00|00|00|00|00|00|00|37|38|38|38|38|39

对应下面的地图:

将地图数字化以后,可以在地图脚本文件中加入地图的尺寸信息(长度|宽度),以上面的地图为例可以在第一行加入20|6,这样在读取第一行之后我们就知道需要分配多大的数组以及用这个尺寸初始化TiledLayer对象。

下面是一个脚本抽象类,所有类型的脚本(地图、怪物、物品)都继承自它。

package  game;

import java.io.*
;

public abstract class
 Script 
{    
    InputStreamReader input;
        
    
protected void
 close() 
    
{
        
if (input != null
)
        
{
            
try {input.close();} catch (Exception e) {}

            input 
= null;
        }

    }

        
    
protected String readLine()
    
{
        
if (input == null{return null;}

        
        
int temp;
        StringBuffer buffer 
= new
 StringBuffer();
        
        
try
 
        
{
            
while ((temp = input.read()) != 13
)
            
{
                
if ((int)temp == -1
)
                
{
                    close();
                    
break
;
                }

                
else if ((int)temp != 10)
                
{
                    buffer.append((
char
)temp);
                }

            }

        }
 catch (Exception e) { close(); }
        
        
return buffer.toString();    
    }

    
    
protected String[] readArrayLine(char delimit)
    
{
        String line;
        String[] array;
        StringBuffer buffer;
        
int
 index, count;
        
char
 c;
        
        
// Count number of items in the array

        line = readLine();
        
        
if (line.length() == 0
)
        
{
            array 
= new String[1
];
            array[
0= ""
;
        }

        
        index 
= 0;
        count 
= 0
;
        
while (index <
 line.length())
        
{
            
if (line.charAt(index++== delimit) {count++;}

        }

        
        
// Parse items into the array
        array = new String[count+1];
        buffer 
= new
 StringBuffer();
        index 
= 0
;
        count 
= 0
;
        
while (index <
 line.length())
        
{
            c 
= line.charAt(index++
);
            
if (c ==
 delimit)
            
{
                array[count
++=
 buffer.toString();
                buffer 
= new
 StringBuffer();
            }

            
else
            
{
                buffer 
=
 buffer.append(c);
            }

        }

        array[count
++= buffer.toString();
        
        
return
 array;
    }

}

下面是专门负责读取地图脚本的代码:

package  game;

import java.io.*
;

public class MapFile extends
 Script
{
    
protected int
 iMapRow;
    
protected int
 iMapCol;
        
    
public int[] Load(int
 level)
    
{
        input 
= new InputStreamReader(getClass().getResourceAsStream("/script/map/level"+level+".map"
));
        
int cnt = 0
;
        String[] size 
= readArrayLine('|'
);
        String[] mapline;
        
if(size.length < 2
)
        
{
            System.out.println(
"map size error!"
);
            
return null
;
        }

        iMapCol 
= Integer.parseInt(size[0]);
        iMapRow 
= Integer.parseInt(size[1
]);
        
int[] map = new int[iMapCol*
iMapRow];
        
while(input != null
)
        
{
            mapline 
= readArrayLine('|'
);
            
if(mapline.length <
 iMapCol)
            
{
                System.out.println(
"map column error!"
);
                
return null
;                
            }

            
for (int n = 0; n < mapline.length; n++)
                map[cnt
++=
 (Integer.valueOf(mapline[n])).intValue();
        }

        close();
        
return map;
    }

    
    
public int getCol()
    
{
        
return
 iMapCol;
    }

    
    
public int getRow()
    
{
        
return
 iMapRow;
    }

}

最后在游戏渲染主类中加入载入地图代码:

    protected TiledLayer createMap(int  level)
    
{
        Image img 
= null
;
        
try

        
{
            img 
= Image.createImage("/res/map/map.png"
);
        }
catch(java.io.IOException e) {System.out.println("createMap"+e);}
        
int[] map = mapfile.Load(level);
        TiledLayer tl 
= new TiledLayer(mapfile.getCol() , mapfile.getRow() , img , 32 , 32
);
        
for(int i = 0;i < map.length;i++
)
        
{
            
int col = i %
 mapfile.getCol();
            
int row = (i - col) /
 mapfile.getCol();
            tl.setCell(col , row , map[i]);
        }

        
return tl;
    }

游戏渲染最好能够由LayerManager来管理,通过其append方法将TiledLayer对象加入其中,在渲染方法中加入:

LayerManangerObject.setViewWindow(PlayerObject.iPosX , StartY , ViewWidth , ViewHeight);
LayerManangerObject.paint(GraphicsObject , StartX , StartY);

在setViewWindow中,将玩家的横坐标作为视口的起始x坐标,只要玩家走动,就会有横向滚轴的效果。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值