2D Java游戏。 在平铺图像上方移动精灵

– > 简介,你可以跳过这部分

我很高兴能够最终在这个平台上发帖,因为我自己通过这个社区获得了如此多的知识; 只是通过阅读。 所以我想说“大家好,谢谢!

实际内容(序幕):

虽然我在我的公司开发Objective-C,但我对JAVA开发完全感兴趣。 我对语法很满意但是在使用awt / swing / Graphics2D时遇到了一些重大问题。

这个概念:

具有800 * 600帧的JAVA应用程序。 在此框架上,您可以看到尺寸为50px²的16 * 12个瓷砖(即gras.jpg或tree.jpg)。 在这个框架上方,一个.png“玩家”正在移动。 该字段使用2维int数组[16] [12]生成,其中0表示“gras”,1表示“tree”。

– >这实际上是“有效”。

第一次尝试:

将(frame.add(…))16 * 12 JLabel与imageIcon“gras”或“tree”一起添加到JLayeredPane
添加(frame.add(…))类“entityLayer”以5ms更新为paint(Graphics g)
{
g.drawImage(imageIcon.getImage());
}
如果我添加带有图块的字段实体图层,则此版本“有效”。 在每种情况下,entityLayer都会用灰色背景覆盖该字段,或者该字段下的“播放器”不可见;

第二次尝试:

在entityLayer绘制(Graphics g)方法中制作所有绘图。 但这不是我的意图。 我希望场地被绘制一次,而“球员”就像半透明背景一样,在场地上方绘制。

题:

我怎样才能让自己真正拥有两个独立的层次,这两个层次同样独立,而另一个层层重叠? 在某种程度上我的尝试是错误的,接近99%。

谢谢你马上。

而不是添加/绘制16 * 12 JLabel,只需将图块图像绘制16 * 12次?

对于这样的事情,我通常会将一个JPanel添加到JFrame,并覆盖JPanel的paint()方法。 实际上,我没有添加JPanel,我添加了我创建的JPanel的子类,你应该这样做,因为我将展示你需要在JPanel中添加一个字段并覆盖paint方法

您的背景图块绘图代码可能类似于:

int tileWidth = 50; int tileHeight = 50; for ( int x = 0; x < 16; x++ ) { for ( int y = 0; y < 12; y++ ) { Image tileImage; int tileType = fieldArray[x][y]; switch ( tileType ) { case 0: { tileImage = myGrassImage; break; } case 2: { tileImage = myTreeImage; break; } } Graphics2D g; g.drawImage(tileImage, x * tileWidth, y * tileHeight, null); } } 

一种适合我的技术是将每个图层的绘图逻辑分成一个单独的类,该类实现Painter接口(或您定义的类似接口)。

 public class TilePainter implements Painter { @Override public void paint( Graphics2D g, Object thePanel, int width, int height ) { //The tile painting code I posted above would go here //Note you may need to add a constructor to this class //that provides references to the needed resources //Eg: images/arrays/etc //Or provides a reference to a object where those resources can be accessed } } 

然后为球员画家:

 public class EntityPainter implements Painter { @Override public void paint( Graphics2D g, Object thePanel, int width, int height ) { g.drawImage(player.getImage(), player.getX(), player.getY(), null); } } 

如果你想知道为什么我将NULL传递给g.drawImage()函数,那么因为对于那个重载函数调用,最后一个参数是一个ImageObserver,这是我们不需要的。

好的,所以一旦你将你的画家分成不同的类,我们需要让JPanel能够使用它们!

这是您需要添加到JPanel的字段:

 List layerPainters; 

您的构造函数应该如下所示:

 public MyExtendedJPanel() { //I use an ArrayList because it will keep the Painters in order List layerPainters = new ArrayList(); TilePainter tilePainter = new TilePainter(Does,This,Need,Args); EntityPainter entityPainter = new EntityPainter(Does,This,Need,Args); //Layers will be painted IN THE ORDER THEY ARE ADDED layerPainters.add(tilePainter); layerPainters.add(entityPainter); } 

现在是最后但最重要的部分:

 @Override public void paint( Graphics g ) { int width = getWidth(); int height = getHeight(); //Loops through all the layers in the order they were added //And tells them to paint onto this panels graphic context for(Painter painter : layerPainters) { painter.paint(g,this,width,height); } }