Hello,
This is my first topic here on JGO and i am glad to be a part of this community. I have a good understanding of java through college courses and self education, but I am relatively new to Java Game Development. I Have made games similar to pong, space invaders, pac man in JFrame but nothing to brag about. Currently I am trying to use the slick2d & lwjgl libraries along with TileD Map Editor for the first time to create a basic RPG. I am trying to have a " Final Fantasy(1-6) / Pokemon" Type movement/map transfer System. I have gotten as far as using “object layers” to create rectangles to use for Collision & transfer data. I dont know how to get the correct location to transfer the player according to the specific rectangles properties.
Within my “transport” objects layer each object has 2 “Properties” (xpos & ypos). These are the location that the player needs to be transported to from that specific object. Along with that how would i use that system to switch actual maps (towns,worldmap,caves etc.). I know this might seem like a “Newb” problem, but it has really put a halt on my game.
GameMap Class
[spoiler]
package com.oraclearts.javagame;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.tiled.TiledMap;
public class GameMap extends TiledMap {
private final List<Shape> collShapes = new ArrayList<Shape>();
private final List<Shape> tranShapes = new ArrayList<Shape>();
public GameMap(String mapPath) throws SlickException {
super(mapPath);
System.out.println(this.collShapes);
System.out.println(this.tranShapes);
//group Id is the physical layer -> int ( ie. 0 = collision 1 = transport )
final int tranGroup = 1;
final int collGroup = 0;
for (int i = 0; i < super.getObjectCount(collGroup); i++) {
Rectangle collRect = new Rectangle(super.getObjectX(collGroup, i),
super.getObjectY(collGroup, i), super.getObjectWidth(
collGroup, i), super.getObjectHeight(collGroup, i));
collShapes.add(collRect);
}
for (int j = 0; j < super.getObjectCount(tranGroup); j++) {
Rectangle tranRect = new Rectangle(super.getObjectX(tranGroup, j),
super.getObjectY(tranGroup, j), super.getObjectWidth(
tranGroup, j), super.getObjectHeight(tranGroup, j));
tranShapes.add(tranRect);
}
}
public List<Shape> getCollShapes() {
return collShapes;
}
public List<Shape> getTranShapes() {
return tranShapes;
}
public boolean isTransport(Shape s) {
Iterator<Shape> jt = tranShapes.iterator();
while (jt.hasNext()) {
if (jt.next().intersects(s))
return true;
}
return false;
}
public boolean isColliding(Shape s) {
Iterator<Shape> it = collShapes.iterator();
while (it.hasNext()) {
if (it.next().intersects(s))
return true;
}
return false;
}
}
[/spoiler]
Game Class
[spoiler]
package com.oraclearts.javagame;
import java.util.Iterator;
import org.lwjgl.input.Keyboard;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
public class Game extends BasicGameState {
private GameMap gameMap;
private Item items;
private Player character;
private Person person = new Person();
private boolean isCollDisplayed = false;
private boolean isTransDisplayed = false;
private static float viewportX = 0;
private static float viewportY = 0;
private static int viewportW = ConfigValues.RESOLUTION_WIDTH;
private static int viewportH = ConfigValues.RESOLUTION_HEIGHT;
private static int viewportWTile = viewportW / ConfigValues.MAP_TILE_SIZE;
private static int viewportHTile = viewportH / ConfigValues.MAP_TILE_SIZE;
private static int limitRight, limitLeft, limitTop, limitBottom;
@Override
public void init(GameContainer container, StateBasedGame state)
throws SlickException {
gameMap = new GameMap(Constant.MAP_PATH);
character = new Player("player", 8 * 32, 12*32);
items = new Item();
limitRight = gameMap.getWidth() * ConfigValues.MAP_TILE_SIZE
- ConfigValues.RESOLUTION_WIDTH;
limitLeft = 0;
limitTop = 0;
limitBottom = gameMap.getHeight() * ConfigValues.MAP_TILE_SIZE
- ConfigValues.RESOLUTION_HEIGHT;
System.out.println("Game.init() called");
}
@Override
public void render(GameContainer container, StateBasedGame state, Graphics g)
throws SlickException {
// offset x and y to display are calculated from a given tile
int x = (int) (viewportX % ConfigValues.MAP_TILE_SIZE);
int y = (int) (viewportY % ConfigValues.MAP_TILE_SIZE);
gameMap.render(-x, -y,
(int) (viewportX / ConfigValues.MAP_TILE_SIZE),
(int) (viewportY / ConfigValues.MAP_TILE_SIZE),
// We have to display one more tile on the left and on the
// bottom because of offset x and y
viewportWTile + ConfigValues.MAP_TILE_SIZE, viewportHTile
+ ConfigValues.MAP_TILE_SIZE,
gameMap.getLayerIndex(Constant.MAP_LAYER_BACKGROUND), false);
gameMap.render(-x, -y, (int) (viewportX / ConfigValues.MAP_TILE_SIZE),
(int) (viewportY / ConfigValues.MAP_TILE_SIZE), viewportWTile
+ ConfigValues.MAP_TILE_SIZE, viewportHTile
+ ConfigValues.MAP_TILE_SIZE,
gameMap.getLayerIndex(Constant.MAP_LAYER_FOREGROUND), false);
character.render(g);
person.render(g);
gameMap.render(-x, -y, (int) (viewportX / ConfigValues.MAP_TILE_SIZE),
(int) (viewportY / ConfigValues.MAP_TILE_SIZE), viewportWTile
+ ConfigValues.MAP_TILE_SIZE, viewportHTile
+ ConfigValues.MAP_TILE_SIZE,
gameMap.getLayerIndex(Constant.MAP_LAYER_TOP), false);
// Draw hitbox
if (isCollDisplayed) {
Iterator<Shape> it = gameMap.getCollShapes().iterator();
while (it.hasNext()) {
g.draw(it.next());
}
}
if (isTransDisplayed) {
Iterator<Shape> jt = gameMap.getTranShapes().iterator();
while (jt.hasNext()) {
g.draw(jt.next());
}
}
g.drawString("press h", 200, 10);
g.drawString("press t", 200, 20);
g.drawImage(items.BOOTS.get(5),200, 150);
}
@Override
public void update(GameContainer container, StateBasedGame game, int delta)
throws SlickException {
Input input = container.getInput();
float viewportXOffset = 0, viewportYOffset = 0;
float characterVelocityX = 0, characterVelocityY = 0;
int direction = -1;
if (input.isKeyDown(Keyboard.KEY_RIGHT)) {
direction = Character.DIRECTION_RIGHT;
if (character.isCenteredX()) {
viewportXOffset = character.getSpeed();
if (viewportX + viewportXOffset > limitRight) {
viewportXOffset = 0;
characterVelocityX = character.getSpeed();
}
} else {
characterVelocityX = character.getSpeed();
}
} else if (input.isKeyDown(Keyboard.KEY_LEFT)) {
direction = Character.DIRECTION_LEFT;
if (character.isCenteredX()) {
viewportXOffset = -character.getSpeed();
if (viewportX + viewportXOffset < limitLeft) {
viewportXOffset = 0;
characterVelocityX = -character.getSpeed();
}
} else {
characterVelocityX = -character.getSpeed();
}
} else if (input.isKeyDown(Keyboard.KEY_UP)) {
direction = Character.DIRECTION_UP;
if (character.isCenteredY()) {
viewportYOffset = -character.getSpeed();
if (viewportY + viewportYOffset < limitTop) {
viewportYOffset = 0;
characterVelocityY = -character.getSpeed();
}
} else {
characterVelocityY = -character.getSpeed();
}
} else if (input.isKeyDown(Keyboard.KEY_DOWN)) {
direction = Character.DIRECTION_DOWN;
if (character.isCenteredY()) {
viewportYOffset = character.getSpeed();
if (viewportY + viewportYOffset > limitBottom) {
viewportYOffset = 0;
characterVelocityY = character.getSpeed();
}
} else {
characterVelocityY = character.getSpeed();
}
} else if (input.isKeyPressed(Keyboard.KEY_H)) {
character.toggleDrawingCollision();
this.isCollDisplayed = !isCollDisplayed;
} else if (input.isKeyPressed(Keyboard.KEY_T)) {
character.toggleDrawingTransport();
this.isTransDisplayed = !isTransDisplayed;
}
// COLLISION DETECTION
if(direction != -1) {
// Character is colliding ?
boolean collide = false;
Iterator<Shape> it = gameMap.getCollShapes().iterator();
while(it.hasNext()) {
Shape s = it.next();
Shape nextS = new Rectangle(s.getX()-viewportXOffset, s.getY()-viewportYOffset, s.getWidth(), s.getHeight());
collide = nextS.intersects(character.getNextMoveCollbox(direction, characterVelocityX, characterVelocityY));
if(collide)
break;
}
// Character is transporting ?
boolean transport = false;
Iterator<Shape> jt = gameMap.getTranShapes().iterator();
while(jt.hasNext()) {
Shape s = jt.next();
Shape nextS = new Rectangle(s.getX()-viewportXOffset, s.getY()-viewportYOffset, s.getWidth(), s.getHeight());
transport = nextS.intersects(character.getNextMoveTranbox(direction, characterVelocityX, characterVelocityY));
if(transport){
character.setX(70);
character.setY(90);
break;}
}
if(!collide) {
// Updating viewport
viewportX += viewportXOffset;
viewportY += viewportYOffset;
character.moveCharacter(direction, delta, characterVelocityX, characterVelocityY);
// Updating hitbox coordinates depending on viewport
it = gameMap.getCollShapes().iterator();
while(it.hasNext()) {
Shape s = it.next();
s.setX(s.getX()-viewportXOffset);
s.setY(s.getY()-viewportYOffset);
}
jt = gameMap.getTranShapes().iterator();
while(jt.hasNext()) {
Shape s = jt.next();
s.setX(s.getX()-viewportXOffset);
s.setY(s.getY()-viewportYOffset);
}
} else {
character.moveCharacter(direction, delta, 0, 0);
}
}// End Collision Detection (if dir !=-1)
}
@Override
public int getID() {
System.out.println("Game.getID() called");
return Constant.ID_GAME_STATE;
}
}
[/spoiler]
Testmap File (.txm)
[spoiler]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map SYSTEM "http://mapeditor.org/dtd/1.0/map.dtd">
<map version="1.0" orientation="orthogonal" width="60" height="60" tilewidth="32" tileheight="32">
<tileset firstgid="1" name="ground" tilewidth="32" tileheight="32">
<image source="ground.png" trans="ff5ef7" width="512" height="1280"/>
</tileset>
<tileset firstgid="641" name="outdoorObjects" tilewidth="32" tileheight="32">
<image source="outdoorObjects.png" trans="ff5ef7" width="512" height="1920"/>
</tileset>
<layer name="background" width="60" height="60">
<data encoding="base64" compression="gzip">
H4sIAAAAAAAAC+3ZQQrCQAyF4dGVN3DdI7iqKw/jFdx5elukEETBJgPpa/7AWz46n7HC4HBobUjKPNH+2pl7F0fseb39JZHne7z34/pYr6dvzx55voo3Grzb9tr3t4q3Rx8v3k/vwxF73sw++2W/1feLd7/eapN9f610/+3R93grvb/Z58WLFy9evL+93I/Y77fPd0mF/fb6f0Dl9yoaNa/9Pmf1PeO5m2wl3jlP3VPTys3PxSsQvHjx4lUJXrx48aoEL168eFWCFy/e94xTrmIZA94e8/wzexm8ePHqjor3BRrlwZZAOAAA
</data>
</layer>
<layer name="foreground" width="60" height="60">
<data encoding="base64" compression="gzip">
H4sIAAAAAAAAC+2ZS07DMBCGk0C5QIU4Bys2QPewr5DYcwcCx+gFeImuKTfopbokEbUwqcex4xk/xv6lUe20fnwdT+xJqipdPXbWdvZkUdZpeUQ2VRRh88auwuvG+3zsNh/q9li8i5H6mHy1L+vZnnc3U/cNXQ/Zvvi38BbedJUzr/h04X1wPD9Tt8fmjV2CRWYqvIUXkmv+S90+Z//mtB9h8aaS/w555f2JY/6rimPu63kqb4r5b27+FSyFlzdvLvvvkIuzfyHmFHlN8l9OvGMyjVm5fl7bj7NqUKZ7oI9Bv3eAf8X4bWV/v2rRZ42j684uOjvT+KPwpst7VdHyzqXzaSzl3sc9L/QbTv7tJXghufJ+G+YwvtSv6UvN9yH9+07wX70Afa721yl5vwL5/lUzLrf4HVMsvLq1oFqjU2MhFl5f4soLrReZV859Y+VVcdjsianxukrw2rw/UvGG2ntshcWbinzyUpynbJWzf0PsR2+Nvo6t0LybPd929r9OJYhX93wSg/dTcDZ/rKK+JmQexq/J81iK+N16updN5cW0m/rXsPvVWW68Nu8Hsce+rQ+NM+99QF7TMqWdnvjn9elfnzbl/eAPQ7YY3EA4AAA=
</data>
</layer>
<layer name="top" width="60" height="60">
<data encoding="base64" compression="gzip">
H4sIAAAAAAAAC+3X4QmAIBCAUbMcpP3aqhFaqjHaQBB/nOZ7IHgHN8CXEqzhOua+h7e07Ue7B4BZnFv7G+keILpf9S+9ovtV/wKwiuh+1b/QZy/z/QEAACDCnevz3zy5PgMAa/oApkeejEA4AAA=
</data>
</layer>
<objectgroup name="collision" width="60" height="60">
<object name="statue" type="collision" x="227" y="119" width="28" height="32"/>
<object name="guard1" type="collision" x="323" y="221" width="28" height="32"/>
<object name="guard2" type="collision" x="130" y="219" width="28" height="32"/>
<object name="leftWall" type="collision" x="3" y="2" width="32" height="476"/>
<object name="rightWall" type="collision" x="447" y="2" width="32" height="473"/>
<object name="topWall" type="collision" x="34" y="2" width="415" height="32"/>
<object name="bottomWall" type="collision" x="33" y="466" width="416" height="10"/>
<object name="topWall2" type="collision" x="36" y="37" width="188" height="17"/>
<object name="topWall3" type="collision" x="257" y="36" width="188" height="17"/>
<object name="collide" type="collision" x="290" y="163" width="28" height="27"/>
<object name="statue" type="collision" x="736" y="117" width="28" height="32"/>
<object name="guard1" type="collision" x="832" y="219" width="28" height="32"/>
<object name="guard2" type="collision" x="639" y="217" width="28" height="32"/>
<object name="leftWall" type="collision" x="512" y="0" width="32" height="476"/>
<object name="rightWall" type="collision" x="956" y="0" width="96" height="64"/>
<object name="topWall" type="collision" x="543" y="0" width="415" height="32"/>
<object name="bottomWall" type="collision" x="542" y="464" width="416" height="10"/>
<object name="topWall2" type="collision" x="545" y="31" width="238" height="19"/>
<object name="topWall3" type="collision" x="766" y="34" width="188" height="17"/>
<object name="collide" type="collision" x="799" y="161" width="28" height="27"/>
<object name="statue" type="collision" x="1248" y="117" width="28" height="32"/>
<object name="guard1" type="collision" x="1344" y="219" width="28" height="32"/>
<object name="guard2" type="collision" x="1151" y="217" width="28" height="32"/>
<object name="leftWall" type="collision" x="958" y="176" width="96" height="320"/>
<object name="rightWall" type="collision" x="1468" y="0" width="32" height="473"/>
<object name="topWall" type="collision" x="1055" y="0" width="415" height="32"/>
<object name="bottomWall" type="collision" x="1054" y="464" width="416" height="10"/>
<object name="topWall2" type="collision" x="1057" y="35" width="234" height="17"/>
<object name="topWall3" type="collision" x="1278" y="34" width="188" height="17"/>
<object name="collide" type="collision" x="1311" y="161" width="28" height="27"/>
<object name="statue" type="collision" x="224" y="629" width="28" height="32"/>
<object name="guard1" type="collision" x="320" y="731" width="28" height="32"/>
<object name="guard2" type="collision" x="127" y="729" width="28" height="32"/>
<object name="leftWall" type="collision" x="0" y="512" width="32" height="476"/>
<object name="rightWall" type="collision" x="448" y="528" width="96" height="384"/>
<object name="topWall" type="collision" x="31" y="512" width="415" height="32"/>
<object name="bottomWall" type="collision" x="30" y="976" width="1440" height="32"/>
<object name="topWall2" type="collision" x="33" y="547" width="188" height="17"/>
<object name="topWall3" type="collision" x="254" y="546" width="188" height="17"/>
<object name="collide" type="collision" x="287" y="673" width="28" height="27"/>
<object name="statue" type="collision" x="736" y="629" width="28" height="32"/>
<object name="guard1" type="collision" x="832" y="731" width="28" height="32"/>
<object name="guard2" type="collision" x="639" y="729" width="28" height="32"/>
<object name="rightWall" type="collision" x="956" y="512" width="32" height="473"/>
<object name="topWall" type="collision" x="543" y="512" width="415" height="32"/>
<object name="bottomWall" type="collision" x="542" y="976" width="416" height="10"/>
<object name="topWall2" type="collision" x="545" y="547" width="188" height="17"/>
<object name="topWall3" type="collision" x="766" y="546" width="188" height="17"/>
<object name="collide" type="collision" x="799" y="673" width="28" height="27"/>
<object name="statue" type="collision" x="1248" y="629" width="28" height="32"/>
<object name="guard1" type="collision" x="1344" y="731" width="28" height="32"/>
<object name="guard2" type="collision" x="1151" y="729" width="28" height="32"/>
<object name="leftWall" type="collision" x="1024" y="512" width="32" height="476"/>
<object name="rightWall" type="collision" x="1468" y="512" width="32" height="473"/>
<object name="topWall" type="collision" x="1055" y="512" width="415" height="32"/>
<object name="bottomWall" type="collision" x="1054" y="976" width="416" height="10"/>
<object name="topWall2" type="collision" x="1057" y="547" width="188" height="17"/>
<object name="topWall3" type="collision" x="1278" y="546" width="188" height="17"/>
<object name="collide" type="collision" x="1311" y="673" width="28" height="27"/>
<object name="collide" type="collision" x="160" y="160" width="28" height="27"/>
<object name="rightWall" type="collision" x="1504" y="-32" width="32" height="1792"/>
<object name="bottomWall" type="collision" x="32" y="1728" width="608" height="32"/>
<object name="bottomWall" type="collision" x="0" y="1024" width="32" height="736"/>
<object name="bottomWall" type="collision" x="704" y="1728" width="800" height="32"/>
<object name="bottomWall" type="collision" x="64" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="160" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="256" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="352" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="448" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="544" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="640" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="736" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="832" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="928" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="1024" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="1120" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="1216" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="1312" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="1408" y="1120" width="32" height="32"/>
<object name="bottomWall" type="collision" x="1440" y="1216" width="32" height="32"/>
<object name="bottomWall" type="collision" x="576" y="1216" width="32" height="32"/>
<object name="bottomWall" type="collision" x="1056" y="1312" width="32" height="32"/>
<object name="bottomWall" type="collision" x="448" y="1536" width="32" height="32"/>
<object name="bottomWall" type="collision" x="544" y="1664" width="32" height="32"/>
<object name="bottomWall" type="collision" x="768" y="1664" width="32" height="32"/>
<object name="bottomWall" type="collision" x="608" y="1664" width="32" height="32"/>
<object name="bottomWall" type="collision" x="736" y="1664" width="32" height="32"/>
</objectgroup>
<objectgroup name="transport" width="60" height="60">
<object name="ent5" type="transport" x="226" y="36" width="28" height="27">
<properties>
<property name="xpos" value="39"/>
<property name="ypos" value="32"/>
</properties>
</object>
<object name="exit4" type="transport" x="224" y="448" width="28" height="27">
<properties>
<property name="xpos" value="7"/>
<property name="ypos" value="18"/>
</properties>
</object>
<object name="exit3" type="transport" x="736" y="448" width="28" height="27">
<properties>
<property name="xpos" value="23"/>
<property name="ypos" value="18"/>
</properties>
</object>
<object name="exit2" type="transport" x="1248" y="448" width="28" height="27">
<properties>
<property name="xpos" value="39"/>
<property name="ypos" value="18"/>
</properties>
</object>
<object name="exit1" type="transport" x="1248" y="960" width="28" height="27">
<properties>
<property name="xpos" value="39"/>
<property name="ypos" value="32"/>
</properties>
</object>
<object name="ent2" type="transport" x="1248" y="544" width="28" height="27">
<properties>
<property name="xpos" value="39"/>
<property name="ypos" value="13"/>
</properties>
</object>
<object name="ent3" type="transport" x="736" y="544" width="28" height="27">
<properties>
<property name="xpos" value="23"/>
<property name="ypos" value="13"/>
</properties>
</object>
<object name="ent4" type="transport" x="224" y="544" width="28" height="27">
<properties>
<property name="xpos" value="7"/>
<property name="ypos" value="13"/>
</properties>
</object>
<object name="ent1" type="transport" x="1248" y="992" width="28" height="27">
<properties>
<property name="xpos" value="39"/>
<property name="ypos" value="29"/>
</properties>
</object>
<object name="playerstart" type="transport" x="672" y="1504" width="28" height="27">
<properties>
<property name="xpos" value="21"/>
<property name="ypos" value="47"/>
</properties>
</object>
</objectgroup>
</map>
[/spoiler]
Please any help/advice would be greatly appreciated. Or if there’s a good tutorial or resource you know of that could steer me in the right direction. Thank you
Slick:
http://slick.ninjacave.com/javadoc/
Lwjgl:
http://www.lwjgl.org/wiki/index.php?title=Main_Page#Getting_started
TileD Map Editor: