Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 对于一个简单的2D游戏,是否有一种有效的方法将纹理加载为.PNG图像_Java_File_Textures - Fatal编程技术网

Java 对于一个简单的2D游戏,是否有一种有效的方法将纹理加载为.PNG图像

Java 对于一个简单的2D游戏,是否有一种有效的方法将纹理加载为.PNG图像,java,file,textures,Java,File,Textures,我正在编写一个简单的基于2D块的游戏(类似于Minecraft)来开始使用Java。我有很多游戏机制,比如world generation,但加载纹理既笨重又低效。基本上,我使用加载函数分别加载所有纹理(纹理是16x16.PNG文件)。游戏中的每个块都有一个名称(例如“石头”、“泥土”),当游戏渲染瓷砖时,它会从textureManager类加载纹理。这是可行的,但我必须硬编码每个纹理加载和返回。我想做的是让纹理自动加载,但仍然有它们的字符串索引。例如,我希望游戏加载纹理文件夹中的所有.PNG文

我正在编写一个简单的基于2D块的游戏(类似于Minecraft)来开始使用Java。我有很多游戏机制,比如world generation,但加载纹理既笨重又低效。基本上,我使用加载函数分别加载所有纹理(纹理是16x16.PNG文件)。游戏中的每个块都有一个名称(例如“石头”、“泥土”),当游戏渲染瓷砖时,它会从textureManager类加载纹理。这是可行的,但我必须硬编码每个纹理加载和返回。我想做的是让纹理自动加载,但仍然有它们的字符串索引。例如,我希望游戏加载纹理文件夹中的所有.PNG文件,但保留它们的名称,这样我就可以说loadTexture(“石头”)

这是我当前的纹理管理器代码。当游戏开始时,它简单地加载每个文件,并为背景瓷砖使每个文件变暗。这是一个痛苦的添加新的纹理,只是没有效率

package graphics;

import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;

public class textureManager {
    private static final BufferedImage darken(BufferedImage image) {
        return new RescaleOp(.7f, 0, null).filter(image, null);
    }

    private static final String path = "/assets/textures/";
    // textures 
    public static final BufferedImage unknown   = renderer.loadImage(path + "unknown.png");
    private static final BufferedImage stone    = renderer.loadImage(path + "stone.png");
    private static final BufferedImage grass    = renderer.loadImage(path + "grass.png");
    private static final BufferedImage dirt     = renderer.loadImage(path + "dirt.png");
    private static final BufferedImage iron_ore = renderer.loadImage(path + "iron_ore.png");
    private static final BufferedImage coal_ore = renderer.loadImage(path + "coal_ore.png");
    private static final BufferedImage diamond_ore = renderer.loadImage(path + "diamond_ore.png");
    private static final BufferedImage bedrock  = renderer.loadImage(path + "bedrock.png");
    private static final BufferedImage andesite = renderer.loadImage(path + "andesite.png");
    private static final BufferedImage granite  = renderer.loadImage(path + "granite.png");
    private static final BufferedImage marble   = renderer.loadImage(path + "marble.png");

    // darkened textures
    private static final BufferedImage dark_stone = darken(stone);
    private static final BufferedImage dark_grass = darken(grass);
    private static final BufferedImage dark_dirt = darken(dirt);
    private static final BufferedImage dark_iron_ore = darken(iron_ore);
    private static final BufferedImage dark_coal_ore = darken(coal_ore);
    private static final BufferedImage dark_diamond_ore = darken(diamond_ore);
    private static final BufferedImage dark_andesite = darken(andesite);
    private static final BufferedImage dark_granite = darken(granite);
    private static final BufferedImage dark_marble = darken(marble);

    // animations
    private static Animation player   = new Animation("player");
    private static Animation lava     = new Animation("lava");
    private static Animation plant_01 = new Animation("plant_01");

    /** returns the textures of the name provided */
    public static BufferedImage getTexture(String name, boolean darken) {
        if(name.equals("air")) return null;
        if(name.equals("stone"))    if(!darken) return stone;           else return dark_stone;
        if(name.equals("grass"))    if(!darken) return grass;           else return dark_grass;
        if(name.equals("dirt"))     if(!darken) return dirt;            else return dark_dirt;
        if(name.equals("iron_ore")) if(!darken) return iron_ore;        else return dark_iron_ore;
        if(name.equals("coal_ore")) if(!darken) return coal_ore;        else return dark_coal_ore;
        if(name.equals("diamond_ore")) if(!darken) return diamond_ore;  else return dark_diamond_ore;
        if(name.equals("bedrock"))  return bedrock;
        if(name.equals("andesite")) if(!darken) return andesite;        else return dark_andesite;
        if(name.equals("granite"))  if(!darken) return granite;         else return dark_granite;
        if(name.equals("marble"))   if(!darken) return marble;          else return dark_marble;

        return unknown;
    }

    /** returns the animation of the name provided */
    public static Animation getAnimation(String name) {
        if(name.equals("player"))   return player;
        if(name.equals("lava"))     return lava;
        if(name.equals("plant_01")) return plant_01;

        return null;
    }
}
虽然这段代码有效,但我想添加一种更有效的方法,但我不知道如何添加。我曾考虑使用数组列表来存储图像,但它不接受字符串索引。也许是一个可以管理数组列表和名称索引的自定义类


注意:动画是一个自定义类,用于设置从文件夹加载的纹理的动画。这些文件可以忽略。

我的方法是不列出所有要加载的文件。加载该路径中的所有文件。将它们放入贴图
map textures=new HashMap()
然后根据文件名创建密钥。然后可以生成并添加深色纹理,将“深色”或“d”添加到
。然后在“获取纹理”(get texture)中,您需要做的就是
if(变暗)纹理。get('d'+name)else纹理。get(name)

一旦从文件中加载了所有纹理,就可以获得黑色版本

textures.putAll(textures.entrySet().stream().collect(Collectors.toMap(entry->"d"+entry.getKey(),entry->darken(entry.getValue()))));
你想要一个

Map的一个常见(可能是最常见)实现是:


我目前正在将文件加载到哈希映射中。我将结合您的响应和之前的另一个代码,并制作一个纹理加载函数。谢谢你的第二个例子效果很好。我得到了渲染纹理时要加载的枚举列表。唯一的问题是,如果找不到块而不是返回未知值(只是一个空白纹理),枚举将导致游戏崩溃。我有一些代码来检查一个值是否有效,但由于渲染器每帧必须调用getTexture函数大约2400次,因此检查将帧速率降低得太多,无法播放。“找不到块”是什么意思?你是说纹理类型可以为空吗?如果它不是null,那么根据定义,它必须是枚举常量之一,并且必须有对应的映像。
private static final Map<String, Map<Boolean, BufferedImage>> textures;

static {
    String[] baseNames = {
        "unknown",
        "stone",
        "grass",
        "dirt",
        "iron_ore",
        "coal_ore",
        "diamond_ore",
        "bedrock",
        "andesite",
        "granite",
        "marble",
    };

    Map<String, Map<Boolean, BufferedImage>> map = new HashMap<>();
    for (String baseName : baseNames) {
        BufferedImage regular =
            renderer.loadImage(path + baseName + ".png");
        BufferedImage dark = darken(regular);

        Map<Boolean, BufferedImage> regularAndDark = new HashMap<>(2);
        regularAndDark.put(false, regular);
        regularAndDark.put(true, dark);

        map.put(baseName, Collections.unmodifiableMap(regularAndDark));
    }

    textures = Collections.unmodifiableMap(map);
}

/** returns the textures of the name provided */
public static BufferedImage getTexture(String name, boolean darken) {
    Map<Boolean, BufferedImage>> matches = textures.get(name);
    assert matches != null : "No textures for name \"" + name + "\"";
    return matches.get(darken);
}
public enum TextureType {
    UNKNOWN,
    STONE,
    GRASS,
    DIRT,
    IRON_ORE,
    COAL_ORE,
    DIAMOND_ORE,
    BEDROCK,
    ANDESITE,
    GRANITE,
    MARBLE,
}

private static class Textures {
    final BufferedImage regular;
    final BufferedImage dark;

    Textures(BufferedImage regular) {
        this.regular = Objects.requireNonNull(regular,
            "Image cannot be null");
        this.dark = darken(regular);
    }
}

private static final Map<TextureType, Textures> textures;

static {
    Map<TextureType, Textures> map = new EnumMap(TextureType.class);
    for (TextureType type : TextureType.values()) {
        map.put(type,
            new Textures(renderer.loadImage(path + baseName + ".png")));
    }

    textures = Collections.unmodifiableMap(map);
}

/** returns the textures of the name provided */
public static BufferedImage getTexture(TextureType type, boolean darken) {
    Objects.requireNonNull(type, "Texture type cannot be null");
    Textures match = textures.get(type);
    return darken ? match.dark : match.regular;
}