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

📄 hextileset.java

📁 MegaMek is a networked Java clone of BattleTech, a turn-based sci-fi boardgame for 2+ players. Fight
💻 JAVA
字号:
/* * MegaMek - Copyright (C) 2000-2002 Ben Mazur (bmazur@sev.org) * *  This program is free software; you can redistribute it and/or modify it *  under the terms of the GNU General Public License as published by the Free *  Software Foundation; either version 2 of the License, or (at your option) *  any later version. * *  This program is distributed in the hope that it will be useful, but *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *  for more details. *//* * HexTileset.java * * Created on May 9, 2002, 1:33 PM */package megamek.client.ui.swing;import megamek.client.ui.swing.util.ImageCache;import megamek.common.Hex;import megamek.common.IHex;import megamek.common.ITerrain;import megamek.common.Terrains;import megamek.common.util.StringUtil;import javax.swing.JComponent;import java.awt.Image;import java.awt.MediaTracker;import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;import java.io.Reader;import java.io.StreamTokenizer;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Random;import java.util.Vector;/** * Matches each hex with an appropriate image. * * @author Ben */public class HexTileset {    private ArrayList bases = new ArrayList();    private ArrayList supers = new ArrayList();    private ImageCache<IHex,Image> hexToImageCache = new ImageCache<IHex,Image>();    private ImageCache<IHex,List<Image>> hexToImageListCache = new ImageCache<IHex,List<Image>>();    /**     * Creates new HexTileset     */    public HexTileset() {    }    public synchronized void clearHex(IHex hex) {        hexToImageCache.remove(hex);    }    /**     * This assigns images to a hex based on the best matches it can find.     * <p/>     * First it assigns any images to be superimposed on a hex.  These images     * must have a match value of 1.0 to be added, and any time a match of this     * level is achieved, any terrain involved in the match is removed from     * further consideration.     * <p/>     * Any terrain left is used to match a base image for the hex.  This time,     * a match can be any value, and the first, best image is used.     */    public synchronized Object[] assignMatch(IHex hex, JComponent comp) {        IHex hexCopy = hex.duplicate();        List supers = supersFor(hexCopy, comp);        Image base = baseFor(hexCopy, comp);        Object[] pair = new Object[]{base, supers};        hexToImageCache.put(hex, base);        hexToImageListCache.put(hex,supers);        return pair;    }    public synchronized Image getBase(IHex hex, JComponent comp) {        Image i = hexToImageCache.get(hex);        if (i == null) {            Object[] pair = assignMatch(hex, comp);            return (Image) pair[0];        }        return i;    }    public synchronized List<Image> getSupers(IHex hex, JComponent comp) {        List<Image> l = hexToImageListCache.get(hex);        if (l == null) {            Object[] pair = assignMatch(hex, comp);            return (List<Image>) pair[1];        }        return l;    }    /**     * Returns a list of images to be superimposed on the hex.  As noted above,     * all matches must be 1.0, and if such a match is achieved, all terrain     * elements from the tileset hex are removed from the hex.  Thus you want     * to pass a copy of the original to this function.     */    private List supersFor(IHex hex, JComponent comp) {        ArrayList matches = new ArrayList();                // find superimposed image matches        for (Iterator i = supers.iterator(); i.hasNext();) {            HexEntry entry = (HexEntry) i.next();            if (superMatch(hex, entry.getHex()) >= 1.0) {                matches.add(entry.getImage(comp));                // remove involved terrain from consideration                for (int j = 0; j < Terrains.SIZE; j++) {                    if (entry.getHex().containsTerrain(j)) {                        hex.removeTerrain(j);                    }                }            }        }                // assign null, or the matching images to the hex        return matches.size() > 0 ? matches : null;    }    /**     * Returns the best matching base image for this hex.  This works best if     * any terrain with a "super" image is removed.     */    private Image baseFor(IHex hex, JComponent comp) {        HexEntry bestMatch = null;        double match = -1;        // match a base image to the hex        Iterator iter = bases.iterator();        while (iter.hasNext()) {            HexEntry entry = (HexEntry) iter.next();            double thisMatch = baseMatch(hex, entry.getHex());            // stop if perfect match            if (thisMatch == 1.0) {                bestMatch = entry;                break;            }            // compare match with best            if (thisMatch > match) {                bestMatch = entry;                match = thisMatch;            }        }        return bestMatch.getImage(comp);    }        // perfect match    // all but theme    // all but elevation    // all but elevation & theme            public void loadFromFile(String filename) throws IOException {        // make inpustream for board        Reader r = new BufferedReader(new FileReader("data/images/hexes/" + filename)); //$NON-NLS-1$        // read board, looking for "size"        StreamTokenizer st = new StreamTokenizer(r);        st.eolIsSignificant(true);        st.commentChar('#');        st.quoteChar('"');        st.wordChars('_', '_');        while (st.nextToken() != StreamTokenizer.TT_EOF) {            int elevation = 0;            String terrain = null;            String theme = null;            String imageName = null;            if (st.ttype == StreamTokenizer.TT_WORD && (st.sval.equals("base") || st.sval.equals("super"))) { //$NON-NLS-1$ //$NON-NLS-2$                boolean base = st.sval.equals("base"); //$NON-NLS-1$                if (st.nextToken() == StreamTokenizer.TT_NUMBER) {                    elevation = (int) st.nval;                } else {                    elevation = ITerrain.WILDCARD;                }                st.nextToken();                terrain = st.sval;                st.nextToken();                theme = st.sval;                st.nextToken();                imageName = st.sval;                // add to list                if (base) {                    bases.add(new HexEntry(new Hex(elevation, terrain, theme), imageName));                } else {                    supers.add(new HexEntry(new Hex(elevation, terrain, theme), imageName));                }            }        }        r.close();        System.out.println("hexTileset: loaded " + bases.size() + " base images"); //$NON-NLS-1$ //$NON-NLS-2$        System.out.println("hexTileset: loaded " + supers.size() + " super images"); //$NON-NLS-1$ //$NON-NLS-2$    }    /**     * Initializes all the images in this tileset and adds them to the tracker     */    public void loadAllImages(JComponent comp, MediaTracker tracker) {        for (Iterator i = bases.iterator(); i.hasNext();) {            HexEntry entry = (HexEntry) i.next();            if (entry.getImage() == null) {                entry.loadImage(comp);            }            tracker.addImage(entry.getImage(), 1);        }        for (Iterator i = supers.iterator(); i.hasNext();) {            HexEntry entry = (HexEntry) i.next();            if (entry.getImage() == null) {                entry.loadImage(comp);            }            tracker.addImage(entry.getImage(), 1);        }    }    /**     * Adds all images associated with the hex to the specified tracker     */    public synchronized void trackHexImages(IHex hex, MediaTracker tracker) {        Image base = hexToImageCache.get(hex);        List<Image> superImgs = hexToImageListCache.get(hex);        // add base        tracker.addImage(base, 1);                // add superImgs        if (superImgs != null) {            for (Iterator i = superImgs.iterator(); i.hasNext();) {                tracker.addImage((Image) i.next(), 1);            }        }    }    /**     * Loads the image for this hex.     */    public void loadHexImage(IHex hex, JComponent comp, MediaTracker tracker) {    }    public synchronized void reset() {        hexToImageCache = new ImageCache();        hexToImageListCache = new ImageCache();    }    /**     * Match the two hexes using the "super" formula.  All matches must be     * exact, however the match only depends on the original hex matching     * all the elements of the comparision, not vice versa.     * <p/>     * EXCEPTION: a themed original matches any unthemed comparason.     */    private double superMatch(IHex org, IHex com) {        // check elevation        if (com.getElevation() != ITerrain.WILDCARD && org.getElevation() != com.getElevation()) {            return 0;        }        // check terrain        for (int i = 0; i < Terrains.SIZE; i++) {            ITerrain cTerr = com.getTerrain(i);            ITerrain oTerr = org.getTerrain(i);            if (cTerr == null) {                continue;            } else if (oTerr == null                    || (cTerr.getLevel() != ITerrain.WILDCARD                    && oTerr.getLevel() != cTerr.getLevel())                    || (cTerr.hasExitsSpecified()                    && oTerr.getExits() != cTerr.getExits())) {                return 0;            }        }        // A themed original matches any unthemed comparason.        if (com.getTheme() != null &&                !com.getTheme().equalsIgnoreCase(org.getTheme())) {            return 0.0;        }        return 1.0;    }    /**     * Match the two hexes using the "base" formula.     * <p/>     * Returns a value indicating how close of a match the original hex is to     * the comparison hex.  0 means no match, 1 means perfect match.     */    private double baseMatch(IHex org, IHex com) {        double elevation;        double terrain;        double theme;                // check elevation        if (com.getElevation() == ITerrain.WILDCARD) {            elevation = 1.0;        } else {            elevation = 1.01 / (Math.abs(org.getElevation() - com.getElevation()) + 1.01);        }                // Determine maximum number of terrain matches.        // Bug 732188: Have a non-zero minimum terrain match.        double maxTerrains = Math.max(org.terrainsPresent(), com.terrainsPresent());        double matches = 0.0;        for (int i = 0; i < Terrains.SIZE; i++) {            ITerrain cTerr = com.getTerrain(i);            ITerrain oTerr = org.getTerrain(i);            if (cTerr == null || oTerr == null) {                continue;            }            double thisMatch = 0;            if (cTerr.getLevel() == ITerrain.WILDCARD) {                thisMatch = 1.0;            } else {                thisMatch = 1.0 / (Math.abs(oTerr.getLevel() - cTerr.getLevel()) + 1.0);            }            // without exit match, terrain counts... um, half?            if (cTerr.hasExitsSpecified() && oTerr.getExits() != cTerr.getExits()) {                thisMatch *= 0.5;            }            // add up match value            matches += thisMatch;        }        if (maxTerrains == 0) {            terrain = 1.0;        } else {            terrain = matches / maxTerrains;        }                // check theme        if (com.getTheme() == org.getTheme() ||                (com.getTheme() != null &&                com.getTheme().equalsIgnoreCase(org.getTheme()))) {            theme = 1.0;        } else {            // also don't throw a match entirely out because the theme is off            theme = 0.0001;        }        return elevation * terrain * theme;    }    private class HexEntry {        private IHex hex;        private String imageFile;        private Image image;        private Vector images;        private Vector filenames;        private Random r;        public HexEntry(IHex hex, String imageFile) {            this.hex = hex;            this.imageFile = imageFile;            r = new Random();            filenames = StringUtil.splitString(imageFile, ";"); //$NON-NLS-1$        }        public IHex getHex() {            return hex;        }        public Image getImage() {            return image;        }        public String getImageFileName() {            return "data/images/hexes/" + imageFile; //$NON-NLS-1$        }        public Image getImage(JComponent comp) {            if (images == null) {                loadImage(comp);            }            if (images.size() > 1) {                int rand = (int) (r.nextDouble() * images.size());                return (Image) images.elementAt(rand);            }			return (Image) images.firstElement();        }        public void loadImage(JComponent comp) {            images = new Vector();            for (int i = 0; i < filenames.size(); i++) {                String filename = (String) filenames.elementAt(i);                images.addElement(comp.getToolkit().getImage("data/images/hexes/" + filename)); //$NON-NLS-1$            }//      image = comp.getToolkit().getImage("data/images/hexes/" + imageFile);        }    }}

⌨️ 快捷键说明

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