📄 minimap.java
字号:
/* * MegaMek - Copyright (C) 2002,2003,2004,2005 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. */package megamek.client.ui.AWT;import java.awt.*;import java.awt.event.*;import java.util.Enumeration;import java.util.Vector;import java.io.*;import megamek.client.Client;import megamek.client.event.BoardViewEvent;import megamek.client.event.BoardViewListener;import megamek.client.event.BoardViewListenerAdapter;import megamek.client.ui.AWT.util.PlayerColors;import megamek.common.*;import megamek.common.actions.*;import megamek.common.event.BoardEvent;import megamek.common.event.BoardListener;import megamek.common.event.BoardListenerAdapter;import megamek.common.event.GameBoardChangeEvent;import megamek.common.event.GameBoardNewEvent;import megamek.common.event.GameListener;import megamek.common.event.GameListenerAdapter;import megamek.common.event.GamePhaseChangeEvent;import megamek.common.event.GameTurnChangeEvent;/** * Displays all the mapsheets in a scaled-down size. */public class MiniMap extends Canvas { // these indices match those in Terrains.java, and are therefore sensitive to any changes there private final static Color[] m_terrainColors = new Color[Terrains.SIZE]; private static Color HEAVY_WOODS; private static Color BACKGROUND; private static Color SINKHOLE; private static Color SMOKE_AND_FIRE; private final static int SHOW_NO_HEIGHT = 0; private final static int SHOW_GROUND_HEIGHT = 1; private final static int SHOW_BUILDING_HEIGHT = 2; private final static int SHOW_TOTAL_HEIGHT = 3; private final static int NBR_MODES = 3; private Image m_mapImage; private BoardView1 m_bview; private IGame m_game; private Dialog m_dialog; private static final int margin = 6; private int topMargin; private int leftMargin; private static final int buttonHeight = 14; private boolean minimized = false; private int heightBufer; private int unitSize = 6;//variable which define size of triangle for unit representation private Vector roadHexIndexes = new Vector(); private int zoom = GUIPreferences.getInstance().getMinimapZoom(); private int[] hexSide = {3,5,6,8,10,12}; private int[] hexSideByCos30 = {3,4,5,7,9,10}; private int[] hexSideBySin30 = {2,2,3,4,5,6}; private int[] halfRoadWidthByCos30 = {0,0,1,2,2,3}; private int[] halfRoadWidthBySin30 = {0,0,1,1,1,2}; private int[] halfRoadWidth = {0,0,1,2,3,3}; private int heightDisplayMode = SHOW_NO_HEIGHT; Coords firstLOS; Coords secondLOS; private Client m_client; private ClientGUI clientgui; /** * Creates and lays out a new minimap. */ public MiniMap(Dialog d, IGame g, BoardView1 bview) throws IOException { m_game = g; m_bview = bview; m_dialog = d; initializeColors(); m_bview.addBoardViewListener(boardViewListener); m_game.addGameListener(gameListener); m_game.getBoard().addBoardListener(boardListener); addMouseListener(mouseListener); addComponentListener(componentListener); m_dialog.addComponentListener(componentListener); m_dialog.setResizable(false); // TODO: replace this quick-and-dirty with some real size calculator. Dimension size = getSize(); boolean updateSize = false; if ( size.width < GUIPreferences.getInstance().getMinimumSizeWidth()) { size.width = GUIPreferences.getInstance().getMinimumSizeWidth(); updateSize = true; } if ( size.height < GUIPreferences.getInstance().getMinimumSizeHeight() ) { size.height = GUIPreferences.getInstance().getMinimumSizeHeight(); updateSize = true; } if ( updateSize ) { setSize( size ); } setLocation( GUIPreferences.getInstance().getMinimapPosX(), GUIPreferences.getInstance().getMinimapPosY() ); } public MiniMap(Dialog d, ClientGUI c, BoardView1 bview) throws IOException { this (d, c.getClient().game, bview); clientgui = c; c.minimapW.addKeyListener(c.menuBar); addKeyListener(c.menuBar); // this may come in useful later... m_client=c.getClient(); } public synchronized void update(Graphics g) { paint(g); } public void paint(Graphics g) { if (m_mapImage != null) { g.drawImage(m_mapImage, 0, 0, this); } } /* * Initialize default colours and override with config file if there is one. */ private void initializeColors() throws IOException { // set up defaults -- this might go away later... BACKGROUND = Color.black; m_terrainColors[0] = new Color(218,215,170); SINKHOLE = new Color(218,215,170); m_terrainColors[Terrains.WOODS] = new Color(180,230,130); HEAVY_WOODS = new Color(160,200,100); m_terrainColors[Terrains.ROUGH] = new Color(215,181,0); m_terrainColors[Terrains.RUBBLE] = new Color(200,200,200); m_terrainColors[Terrains.WATER] = new Color(200,247,253); m_terrainColors[Terrains.PAVEMENT] = new Color(204,204,204); m_terrainColors[Terrains.ROAD] = new Color(71,79,107); m_terrainColors[Terrains.FIRE] = Color.red; m_terrainColors[Terrains.SMOKE] = new Color(204,204,204); SMOKE_AND_FIRE = new Color(153,0,0); m_terrainColors[Terrains.SWAMP] = new Color(49,136,74); m_terrainColors[Terrains.BUILDING] = new Color(204,204,204); m_terrainColors[Terrains.BRIDGE] = new Color(109,55,25); m_terrainColors[Terrains.ICE] = new Color(204,204,255); m_terrainColors[Terrains.MAGMA] = new Color(200,0,0); m_terrainColors[Terrains.MUD] = new Color(218, 160, 100); m_terrainColors[Terrains.JUNGLE] = new Color(180,230,130); // now try to read in the config file int red; int green; int blue; File coloursFile = new File("data/images/hexes/" + GUIPreferences.getInstance().getMinimapColours()); //$NON-NLS-1$ // only while the defaults are hard-coded! if(!coloursFile.exists()) { return; } Reader cr = new FileReader(coloursFile); StreamTokenizer st = new StreamTokenizer(cr); st.lowerCaseMode(true); st.quoteChar('"'); st.commentChar('#'); scan: while (true) { red=0; green=0; blue=0; switch(st.nextToken()) { case StreamTokenizer.TT_EOF: break scan; case StreamTokenizer.TT_EOL: break scan; case StreamTokenizer.TT_WORD: // read in String key = st.sval; if (key.equals("unitsize")) { //$NON-NLS-1$ st.nextToken(); unitSize = (int)st.nval; } else if (key.equals("background")) { //$NON-NLS-1$ st.nextToken(); red = (int)st.nval; st.nextToken(); green = (int)st.nval; st.nextToken(); blue = (int)st.nval; BACKGROUND = new Color(red,green,blue); } else if (key.equals("heavywoods")) { //$NON-NLS-1$ st.nextToken(); red = (int)st.nval; st.nextToken(); green = (int)st.nval; st.nextToken(); blue = (int)st.nval; HEAVY_WOODS = new Color(red,green,blue); } else if (key.equals("sinkhole")) { //$NON-NLS-1$ st.nextToken(); red = (int)st.nval; st.nextToken(); green = (int)st.nval; st.nextToken(); blue = (int)st.nval; SINKHOLE = new Color(red,green,blue); } else if (key.equals("smokeandfire")) { //$NON-NLS-1$ st.nextToken(); red = (int)st.nval; st.nextToken(); green = (int)st.nval; st.nextToken(); blue = (int)st.nval; SMOKE_AND_FIRE = new Color(red,green,blue); } else { st.nextToken(); red = (int)st.nval; st.nextToken(); green = (int)st.nval; st.nextToken(); blue = (int)st.nval; m_terrainColors[Terrains.getType(key)]=new Color(red,green,blue); } } } cr.close(); } private void initializeMap() { // sanity check (cfg file could be hosed) if (zoom < 0) { zoom = 0; } else if (zoom > (hexSide.length - 1)) { zoom = (hexSide.length - 1); } int requiredWidth, requiredHeight; int currentHexSide = hexSide[zoom]; int currentHexSideByCos30 = hexSideByCos30[zoom]; int currentHexSideBySin30 = hexSideBySin30[zoom]; topMargin = margin; leftMargin = margin; requiredWidth = m_game.getBoard().getWidth()*(currentHexSide + currentHexSideBySin30) + currentHexSideBySin30 + 2*margin; requiredHeight = (2*m_game.getBoard().getHeight() + 1)*currentHexSideByCos30 + 2*margin + buttonHeight; //ensure its on screen Rectangle virtualBounds = new Rectangle(); GraphicsEnvironment ge = GraphicsEnvironment. getLocalGraphicsEnvironment(); GraphicsDevice[] gs = ge.getScreenDevices(); for (int j = 0; j < gs.length; j++) { GraphicsDevice gd = gs[j]; GraphicsConfiguration[] gc = gd.getConfigurations(); for (int i=0; i < gc.length; i++) { virtualBounds = virtualBounds.union(gc[i].getBounds()); } } //zoom out if its too big for the screen while(zoom>0 && (requiredWidth>virtualBounds.width || requiredHeight>virtualBounds.height)) { zoom--; currentHexSide = hexSide[zoom]; currentHexSideByCos30 = hexSideByCos30[zoom]; currentHexSideBySin30 = hexSideBySin30[zoom]; requiredWidth = m_game.getBoard().getWidth()*(currentHexSide + currentHexSideBySin30) + currentHexSideBySin30 + 2*margin; requiredHeight = (2*m_game.getBoard().getHeight() + 1)*currentHexSideByCos30 + 2*margin + buttonHeight; } int x = getParent().getLocation().x; int y = getParent().getLocation().y; if(x + requiredWidth > virtualBounds.getMaxX()) { x = (int)(virtualBounds.getMaxX() - requiredWidth); } if(x < virtualBounds.getMinX()) { x = (int)(virtualBounds.getMinX()); } if(y + requiredHeight > virtualBounds.getMaxY()) { y = (int)(virtualBounds.getMaxY() - requiredHeight); } if(y < virtualBounds.getMinY()) { y = (int)(virtualBounds.getMinY()); } getParent().setLocation(x,y); setSize(requiredWidth, requiredHeight); m_dialog.pack(); //m_dialog.show(); m_mapImage = createImage(getSize().width,getSize().height); if (getSize().width > requiredWidth) leftMargin = ((getSize().width - requiredWidth)/2) + margin; if (getSize().height > requiredHeight) topMargin = ((getSize().height - requiredHeight)/2) + margin; drawMap(); } // draw everything public synchronized void drawMap() { if (m_mapImage == null) { return; } if ( !m_dialog.isVisible() ) return; Graphics g = m_mapImage.getGraphics(); Color oldColor = g.getColor(); g.setColor(BACKGROUND); g.fillRect(0,0,getSize().width,getSize().height); g.setColor(oldColor); if (!minimized) { roadHexIndexes.removeAllElements(); for (int j = 0; j < m_game.getBoard().getWidth(); j++) { for (int k = 0; k < m_game.getBoard().getHeight(); k++) { IHex h = m_game.getBoard().getHex(j, k); g.setColor(terrainColor(h, j, k)); paintCoord(g, j, k, true); } } if (firstLOS != null) paintSingleCoordBorder(g, firstLOS.x, firstLOS.y, Color.red); if (secondLOS != null) paintSingleCoordBorder(g, secondLOS.x, secondLOS.y, Color.red); if (! roadHexIndexes.isEmpty()) paintRoads(g); if (SHOW_NO_HEIGHT!=heightDisplayMode) { for (int j = 0; j < m_game.getBoard().getWidth(); j++) { for (int k = 0; k < m_game.getBoard().getHeight(); k++) { IHex h = m_game.getBoard().getHex(j, k); paintHeight(g, h, j , k); } } } // draw Drop Zone if (null!=m_client && null!=m_game) { // sanity check! if (IGame.PHASE_DEPLOYMENT == m_game.getPhase()) { GameTurn turn = m_game.getTurn(); if (turn != null && turn.getPlayerNum() == m_client.getLocalPlayer().getId()) { for (int j = 0; j < m_game.getBoard().getWidth(); j++) { for (int k = 0; k < m_game.getBoard().getHeight(); k++) { if (m_game.getBoard().isLegalDeployment(new Coords(j,k), m_client.getLocalPlayer())) { paintSingleCoordBorder(g,j,k,Color.yellow);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -