Java RPG的对象层
我正在尝试用java制作一个基本的RPG。我想我对java的基础知识掌握得很好,但说到这方面,我肯定是个初学者。无论如何,我认为最好创建一个包含两层的地图:一个包含水、岩石、草等的地形层。。。还有一个包含树木、房屋、物品的对象层——玩家可以与之交互的东西。到目前为止,我有一个地形层,使用2维阵列生成。我的问题是:如何创建一个对象层,更具体地说,如何创建一个包含可以与坐标交互的对象的层 以下是我到目前为止的情况。很抱歉,我的代码必须组织得很奇怪-就像我说的,我是这方面的初学者。谢谢你抽出时间 -马库斯Java RPG的对象层,java,Java,我正在尝试用java制作一个基本的RPG。我想我对java的基础知识掌握得很好,但说到这方面,我肯定是个初学者。无论如何,我认为最好创建一个包含两层的地图:一个包含水、岩石、草等的地形层。。。还有一个包含树木、房屋、物品的对象层——玩家可以与之交互的东西。到目前为止,我有一个地形层,使用2维阵列生成。我的问题是:如何创建一个对象层,更具体地说,如何创建一个包含可以与坐标交互的对象的层 以下是我到目前为止的情况。很抱歉,我的代码必须组织得很奇怪-就像我说的,我是这方面的初学者。谢谢你抽出时间 -马
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";
}
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();
}
}
import javax.swing.*;
导入java.awt.geom.*;
导入java.awt.*;
导入java.awt.event.*;
导入javax.imageio.*;
导入javax.imageio.imageio.*;
导入java.awt.image.*;
导入java.awt.image.buffereImage.*;
导入java.io.File.*;
导入java.io.*;
导入java.awt.Graphics2D.*;
公共类mapStoreII扩展JFrame实现KeyListener{
缓冲图像;
整数宽度=32;
整数高度=32;
int-px=656;
int-py=656;
int[][]映射_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}
};
公共地图库II(){
设置大小(875750);
设置位置(800150);
setTitle(“测试有机物第1版”);
可设置大小(真);
挫折背景(颜色:黑色);
setDefaultCloseOperation(关闭时退出);
addKeyListener(此);
setVisible(真);
}
公共空间绘制(图形g){
Graphics2D graphics=(Graphics2D)g;
for(int y=0;y听起来是一个很棒的项目!几年前,我编写了一个名为Java RPG/roguelike的游戏,玩得很开心。它都是开源的,所以请随意探索
以下几点可能会对您有所帮助:
- 我有一个叫做Map()的对象
- 贴图同时存储了平铺(在int[]数组中)和对象(在Thing[]数组中)。我使用了一维数组,并使用(x+y*mapWidth)计算了它们的偏移量,但同样可以使用二维数组
- Thing是一个单独的类,它描述了一个对象的所有属性和行为。它还包含一个指向另一个对象的“下一个”指针,这样您就可以在一个正方形中链接一个对象列表
- 将图形代码与游戏逻辑和游戏数据结构分离是一个好主意。这有助于保持代码的可维护性和灵活性-例如,当您希望存储多个不可见的地图时。在我的例子中,我使用了一个扩展的JPanel并知道如何绘制地图,但地图对象本身不包含GUI或dra机翼相关代码
无论如何,我希望这是有帮助的。祝你好运!如果我可以问的话,你想通过保持两层分开来实现什么?人们会认为与对象交互的一个自然补充就是与地形交互。这将允许更可扩展的游戏设计
也许可以创建一个名为Tile
的模型对象来表示每个网格,然后在该类上有一个名为interactive
的布尔属性。这样,将来您可以很容易地更改soemthing是否是交互的。您还可以使用接口来确定它是充当交互角色还是使用继承我要一个瓷砖班
另一件事,您可能希望将文件创建提取到您的paint
方法之外的其他地方。感谢您的输入,我实际上做了类似的操作。在一个单独的数组中对每个磁贴应用了真/假状态(我知道这是不必要的),但我遇到的一个问题是,我不知道确定我的角色是否在某个磁贴上的最佳方法。简言之,我在将我的播放器(红色圆圈)连接到地图上时遇到了问题。你是对的,这是不必要的-某种专用的MapTile类会更好。你还可以添加一个属性来处理“无法通行”问题你的其他评论中有问题。当玩家点击“左”时,检查以确保下一个平铺(如果存在)将passable属性设置为true
。对于角色问题,您可以始终存储玩家当前的X和Y,只需在当前磁贴上使用角色图像重新绘制。好的,我明白您的意思。问题是实际上没有“磁贴”但是只有32x32像素的图像。假设我的角色一次移动32像素(虽然在上面的代码中我有8个);因此我可以检查左移的x和y坐标是多少,但我无法指定“左分幅”布尔状态,因为这里没有平铺对象,只有图像。我希望我在这里讲得通。再次感谢你的评论。如果你的图像是32像素,你的角色移动了32像素,那么每个