GPWiki.org
GPWiki.org
It is currently Wed Jun 19, 2013 9:38 pm

All times are UTC




Post new topic Reply to topic  [ 15 posts ] 
Author Message
PostPosted: Fri Aug 12, 2011 9:23 am 
Hello all, I am very new to game programming. I am currently using the
Slick2D Library to assist me in making a game. I am trying to create a scrolling level like you would have in Zelda where the player reaches the edge of the screen and goes onto the next. I am using a Tile Map to load the level and have defined tiles within the map editor where the collision is to take place (walls, trees). Anyway, when I compile the code and run, the map loads and I can move the sprite around. Currently I cannot get the map to "scroll" in any direction. In addition each direction gives me different results. When heading North, or West I crash (array index out of bounds)
When I head south, I get "blocked" (collision point) from reaching the edge. Sorry for the long post. Any help in figuring out why the scrolling does not work is greatly appreciated. Here is the code.

Code:
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GameWorld;

/**
 *
 * @author Matt
 */

import org.newdawn.slick.*;
import org.newdawn.slick.tiled.TiledMap;
import org.newdawn.slick.state.*;
import org.newdawn.slick.gui.TextField;



public class GamePlayState extends BasicGameState{
   
    private int stateID = 0;
    private TiledMap level1;
    private Animation sprite,up,down,left,right;
    private float x = 34f, y = 34f;
    //is the current tile of the tile map "blocked"
    private boolean[][] blocked;
    //
    private boolean[][] collidable;
    private static final int SIZE = 32;
    private static final int TILE_SIZE = 32;
    private static final float SPEED = 0.003f;
    private TextField text1;
    /** The width of the display in tiles */
    private int widthInTiles;
   /** The height of the display in tiles */
    private int heightInTiles;
   
    /** The offset from the centre of the screen to the top edge in tiles */
    private int topOffsetInTiles;
   /** The offset from the centre of the screen to the left edge in tiles */
    private int leftOffsetInTiles;
    /** The angle the player is facing */
    private float ang;
   /** The x component of the movement vector */
    private float dirX;
   /** The y component of themovement vector */
    private float dirY;
   
    /** The player's x position in tiles */
    private float playerX =20;
   /** The player's y position in tiles */
    private float playerY = 20;
       
    private enum STATES{START_GAME_STATE,PAUSE_GAME_STATE,GAME_OVER_STATE};
    private STATES currentState = null;
   

    public GamePlayState(int stateID)
    {
        this.stateID = stateID;
    }
 
   
    @Override
    public int getID() {
        return stateID;
    }
   
    @Override
    public void init(GameContainer container, StateBasedGame sb) throws SlickException
    {
        //assigning instance variable of object TileMap to the level1 Map Location
        level1 = new TiledMap("C:/Users/Matt/Downloads/desert.tmx");
        /*storing the image files for movement in an array so that different images can be loaded when player has new weapons. 
        and more importantly to help animate the sprite 
        */
        Image []  movementUp = {new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_bk1.gif")
                               ,new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_bk2.gif")};
        Image []  movementDown = {new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_fr1.gif")
                               ,new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_fr2.gif")};
        Image []  movementLeft = { new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_lf1.gif")
                               ,new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_lf2.gif")};
        Image []  movementRight ={ new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_rt1.gif")
                                ,new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_rt2.gif")};
       
        //determine how often the images are to be redrawn
        int [] duration = {300,300};
       
        //animate the sprite as the user presses the key
        up = new Animation(movementUp,duration,false);
        down = new Animation(movementDown,duration,false);
        left = new Animation(movementLeft,duration,false);
        right = new Animation(movementRight,duration,false);
       
        //set default orientation of the sprite
        sprite = right;
        sprite.setAutoUpdate(false);
       
               
        //add collision detection to the walls that have the blocked Map property
        blocked = new boolean[level1.getWidth()][level1.getHeight()];
        collidable =  new boolean[level1.getWidth()][level1.getHeight()];
        for (int a=0;a<level1.getWidth();a++) {
         for (int b=0;b<level1.getHeight();b++) {
            int tileID = level1.getTileId(a, b, 0);
            String value = level1.getTileProperty(tileID, "blocked", "false");
            if ("true".equals(value)) {
               blocked[a][b] = true;
            }
         }
   }
       
        // caculate some layout values for rendering the tilemap. How many tiles
      // do we need to render to fill the screen in each dimension and how far is
      // it from the centre of the screen
      widthInTiles = container.getWidth() / TILE_SIZE;
      heightInTiles = container.getHeight() / TILE_SIZE;
      topOffsetInTiles = heightInTiles / 2;
      leftOffsetInTiles = widthInTiles / 2;
    } 
   
   
    @Override
    public void update(GameContainer container, StateBasedGame sb, int delta) throws SlickException
    {
         
        //update the sprite movement as the keys are pressed
        Input input = container.getInput();
        float fdelta = delta*0.1f;
       
            if (input.isKeyDown(Input.KEY_UP))
            {
                sprite = up;
                if (!(isBlocked(x, y - fdelta) || isBlocked(x+SIZE-1, y - fdelta)))
                     {
                    sprite.update(delta);
                    // The lower the delta the slowest the sprite will animate.
                    y -= delta * 0.1f;
                     }
            }
            else if (input.isKeyDown(Input.KEY_DOWN))
                 {
                    sprite = down;
                    if (!(isBlocked(x, y + SIZE + fdelta) || isBlocked(x+SIZE-1, y + SIZE + fdelta)))
                    {
                         sprite.update(delta);
                         y += fdelta;
                    }
                 }
                 else if (input.isKeyDown(Input.KEY_LEFT))
                 {
                    sprite = left;
                    if(!(isBlocked(x-fdelta,y) || isBlocked(x-fdelta,y+SIZE-1)))
                    {
                        sprite.update(delta);
                        x -= fdelta;
                    }
                 }
                 else if (input.isKeyDown(Input.KEY_RIGHT))
                 {
                    sprite = right;
                    if (!(isBlocked(x + SIZE + fdelta, y) || isBlocked(x + SIZE + fdelta, y+SIZE-1)))
                    {   
                        sprite.update(delta);
                        x += fdelta;
                    }
                 }

     
    }
   

   
   
    @Override
    public void render(GameContainer container, StateBasedGame sb, Graphics g) throws SlickException
    {
       // draw the appropriate section of the tilemap based on the centre (hence the -(SIZE/2)) of
      // the player
      int playerTileX = (int) playerX;
      int playerTileY = (int) playerY;
      
      // caculate the offset of the player from the edge of the tile. As the player moves around this
      // varies and this tells us how far to offset the tile based rendering to give the smooth
      // motion of scrolling
      int playerTileOffsetX = (int) ((playerTileX - playerX) * TILE_SIZE);
      int playerTileOffsetY = (int) ((playerTileY - playerY) * TILE_SIZE);
      
      // render the section of the map that should be visible. Notice the -1 and +3 which renders
      // a little extra map around the edge of the screen to cope with tiles scrolling on and off
      // the screen
      level1.render(playerTileOffsetX - (SIZE / 2), playerTileOffsetY - (SIZE / 2),
               playerTileX - leftOffsetInTiles - 1,
               playerTileY - topOffsetInTiles - 1,
               widthInTiles + 3, heightInTiles + 3);
      
      // draw entities relative to the player that must appear in the centre of the screen
      g.translate(400 - (int) (playerX * 32), 300 - (int) (playerY * 32));
      
      //drawTank(g, playerX, playerY, ang);
      // draw other entities here if there were any
      
      g.resetTransform();
       // TextField field = new TextField();
        //render the map onto the screen
      //  level1.render(0,0);
                sprite.draw((int)x,(int)y);
       // fontTest.drawString(20.0f, 20.0f, "Slick displaying True Type Fonts", Color.green)
           
       
       
    }
   
   
    private boolean isBlocked(float aBlock, float bBlock)
    {
        int a = (int)aBlock/SIZE;
        int b = (int)bBlock/SIZE;
        return blocked[a][b];
    }
   
   /* private boolean isCollectable(float x,float y)
    {
        int xBlock = (int)x / SIZE;
        int yBlock = (int)y / SIZE;
        return collidable[xBlock][yBlock];
    }  */       
   
}


Top
  
 
PostPosted: Fri Aug 12, 2011 6:33 pm 
Harmlessness does no harm
User avatar

Joined: Tue Sep 14, 2004 8:37 pm
Posts: 3855
Location: Ferriday, LA, US
From what I can tell, you aren't checking for the edges of the map, or compensating for rendering at the map edges.

Should simply be a matter of checking if the left edge of the rendering area is at a pixel with a value less than zero:

Code:
if (leftEdgeOfRenderedArea < 0) {
    leftEdgeOfRenderedArea = 0;
    rightEdgeOfRenderedArea = renderAreaWidth;
}


Do the same for the vertical plane, and that should fix it. Note that you will need to change the variable names to suit your code, and that this check should come before you render or otherwise make any calculations based on the viewing plane location.

_________________
What most people don't understand about "enlightenment" is that it is not an end-goal; but where you find yourself just before taking a new "first step."


Top
 Profile  
 
PostPosted: Sat Aug 13, 2011 4:21 pm 
Thank You. It is scrolling now. The major problem is that it is scrolling way to fast. I can go from one end to the other in less than 2 seconds. Here
is the new code.

Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GameWorld;

/**
 *
 * @author Matt
 */

import org.newdawn.slick.*;
import org.newdawn.slick.tiled.TiledMap;
import org.newdawn.slick.state.*;
import org.newdawn.slick.gui.TextField;



public class GamePlayState extends BasicGameState{
   
    private int stateID = 0;
    private TiledMap level1;
    private Animation sprite,up,down,left,right,spin;
    private float x = 34f, y = 34f;
    private boolean[][] blocked;
    private boolean[][] collidable;
    private static final int SIZE = 32;
    private static final int TILE_SIZE = 32;
    private static final float SPEED = 0.003f;
    private int scrollOffset;
    private TextField text1;
    private int widthInTiles;
    private int heightInTiles;
    private int topOffsetInTiles;
    private int leftOffsetInTiles;
    private float ang;
    private float dirX;
    private float dirY;
   // private float playerX =20;
   //private float playerY = 20;
    private enum STATES{START_GAME_STATE,PAUSE_GAME_STATE,GAME_OVER_STATE};
    private STATES currentState = null;
   

    public GamePlayState(int stateID)
    {
        this.stateID = stateID;
    }
 
   
    @Override
    public int getID() {
        return stateID;
    }
   
    @Override
    public void init(GameContainer container, StateBasedGame sb) throws SlickException
    {
        Image []  movementUp = {new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_bk1.gif")
                               ,new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_bk2.gif")};
        Image []  movementDown = {new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_fr1.gif")
                               ,new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_fr2.gif")};
        Image []  movementLeft = { new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_lf1.gif")
                               ,new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_lf2.gif")};
        Image []  movementRight ={ new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_rt1.gif")
                                ,new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_rt2.gif")};
       
        int [] duration = {300,300};
       
        //animate the sprite as the user presses the key
        up = new Animation(movementUp,duration,false);
        down = new Animation(movementDown,duration,false);
        left = new Animation(movementLeft,duration,false);
        right = new Animation(movementRight,duration,false);
       
        widthInTiles = container.getWidth() / TILE_SIZE;
   heightInTiles = container.getHeight() / TILE_SIZE;
   topOffsetInTiles = heightInTiles / 2;
   leftOffsetInTiles = widthInTiles / 2;
       
        sprite = right;
        //sprite.setAutoUpdate(false);
               
        //assigning instance variable of object TileMap to the level1 Map Location
        level1 = new TiledMap("C:/Users/Matt/Downloads/desert.tmx");
                     
        //add collision detection to the walls that have the blocked Map property
        blocked = new boolean[level1.getWidth()][level1.getHeight()];
        //collidable =  new boolean[level1.getWidth()][level1.getHeight()];
        for (int xAxis=0;xAxis<level1.getWidth();xAxis++) {
      for (int yAxis=0;yAxis<level1.getHeight();yAxis++) {
         int tileID = level1.getTileId(xAxis, yAxis,0);
         String value = level1.getTileProperty(tileID, "blocked", "false");
         if ("true".equals(value)) {
            blocked[xAxis][yAxis] = true;
         }
      }
   }
    }
   
    private boolean isBlocked(float x, float y)
    {
        int xBlock = (int)x/SIZE;
        int yBlock = (int)y/SIZE;
        return blocked[xBlock][yBlock];
    }
   
       
        // caculate some layout values for rendering the tilemap. How many tiles
      // do we need to render to fill the screen in each dimension and how far is
      // it from the centre of the screen
 
    @Override
    public void update(GameContainer container, StateBasedGame sb, int delta) throws SlickException
    {
         
        //update the sprite movement as the keys are pressed
        Input input = container.getInput();
        float fdelta = delta*0.1f;
       
            if (input.isKeyDown(Input.KEY_UP))
            {
                sprite = up;
                if (!(isBlocked(x, y - fdelta) || isBlocked(x+SIZE-1, y - fdelta)))
                     {
                    sprite.update(delta);
                    // The lower the delta the slowest the sprite will animate.
                    y -= delta * 0.1f;
                         
                     }
            }
            else if (input.isKeyDown(Input.KEY_DOWN))
                 {
                    sprite = down;
                    if (!(isBlocked(x, y + SIZE + fdelta) || isBlocked(x+SIZE-1, y + SIZE + fdelta)))
                    {
                         sprite.update(delta);
                         y += fdelta;
                         
                    }
                 }
                 else if (input.isKeyDown(Input.KEY_LEFT))
                 {
                    sprite = left;
                    if(!(isBlocked(x-fdelta,y) || isBlocked(x-fdelta,y+SIZE-1)))
                    {
                        sprite.update(delta);
                        x -= fdelta;
                    }
                 }
                 else if (input.isKeyDown(Input.KEY_RIGHT))
                 {
                    sprite = right;
                    if (!(isBlocked(x + SIZE + fdelta, y) || isBlocked(x + SIZE + fdelta, y+SIZE-1)))
                    {   
                        sprite.update(delta);
                        x += fdelta;
                    }
                 }

     
    }

 
    @Override
    public void render(GameContainer container, StateBasedGame sb, Graphics g) throws SlickException
    {
       // draw the appropriate section of the tilemap based on the centre (hence the -(SIZE/2)) of
      // the player
        float fpx = x;
        float fpy = y;
       
   int playerTileX = (int)fpx;
   int playerTileY = (int)fpy;
        // caculate the offset of the player from the edge of the tile. As the player moves around this
   // varies and this tells us how far to offset the tile based rendering to give the smooth
   // motion of scrolling
   int playerTileOffsetX = (int) ((playerTileX - fpx) * TILE_SIZE);
   int playerTileOffsetY = (int) ((playerTileY - fpy) * TILE_SIZE);
      
   // render the section of the map that should be visible. Notice the -1 and +3 which renders
   // a little extra map around the edge of the screen to cope with tiles scrolling on and off
   // the screen
        level1.render(playerTileOffsetX,
                      playerTileOffsetY,
                      playerTileX - leftOffsetInTiles - 1,
                      playerTileY - topOffsetInTiles - 1,
                 widthInTiles + 3,
                      heightInTiles + 3);
       
       
         
        // scrollOffset += 20*0.1f/1000f;     
   // draw entities relative to the player that must appear in the centre of the screen
   g.translate(400 - (int) (fpx * SIZE), 300 - (int) (fpy * SIZE));
   //drawTank(g, playerX, playerY, ang);
   // draw other entities here if there were any
       
        sprite.draw((int)(x* SIZE),(int)(y* SIZE));
        g.resetTransform();
   
          
       // TextField field = new TextField();
        //render the map onto the screen
      //  level1.render(0,0);
               
       // fontTest.drawString(20.0f, 20.0f, "Slick displaying True Type Fonts", Color.green)
           
       
       
    }
   
   
   
   /* private boolean isCollectable(float x,float y)
    {
        int xBlock = (int)x / SIZE;
        int yBlock = (int)y / SIZE;
        return collidable[xBlock][yBlock];
    }  */       
   
}



Top
  
 
PostPosted: Sat Aug 13, 2011 7:32 pm 
Harmlessness does no harm
User avatar

Joined: Tue Sep 14, 2004 8:37 pm
Posts: 3855
Location: Ferriday, LA, US
IIRC, Java has a bit of a "quirk" when it comes to setting floats using an integer variable on the left-hand side of an equation. See if this changes anything at all...

Before:
Code:
float fdelta = delta*0.1f;


After:
Code:
float fdelta = (float)delta*0.1f;


Also, are you using a time-based update scheme (using a method to get the system's elapsed time)? Many times a developer will base something like this on how much time has passed since the last update in order to keep things moving at a rate relative to the speed of processing.

Something like that isn't necessary; I'm just curious as I didn't really see anything along those lines in your code.

_________________
What most people don't understand about "enlightenment" is that it is not an end-goal; but where you find yourself just before taking a new "first step."


Top
 Profile  
 
PostPosted: Sun Aug 14, 2011 12:17 pm 
As far as your question goes, I don't really know. Since I am so new to game programming, I borrowed the code from an open source and just modified it to suite my needs.

As far as the speed being to fast I did the following

Instead of:
Code:
float fdelta = delta*0.1f;


I did this
Code:
float fdelta = delta *0.051f


Now I have another problem. Ever since I got the map to scroll, my collision detection no longer works. The code snipet below is where I check for collision. The value never becomes true. To prove this to myself I included an System.Print of the value and it is always false.

Code:
//add collision detection to the walls that have the blocked Map property
        blocked = new boolean[level1.getWidth()][level1.getHeight()];
        //collidable =  new boolean[level1.getWidth()][level1.getHeight()];
        for (int xAxis=0;xAxis<level1.getWidth();xAxis++) {
      for (int yAxis=0;yAxis<level1.getHeight();yAxis++) {
         int tileID = level1.getTileId(xAxis, yAxis,0);
         String value = level1.getTileProperty(tileID, "blocked", "false");
                        System.out.println(value);
         if ("true".equals(value)) {
            blocked[xAxis][yAxis] = true;
                        }
      }
               
   }
   
   
    private boolean isBlocked(float x, float y)
    {
        int xBlock = (int)x/SIZE;
        int yBlock = (int)y/SIZE;
        return blocked[xBlock][yBlock];
    }


Top
  
 
PostPosted: Sun Aug 14, 2011 12:34 pm 
I take that back. It turns out the value is returning true. The collision is just not working. Take a look at the sample Sys Out.

Code:
false
false
false
false
false
true
true
true
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false


See where the values are true. These are tiles that have a "blocked" property attached to them so they are supposed to create a collision when walked into.


Top
  
 
PostPosted: Sun Aug 14, 2011 2:01 pm 
The thing that is funny is that if I change

Code:
if ("true".equals(value)) {
            blocked[xAxis][yAxis] = true;
                        }


to

Code:
if ("false".equals(value)) {
            blocked[xAxis][yAxis] = true;
                        }



All of the tiles with a "false" property or no collision, they do become "blocked"


Top
  
 
PostPosted: Mon Aug 15, 2011 11:48 am 
Harmlessness does no harm
User avatar

Joined: Tue Sep 14, 2004 8:37 pm
Posts: 3855
Location: Ferriday, LA, US
Your "isBlocked" function needs a bit of tweaking is all. The x/y arguments you are feeding it are based on the player's location -- and since that location is no longer going to be divisible by the tile size -- you'll need to take that into account.

That is, at least from what I can tell from the code. I don't know if there is anything else that needs to be dealt with, but if you continue to have trouble, just holler. :)

_________________
What most people don't understand about "enlightenment" is that it is not an end-goal; but where you find yourself just before taking a new "first step."


Top
 Profile  
 
PostPosted: Mon Aug 15, 2011 1:10 pm 
Dexterous Droid
User avatar

Joined: Wed Aug 18, 2004 7:40 pm
Posts: 3746
Location: South Africa
Try stepping through your code line by line with a debugger, it'll help you to see what's happening and should allow you to fix your problems or at least have a better idea about what's wrong.

_________________
Whatever the mind can conceive and believe, it can achieve


Top
 Profile  
 
PostPosted: Mon Aug 15, 2011 11:59 pm 
theraje wrote:
Your "isBlocked" function needs a bit of tweaking is all. The x/y arguments you are feeding it are based on the player's location -- and since that location is no longer going to be divisible by the tile size -- you'll need to take that into account.


I tried several different things to get this to work and still no luck. Any other help is appreciated. By the way, is there a better way of achieving the scrolling that would make detecting the collision easier?


Top
  
 
PostPosted: Tue Aug 16, 2011 9:46 pm 
Dexterous Droid
User avatar

Joined: Wed Aug 18, 2004 7:40 pm
Posts: 3746
Location: South Africa
What did you try? Letting us know what you've already looked into lets us look for other possible problems.

_________________
Whatever the mind can conceive and believe, it can achieve


Top
 Profile  
 
PostPosted: Thu Aug 18, 2011 9:30 am 
Sorry for the delayed response. My collision detection is somewhat working now but still has a lot of problems.

When moving in either the UP or LEFT directions, the collision has to be dead on in order for it to work, otherwise the sprite pass right through the tile. When moving in the DOWN or RIGHT direction, the sprite can pass more than half way through the tile before the collision kicks in.

I am fairly sure I am doing something wrong in the update method which contains the character movement calculations, or if could be an error in the tryMove method which gets called as part of the character movement. Forgive me but math was not my best subject.

I am re-posting the new code. The update, isBlocked and tryMove methods, are where I have made changes.

Spoiler: show
Code:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package GameWorld;

/**
*
* @author Matt
*/

import org.newdawn.slick.*;
import org.newdawn.slick.tiled.TiledMap;
import org.newdawn.slick.state.*;
import org.newdawn.slick.gui.TextField;



public class GamePlayState extends BasicGameState{
   
    private int stateID = 0;
    private TiledMap level1;
    private Animation sprite,up,down,left,right,spin;
    private float x = 34f, y = 34f;
    private boolean[][] blocked;
    private boolean[][] collidable;
    private static final int SIZE = 32;
    private static final int TILE_SIZE = 32;
    private static final float SPEED = 0.003f;
    private int scrollOffset;
    private TextField text1;
    private int widthInTiles;
    private int heightInTiles;
    private int topOffsetInTiles;
    private int leftOffsetInTiles;
    private float ang;
    private float dirX;
    private float dirY;
    private float playerX =20;
    private float playerY = 20;
    private enum STATES{START_GAME_STATE,PAUSE_GAME_STATE,GAME_OVER_STATE};
    private STATES currentState = null;
   

    public GamePlayState(int stateID)
    {
        this.stateID = stateID;
    }

   
    @Override
    public int getID() {
        return stateID;
    }
   
    @Override
    public void init(GameContainer container, StateBasedGame sb) throws SlickException
    {
        Image []  movementUp = {new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_bk1.gif")
                               ,new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_bk2.gif")};
        Image []  movementDown = {new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_fr1.gif")
                               ,new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_fr2.gif")};
        Image []  movementLeft = { new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_lf1.gif")
                               ,new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_lf2.gif")};
        Image []  movementRight ={ new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_rt1.gif")
                                ,new Image("C:/Users/Matt/Downloads/last-guardian-sprites/last-guardian-sprites/amg1_rt2.gif")};
       
        int [] duration = {300,300};
       
        //animate the sprite as the user presses the key
        up = new Animation(movementUp,duration,false);
        down = new Animation(movementDown,duration,false);
        left = new Animation(movementLeft,duration,false);
        right = new Animation(movementRight,duration,false);
       
        widthInTiles = container.getWidth() / TILE_SIZE;
        heightInTiles = container.getHeight() / TILE_SIZE;
        topOffsetInTiles = heightInTiles / 2;
        leftOffsetInTiles = widthInTiles / 2;
       
        sprite = right;
        //sprite.setAutoUpdate(false);
               
        //assigning instance variable of object TileMap to the level1 Map Location
        level1 = new TiledMap("C:/Users/Matt/Downloads/desert.tmx");
        System.out.println(container.getWidth());             
        //add collision detection to the walls that have the blocked Map property
        blocked = new boolean[level1.getWidth()][level1.getHeight()];
        //collidable =  new boolean[level1.getWidth()][level1.getHeight()];
        for (int xAxis=0;xAxis<level1.getWidth();xAxis++) {
      for (int yAxis=0;yAxis<level1.getHeight();yAxis++) {
         int tileID = level1.getTileId(xAxis, yAxis,0);
         String value = level1.getTileProperty(tileID, "blocked", "false");
         if ("true".equalsIgnoreCase(value)) {
            System.out.println("tileID" + tileID + "Blocked");
            blocked[xAxis][yAxis] = true;
           
         }
      }
   }
}
   
    private boolean isBlocked(float x, float y)
    {
     
      return blocked[(int)x][(int)y];
    }
   
   
   
       
        // caculate some layout values for rendering the tilemap. How many tiles
      // do we need to render to fill the screen in each dimension and how far is
      // it from the centre of the screen

    @Override
   public void update(GameContainer container, StateBasedGame sb, int delta) throws SlickException
    {
         
        //update the sprite movement as the keys are pressed
        Input input = container.getInput();
        float fdelta = delta*0.0051f;
       
            if (input.isKeyDown(Input.KEY_UP))
            {
                sprite = up;
                if (tryMove(dirX, dirY - fdelta) || tryMove(dirX-1, -dirY - fdelta))
               // if (tryMove(dirX * delta , dirY * delta))
                     {
                    sprite.update(delta);
                    // The lower the delta the slowest the sprite will animate.
                   // y -= delta * 0.0051f;
                         
                     }
            }
            else if (input.isKeyDown(Input.KEY_DOWN))
                 {
                    sprite = down;
                    if (tryMove(-dirX, -dirY + fdelta) || tryMove(dirX-1, -dirY + fdelta))
                  //  if (tryMove(-dirX * fdelta * SPEED, -dirY * delta * SPEED))
                    {
                         sprite.update(delta);
                         y += fdelta;
                         
                    }
                 }
                 else if (input.isKeyDown(Input.KEY_LEFT))
                 {
                    sprite = left;
                    if(tryMove(-dirX-fdelta,dirY) || tryMove(dirX-fdelta,dirY-1))
                    {
                        sprite.update(delta);
                        x -= fdelta;
                    }
                 }
                 else if (input.isKeyDown(Input.KEY_RIGHT))
                 {
                    sprite = right;
                    if (tryMove(dirX + fdelta, dirY) || tryMove(dirX +  fdelta, dirY-1))
                    {   
                        sprite.update(delta);
                        x += fdelta;
                    }
                 }

     
    }
   //THIS IS A NEW METHOD
   private boolean tryMove(float x, float y) {
      float newx = playerX + x;
      float newy = playerY + y;
      
      // first we try the real move, if that doesn't work
      // we try moving on just one of the axis (X and then Y)
      // this allows us to slide against edges
      if (isBlocked(newx,newy)) {
         if (isBlocked(newx, playerY)) {
            if (isBlocked(playerX, newy)) {
               // can't move at all!
               return false;
            } else {
               playerY = newy;
               return true;
            }
         } else {
            playerX = newx;
            return true;
         }
      } else {
         playerX = newx;
         playerY = newy;
         return true;
      }
   }
   
   
    @Override
    public void render(GameContainer container, StateBasedGame sb, Graphics g) throws SlickException
    {
       // draw the appropriate section of the tilemap based on the centre (hence the -(SIZE/2)) of
      // the player
      //  float fpx = x;
      //  float fpy = y;
       
   int playerTileX = (int)playerX;
   int playerTileY = (int)playerY;
          int mapOffsetX = 13;
          int mapOffsetY = 10;
         
        // caculate the offset of the player from the edge of the tile. As the player moves around this
   // varies and this tells us how far to offset the tile based rendering to give the smooth
   // motion of scrolling
   int playerTileOffsetX = (int) ((playerTileX - playerX) * TILE_SIZE);
   int playerTileOffsetY = (int) ((playerTileY - playerY) * TILE_SIZE);
     
   // render the section of the map that should be visible. Notice the -1 and +3 which renders
   // a little extra map around the edge of the screen to cope with tiles scrolling on and off
   // the screen
        level1.render(playerTileOffsetX - (SIZE / 2), playerTileOffsetY - (SIZE / 2),
               playerTileX - leftOffsetInTiles - 1,
               playerTileY - topOffsetInTiles - 1,
               widthInTiles + 3, heightInTiles + 3);
       
       
         
        // scrollOffset += 20*0.1f/1000f;     
   // draw entities relative to the player that must appear in the centre of the screen
  g.translate(400 - (int) (playerX * 32), 300 - (int) (playerY * 32));
 
   // draw other entities here if there were any
   //   sprite.draw((int)x,(int)y);
      sprite.draw((int)(playerX* SIZE),(int)(playerY* SIZE));
    //sprite.draw(playerX,playerY);
        g.resetTransform();
   
         
       // TextField field = new TextField();
        //render the map onto the screen
      //  level1.render(0,0);
               
       // fontTest.drawString(20.0f, 20.0f, "Slick displaying True Type Fonts", Color.green)
           
       
       
    }
   
   
   
   /* private boolean isCollectable(float x,float y)
    {
        int xBlock = (int)x / SIZE;
        int yBlock = (int)y / SIZE;
        return collidable[xBlock][yBlock];
    }  */       
   
}


Top
  
 
PostPosted: Thu Aug 18, 2011 9:52 am 
Bibliotherapist
User avatar

Joined: Wed Nov 03, 2004 1:28 pm
Posts: 6754
Location: Oxford, Englandshire
Holy wall of text Batman!

I've edited your post to roll up the code. Makes for easier thread viewing.

_________________
10 PRINT "Bad Monkey ";
20 GOTO 10


Top
 Profile  
 
PostPosted: Sun Aug 21, 2011 6:05 pm 
Thanks to everyone for helping. I have moved on. I have a new issue however. I am trying to load a new tilemap from an existing one. Kinda like in an RPG when you reach a new area and know that a new map has been loaded. Right now I am receiving a null pointer exception. Here is some snipets of what I am doing. To be honest I am not very experienced I am not even sure if I am approaching this the best way. Any help you can provide would be great.

Code:
private TiledMap[] level;  // array of tilemap objects
private boolean[][] nextLevel;
private int nxtLvl = 0;


Code:
//initlizing the tilemaps  ***Null Pointer Exception Here***
     level[0] = new TiledMap("C:/Users/Matt/Downloads/desert.tmx");
        level[1] = new TiledMap("C:/Users/Matt/Downloads/village.tmx");

        System.out.println(container.getWidth());             
        //add collision detection to the walls that have the blocked Map property
        blocked = new boolean[level[nxtLvl].getWidth()][level[nxtLvl].getHeight()];
        nextLevel = new boolean[level[nxtLvl].getWidth()][level[nxtLvl].getHeight()];
        //collidable =  new boolean[level1.getWidth()][level1.getHeight()];
        for (int xAxis=0;xAxis<level[nxtLvl].getWidth();xAxis++) {
      for (int yAxis=0;yAxis<level[nxtLvl].getHeight();yAxis++) {
         int tileID = level[nxtLvl].getTileId(xAxis, yAxis,0);
         String value = level[nxtLvl].getTileProperty(tileID, "blocked", "false");
         String next = level[nxtLvl].getTileProperty(tileID, "nextLevel", "false");
         if ("true".equalsIgnoreCase(value)) {
            System.out.println("tileID" + tileID + "Blocked");
            blocked[xAxis][yAxis] = true;
         }
         if("true".equalsIgnoreCase(next)){
             nextLevel[xAxis][yAxis] = true;
             nxtLvl++;  // if this tile is "touched"  incr counter
             System.out.println("This is level" + nxtLvl);
         }
         
      }


Code:
 level[nxtLvl].render(playerTileOffsetX - (SIZE / 2), playerTileOffsetY - (SIZE / 2),
               playerTileX - leftOffsetInTiles - 1,
               playerTileY - topOffsetInTiles - 1,
               widthInTiles + 3, heightInTiles + 3);


Top
  
 
PostPosted: Sun Aug 21, 2011 6:28 pm 
Woops, my bad. I forgot to initilize the array properly.

private TiledMap[] level;

should have been

private TiledMap[] level = new TiledMap[numberOfObjects];


Top
  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group