2D Java 游戏.在平铺图像上方移动精灵 [英] 2D Java Game. Moving sprite above tiled images

查看:24
本文介绍了2D Java 游戏.在平铺图像上方移动精灵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

尽管我在公司中使用 Objective-C 进行开发,但我对 JAVA 开发完全感兴趣.我对语法很满意,但在使用 awt/swing/Graphics2D 时遇到了一些重大问题.

Though I'm developing in Objective-C in my company, I am utterly interested in JAVA development. I am quite comfortable with the syntax but have some major troubles with awt/swing/Graphics2D.

具有 800*600 帧的 JAVA 应用程序.在此框架上,您可以看到 16*12 块(即 gras.jpg 或 tree.jpg),大小为 50px².在此 Frame 上方,一个 .png播放器"正在移动.该字段由一个二维 int 数组[16][12] 生成,其中 0 表示gras",1 表示树".

JAVA Application with a 800*600 Frame. On this Frame you can see 16*12 tiles (i.e. gras.jpg or tree.jpg) with a size of 50px². Above this Frame a .png "player" is moving. The field is generated with a 2 dimensional int array[16][12] where a 0 symbolizes "gras" and 1 means "tree".

-> 这实际上是工作".

-> This is actually "working".

向 JLayeredPane 添加 (frame.add(...)) 16*12 JLabels with imageIcongras"或tree"
添加 (frame.add(...)) 类entityLayer",它在 5 毫秒内使用油漆更新(图形 g)
{
g.drawImage(imageIcon.getImage());
}
如果我添加带有瓷砖的字段实体层,则此版本有效".在其他任何情况下,entityLayer 都会用灰色背景覆盖该字段,或者玩家"在该字段下不可见;

Adding (frame.add(...)) 16*12 JLabels with imageIcon "gras" or "tree" to a JLayeredPane
Adding (frame.add(...)) class "entityLayer" wich is updated at 5ms with paint(Graphics g)
{
g.drawImage(imageIcon.getImage());
}
This Version "works" if I add either the field with tiles or the entity layer. In every case else either the entityLayer overlays the field with a grey background or the "player" is not visible under the field;

在 entityLayer 绘制(Graphics g)方法中的所有绘图.但这不是我的意图.我希望该场被绘制一次,并且玩家"像一个半透明的背景一样,被绘制在该场的上方.

Making all the drawings in the entityLayer paint(Graphics g) method. But thats not what I intended. I want the field to be drawn once and the "player" with, like a translucent background, drawn above the field.

我怎样才能让自己真正拥有两个独立的层,这两个层都是同样独立的,而不会相互重叠?我几乎 99% 确信我的尝试在某种程度上是错误的.

How can I get myself in a position to actually have two seperate layers, that are both equally independent with out having one overlapping the other? Im nearly 99% shure my attempt is wrong in some way.

马上谢谢你.

推荐答案

不是添加/绘制 16*12 JLabels,而是绘制 16*12 次平铺图像?

Instead of adding/drawing 16*12 JLabels, just draw the tile image 16*12 times?

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

For things like this, I usually add a single JPanel to a JFrame, and override the JPanel's paint() method. Actually, I don't add a JPanel, I add a subclass of JPanel that I have created, you should do the same, as I will show you will need to add a field to the JPanel and override the paint method

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

Your background tile drawing code might look similar to:

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 接口(或您定义的类似接口).

A technique that works well for me is to separate the drawing logic of each layer into a separate class that implements the Painter interface (or a similar interface you define).

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,我们不需要为此目的.

If you are wondering why I am passing NULLs into the g.drawImage() function, its because for that overloaded function call the last parameter is an ImageObserver, which is something we do not need for this purpose.

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

Ok, so once you have your painters separated into different classes we need to make the JPanel capable of using them!

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

This is the field that you need to add to your JPanel:

List<Painter> layerPainters;

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

Your constructor should look something like this:

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

    }

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

Now for the last but most important part:

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

这篇关于2D Java 游戏.在平铺图像上方移动精灵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆