Object Layer for a Java RPG
I'm trying to make a basic RPG in java. I think I have a good hold of the basics of java, but when it comes to this stuff I'm definitely a beginner. Anyway, I thought that it would be best to create a map with two layers: a terrain layer with water, rocks, grass, etc... and an object layer with trees, houses, items- things that the player can interact with. So far I have a terrain layer, produced using a 2-Dim array. My question is: how can I make an object layer, more specifically, how can I make a layer that contains objects whose coordinates can be interacted with?
Below is what I have so far. I apologize, my code must be organized strangely- like I said, I'm a beginner with this. Thanks for your time.
-Marcus
import javax.swing.*;
import java.awt.geom.*;
import java.awt.*;
import java.awt.event.*;
import javax.imageio.*;
import javax.imageio.ImageIO.*;
import java.awt.image.*;
import java.awt.image.BufferedImage.*;
import java.io.File.*;
import java.io.*;
import java.awt.Graphics2D.*;
public class mapStoreII extends JFrame implements KeyListener{
BufferedImage pic;
int width = 32;
int height = 32;
int px = 656;
int py = 656;
int[][] map_1 = {
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,10,5,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,3,14,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,13,6,12,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,16,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,1,1,1}
};
public mapStoreII(){
setSize(875,750);
setLocation(800,150);
setTitle("Test_Organics_v.1");
setResizable(true);
setBackground(Color.black);
setDefaultCloseOperation(EXIT_ON_CLOSE);
addKeyListener(this);
setVisible(true);
}
public void paint(Graphics g){
Graphics2D graphics = (Graphics2D) g;
for(int y = 0; y<20; y++){
for(int x = 0; x<24; x++){
try {
pic = ImageIO.read(new File(getImage(getMap(y,x))));
} catch (IOException e) {}
graphics.drawImage(pic, (x*width)+50, (y*height)+50, null);
graphics.setPaint(Color.red);
graphics.fill(new Ellipse2D.Double(px,py,32,32)); //Currently the player.
}
}
}
public int getMap(int y, int x){
return map_1[y][x];
}
public String getImage(int a){
if(a==2){
return "shoreline_1.png";
}
else if(a==1){
return "water_1.png";
}
else if(a==9){
return "player_on_dirt_1.png";
}
else if(a==3){
return "island_left.png";
}
else if(a==4){
return "island_right.png";
}
else if(a==5){
return "island_up.png";
}
else if(a==6){
return "island_down.png";
}
开发者_JS百科 else if(a==7){
return "chemical_1.png";
}
else if(a==10){
return "island_topLC.png";
}
else if(a==11){
return "island_topRC.png";
}
else if(a==12){
return "island_botRC.png";
}
else if(a==13){
return "island_botLC.png";
}
else if(a==14){
return "island_center.png";
}
else if(a==15){
return "shoreline_2.png";
}
else if(a==16){
return "shoreline_3.png";
}
else{
return "grassydirt_1.png";
}
}
public void keyPressed(KeyEvent event){
int code = event.getKeyCode();
if(code == KeyEvent.VK_LEFT || code == KeyEvent.VK_A){
px-=8;
repaint();
}
else if(code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_D){
px+=8;
repaint();
}
else if(code == KeyEvent.VK_UP || code == KeyEvent.VK_W){
py-=8;
repaint();
}
else if(code == KeyEvent.VK_DOWN || code == KeyEvent.VK_S){
py+=8;
repaint();
}
else if(code == KeyEvent.VK_I){
lineDraw inventory = new lineDraw(); //Opens an inventory.
}
}
public void keyReleased(KeyEvent event){
}
public void keyTyped(KeyEvent event){
}
public static void main(String[] args){
JFrame frame = new mapStoreII();
}
}
Sounds like a great project! I had a lot of fun writing a Java RPG / roguelike game called Tyrant a few years back. It's all open source so feel free to explore!
Some points you may find helpful:
- I had an object called Map (Map.java source)
- A Map stored both the tiles (in an int[] array) and objects (in a Thing[] array). I used one-dimensional arrays and calculated offsets into them using (x+y*mapWidth) but you can equally well use a 2 dimensional array
- Thing was a separate class that describes all the properties and behaviours of an object. It also contained a "next" pointer to another Thing, so that you could chain together a list of Things in a single square.
- It's a good idea to separate the graphics code from your game logic and game data structures. This helps keep your code maintainable and flexible - for example when you want to have store multiple maps that are not visible. In my case, I used a MapPanel GUI component which extended JPanel and knew how to draw a Map, but the Map object itself contained no GUI or drawing related code.
Anyway hope this is helpful. Good luck!
If I may ask, what are you trying to accomplish by keeping the 2 layers separate? One would think that a natural complement of interacting with objects is to interact with the terrain as well. It would allow for a more extensible game design.
Perhaps create a model object called Tile
to represent each grid and then have a boolean property on that class called interactive
. That way you can easily change in the future whether soemthing is interactive. You could also conceivably use interfaces to determine if it serves an interactive role or use inheritance and have a TileClass
Another thing, you may want to extract your file creation to somewhere other than your paint
method.
精彩评论