Package sc.tools

Source Code of sc.tools.MapTool

package sc.tools;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import sc.math.SimplexNoise;
import sc.server.Server;
import sc.server.world.Tile;

public final class MapTool extends JFrame implements ActionListener
{

  /** The version of the serialised form of this class. */
  private static final long serialVersionUID = 1L;

  /** Constants */
  private static final int WIDTH = 1000;
  private static final int DEPTH = 1000;
  private static final int WATERLEVEL = 10;
  private static final int WATERBORDER = 100;
  private static final int LANDRISE = 5;

  /** Display elements */
  private static JLabel canvasLabel;
  private static BufferedImage map;
  private static int[] pixels;
  private static JLabel treeCountValue;

  /** Map statistics */
  private static int tree_count;

  /**
   * Creates an instance of MapMaker.
   *
   * @param width
   * @param height
   * @throws SQLException
   * @throws ClassNotFoundException
   */
  public MapTool(int width, int height) throws ClassNotFoundException,
      SQLException
  {
    setTitle("Map Maker");
    setSize(width, height);
    layoutWindow();
    setVisible(true);
  }

  /**
   * Lays out the window controls.
   */
  private void layoutWindow()
  {
    JButton btn;

    // Add the controls panel to the left hand side
    JPanel panel = new JPanel(new BorderLayout());
    getContentPane().add(panel, BorderLayout.WEST);

    // Add a reload map button to the top of the panel
    btn = new JButton("Reload");
    btn.addActionListener(this);
    panel.add(btn, BorderLayout.NORTH);

    // Add a save button to the top of the panel
    btn = new JButton("Save");
    btn.addActionListener(this);
    panel.add(btn, BorderLayout.SOUTH);

    // Add a info panel
    JPanel infopanel = new JPanel(new GridLayout(7, 1));
    panel.add(infopanel, BorderLayout.CENTER);

    // Add number of trees labels
    JLabel treeCountLabel = new JLabel("Trees:");
    treeCountValue = new JLabel("0");
    JPanel treeCountPanel = new JPanel();
    treeCountPanel.add(treeCountLabel);
    treeCountPanel.add(treeCountValue);
    infopanel.add(treeCountPanel);

    map = new BufferedImage(WIDTH, DEPTH, BufferedImage.TYPE_INT_RGB);
    canvasLabel = new JLabel(new ImageIcon(map));
    canvasLabel.setHorizontalAlignment(JLabel.CENTER);
    JScrollPane sp = new JScrollPane(canvasLabel);
    getContentPane().add(sp, BorderLayout.CENTER);

    addWindowListener(new WindowAdapter()
    {
      public void windowClosing(WindowEvent e)
      {
        System.exit(0);
      }
    });

    // Get a direct direct DataBuffer onto the bufferedimage
    WritableRaster raster = map.getRaster();
    pixels = ((DataBufferInt) raster.getDataBuffer()).getData();
  }

  /**
   * (Re)generates the world map.
   */
  public void regenerate()
  {
    double combined;
    int height;

    // Set random seeds
    int octave1_seed = (int) (Math.random() * 5000);
    int octave2_seed = (int) (Math.random() * 5000);
    int trees_seed = (int) (Math.random() * 5000);

    // Zero statistics
    tree_count = 0;

    for (int y = 0; y < DEPTH; y++)
    {
      for (int x = 0; x < WIDTH; x++)
      {

        /** There are multiple layers of noise that make up the terrain */

        // Layer 0: Defines a tapered edge so water frames the map
        double taper = 0;
        if (y < WATERBORDER)
        {
          taper = ((double) (WATERBORDER - y) / WATERBORDER);
        } else if (y > DEPTH - WATERBORDER)
        {
          taper = ((double) (y - DEPTH + WATERBORDER) / WATERBORDER);
        }
        if (x < WATERBORDER)
        {
          taper += ((double) (WATERBORDER - x) / WATERBORDER);
        } else if (x > WIDTH - WATERBORDER)
        {
          taper += ((double) (x - WIDTH + WATERBORDER) / WATERBORDER);
        }
        double octave0 = ((LANDRISE + WATERLEVEL - 128) / 128f)
            - (taper * taper);

        // Layer 1: Defines the large scale water and land forms
        double octave1 = SimplexNoise.noise(x * 0.005, y * 0.005,
            octave1_seed);

        // Layer 2: Defines smaller scale deformations
        double octave2 = SimplexNoise.noise(x * 0.02, y * 0.02,
            octave2_seed) * 0.2;

        // Combine the layers together
        combined = octave0 + octave1 + octave2;

        // Bound noise to the range [-1, 1]
        if (combined > 1)
          combined -= (combined - 1);
        else if (combined < -1)
          combined = -1;

        // Convert combined noise to height
        // [-1, 1] => [0, 256]
        height = (int) Math.round(combined * 128) + 128;

        // Set the green colour component of the pixel to represent
        // height
        int rgb = height << 8;

        if (height < WATERLEVEL)
        {
          // DEBUG: For testing set pixel to blue if below WATERLEVEL
          rgb += 75;
        } else
        {
          // We are above WATERLEVEL so apply trees
          if (Math.random() > SimplexNoise.noise(x * 0.005,
              y * 0.005, trees_seed) + 0.8)
          {
            rgb += 128;
            tree_count++;
          }
        }

        pixels[y * WIDTH + x] = rgb;
      }
    }

    // Update map info
    canvasLabel.repaint();
    treeCountValue.setText(String.valueOf(tree_count));
  }

  /**
   * Saves the current world map to disk.
   */
  public void save()
  {
    int x = 0;
    int z = 0;

    // Make a Tile out of each pixel in the image
    for (int i = 0; i < pixels.length; i++)
    {
      int height = (pixels[i] & 0x0000FF00) >> 8;
      new Tile((x - Tile.HALFMAPSIZE) * Tile.WIDTH, height,
          (z - Tile.HALFMAPSIZE) * Tile.WIDTH);

      x++;
      if (x == WIDTH)
      {
        x = 0;
        z++;
      }
    }
  }

  @Override
  public void actionPerformed(ActionEvent e)
  {
    if (e.getActionCommand() == "Reload")
    {
      regenerate();
    } else if (e.getActionCommand() == "Save")
    {
      save();
    }
  }

  /**
   * Program entry point.
   *
   * @param args
   */
  public static void main(String[] args)
  {
    try
    {
      MapTool mm = new MapTool(1024, 738);
      mm.regenerate();
    }
    catch (Exception e)
    {
      Server.logger.severe(e.getMessage());
    }
  }
}
TOP

Related Classes of sc.tools.MapTool

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.