首页 > 代码库 > libgdx学习记录11——平铺地图TiledMap

libgdx学习记录11——平铺地图TiledMap

地图对于游戏场景十分重要,很多游戏都需要对地图进行编辑,可使用TileMap进行编辑并生成对应的tmx格式地图文件。

编辑好后,可通过TmxMapLoader来读取地图文件。可通过一个正交相机OthographicCamera和正交地图渲染器OrthogonalTiledMapRenderer来进行显示。

实例如下:

  1 package com.fxb.newtest;
  2 
  3 import com.badlogic.gdx.ApplicationAdapter;
  4 import com.badlogic.gdx.Gdx;
  5 import com.badlogic.gdx.Input;
  6 import com.badlogic.gdx.graphics.GL10;
  7 import com.badlogic.gdx.graphics.OrthographicCamera;
  8 import com.badlogic.gdx.graphics.Texture;
  9 import com.badlogic.gdx.graphics.g2d.SpriteBatch;
 10 import com.badlogic.gdx.graphics.g2d.TextureRegion;
 11 import com.badlogic.gdx.maps.MapLayer;
 12 import com.badlogic.gdx.maps.objects.RectangleMapObject;
 13 import com.badlogic.gdx.maps.tiled.TiledMap;
 14 import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
 15 import com.badlogic.gdx.maps.tiled.TmxMapLoader;
 16 import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
 17 import com.badlogic.gdx.scenes.scene2d.InputEvent;
 18 import com.badlogic.gdx.scenes.scene2d.InputListener;
 19 import com.badlogic.gdx.scenes.scene2d.Stage;
 20 import com.badlogic.gdx.scenes.scene2d.ui.Image;
 21 
 22 public class Lib010_TiledMap extends ApplicationAdapter{
 23 
 24     TiledMap map;
 25     OrthogonalTiledMapRenderer renderer;
 26     OrthographicCamera camera;
 27     TextureRegion regionPurple;
 28     TextureRegion regionBlue;
 29     TextureRegion regionGreen;
 30     
 31     TiledMapTileLayer layer1;
 32     
 33     Stage stage;
 34     Image imgGreen;
 35     
 36     enum StateX{ move_still, move_right, move_left };
 37     enum StateY{ move_still, move_up, move_down };
 38 
 39     StateX stateX = StateX.move_still;
 40     StateY stateY = StateY.move_still;
 41     
 42     float clicktimeX = 0;
 43     float clicktimeY = 0;
 44     float currentTime = 0;
 45     
 46     @Override
 47     public void create() {
 48         // TODO Auto-generated method stub
 49         
 50         map = new TmxMapLoader().load( "map1/test1.tmx" );
 51         renderer = new OrthogonalTiledMapRenderer( map );
 52         stage = new Stage( Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false, renderer.getSpriteBatch() );
 53         
 54         regionPurple = new TextureRegion( new Texture( Gdx.files.internal( "map1/bullet_purple_32.png" ) ) );
 55         regionBlue = new TextureRegion( new Texture( Gdx.files.internal( "map1/bullet_blue_32.png" ) ) );
 56         regionGreen = new TextureRegion( new Texture( Gdx.files.internal( "map1/bullet_green_32.png" ) ) );
 57         
 58         camera = new OrthographicCamera( 32*30, 32*12 );
 59         //camera.setToOrtho( false, 32*30, 32*12 );
 60         camera.position.set( 32*30/2, 32*12/2, 0 );
 61         camera.update();
 62         
 63         layer1 = (TiledMapTileLayer)map.getLayers().get(0);
 64         MapLayer layer2 = map.getLayers().get(1);
 65         
 66         System.out.println( layer1.getName()+"\n"+layer2.getName() );
 67         
 68         int count =  layer2.getObjects().getCount();
 69         System.out.println(count);
 70         for( int i=0; i<count; ++i ){
 71             RectangleMapObject obj = (RectangleMapObject)layer2.getObjects().get(i);
 72             String strName = obj.getName();
 73             
 74             
 75             if( strName != null ){
 76                 System.out.print( strName+"\t" );
 77                 if( obj.getProperties() != null ){
 78                     if( obj.getProperties().get("level")!=null ){
 79                         String strProperty = obj.getProperties().get("level").toString();
 80                         System.out.println( strProperty );    
 81                         
 82                         float x = obj.getRectangle().getX();
 83                         float y = obj.getRectangle().getY();
 84                         //System.out.println( x/32+","+y/32 );
 85                         Image tempImg = new Image( regionPurple );
 86                         tempImg.setSize( 32, 32 );
 87                         tempImg.setPosition( x, y );
 88                         stage.addActor( tempImg );                    
 89                     }
 90                     else if( obj.getProperties().get("time")!=null ){
 91                         float x = obj.getRectangle().getX();
 92                         float y = obj.getRectangle().getY();
 93                         //System.out.println( x/32+","+y/32 );
 94                         Image tempImg = new Image( regionBlue );
 95                         tempImg.setSize( 32, 32 );
 96                         tempImg.setPosition( x, y );
 97                         stage.addActor( tempImg );                        
 98                     }
 99                     
100                 }
101                 
102 
103             }
104         }
105         
106         
107         imgGreen = new Image( regionGreen );
108         imgGreen.setSize( 32, 32 );
109         stage.addActor( imgGreen );
110         imgGreen.setPosition( 0, 0 );
111         
112         stage.addListener(new InputListener(){
113             @Override
114             public boolean keyDown(InputEvent event, int keycode) {
115                 // TODO Auto-generated method stub
116                 if( keycode == Input.Keys.UP ){
117                     //imgGreen.translate( 0, 32 );
118                     stateY = StateY.move_up;
119                     MoveY();
120                     clicktimeY = currentTime;
121                     //state = State.move_still;
122                 }
123                 else if( keycode == Input.Keys.DOWN ){
124                     //imgGreen.translate( 0, -32 );
125                     stateY = StateY.move_down;
126                     MoveY();
127                     clicktimeY = currentTime;
128                     //state = State.move_still;
129                 }
130                 
131                 if( keycode == Input.Keys.LEFT ){
132                     //imgGreen.translate( -32, 0 );
133                     stateX = StateX.move_left;
134                     MoveX();
135                     clicktimeX = currentTime;
136                     //state = State.move_still;
137                 }                
138                 else if( keycode == Input.Keys.RIGHT ){
139                     //imgGreen.translate( 32, 0 );
140                     stateX = StateX.move_right;
141                     MoveX();
142                     clicktimeX = currentTime;
143                     //state = State.move_still;
144                 }                
145                 return true;
146             }
147 
148             @Override
149             public boolean keyUp(InputEvent event, int keycode) {
150                 // TODO Auto-generated method stub
151                 if( keycode == Input.Keys.UP ){
152                     //imgGreen.translate( 0, 32 );
153                     stateY = StateY.move_still;
154                 }
155                 else if( keycode == Input.Keys.DOWN ){
156                     //imgGreen.translate( 0, -32 );
157                     stateY = StateY.move_still;
158                 }
159                 
160                 if( keycode == Input.Keys.LEFT ){
161                     //imgGreen.translate( -32, 0 );
162                     stateX = StateX.move_still;
163                 }                
164                 else if( keycode == Input.Keys.RIGHT ){
165                     //imgGreen.translate( 32, 0 );
166                     stateX = StateX.move_still;
167                 }                
168                 return true;
169             }
170             
171             
172         });
173         
174         Gdx.input.setInputProcessor( stage );
175     }
176 
177     public void MoveX(){
178         float x0 = imgGreen.getX();
179         float y0 = imgGreen.getY();
180         int x1 = 0, y1 = 0;
181         int x2 = 0, y2 = 0;
182         int x3 = 0, y3 = 0;
183         
184         float speed = 2;
185         
186         switch( stateX ){
187             case move_right: 
188                 imgGreen.translate( speed, 0 );
189                 x1 = (int)( (imgGreen.getX()+31)/32 );
190                 x2 = x3 = x1;
191                 
192                 y1 = (int)( (imgGreen.getY()+1)/32 );
193                 y2 = (int)( (imgGreen.getY()+15)/32 );
194                 y3 = (int)( (imgGreen.getY()+31)/32 );
195                 break;
196             case move_left: 
197                 imgGreen.translate( -speed, 0 );
198                 x1 = (int)( (imgGreen.getX()+1)/32 );
199                 x2 = x3 = x1;
200                 
201                 y1 = (int)( (imgGreen.getY()+1)/32 );
202                 y2 = (int)( (imgGreen.getY()+15)/32 );
203                 y3 = (int)( (imgGreen.getY()+31)/32 );
204                 break;
205             default:
206                 break;
207         }
208         if( layer1.getCell( x1, y1 )!=null || layer1.getCell( x2, y2 )!=null || layer1.getCell( x3, y3 )!=null ){
209             imgGreen.setPosition( x0, y0 );
210         }
211         
212     }
213     
214     public void MoveY(){
215         float x0 = imgGreen.getX();
216         float y0 = imgGreen.getY();
217         int x1 = 0, y1 = 0;
218         int x2 = 0, y2 = 0;
219         int x3 = 0, y3 = 0;
220         
221         float speed = 2;
222         switch( stateY ){
223         case move_up: 
224             imgGreen.translate( 0, speed );
225             x1 = (int)( (imgGreen.getX()+1)/32 );            
226             x2 = (int)( (imgGreen.getX()+15)/32 );
227             x3 = (int)( (imgGreen.getX()+31)/32 );
228             
229             y1 = (int)( (imgGreen.getTop()-1)/32 );
230             y2 = y3 = y1;
231             //x2 = x3 = x1;
232             break;
233         case move_down: 
234             imgGreen.translate( 0, -speed );
235             x1 = (int)( (imgGreen.getX()+1)/32 );
236             x2 = (int)( (imgGreen.getX()+15)/32 );
237             x3 = (int)( (imgGreen.getX()+31)/32 );
238             
239             y1 = (int)( (imgGreen.getY()+1)/32 );
240             y2 = y3 = y1;
241             break;
242         default:
243             break;
244         }
245 
246         if( layer1.getCell( x1, y1 )!=null || layer1.getCell( x2, y2 )!=null || layer1.getCell( x3, y3 )!=null ){
247             imgGreen.setPosition( x0, y0 );
248         }                
249     }
250     
251     @Override
252     public void render() {
253         // TODO Auto-generated method stub
254         Gdx.gl.glClearColor( 0.5f, 0.5f, 0.5f, 1 );
255         Gdx.gl.glClear( GL10.GL_COLOR_BUFFER_BIT );
256         
257         renderer.setView(camera);
258         renderer.render();
259         
260     
261         currentTime += Gdx.graphics.getDeltaTime();
262         if( currentTime - clicktimeX > 0.15f ){
263             MoveX();
264         }
265         if( currentTime - clicktimeY > 0.15f ){
266             MoveY();
267         }
268             
269         stage.act();
270         stage.draw();
271     }
272 
273     @Override
274     public void dispose() {
275         // TODO Auto-generated method stub
276         super.dispose();
277     }
278 
279     
280 }

运行结果:

地图是自己随便编辑的。有两个图层,一个背景层,一个对象层。对象层可通过getCell()函数获取地图单元。

通过layer.getMapObject()可获取对应的对象。

MapObject可通过getProperties().get("level")这种形式获取对象的键值,以便在程序中使用。

要获取object的x,y坐标以及长宽时,需将MapObject转化为RectangleMapObject,然后获取其Rectangle就行了。

另外,地图中涉及碰撞检测,一般在控制物体(一般是玩家)的边缘设置2-3个检测点,最好不要设置在两边,而是靠近边缘的点。

大概就这么多了,比较粗糙,记录而已。。