c# - Moving Platforms in a Tile Map -


i using tile map if moving platform hits tile should go direction. using list both tilemap , platform, helps keep things neat.

the image below shows platform, in motion , when collides 1 of black circles should change directions , head opposite way going.

image of platform , colliding tile

unfortunately having problem need find correct platform go other direction. created list in main class , not know how call upon list inside class besides main.

question:

how call upon list holding multiple objects going in different directions, in different position, , created in main class, can know if platform colliding tile?

simply put, how make platform collide tile?

here process tile map must go through used , called:

to make tile map 2 classes used, block class , game1 class (the main class).

inside block class texture, position, , blockstate (which decides thing do)

    public block(texture2d texture, vector2 position, int blockstate)     {         this.texture = texture;         this.position = position;         this.blockstate = blockstate;     } 

then block class use method uses player class.

    public player blockcollision(player player)     {          rectangle top = new rectangle((int)position.x + 5, (int)position.y - 10, texture.width - 10, 10);         rectangle bottom = new rectangle((int)position.x + 5, (int)position.y + texture.height, texture.width - 10, 10);         rectangle left = new rectangle((int)position.x - 10, (int)position.y + 5, 10, texture.height - 10);         rectangle right = new rectangle((int)position.x + texture.width, (int)position.y + 5, 10, texture.height - 10);          if (blockstate == 1 || (blockstate == 2 && !player.goingup))         {             if (top.intersects(new rectangle((int)player.position.x, (int)player.position.y, player.texture.width, player.texture.height)))             {                 if (player.position.y + player.texture.height > position.y && player.position.y + player.texture.height < position.y + texture.height / 2)                 {                     player.position.y = player.ground = position.y - player.texture.height;                     player.velocity.y = 0;                     player.isjumping = false;                     player.time = 0;                     player.botcollision = true;                 }             }         }          return player;     } 

then draw method.

    public void draw(spritebatch spritebatch)     {         spritebatch.draw(texture, new rectangle((int)position.x, (int)position.y, texture.width, texture.height), color.white);     } 

we move on main class game1.

i create lists both blocks , platforms.

    list<block> blocks;     list<movingplatform> platforms; 

using char system create map.

    list<char[,]> levels = new list<char[,]>();     public int tilewidth, tileheight; 

then in initialize method call on lists , create map.

    protected override void initialize()     {         blocks = new list<block>();         platforms = new list<movingplatform>();          char[,] level1 = {{'.','.','#'},                           {'.','.','#'},                           {'.','.','#'}};          levels.add(level1);          base.initialize();     } 

then void loadlevel called on.

    void loadlevel(int level)     {         blocks.clear();         platforms.clear();          player.position = vector2.zero;          tilewidth = levels[level].getlength(1);         tileheight = levels[level].getlength(0);          texture2d blockspritea = content.load<texture2d>("blocka2");          (int x = 0; x < tilewidth; x++)         {             (int y = 0; y < tileheight; y++)             {                  //background                 blocks.add(new block(background, new vector2(x * 50, y * 50), 0));                  //impassable blocks                 if (levels[level][y, x] == '#')                 {                     blocks.add(new block(blockspritea, new vector2(x * 50, y * 50), 1));                 }                  //vertical moving platform                 if (levels[level][y, x] == '=')                 {                     platforms.add(new movingplatform(platform, new vector2(x * 50, y * 50), 3.0f, true));                 } 

then in update call on lists.

        foreach (block b in blocks)         {             player = b.blockcollision(player);         }          foreach (movingplatform m in platforms)         {             player = m.blockcollision(player);             m.update(gametime);         } 

finally draw method calls on them.

        foreach (block b in blocks)         {             b.draw(spritebatch);         }          foreach (movingplatform m in platforms)         {             m.draw(spritebatch);         } 

i think understand question, not sure, going hazard answer anyway.

i think need move stuff out of main game class. have concept of map , bunch of stuff belongs map (platforms, blocks) it's idea encapsulate in own class, eg:

class map {     public list<block> blocks;     public list<movingplatform> platforms;      void loadlevel(int level)     {         ///     } } 

now makes code cleaner, have map object can pass around.

so example enable movingplatform have access on map, need pass reference map parameter movingplatform constructor saves away private field. eg:

class movingplatform {     map _map;     public movingplatform(map map, vector2 position, ...)     {         _map = map;     }      public void update(gametime gametime)     {         //move platform         //detect collision         //have access blocks , other platforms on map         //_map.blocks;         //_map.platforms;     } } 

so in map class loadlevel() method you'd pass in 'this' first parameter of movingplatform constructor:

class map {     void loadlevel(int level)     {         //vertical moving platform         if (levels[level][y, x] == '=')         {             platforms.add(new movingplatform(this, ...));         }     } } 

you can add other map specific things (even reference player?) map class , movingplatforms automatically have access them.

this called dependency injection. movingplatform class has dependency on map , injecting dependency in through constructor.

edit:

for collision add bounds property tile , movingplatform class. makes easier current rectangle bounds of them. intersectstile method in movingplatform return true if platform intersects specified tile.

class tile {     rectangle bounds     {                 {             return new rectangle((int)position.x, (int)position.y, tilewidth, tileheight);         }     } }  class movingplatform {     rectangle bounds     {                 {             return new rectangle((int)position.x, (int)position.y, platformwidth, platformheight);         }     }      //returns true if platform intersects specified tile     bool intersectstile(tile tile)     {         return bounds.intersects(tile.bounds);     } } 

then in movingplatfom class in update method platform moved each frame, check if there collision after movement. if there collision out movement , reverse platform direction, next frame move opposite way.

class movingplatform {     void update(tile[] collidabletiles)     {         position += direction;          //test collision         bool iscollision = collisiontest(collidabletiles);         if (iscollision)         {             //undo movement , change direction             position -= direction;             direction = newdirection;         }     }      //returns true if platform intersects of specified tiles     bool collisiontest(tile[] tiles)     {         foreach (tile tile in tiles)             if (intersectstile(tile))                 return true;         return false;     } } 

for above work need pass in list of collidable tiles on map movingplatform update. call each movingplatform in map class, passing list of collidable tiles.

class map {     list<tile> _collidabletiles;      void update(gametime gametime)     {         foreach (movingplatform platform in movingplatforms)         {             platform.update(_collidabletiles);         }     } } 

that's 1 way of doing it. better way though instead of passing in collidable tiles, movingplatform grab tiles around , test those.

class movingplatform {     void update()     {         position += direction;          //test collision         tile[] tiles = _map.getnearbytiles(position);         foreach (tile tile in tiles)             if (tile.issolid)                 if (intersectstile(tile))                 {                     //undo movement , change direction                     position -= direction;                     direction = newdirection;                     break;                 }     } } 

so way tiles have issolid property , set true cause moving platforms collide them.

class tile {     bool issolid; } 

Comments

Popular posts from this blog

windows - Single EXE to Install Python Standalone Executable for Easy Distribution -

c# - Access objects in UserControl from MainWindow in WPF -

javascript - How to name a jQuery function to make a browser's back button work? -