This is my first attempt for smooth tile scrolling in Slick. The offx/offy coordinates are not entirely correct for hero, smaller than the tile image but it’s a good start the “smooth” part comes from shx/shy variables which offset the rendering position. The code is after the break:
Update: Check the project source code page at Google Code: http://code.google.com/p/jmuonline/
package scroller;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.tiled.TiledMap;
/**
*
* @author aquilax
*/
public class Scroller2 extends BasicGame{
private TiledMap map = null;
private Hero hero = null;
final static int screenw = 432;
final static int screenh = 336;
final static int centerx = screenw/2;
final static int centery = screenh/2;
final static int visx = 9;
final static int visy = 7;
final static float halfvisx = visx/2;
final static float halfvisy = visy/2;
private int tileW;
private int tileH;
private int mapW;
private int mapH;
private boolean[][] blocked;
private int offx;
private int offy;
public Scroller2(){
super("Scroller2");
}
@Override
public void init(GameContainer container) throws SlickException {
map = new TiledMap("data/testone.tmx");
tileW = map.getTileWidth();
tileH = map.getTileHeight();
mapW = map.getWidth();
mapH = map.getHeight();
fillBlocked(map);
hero = new Hero("data/hero.png");
hero.speed = 1;
hero.xtile = Integer.parseInt(map.getMapProperty("herox", "16"));
hero.ytile = Integer.parseInt(map.getMapProperty("heroy", "8"));
hero.xpos = centerx - hero.awidth/2;
hero.ypos = centery - hero.aheight/2;
offx = hero.xtile*tileW;
offy = hero.ytile*tileH;
}
@Override
public void update(GameContainer container, int delta) throws SlickException {
Input input = container.getInput();
if (input.isKeyDown(Input.KEY_LEFT)) {
moveChar(hero, -1, 0);
}
if (input.isKeyDown(Input.KEY_RIGHT)) {
moveChar(hero, +1, 0);
}
if (input.isKeyDown(Input.KEY_UP)) {
moveChar(hero, 0, -1);
}
if (input.isKeyDown(Input.KEY_DOWN)) {
moveChar(hero, 0, +1);
}
}
public void render(GameContainer container, Graphics g) throws SlickException {
int shx = (int)(offx/tileW)*tileW - offx;
int shy = (int)(offy/tileH)*tileH - offy;
map.render(shx, shy, (int)(offx/tileW-halfvisx), (int)(offy/tileH-halfvisy), visx+1, visy+1);
hero.draw(hero.xpos, hero.ypos);
g.setColor(Color.red);
g.drawString("offx "+offx, 300, 10);
g.drawString("offy "+offy, 300, 30);
}
public static void main(String[] args) throws SlickException {
AppGameContainer app = new AppGameContainer(new Scroller2());
app.setDisplayMode(screenw, screenh, false);
app.start();
}
private void fillBlocked(TiledMap map) {
blocked = new boolean[mapW][mapH];
for(int x = 0; x < mapW; x++){
for (int y = 0; y < mapH; y++){
blocked[x][y] = "true".equals(map.getTileProperty(map.getTileId(x, y, 0), "blocked", "false"));
}
}
}
private void moveChar(Hero ob, int dirx, int diry) {
offx += (int)(dirx*ob.speed);
offy += (int)(diry*ob.speed);
}
}