【问题标题】:Sprites & Layers精灵和图层
【发布时间】:2014-05-19 06:48:50
【问题描述】:

所以最近我决定尝试制作某种形式的精灵游戏,类似于较早的最终幻想游戏。我主要将其作为一个代码学习过程,而不是使用 RPGMaker 之类的东西来实际创建一个想法。

我最关心的部分是如何以简单的方式正确绘制多层图像(例如静态 Sprite、背景图像等)。虽然我通常只是测试一堆东西来查看而不是询问,但我意识到在编码中实现任何一件事的方法有很多(可能很简单)。

有哪些方法(或类)可以实现这一点?最好是一种易于更改层在哪里的方法(B前面的层A......哦,随时等待A前面没有B!)

我希望这不是一个太宽泛的问题.. .

谢谢。

【问题讨论】:

    标签: java layer


    【解决方案1】:

    最基本的方法是painter's algorithm,只需按照与屏幕距离相反的顺序绘制图层(例如,首先是背景,然后是字符,然后是前景)。

    每个层都由一个简单的类表示,例如:

    public class Layer
    {
       List<Sprite> sprites;
    
       public void draw(Graphics g)
       {
          for (Sprite sprite : sprites)
             sprite.draw(g);
       }
    }
    

    精灵在哪里:

    public class Sprite
    {
       BufferedImage image;
       float x, y, w, h;
    
       public void draw(Graphics g)
       {
          g.drawImage(image, (int)x, (int)y, (int)(x+w), (int)(y+h), 0, 0, image.getWidth(), image.getHeight(), null);
       }
    }
    

    在这里,背景将是一个具有屏幕大小的单个精灵的图层。您可以对背景层进行子类化以实现视差等效果。

    最后,您的图层将成为场景的一部分:

    public class Scene
    {
       List<Layer> layers;
    
       public void draw(Graphics g)
       {
          for (Layer layer : layers)
             layer.draw(g);
       }
    }
    

    更改渲染顺序就像更改场景中“图层”列表中的顺序一样简单。

    【讨论】:

    • 这看起来像我要找的东西!编辑:只是为了确保我完全理解,使用“图层”字段我调用类的绘制函数(这是“玩家”可以看到的每个精灵和对象),它使用自己的样式(取决于对象)被“绘制”到屏幕上
    • @user3650756 想换个说法?没看懂,抱歉。总结一下:一个场景是一个图层列表,一个图层是一个精灵列表。场景中图层的顺序决定了它们的渲染顺序。图层必须按其距离的相反顺序(“远先”)进行渲染,才能正确渲染场景。
    【解决方案2】:

    您是否希望将前景图像放入背景图像?如果是,那么下面的代码会有所帮助:

    public class Image {
    
        public static void main(String args[]) throws IOException {
            BufferedImage bgImage = ImageIO.read(new File("1.jpg"));
            BufferedImage fgImage =ImageIO.read(new File("2.jpg"));
            BufferedImage overlayedImage = overlay(bgImage, fgImage);
            if (overlayedImage != null) {
                 File outputfile = new File("3.jpg");
                 ImageIO.write(overlayedImage, "jpg", outputfile);
            } else {}
        }
    
        public static BufferedImage overlay(BufferedImage bgImage,
                BufferedImage fgImage) {
    
            Graphics2D g = bgImage.createGraphics();
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            g.drawImage(bgImage, 0, 0, null);
            g.drawImage(fgImage, 0, 0, null);
            g.dispose();
            return bgImage;
        }
    }
    

    【讨论】: