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

时间:2010-11-15 22:01:48

标签: java swing 2d

- > 简介,您可以跳过此部分

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

实际内容(序幕):

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

概念:

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

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

首先尝试:

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

第二次尝试:

在entityLayer绘制(Graphics g)方法中制作所有绘图。但这不是我的意图。我希望将该字段绘制一次,并将“播放器”与半透明背景一起绘制在上方字段。

问题:

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

马上感谢你。

1 个答案:

答案 0 :(得分:1)

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

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

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

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<Painter> layerPainters;

你的构造函数应该是这样的:

public MyExtendedJPanel()
    {
        //I use an ArrayList because it will keep the Painters in order
        List<Painter> layerPainters = new ArrayList<Painter>();

        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);
    }
}