⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 maploader.java

📁 Developing Games in Java 源代码
💻 JAVA
字号:
package com.brackeen.javagamebook.bsp2D;

import java.io.*;
import java.util.*;
import com.brackeen.javagamebook.math3D.*;
import com.brackeen.javagamebook.game.GameObject;

/**
    The MapLoader class loads maps from a text file based on
    the Alias|Wavefront OBJ file specification.

    MAP file commands:
    <pre>
    v [x] [y] [z]        - Define a vertex with floating-point
                           coords (x,y,z).
    mtllib [filename]    - Load materials from an external .mtl
                           file.
    usemtl [name]        - Use the named material (loaded from a
                           .mtl file) for the next floor, ceiling,
                           or wall.
    ambientLightIntensity
        [value]          - Defines the ambient light intensity
                           for the next room, from 0 to 1.
    pointlight [v]       - Defines a point light located at the
        [intensity]        specfied vector. Optionally, light
        [falloff]          intesity and falloff distance can
                           be specified.
    player [v] [angle]   - Specifies the starting location of the
                           player and optionally a starting
                           angle, in radians, around the y-axis.
    obj [uniqueName]     - Defines an object from an external
        [filename] [v]     OBJ file. The unique name allows this
        [angle]            object to be uniquely identfied, but
                           can be "null" if no unique name is
                           needed. The filename is an external
                           OBJ file. Optionally, the starting
                           angle, in radians, around the y-axis
                           can be specified.
    room [name]          - Defines a new room, optionally giving
                           the room a name. A room consists of
                           vertical walls, a horizontal floor
                           and a horizontal ceiling. Concave rooms
                           are currently not supported, but can be
                           simulated by adjacent convex rooms.
    floor [height]       - Defines the height of the floor of
                           the current room, using the current
                           material. The current material can
                           be null, in which case no floor
                           polygon is created. The floor can be
                           above the ceiling, in which case a
                           "pillar" or "block" structure is
                           created, rather than a "room".
    ceil [height]        - Defines the height of the ceiling of
                           the current room, using the current
                           material. The current material can
                           be null, in which case no ceiling
                           polygon is created. The ceiling can be
                           below the floor, in which case a
                           "pillar" or "block" structure is
                           created, rather than a "room".
    wall [x] [z]         - Defines a wall vertex in a room using
         [bottom] [top]    the specified x and z coordinates.
                           Walls should be defined in clockwise
                           order. If "bottom" and "top" is not
                           defined, the floor and ceiling height
                           are used. If the current material is
                           null, or bottom is equal to top, no
                           wall polygon is created.
    </pre>
*/
public class MapLoader extends ObjectLoader {

    private BSPTreeBuilder builder;
    private Map loadedObjects;
    private Transform3D playerStart;
    private RoomDef currentRoom;
    private List rooms;
    private List mapObjects;

    // use a separate ObjectLoader for objects
    private ObjectLoader objectLoader;


    /**
        Creates a new MapLoader using the default BSPTreeBuilder.
    */
    public MapLoader() {
        this(null);
    }


    /**
        Creates a new MapLoader using the specified BSPTreeBuilder.
        If the builder is null, a default BSPTreeBuilder
        is created.
    */
    public MapLoader(BSPTreeBuilder builder) {
        if (builder == null) {
            this.builder = new BSPTreeBuilder();
        }
        else {
            this.builder = builder;
        }
        parsers.put("map", new MapLineParser());
        objectLoader = new ObjectLoader();
        loadedObjects = new HashMap();
        rooms = new ArrayList();
        mapObjects = new ArrayList();
    }


    /**
        Loads a map file and creates a BSP tree. Objects
        created can be retrieved from the getObjectsInMap()
        method.
    */
    public BSPTree loadMap(String filename) throws IOException {
        currentRoom = null;
        rooms.clear();
        vertices.clear();
        mapObjects.clear();
        playerStart = new Transform3D();

        path = new File(filename).getParentFile();

        parseFile(filename);

        return createBSPTree();
    }


    /**
        Creates a BSP tree from the rooms defined in the map file.
    */
    protected BSPTree createBSPTree() {
        // extract all polygons
        List allPolygons = new ArrayList();
        for (int i=0; i<rooms.size(); i++) {
            RoomDef room = (RoomDef)rooms.get(i);
            allPolygons.addAll(room.createPolygons());
        }

        // build the tree
        BSPTree tree = builder.build(allPolygons);

        // create polygon surfaces based on the lights.
        tree.createSurfaces(lights);
        return tree;
    }


    /**
        Gets a list of all objects degined in the map file.
    */
    public List getObjectsInMap() {
        return mapObjects;
    }


    /**
        Gets the player start location defined in the map file.
    */
    public Transform3D getPlayerStartLocation() {
        return playerStart;
    }


    /**
        Sets the lights used for OBJ objects.
    */
    public void setObjectLights(List lights,
        float ambientLightIntensity)
    {
        objectLoader.setLights(lights, ambientLightIntensity);
    }


    /**
        Parses a line in a MAP file.
    */
    protected class MapLineParser implements LineParser {

        public void parseLine(String line) throws IOException,
            NoSuchElementException
        {
            StringTokenizer tokenizer = new StringTokenizer(line);
            String command = tokenizer.nextToken();

            if (command.equals("v")) {
                // create a new vertex
                vertices.add(new Vector3D(
                    Float.parseFloat(tokenizer.nextToken()),
                    Float.parseFloat(tokenizer.nextToken()),
                    Float.parseFloat(tokenizer.nextToken())));
            }
            else if (command.equals("mtllib")) {
                // load materials from file
                String name = tokenizer.nextToken();
                parseFile(name);
            }
            else if (command.equals("usemtl")) {
                // define the current material
                String name = tokenizer.nextToken();
                if ("null".equals(name)) {
                    currentMaterial = new Material();
                }
                else {
                    currentMaterial =
                        (Material)materials.get(name);
                    if (currentMaterial == null) {
                        currentMaterial = new Material();
                        System.out.println("no material: " + name);
                    }
                }
            }
            else if (command.equals("pointlight")) {
                // create a point light
                Vector3D loc = getVector(tokenizer.nextToken());
                float intensity = 1;
                float falloff = PointLight3D.NO_DISTANCE_FALLOFF;
                if (tokenizer.hasMoreTokens()) {
                    intensity =
                        Float.parseFloat(tokenizer.nextToken());
                }
                if (tokenizer.hasMoreTokens()) {
                    falloff =
                        Float.parseFloat(tokenizer.nextToken());
                }
                lights.add(new PointLight3D(loc.x, loc.y, loc.z,
                    intensity, falloff));
            }
            else if (command.equals("ambientLightIntensity")) {
                // define the ambient light intensity
                ambientLightIntensity =
                    Float.parseFloat(tokenizer.nextToken());
            }
            else if (command.equals("player")) {
                // define the player start location
                playerStart.getLocation().setTo(
                    getVector(tokenizer.nextToken()));
                if (tokenizer.hasMoreTokens()) {
                    playerStart.setAngleY(
                        Float.parseFloat(tokenizer.nextToken()));
                }
            }
            else if (command.equals("obj")) {
                // create a new obj from an object file
                String uniqueName = tokenizer.nextToken();
                String filename = tokenizer.nextToken();
                // check if the object is already loaded
                PolygonGroup object =
                    (PolygonGroup)loadedObjects.get(filename);
                if (object == null) {
                    File file = new File(path, filename);
                    String filePath = file.getPath();
                    object = objectLoader.loadObject(filePath);
                    loadedObjects.put(filename, object);
                }
                Vector3D loc = getVector(tokenizer.nextToken());
                PolygonGroup mapObject =
                    (PolygonGroup)object.clone();
                mapObject.getTransform().getLocation().setTo(loc);
                if (!uniqueName.equals("null")) {
                    mapObject.setName(uniqueName);
                }
                if (tokenizer.hasMoreTokens()) {
                    mapObject.getTransform().setAngleY(
                        Float.parseFloat(tokenizer.nextToken()));
                }
                mapObjects.add(mapObject);
            }
            else if (command.equals("trigger")) {
                String uniqueName = tokenizer.nextToken();
                Vector3D loc = getVector(tokenizer.nextToken());
                float r = Float.parseFloat(tokenizer.nextToken());
                GameObject object = new GameObject(
                    new PolygonGroup(uniqueName));
                object.getTransform().getLocation().setTo(loc);
                object.getBounds().setTopHeight(32);
                object.getBounds().setRadius(r);
                mapObjects.add(object);
            }
            else if (command.equals("room")) {
                // start a new room
                currentRoom = new RoomDef(ambientLightIntensity);
                rooms.add(currentRoom);
            }
            else if (command.equals("floor")) {
                // define a room's floor
                float y = Float.parseFloat(tokenizer.nextToken());
                currentRoom.setFloor(y, currentMaterial.texture);
            }
            else if (command.equals("ceil")) {
                // define a room's ceiling
                float y = Float.parseFloat(tokenizer.nextToken());
                currentRoom.setCeil(y, currentMaterial.texture);
            }
            else if (command.equals("wall")) {
                // define a wall vertex in a room.
                float x = Float.parseFloat(tokenizer.nextToken());
                float z = Float.parseFloat(tokenizer.nextToken());
                if (tokenizer.hasMoreTokens()) {
                    float bottom =
                        Float.parseFloat(tokenizer.nextToken());
                    float top =
                        Float.parseFloat(tokenizer.nextToken());
                    currentRoom.addVertex(x, z, bottom, top,
                        currentMaterial.texture);
                }
                else {
                    currentRoom.addVertex(x, z,
                        currentMaterial.texture);
                }
            }
            else {
                System.out.println("Unknown command: " + command);
            }
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -