├── .classpath
├── .gitignore
├── .idea
├── codeStyleSettings.xml
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
└── uiDesigner.xml
├── .project
├── .settings
└── org.eclipse.jdt.core.prefs
├── LICENSE
├── MapMaker.iml
├── README.md
├── bin
├── controller
│ ├── UiController$1.class
│ ├── UiController$MapTask.class
│ └── UiController.class
├── image
│ ├── FantasyImageManager.class
│ ├── HeatmapImageManager$1.class
│ ├── HeatmapImageManager.class
│ ├── ImageManager$1.class
│ ├── ImageManager.class
│ ├── RINGBEARER.TTF
│ └── ZoomManager.class
├── map
│ ├── Map.class
│ ├── PerlinMap.class
│ ├── RandomMap.class
│ ├── RevisedSmoothMap.class
│ └── SmoothMap.class
├── metrics
│ ├── Metric.class
│ └── MetricKey.class
├── model
│ ├── BiomeType.class
│ ├── City.class
│ ├── Direction.class
│ ├── Grid.class
│ ├── Location.class
│ ├── LocationType.class
│ ├── Point.class
│ ├── PointComparator.class
│ ├── Terrain.class
│ └── TerrainType.class
├── noise
│ ├── Noise.class
│ ├── PerlinNoise.class
│ ├── RandomNoise.class
│ ├── RevisedSmoothNoise.class
│ ├── SmoothNoise.class
│ └── SphericalNoise.class
├── procedural
│ ├── BiomeGeneration.class
│ ├── CityGeneration$1.class
│ ├── CityGeneration$CityComparator.class
│ ├── CityGeneration.class
│ ├── ContinentGeneration.class
│ ├── HumidityGeneration$1.class
│ ├── HumidityGeneration.class
│ ├── HumidityGenerationV2$1.class
│ ├── HumidityGenerationV2.class
│ ├── LakesAndRiversGeneration.class
│ ├── NameGeneration$1.class
│ ├── NameGeneration.class
│ ├── TemperatureGeneration.class
│ ├── TerritoryGeneration.class
│ ├── TerritoryGenerationV2$Coords.class
│ ├── TerritoryGenerationV2.class
│ ├── WindCurrents.class
│ └── WindCurrentsV2.class
├── test
│ └── ImageManagerTester.class
└── view
│ ├── BasicNoiseDialog.class
│ ├── ColorMapDialog$1.class
│ ├── ColorMapDialog.class
│ ├── MapEditorDialog$1.class
│ ├── MapEditorDialog.class
│ ├── SmoothColorMapDialog$1.class
│ ├── SmoothColorMapDialog.class
│ └── main.fxml
├── deployed
└── mapmakeralpha.jar
├── mapmaker.properties
├── mapmaker.xml
├── module_mapmaker.xml
└── src
├── Main.java
├── controller
└── UiController.java
├── image
├── FantasyImageManager.java
├── HeatmapImageManager.java
├── ImageManager.java
├── RINGBEARER.TTF
└── ZoomManager.java
├── map
├── Map.java
├── PerlinMap.java
├── RandomMap.java
├── RevisedSmoothMap.java
└── SmoothMap.java
├── metrics
├── Metric.java
└── MetricKey.java
├── model
├── BiomeType.java
├── City.java
├── Direction.java
├── Grid.java
├── Location.java
├── LocationType.java
├── Point.java
├── PointComparator.java
├── Terrain.java
└── TerrainType.java
├── noise
├── Noise.java
├── PerlinNoise.java
├── RandomNoise.java
├── RevisedSmoothNoise.java
├── SmoothNoise.java
└── SphericalNoise.java
├── packages
├── bundles
│ ├── daddy.html
│ └── daddy.jnlp
├── daddy.html
└── daddy.jnlp
├── procedural
├── BiomeGeneration.java
├── CityGeneration.java
├── ContinentGeneration.java
├── HumidityGeneration.java
├── HumidityGenerationV2.java
├── LakesAndRiversGeneration.java
├── NameGeneration.java
├── TemperatureGeneration.java
├── TerritoryGeneration.java
├── TerritoryGenerationV2.java
├── WindCurrents.java
└── WindCurrentsV2.java
├── test
└── ImageManagerTester.java
└── view
├── BasicNoiseDialog.java
├── ColorMapDialog.java
├── MapEditorDialog.java
├── SmoothColorMapDialog.java
├── main.fxml
├── main.fxml~
└── test.fxml
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # =========================
18 | # Operating System Files
19 | # =========================
20 |
21 | # OSX
22 | # =========================
23 |
24 | .DS_Store
25 | .AppleDouble
26 | .LSOverride
27 |
28 | # Icon must end with two \r
29 | Icon
30 |
31 |
32 | # Thumbnails
33 | ._*
34 |
35 | # Files that might appear on external disk
36 | .Spotlight-V100
37 | .Trashes
38 |
39 | # Directories potentially created on remote AFP share
40 | .AppleDB
41 | .AppleDesktop
42 | Network Trash Folder
43 | Temporary Items
44 | .apdisk
--------------------------------------------------------------------------------
/.idea/codeStyleSettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/uiDesigner.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 | -
9 |
10 |
11 | -
12 |
13 |
14 | -
15 |
16 |
17 | -
18 |
19 |
20 |
21 |
22 |
23 | -
24 |
25 |
26 |
27 |
28 |
29 | -
30 |
31 |
32 |
33 |
34 |
35 | -
36 |
37 |
38 |
39 |
40 |
41 | -
42 |
43 |
44 |
45 |
46 | -
47 |
48 |
49 |
50 |
51 | -
52 |
53 |
54 |
55 |
56 | -
57 |
58 |
59 |
60 |
61 | -
62 |
63 |
64 |
65 |
66 | -
67 |
68 |
69 |
70 |
71 | -
72 |
73 |
74 | -
75 |
76 |
77 |
78 |
79 | -
80 |
81 |
82 |
83 |
84 | -
85 |
86 |
87 |
88 |
89 | -
90 |
91 |
92 |
93 |
94 | -
95 |
96 |
97 |
98 |
99 | -
100 |
101 |
102 | -
103 |
104 |
105 | -
106 |
107 |
108 | -
109 |
110 |
111 | -
112 |
113 |
114 |
115 |
116 | -
117 |
118 |
119 | -
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | MapMaker
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
5 | org.eclipse.jdt.core.compiler.compliance=1.8
6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
11 | org.eclipse.jdt.core.compiler.source=1.8
12 |
--------------------------------------------------------------------------------
/MapMaker.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MapMaker
2 | Generate realistic fictional maps
3 |
4 | 
5 |
6 | MapMaker is a multiplatform program written in Java that generates maps using random and procedural generation to create realistic fictional worlds. Users can customize their maps via a variety of parameters:
7 | * Persistence - The greater the persistence, the more "broken" up the map is and vice versa
8 | * Octaves - The greater the number of octaves, the more detailed the map is and vice versa
9 | * Land/Hill/Mountain Gen - The lower the number, the more terrain of that type and vice versa
10 |
11 | You can also view political maps for your world by toggling the political map check box.
12 |
13 | 
14 |
15 | The underlying algorithm behind MapMaker is Perlin Noise, which efficiently and randomly generates a two dimensional height map.
16 |
17 | [Read more about the creation of this application here](https://medium.com/@JelloRanger/random-and-procedural-map-generation-part-1-noise-and-maps-cc78fc776172)
18 |
--------------------------------------------------------------------------------
/bin/controller/UiController$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/controller/UiController$1.class
--------------------------------------------------------------------------------
/bin/controller/UiController$MapTask.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/controller/UiController$MapTask.class
--------------------------------------------------------------------------------
/bin/controller/UiController.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/controller/UiController.class
--------------------------------------------------------------------------------
/bin/image/FantasyImageManager.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/image/FantasyImageManager.class
--------------------------------------------------------------------------------
/bin/image/HeatmapImageManager$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/image/HeatmapImageManager$1.class
--------------------------------------------------------------------------------
/bin/image/HeatmapImageManager.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/image/HeatmapImageManager.class
--------------------------------------------------------------------------------
/bin/image/ImageManager$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/image/ImageManager$1.class
--------------------------------------------------------------------------------
/bin/image/ImageManager.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/image/ImageManager.class
--------------------------------------------------------------------------------
/bin/image/RINGBEARER.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/image/RINGBEARER.TTF
--------------------------------------------------------------------------------
/bin/image/ZoomManager.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/image/ZoomManager.class
--------------------------------------------------------------------------------
/bin/map/Map.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/map/Map.class
--------------------------------------------------------------------------------
/bin/map/PerlinMap.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/map/PerlinMap.class
--------------------------------------------------------------------------------
/bin/map/RandomMap.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/map/RandomMap.class
--------------------------------------------------------------------------------
/bin/map/RevisedSmoothMap.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/map/RevisedSmoothMap.class
--------------------------------------------------------------------------------
/bin/map/SmoothMap.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/map/SmoothMap.class
--------------------------------------------------------------------------------
/bin/metrics/Metric.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/metrics/Metric.class
--------------------------------------------------------------------------------
/bin/metrics/MetricKey.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/metrics/MetricKey.class
--------------------------------------------------------------------------------
/bin/model/BiomeType.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/model/BiomeType.class
--------------------------------------------------------------------------------
/bin/model/City.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/model/City.class
--------------------------------------------------------------------------------
/bin/model/Direction.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/model/Direction.class
--------------------------------------------------------------------------------
/bin/model/Grid.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/model/Grid.class
--------------------------------------------------------------------------------
/bin/model/Location.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/model/Location.class
--------------------------------------------------------------------------------
/bin/model/LocationType.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/model/LocationType.class
--------------------------------------------------------------------------------
/bin/model/Point.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/model/Point.class
--------------------------------------------------------------------------------
/bin/model/PointComparator.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/model/PointComparator.class
--------------------------------------------------------------------------------
/bin/model/Terrain.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/model/Terrain.class
--------------------------------------------------------------------------------
/bin/model/TerrainType.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/model/TerrainType.class
--------------------------------------------------------------------------------
/bin/noise/Noise.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/noise/Noise.class
--------------------------------------------------------------------------------
/bin/noise/PerlinNoise.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/noise/PerlinNoise.class
--------------------------------------------------------------------------------
/bin/noise/RandomNoise.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/noise/RandomNoise.class
--------------------------------------------------------------------------------
/bin/noise/RevisedSmoothNoise.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/noise/RevisedSmoothNoise.class
--------------------------------------------------------------------------------
/bin/noise/SmoothNoise.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/noise/SmoothNoise.class
--------------------------------------------------------------------------------
/bin/noise/SphericalNoise.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/noise/SphericalNoise.class
--------------------------------------------------------------------------------
/bin/procedural/BiomeGeneration.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/BiomeGeneration.class
--------------------------------------------------------------------------------
/bin/procedural/CityGeneration$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/CityGeneration$1.class
--------------------------------------------------------------------------------
/bin/procedural/CityGeneration$CityComparator.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/CityGeneration$CityComparator.class
--------------------------------------------------------------------------------
/bin/procedural/CityGeneration.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/CityGeneration.class
--------------------------------------------------------------------------------
/bin/procedural/ContinentGeneration.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/ContinentGeneration.class
--------------------------------------------------------------------------------
/bin/procedural/HumidityGeneration$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/HumidityGeneration$1.class
--------------------------------------------------------------------------------
/bin/procedural/HumidityGeneration.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/HumidityGeneration.class
--------------------------------------------------------------------------------
/bin/procedural/HumidityGenerationV2$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/HumidityGenerationV2$1.class
--------------------------------------------------------------------------------
/bin/procedural/HumidityGenerationV2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/HumidityGenerationV2.class
--------------------------------------------------------------------------------
/bin/procedural/LakesAndRiversGeneration.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/LakesAndRiversGeneration.class
--------------------------------------------------------------------------------
/bin/procedural/NameGeneration$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/NameGeneration$1.class
--------------------------------------------------------------------------------
/bin/procedural/NameGeneration.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/NameGeneration.class
--------------------------------------------------------------------------------
/bin/procedural/TemperatureGeneration.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/TemperatureGeneration.class
--------------------------------------------------------------------------------
/bin/procedural/TerritoryGeneration.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/TerritoryGeneration.class
--------------------------------------------------------------------------------
/bin/procedural/TerritoryGenerationV2$Coords.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/TerritoryGenerationV2$Coords.class
--------------------------------------------------------------------------------
/bin/procedural/TerritoryGenerationV2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/TerritoryGenerationV2.class
--------------------------------------------------------------------------------
/bin/procedural/WindCurrents.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/WindCurrents.class
--------------------------------------------------------------------------------
/bin/procedural/WindCurrentsV2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/procedural/WindCurrentsV2.class
--------------------------------------------------------------------------------
/bin/test/ImageManagerTester.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/test/ImageManagerTester.class
--------------------------------------------------------------------------------
/bin/view/BasicNoiseDialog.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/view/BasicNoiseDialog.class
--------------------------------------------------------------------------------
/bin/view/ColorMapDialog$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/view/ColorMapDialog$1.class
--------------------------------------------------------------------------------
/bin/view/ColorMapDialog.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/view/ColorMapDialog.class
--------------------------------------------------------------------------------
/bin/view/MapEditorDialog$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/view/MapEditorDialog$1.class
--------------------------------------------------------------------------------
/bin/view/MapEditorDialog.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/view/MapEditorDialog.class
--------------------------------------------------------------------------------
/bin/view/SmoothColorMapDialog$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/view/SmoothColorMapDialog$1.class
--------------------------------------------------------------------------------
/bin/view/SmoothColorMapDialog.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/bin/view/SmoothColorMapDialog.class
--------------------------------------------------------------------------------
/bin/view/main.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
96 |
102 |
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/deployed/mapmakeralpha.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/deployed/mapmakeralpha.jar
--------------------------------------------------------------------------------
/mapmaker.properties:
--------------------------------------------------------------------------------
1 | path.variable.kotlin_bundled=C\:\\Program Files (x86)\\JetBrains\\IntelliJ IDEA Community Edition 2016.1.2\\plugins\\Kotlin\\kotlinc
2 | path.variable.maven_repository=C\:\\Users\\jacob\\.m2\\repository
3 | jdk.home.1.8=C\:/Program Files/Java/jdk1.8.0_65
4 | javac2.instrumentation.includeJavaRuntime=false
--------------------------------------------------------------------------------
/mapmaker.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/module_mapmaker.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/src/Main.java:
--------------------------------------------------------------------------------
1 | /*import view.ColorMapDialog;
2 | import view.SmoothColorMapDialog;
3 | import view.BasicNoiseDialog;
4 | import map.*;
5 | import noise.*;
6 |
7 | import static javafx.application.Application.launch;
8 |
9 | public class Main {
10 |
11 | private final static int WIDTH = 1000;
12 |
13 | private final static int HEIGHT = 1000;
14 |
15 | private final static double LANDGEN = 0;
16 |
17 | private final static double WATERGEN = -0.5;
18 |
19 | private final static double MOUNTAINGEN = 0.5;
20 |
21 | private final static double HILLGEN = 0.4;
22 |
23 | private final static double BEACHGEN = -0.0125;
24 |
25 | private final static double FORESTGEN = 0.2;
26 |
27 | public static void main(String[] args) {
28 |
29 | double seed = Math.random();
30 | double seedForest = Math.random();
31 |
32 | System.out.println("seed: " + seed);
33 | System.out.println("forest seed: " + seedForest);
34 |
35 | //displayRandomMap(WIDTH, HEIGHT, seed, seedForest, LANDGEN, WATERGEN, MOUNTAINGEN, HILLGEN, BEACHGEN, FORESTGEN);
36 | //displaySmoothMap(WIDTH, HEIGHT, 10, seed, seedForest, LANDGEN, WATERGEN, MOUNTAINGEN, HILLGEN, BEACHGEN, FORESTGEN);
37 | //displayRevisedSmoothMap(WIDTH, HEIGHT, seed, seedForest, LANDGEN, WATERGEN, MOUNTAINGEN, HILLGEN, BEACHGEN, FORESTGEN);
38 | //displayRandomNoise(WIDTH, HEIGHT, seed);
39 | //displaySmoothNoise(WIDTH, HEIGHT, seed, 5);
40 | //displaySmoothNoise(WIDTH, HEIGHT, seed, 10);
41 | //displayRevisedSmoothNoise(WIDTH, HEIGHT, seed);
42 | //displayPerlinNoise(WIDTH, HEIGHT, seed);
43 | displayPerlinMap(WIDTH, HEIGHT, seed, seedForest, LANDGEN, WATERGEN, MOUNTAINGEN, HILLGEN, BEACHGEN, FORESTGEN);
44 | //displayPerlinMapWithTexturing(WIDTH, HEIGHT, seed, seedForest, LANDGEN, WATERGEN, MOUNTAINGEN, HILLGEN, BEACHGEN, FORESTGEN);
45 |
46 | launch(args);
47 | }
48 |
49 | // DIALOGS
50 | private static void openBasicNoiseDialog(Noise noise) {
51 | BasicNoiseDialog.plotNoise(noise);
52 | }
53 |
54 | private static void openColorMapDialog(Map map) {
55 | ColorMapDialog dialog = new ColorMapDialog();
56 | dialog.plotMap(map);
57 | }
58 |
59 | private static void openSmoothColorMapDialog(Map map) {
60 | SmoothColorMapDialog dialog = new SmoothColorMapDialog();
61 | dialog.plotMap(map);
62 | }
63 |
64 | // MAPS
65 | private static void displayRandomMap(int width,
66 | int height,
67 | double seed,
68 | double seedForest,
69 | double landGen,
70 | double waterGen,
71 | double mountainGen,
72 | double hillGen,
73 | double beachGen,
74 | double forestGen) {
75 |
76 | RandomMap randomMap = new RandomMap(width,
77 | height,
78 | seed,
79 | seedForest,
80 | landGen,
81 | waterGen,
82 | mountainGen,
83 | hillGen,
84 | beachGen,
85 | forestGen);
86 |
87 | randomMap.generateMap();
88 | openColorMapDialog(randomMap);
89 | }
90 |
91 | private static void displaySmoothMap(int width,
92 | int height,
93 | int degrees,
94 | double seed,
95 | double seedForest,
96 | double landGen,
97 | double waterGen,
98 | double mountainGen,
99 | double hillGen,
100 | double beachGen,
101 | double forestGen) {
102 |
103 | SmoothMap smoothMap = new SmoothMap(width,
104 | height,
105 | seed,
106 | seedForest,
107 | degrees,
108 | landGen,
109 | waterGen,
110 | mountainGen,
111 | hillGen,
112 | beachGen,
113 | forestGen);
114 |
115 | smoothMap.generateMap();
116 | openColorMapDialog(smoothMap);
117 | //openSmoothColorMapDialog(smoothMap);
118 | }
119 |
120 | private static void displayRevisedSmoothMap(int width,
121 | int height,
122 | double seed,
123 | double seedForest,
124 | double landGen,
125 | double waterGen,
126 | double mountainGen,
127 | double hillGen,
128 | double beachGen,
129 | double forestGen) {
130 |
131 | RevisedSmoothMap revisedSmoothMap = new RevisedSmoothMap(width,
132 | height,
133 | seed,
134 | seedForest,
135 | landGen,
136 | waterGen,
137 | mountainGen,
138 | hillGen,
139 | beachGen,
140 | forestGen);
141 |
142 | revisedSmoothMap.generateMap();
143 | openColorMapDialog(revisedSmoothMap);
144 | //openSmoothColorMapDialog(revisedSmoothMap);
145 | }
146 |
147 | private static void displayPerlinMap(int width,
148 | int height,
149 | double seed,
150 | double seedForest,
151 | double landGen,
152 | double waterGen,
153 | double mountainGen,
154 | double hillGen,
155 | double beachGen,
156 | double forestGen) {
157 |
158 | PerlinMap perlinMap = new PerlinMap(width,
159 | height,
160 | seed,
161 | seedForest,
162 | landGen,
163 | waterGen,
164 | mountainGen,
165 | hillGen,
166 | beachGen,
167 | forestGen);
168 |
169 | perlinMap.generateMap();
170 | openColorMapDialog(perlinMap);
171 | }
172 |
173 | // MAPS WITH TEXTURING
174 |
175 | private static void displayPerlinMapWithTexturing(int width,
176 | int height,
177 | double seed,
178 | double seedForest,
179 | double landGen,
180 | double waterGen,
181 | double mountainGen,
182 | double hillGen,
183 | double beachGen,
184 | double forestGen) {
185 |
186 | PerlinMap perlinMap = new PerlinMap(width,
187 | height,
188 | seed,
189 | seedForest,
190 | landGen,
191 | waterGen,
192 | mountainGen,
193 | hillGen,
194 | beachGen,
195 | forestGen);
196 |
197 | perlinMap.generateMap();
198 | openSmoothColorMapDialog(perlinMap);
199 | }
200 |
201 | // NOISES
202 | private static void displayRandomNoise(int width, int height, double seed) {
203 | RandomNoise randomNoise = new RandomNoise(width, height, seed);
204 | randomNoise.initializeNoiseGrid();
205 | openBasicNoiseDialog(randomNoise);
206 | }
207 |
208 | private static void displaySmoothNoise(int width, int height, double seed, int degrees) {
209 | SmoothNoise smoothNoise = new SmoothNoise(width, height, seed, degrees);
210 | smoothNoise.initializeNoiseGrid();
211 | openBasicNoiseDialog(smoothNoise);
212 | }
213 |
214 | private static void displayRevisedSmoothNoise(int width, int height, double seed) {
215 | RevisedSmoothNoise revisedSmoothNoise = new RevisedSmoothNoise(width, height, seed);
216 | revisedSmoothNoise.initializeNoiseGrid();
217 | openBasicNoiseDialog(revisedSmoothNoise);
218 | }
219 |
220 | private static void displayPerlinNoise(int width, int height, double seed) {
221 | PerlinNoise perlinNoise = new PerlinNoise(width, height, seed, 0.5, 8);
222 | perlinNoise.initializeNoiseGrid();
223 | openBasicNoiseDialog(perlinNoise);
224 | }
225 |
226 | }*/
227 |
--------------------------------------------------------------------------------
/src/controller/UiController.java:
--------------------------------------------------------------------------------
1 | package controller;
2 |
3 | import image.FantasyImageManager;
4 | import image.ImageManager;
5 | import image.ZoomManager;
6 | import javafx.application.Platform;
7 | import javafx.concurrent.Task;
8 | import javafx.concurrent.WorkerStateEvent;
9 | import javafx.embed.swing.SwingFXUtils;
10 | import javafx.event.ActionEvent;
11 | import javafx.event.EventHandler;
12 | import javafx.fxml.FXML;
13 | import javafx.scene.control.*;
14 | import javafx.scene.image.ImageView;
15 | import javafx.scene.image.WritableImage;
16 | import javafx.scene.layout.AnchorPane;
17 | import javafx.stage.FileChooser;
18 | import javafx.stage.Stage;
19 | import map.PerlinMap;
20 |
21 | import javax.imageio.ImageIO;
22 | import java.awt.image.BufferedImage;
23 | import java.io.File;
24 | import java.io.IOException;
25 | import java.util.concurrent.Executors;
26 | import java.util.concurrent.ThreadPoolExecutor;
27 | import java.util.logging.Level;
28 | import java.util.logging.Logger;
29 |
30 | public class UiController {
31 |
32 | private static final String TAG = UiController.class.getSimpleName();
33 |
34 | @FXML
35 | private AnchorPane mCanvasAnchor;
36 |
37 | @FXML
38 | private ProgressIndicator mLoadingCircle;
39 |
40 | @FXML
41 | private Button mGenerateButton;
42 |
43 | @FXML
44 | private Button mWidthDefaultButton;
45 |
46 | @FXML
47 | private Button mHeightDefaultButton;
48 |
49 | @FXML
50 | private Button mPersistenceDefaultButton;
51 |
52 | @FXML
53 | private Button mOctavesDefaultButton;
54 |
55 | @FXML
56 | private Button mLandGenDefaultButton;
57 |
58 | @FXML
59 | private Button mHillGenDefaultButton;
60 |
61 | @FXML
62 | private Button mMountainGenDefaultButton;
63 |
64 | @FXML
65 | private Button mCityGenDefaultButton;
66 |
67 | @FXML
68 | private Button mSaveImageButton;
69 |
70 | @FXML
71 | private TextField mSeedField;
72 |
73 | @FXML
74 | private TextField mWidthTextField;
75 |
76 | @FXML
77 | private TextField mHeightTextField;
78 |
79 | @FXML
80 | private TextField mPersistenceField;
81 |
82 | @FXML
83 | private TextField mOctavesField;
84 |
85 | @FXML
86 | private TextField mLandGenTextField;
87 |
88 | @FXML
89 | private TextField mHillGenTextField;
90 |
91 | @FXML
92 | private TextField mMountainGenTextField;
93 |
94 | @FXML
95 | private TextField mCityGenTextField;
96 |
97 | @FXML
98 | private CheckBox mLandGenCheckBox;
99 |
100 | @FXML
101 | private CheckBox mHillGenCheckBox;
102 |
103 | @FXML
104 | private CheckBox mMountainGenCheckBox;
105 |
106 | @FXML
107 | private CheckBox mRiverGenCheckBox;
108 |
109 | @FXML
110 | private CheckBox mCityGenCheckBox;
111 |
112 | @FXML
113 | private CheckBox mNameGenCheckBox;
114 |
115 | @FXML
116 | private CheckBox mContinentGenCheckBox;
117 |
118 | @FXML
119 | private CheckBox mTerritoryGenCheckBox;
120 |
121 | @FXML
122 | private CheckBox mPoliticalMapCheckBox;
123 |
124 | @FXML
125 | private CheckBox mBiomeGenCheckBox;
126 |
127 | @FXML
128 | private CheckBox mGridCheckBox;
129 |
130 | @FXML
131 | private MenuItem mMenuClose;
132 |
133 | @FXML
134 | private CheckMenuItem mMenuTerrain;
135 |
136 | @FXML
137 | private CheckMenuItem mMenuFantasy;
138 |
139 | private Stage mStage;
140 |
141 | private BufferedImage mTerrainImage;
142 |
143 | private BufferedImage mFantasyImage;
144 |
145 | private ImageManager mImageManager;
146 |
147 | private FantasyImageManager mFantasyImageManager;
148 |
149 | //private List mMapImageCache;
150 |
151 | private boolean mSeedEdited = false;
152 |
153 | private static final int WIDTH = 1000;
154 |
155 | private static final int HEIGHT = 1000;
156 |
157 | private static final double LANDGEN = 0;
158 |
159 | private static final double WATERGEN = -0.5;
160 |
161 | private static final double MOUNTAINGEN = 0.8;
162 |
163 | private static final double HILLGEN = 0.7;
164 |
165 | private static final double BEACHGEN = -0.0125;
166 |
167 | private static final double FORESTGEN = 0.2;
168 |
169 | private static final int CITYGEN = 25;
170 |
171 | private static final double PERSISTENCE = 0.5;
172 |
173 | private static final int OCTAVES = 8;
174 |
175 | public void initialize() {
176 |
177 | mMenuClose.setOnAction(this::handleMenuClose);
178 |
179 | //mMapImageCache = new LinkedList<>();
180 |
181 | generateMap();
182 |
183 | mGenerateButton.setOnAction(this::handleGenerateButtonAction);
184 | mPersistenceDefaultButton.setOnAction(this::handlePersistenceDefaultButtonAction);
185 | mOctavesDefaultButton.setOnAction(this::handleOctavesDefaultButtonAction);
186 | mSaveImageButton.setOnAction(this::handleSaveImageButtonAction);
187 | mSeedField.textProperty().addListener(((observable, oldValue, newValue) -> {
188 | if (!oldValue.equals(newValue)) {
189 | mSeedEdited = true;
190 | }
191 | }));
192 |
193 | // Default Buttons
194 | mWidthDefaultButton.setOnAction(this::handleWidthDefaultButton);
195 | mHeightDefaultButton.setOnAction(this::handleHeightDefaultButton);
196 | mLandGenDefaultButton.setOnAction(this::handleLandGenDefaultButton);
197 | mHillGenDefaultButton.setOnAction(this::handleHillGenDefaultButton);
198 | mMountainGenDefaultButton.setOnAction(this::handleMountainGenDefaultButton);
199 | mCityGenDefaultButton.setOnAction(this::handleCityGenDefaultButton);
200 |
201 | // CheckBox listeners
202 | mPoliticalMapCheckBox.setOnAction(this::handlePoliticalMapCheckBox);
203 |
204 | // Menu items
205 | mMenuTerrain.setSelected(true);
206 | mMenuFantasy.setSelected(false);
207 | mMenuTerrain.setOnAction(this::handleMenuTerrain);
208 | mMenuFantasy.setOnAction(this::handleMenuFantasy);
209 | }
210 |
211 | private void setZoom() {
212 | ZoomManager zoomManager = new ZoomManager(mMenuTerrain.isSelected() ? mTerrainImage : mFantasyImage, mCanvasAnchor);
213 | ImageView imageView = zoomManager.startZoom();
214 | imageView.setId("mapImage");
215 | mCanvasAnchor.getChildren().remove(mCanvasAnchor.lookup("#mapImage"));
216 | mCanvasAnchor.getChildren().add(imageView);
217 | }
218 |
219 | public void setStageAndSetupListeners(Stage stage) {
220 | mStage = stage;
221 | }
222 |
223 | private void handleMenuClose(ActionEvent event) {
224 | Platform.exit();
225 | System.exit(0);
226 | }
227 |
228 | private void handleGenerateButtonAction(ActionEvent event) {
229 | generateMap();
230 | }
231 |
232 | // Default buttons
233 |
234 | private void handlePersistenceDefaultButtonAction(ActionEvent event) {
235 | mPersistenceField.setText(String.valueOf(PERSISTENCE));
236 | }
237 |
238 | private void handleOctavesDefaultButtonAction(ActionEvent event) {
239 | mOctavesField.setText(String.valueOf(OCTAVES));
240 | }
241 |
242 | private void handleWidthDefaultButton(ActionEvent event) {
243 | mWidthTextField.setText(String.valueOf(WIDTH));
244 | }
245 |
246 | private void handleHeightDefaultButton(ActionEvent event) {
247 | mHeightTextField.setText(String.valueOf(HEIGHT));
248 | }
249 |
250 | private void handleLandGenDefaultButton(ActionEvent event) {
251 | mLandGenTextField.setText(String.valueOf(LANDGEN));
252 | mLandGenCheckBox.setSelected(true);
253 | }
254 |
255 | private void handleHillGenDefaultButton(ActionEvent event) {
256 | mHillGenTextField.setText(String.valueOf(HILLGEN));
257 | mHillGenCheckBox.setSelected(true);
258 | }
259 |
260 | private void handleMountainGenDefaultButton(ActionEvent event) {
261 | mMountainGenTextField.setText(String.valueOf(MOUNTAINGEN));
262 | mMountainGenCheckBox.setSelected(true);
263 | }
264 |
265 | private void handleCityGenDefaultButton(ActionEvent event) {
266 | mCityGenTextField.setText(String.valueOf(CITYGEN));
267 | mCityGenCheckBox.setSelected(true);
268 | }
269 |
270 | // CheckBox listeners
271 |
272 | private void handlePoliticalMapCheckBox(ActionEvent event) {
273 | if (mPoliticalMapCheckBox.isSelected()) {
274 | mImageManager.colorPoliticalMap();
275 | } else {
276 | mImageManager.colorMap();
277 | }
278 |
279 | mTerrainImage = mImageManager.getImage();
280 | ImageView imageView = new ImageView();
281 | imageView.setImage(SwingFXUtils.toFXImage(mTerrainImage, null));
282 | imageView.setId("mapImage");
283 | mCanvasAnchor.getChildren().remove(mCanvasAnchor.lookup("#mapImage"));
284 | mCanvasAnchor.getChildren().add(imageView);
285 | setZoom();
286 | }
287 |
288 | // Menu item listeners
289 | private void handleMenuTerrain(ActionEvent event) {
290 | mCanvasAnchor.getChildren().remove(mCanvasAnchor.lookup("#mapImage"));
291 | if (mMenuTerrain.isSelected()) {
292 | mMenuFantasy.setSelected(false);
293 | ImageView imageView = new ImageView();
294 | imageView.setImage(SwingFXUtils.toFXImage(mTerrainImage, null));
295 | imageView.setId("mapImage");
296 | mCanvasAnchor.getChildren().add(imageView);
297 | } else {
298 | mMenuFantasy.setSelected(true);
299 | ImageView imageView = new ImageView();
300 | imageView.setImage(SwingFXUtils.toFXImage(mFantasyImage, null));
301 | imageView.setId("mapImage");
302 | mCanvasAnchor.getChildren().add(imageView);
303 | }
304 | setZoom();
305 | }
306 |
307 | private void handleMenuFantasy(ActionEvent event) {
308 | mCanvasAnchor.getChildren().remove(mCanvasAnchor.lookup("#mapImage"));
309 | if (mMenuFantasy.isSelected()) {
310 | mMenuTerrain.setSelected(false);
311 | ImageView imageView = new ImageView();
312 | imageView.setImage(SwingFXUtils.toFXImage(mFantasyImage, null));
313 | imageView.setId("mapImage");
314 | mCanvasAnchor.getChildren().add(imageView);
315 | } else {
316 | mMenuTerrain.setSelected(true);
317 | ImageView imageView = new ImageView();
318 | imageView.setImage(SwingFXUtils.toFXImage(mTerrainImage, null));
319 | imageView.setId("mapImage");
320 | mCanvasAnchor.getChildren().add(imageView);
321 | }
322 | setZoom();
323 | }
324 |
325 | private void handleSaveImageButtonAction(ActionEvent event) {
326 | BufferedImage saveImage = mMenuTerrain.isSelected() ? mTerrainImage : mFantasyImage;
327 |
328 | FileChooser fileChooser = new FileChooser();
329 | fileChooser.setTitle(mSaveImageButton.getText());
330 | fileChooser.setInitialDirectory(new File(System.getProperty("user.home"), "Pictures"));
331 | FileChooser.ExtensionFilter extensionFilter = new FileChooser.ExtensionFilter("PNG", "*.png");
332 | fileChooser.getExtensionFilters().add(extensionFilter);
333 | File file = fileChooser.showSaveDialog(mStage);
334 | if (file != null) {
335 | try {
336 | WritableImage writableImage = new WritableImage(saveImage.getWidth(),
337 | saveImage.getHeight());
338 | SwingFXUtils.toFXImage(saveImage, writableImage);
339 | ImageIO.write(SwingFXUtils.fromFXImage(writableImage, null), "png", file);
340 | } catch (IOException ioe) {
341 | Logger.getLogger(TAG).log(Level.SEVERE, null, ioe);
342 | }
343 | }
344 | }
345 |
346 | private void generateMap() {
347 |
348 | mCanvasAnchor.getChildren().remove(mCanvasAnchor.lookup("#mapImage"));
349 |
350 | verifyFields();
351 |
352 | /*if (mMapImageCache.size() > 0) {
353 | ImageView imageView = mMapImageCache.remove(0);
354 | mCanvasAnchor.getChildren().remove(mCanvasAnchor.lookup("#mapImage"));
355 | mCanvasAnchor.getChildren().add(imageView);
356 | setupCache(1);
357 | return;
358 | }*/
359 |
360 | // disable generate button while map is being computed
361 | mGenerateButton.setDisable(true);
362 | mLoadingCircle.setVisible(true);
363 |
364 | // run map generation in a background thread (so UI doesn't freeze)
365 | ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
366 | MapTask mapTask = new MapTask();
367 | executor.execute(mapTask);
368 |
369 | // listen to result of UI thread, display the map and reenable the generate button
370 | mapTask.addEventHandler(WorkerStateEvent.WORKER_STATE_SUCCEEDED,
371 | new EventHandler() {
372 | @Override
373 | public void handle(WorkerStateEvent event) {
374 | //ImageView imageView = new ImageView();
375 | //imageView.setImage(SwingFXUtils.toFXImage(mapTask.getValue(), null));
376 | //mCanvasAnchor.getChildren().remove(mCanvasAnchor.lookup("#mapImage"));
377 | mCanvasAnchor.getChildren().add(mapTask.getValue());
378 | mGenerateButton.setDisable(false);
379 | mLoadingCircle.setVisible(false);
380 | mSeedEdited = false;
381 | //setupCache(3);
382 | //setZoom();
383 |
384 | if (mTerritoryGenCheckBox.isSelected()) {
385 | mPoliticalMapCheckBox.setDisable(false);
386 | } else {
387 | mPoliticalMapCheckBox.setDisable(true);
388 | }
389 |
390 | setZoom();
391 | }
392 | });
393 | }
394 |
395 | // Cache n maps to be generated in a background thread
396 | /*private void setupCache(int n) {
397 |
398 | verifyFields();
399 |
400 | // run map generation cache in a background thread
401 | ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
402 | MapTask mapTask = new MapTask();
403 | executor.execute(mapTask);
404 |
405 | mapTask.addEventHandler(WorkerStateEvent.WORKER_STATE_SUCCEEDED,
406 | new EventHandler() {
407 | @Override
408 | public void handle(WorkerStateEvent event) {
409 | mMapImageCache.add(mapTask.getValue());
410 | if (n - 1 > 0) {
411 | setupCache(n - 1);
412 | }
413 | }
414 | });
415 | }*/
416 |
417 | private void verifyFields() {
418 | if (!mWidthTextField.getText().matches("^-?\\d+$")) {
419 | mWidthTextField.setText(String.valueOf(WIDTH));
420 | }
421 | if (!mHeightTextField.getText().matches("^-?\\d+$")) {
422 | mHeightTextField.setText(String.valueOf(HEIGHT));
423 | }
424 | if (!isDouble(mPersistenceField.getText())) {
425 | mPersistenceField.setText(String.valueOf(PERSISTENCE));
426 | }
427 | if (!mOctavesField.getText().matches("^-?\\d+$")) { // if not integer
428 | mOctavesField.setText(String.valueOf(OCTAVES));
429 | }
430 | if (!isDouble(mLandGenTextField.getText())) {
431 | mLandGenTextField.setText(String.valueOf(LANDGEN));
432 | }
433 | if (!isDouble(mHillGenTextField.getText())) {
434 | mHillGenTextField.setText(String.valueOf(HILLGEN));
435 | }
436 | if (!isDouble(mMountainGenTextField.getText())) {
437 | mMountainGenTextField.setText(String.valueOf(MOUNTAINGEN));
438 | }
439 | if (!mCityGenTextField.getText().matches("^-?\\d+$")) {
440 | mCityGenTextField.setText(String.valueOf(CITYGEN));
441 | }
442 | mPoliticalMapCheckBox.setSelected(false);
443 | }
444 |
445 | private double determineSeed() {
446 | double seed;
447 | String seedField = mSeedField.getText();
448 | if (!seedField.isEmpty() && isDouble(seedField) && mSeedEdited) {
449 | seed = Double.parseDouble(seedField);
450 | } else {
451 | seed = Math.random();
452 | mSeedField.setText(String.valueOf(seed));
453 | }
454 | return seed;
455 | }
456 |
457 | private boolean isDouble(String str) {
458 | try {
459 | Double.parseDouble(str);
460 | return true;
461 | } catch (NumberFormatException nfe) {
462 | return false;
463 | }
464 | }
465 |
466 | private class MapTask extends Task {
467 |
468 | private PerlinMap map;
469 |
470 | MapTask() {
471 | this.map = new PerlinMap(Integer.parseInt(mWidthTextField.getText()),
472 | Integer.parseInt(mHeightTextField.getText()),
473 | determineSeed(),
474 | Math.random(),
475 | Double.parseDouble(mLandGenTextField.getText()),
476 | WATERGEN,
477 | Double.parseDouble(mMountainGenTextField.getText()),
478 | Double.parseDouble(mHillGenTextField.getText()),
479 | BEACHGEN,
480 | FORESTGEN,
481 | Integer.parseInt(mCityGenTextField.getText()),
482 | Double.parseDouble(mPersistenceField.getText()),
483 | Integer.parseInt(mOctavesField.getText()),
484 | mLandGenCheckBox.isSelected(),
485 | mHillGenCheckBox.isSelected(),
486 | mMountainGenCheckBox.isSelected(),
487 | mRiverGenCheckBox.isSelected(),
488 | mCityGenCheckBox.isSelected(),
489 | mNameGenCheckBox.isSelected(),
490 | mContinentGenCheckBox.isSelected(),
491 | mTerritoryGenCheckBox.isSelected(),
492 | mBiomeGenCheckBox.isSelected());
493 | }
494 |
495 | @Override
496 | protected ImageView call() {
497 | try {
498 | mImageManager = new ImageManager(map, mGridCheckBox.isSelected());
499 | mFantasyImageManager = new FantasyImageManager(map);
500 | mImageManager.generateImage();
501 | mFantasyImageManager.generate();
502 | mTerrainImage = mImageManager.getImage();
503 | mFantasyImage = mFantasyImageManager.getImage();
504 | ImageView imageView = new ImageView();
505 | imageView.setImage(SwingFXUtils.toFXImage(mTerrainImage, null));
506 | imageView.setId("mapImage");
507 | return imageView;
508 | } catch (Exception e) {
509 | Logger.getLogger(TAG).log(Level.SEVERE, "test", e);
510 | }
511 | return null;
512 | }
513 | }
514 | }
515 |
--------------------------------------------------------------------------------
/src/image/FantasyImageManager.java:
--------------------------------------------------------------------------------
1 | package image;
2 |
3 | import map.PerlinMap;
4 | import metrics.Metric;
5 | import metrics.MetricKey;
6 | import model.LocationType;
7 | import model.Point;
8 | import model.Terrain;
9 | import model.TerrainType;
10 |
11 | import java.awt.*;
12 | import java.awt.image.BufferedImage;
13 | import java.util.ArrayList;
14 | import java.util.LinkedList;
15 | import java.util.List;
16 | import java.util.Set;
17 |
18 | public class FantasyImageManager {
19 |
20 | private static final String TAG = FantasyImageManager.class.getSimpleName();
21 |
22 | private PerlinMap mMap;
23 |
24 | private BufferedImage mImage;
25 |
26 | private List mMountains;
27 |
28 | public FantasyImageManager(PerlinMap map) {
29 | mMap = map;
30 | mImage = new BufferedImage(mMap.getWidth(), mMap.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
31 | mMountains = new ArrayList<>();
32 | }
33 |
34 | public void generate() {
35 | colorMap();
36 | }
37 |
38 | public BufferedImage getImage() {
39 | return mImage;
40 | }
41 |
42 | protected void colorMap() {
43 | Metric.start(MetricKey.FANTASYCOLORMAP);
44 | mImage.getGraphics().fillRect(0, 0, mImage.getWidth(), mImage.getHeight());
45 | for (int y = 0; y < mMap.getHeight(); y++) {
46 | for (int x = 0; x < mMap.getWidth(); x++) {
47 | Terrain terrain = mMap.getTerrain(x, y);
48 | colorByTerrain(terrain);
49 | }
50 | }
51 | colorCities();
52 | colorNames();
53 | Metric.record(MetricKey.FANTASYCOLORMAP);
54 | }
55 |
56 | private void colorCities() {
57 | if (!mMap.isCitiesEnabled()) {
58 | return;
59 | }
60 |
61 | for (int y = 0; y < mMap.getHeight(); y++) {
62 | for (int x = 0; x < mMap.getWidth(); x++) {
63 | Terrain terrain = mMap.getTerrain(x, y);
64 | if (terrain.getLocationType().equals(LocationType.CITY)) {
65 | Graphics graphics = mImage.getGraphics();
66 | graphics.setColor(Color.black);
67 | graphics.fillOval(x - 8/2, y - 8/2, 8, 8);
68 | }
69 | }
70 | }
71 | }
72 |
73 | private void colorNames() {
74 | if (!mMap.isNamesEnabled()) {
75 | return;
76 | }
77 |
78 | Graphics graphics = mImage.getGraphics();
79 | graphics.setFont(new Font("Mercury", Font.BOLD, 14)); //Papyrus, Plantin
80 | for (int y = 0; y < mMap.getHeight(); y++) {
81 | for (int x = 0; x < mMap.getWidth(); x++) {
82 | Terrain terrain = mMap.getTerrain(x, y);
83 | if (terrain.getLocationType().equals(LocationType.CITY)) {
84 | graphics.setColor(Color.black);
85 | graphics.drawString(terrain.getLocation().getName(), x - 8 * 4, y - 8);
86 | }
87 | }
88 | }
89 | }
90 |
91 | private void colorByTerrain(Terrain terrain) {
92 |
93 | if (terrain.getTerrainType().equals(TerrainType.LAND)) {
94 | Set adjacentTerrain = mMap.getNoise().getGrid().getAdjacentTerrainTypes(terrain, 1);
95 | if (adjacentTerrain.contains(TerrainType.BEACH) || adjacentTerrain.contains(TerrainType.WATER)) {
96 | mImage.setRGB(terrain.getX(), terrain.getY(), Color.black.getRGB());
97 | }
98 | } else if (terrain.getTerrainType().equals(TerrainType.RIVER)) {
99 | Set adjacentTerrain = mMap.getNoise().getGrid().getAdjacentTerrainTypes(terrain, 1);
100 | if (adjacentTerrain.contains(TerrainType.LAND)) {
101 | mImage.setRGB(terrain.getX(), terrain.getY(), Color.black.getRGB());
102 | } else {
103 | // Make water transparent
104 | mImage.setRGB(terrain.getX(), terrain.getY(), 0);
105 | }
106 | } else if (terrain.getTerrainType().equals(TerrainType.HILL)) {
107 | if (Math.random() < 0.2) {
108 | for (Point mountain : mMountains) {
109 | if (distance(terrain.getX(), terrain.getY(), mountain.getX(), mountain.getY()) <= 20) {
110 | return;
111 | }
112 | }
113 | drawHill(terrain.getX(), terrain.getY());
114 | mMountains.add(terrain);
115 | }
116 | } else if (terrain.getTerrainType().equals(TerrainType.MOUNTAIN)) {
117 | if (Math.random() < 0.2) {
118 | for (Point mountain : mMountains) {
119 | if (distance(terrain.getX(), terrain.getY(), mountain.getX(), mountain.getY()) <= 20) {
120 | return;
121 | }
122 | }
123 | drawMountain(terrain.getX(), terrain.getY());
124 | mMountains.add(terrain);
125 | }
126 | } else {
127 | // Make water transparent
128 | mImage.setRGB(terrain.getX(), terrain.getY(), 0);
129 | }
130 | }
131 |
132 | private double distance(int x1, int y1, int x2, int y2) {
133 | return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
134 | }
135 |
136 | private void drawHill(int x, int y) {
137 | Graphics graphics = mImage.getGraphics();
138 | graphics.setColor(Color.black);
139 |
140 | List points = new LinkedList<>();
141 | points.add(new Point(x, y));
142 | points.add(new Point(x, y - 3));
143 | points.add(new Point(x + 3, y - 6));
144 | points.add(new Point(x + 8, y - 6));
145 | points.add(new Point(x + 11, y - 3));
146 | points.add(new Point(x + 11, y));
147 |
148 | for (Point point : points) {
149 | point.setY(point.getY() + (int) ((Math.random() - 0.5) * 3));
150 | }
151 |
152 | Point currPoint = points.remove(0);
153 | Point oldPoint = currPoint;
154 | while (!points.isEmpty()) {
155 | currPoint = points.remove(0);
156 | graphics.drawLine(oldPoint.getX(), oldPoint.getY(), currPoint.getX(), currPoint.getY());
157 | oldPoint = currPoint;
158 | }
159 | }
160 |
161 | private void drawMountain(int x, int y) {
162 |
163 | Graphics graphics = mImage.getGraphics();
164 | graphics.setColor(Color.black);
165 |
166 | List points = new LinkedList<>();
167 | points.add(new Point(x, y));
168 | points.add(new Point(x += 4, y -= 4));
169 | points.add(new Point(x += 4, y -= 4));
170 | points.add(new Point(x += 4, y -= 4));
171 |
172 | points.add(new Point(x += 4, y += 4));
173 | points.add(new Point(x += 4, y += 4));
174 | points.add(new Point(x += 4, y += 4));
175 |
176 |
177 | for (Point point : points) {
178 | point.setY(point.getY() + (int) ((Math.random() - 0.5) * 10));
179 | }
180 |
181 | Point currPoint = points.remove(0);
182 | Point oldPoint = currPoint;
183 | while (!points.isEmpty()) {
184 | currPoint = points.remove(0);
185 | graphics.drawLine(oldPoint.getX(), oldPoint.getY(), currPoint.getX(), currPoint.getY());
186 | oldPoint = currPoint;
187 | }
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/src/image/HeatmapImageManager.java:
--------------------------------------------------------------------------------
1 | package image;
2 |
3 | import map.PerlinMap;
4 | import model.Terrain;
5 |
6 | import java.awt.*;
7 |
8 | public class HeatmapImageManager extends ImageManager {
9 |
10 | double min, max;
11 |
12 | public HeatmapImageManager(PerlinMap map) {
13 | super(map, false);
14 | }
15 |
16 | @Override
17 | public void colorTerrain() {
18 |
19 | colorHumidity();
20 | //colorTemperature();
21 |
22 | for (int y = 0; y < mMap.getHeight(); y++) {
23 | for (int x = 0; x < mMap.getWidth(); x++) {
24 |
25 | switch (mMap.getTerrain(x, y).getTerrainType()) {
26 | case WATER:
27 | case RIVER:
28 | case RIVER_BANK:
29 | mImage.setRGB(x, y, Color.white.getRGB());
30 | }
31 |
32 | mImage.setRGB(x, y, mixColorsWithAlpha(
33 | getColorByTerrain(mMap.getTerrain(x, y)),
34 | super.getColorByTerrain(mMap.getTerrain(x, y)), 0).getRGB());
35 | }
36 | }
37 | }
38 |
39 | private void colorHumidity() {
40 | min = mMap.getTerrain(0, 0).getHumidity();
41 | max = mMap.getTerrain(0, 0).getHumidity();
42 |
43 | for (int y = 0; y < mMap.getHeight(); y++) {
44 | for (int x = 0; x < mMap.getWidth(); x++) {
45 |
46 |
47 | switch (mMap.getTerrain(x, y).getTerrainType()) {
48 | case WATER:
49 | case RIVER:
50 | case RIVER_BANK:
51 | continue;
52 | }
53 |
54 | if (mMap.getTerrain(x, y).getHumidity() < min)
55 | min = mMap.getTerrain(x, y).getHumidity();
56 | if (mMap.getTerrain(x, y).getHumidity() > max)
57 | max = mMap.getTerrain(x, y).getHumidity();
58 | }
59 | }
60 | }
61 |
62 | private void colorTemperature() {
63 | min = mMap.getTerrain(0, 0).getTemperature();
64 | max = mMap.getTerrain(0, 0).getTemperature();
65 |
66 | for (int y = 0; y < mMap.getHeight(); y++) {
67 | for (int x = 0; x < mMap.getWidth(); x++) {
68 | if (mMap.getTerrain(x, y).getTemperature() < min)
69 | min = mMap.getTerrain(x, y).getTemperature();
70 | if (mMap.getTerrain(x, y).getTemperature() > max)
71 | max = mMap.getTerrain(x, y).getTemperature();
72 | }
73 | }
74 | }
75 |
76 | @Override
77 | protected Color getColorByTerrain(Terrain terrain) {
78 | return mixColorsWithAlpha(Color.blue, Color.red, normalize(terrain.getHumidity()));
79 | }
80 |
81 | private int normalize(double value) {
82 | final double MIN = 0.0;
83 | final double MAX = 255.0;
84 |
85 | return (int) ((MAX - MIN) / (max - min) * (value - min) + MIN);
86 |
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/image/RINGBEARER.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JelloRanger/MapGenerator/b6ad1b18340db05ba56bcd332a5fdc4fc0368343/src/image/RINGBEARER.TTF
--------------------------------------------------------------------------------
/src/image/ZoomManager.java:
--------------------------------------------------------------------------------
1 | package image;
2 |
3 | import javafx.beans.property.ObjectProperty;
4 | import javafx.beans.property.SimpleObjectProperty;
5 | import javafx.embed.swing.SwingFXUtils;
6 | import javafx.geometry.Point2D;
7 | import javafx.scene.image.ImageView;
8 | import javafx.scene.image.WritableImage;
9 | import javafx.scene.input.ScrollEvent;
10 | import javafx.scene.layout.AnchorPane;
11 |
12 | import java.awt.image.BufferedImage;
13 |
14 | public class ZoomManager {
15 |
16 | private BufferedImage mImage;
17 |
18 | private ImageView mImageView;
19 |
20 | private AnchorPane mAnchorPane;
21 |
22 | private boolean mousePressed = false;
23 |
24 | private double lastX;
25 |
26 | private double lastY;
27 |
28 | public ZoomManager(BufferedImage image, AnchorPane pane) {
29 | mImage = image;
30 | mAnchorPane = pane;
31 | WritableImage writableImage = new WritableImage(mImage.getWidth(), mImage.getHeight());
32 | writableImage = SwingFXUtils.toFXImage(mImage, writableImage);
33 | mImageView = new ImageView(writableImage);
34 | }
35 |
36 | public ImageView startZoom() {
37 |
38 | ObjectProperty mouseDown = new SimpleObjectProperty<>();
39 |
40 | mAnchorPane.setOnMousePressed(e -> {
41 | mousePressed = true;
42 | lastX = e.getX();
43 | lastY = e.getY();
44 | });
45 |
46 | mAnchorPane.setOnMouseReleased(e -> {
47 | mousePressed = false;
48 | });
49 |
50 | mAnchorPane.setOnMouseDragged(e -> {
51 | if (mousePressed) {
52 | double x = e.getX();
53 | double y = e.getY();
54 |
55 | double deltaX = x - lastX;
56 | double deltaY = y - lastY;
57 | mImageView.setTranslateX(mImageView.getTranslateX() + deltaX);
58 | mImageView.setTranslateY(mImageView.getTranslateY() + deltaY);
59 |
60 | lastX = x;
61 | lastY = y;
62 | }
63 | });
64 |
65 | mAnchorPane.addEventHandler(ScrollEvent.ANY, e -> {
66 | double deltaY = e.getDeltaY();
67 | double scale = 1;
68 | double screenX = e.getX();
69 | double screenY = e.getY();
70 | double width = mImageView.getLayoutBounds().getWidth();
71 | double height = mImageView.getLayoutBounds().getHeight();
72 | double imageX = (screenX - mImageView.getTranslateX() - width / 2) / mImageView.getScaleX() + width / 2;
73 | double imageY = (screenY - mImageView.getTranslateY() - height / 2) / mImageView.getScaleY() + height / 2;
74 |
75 | // Zoom based on scroll direction
76 | if (deltaY < 0) {
77 | scale = mImageView.getScaleX() * (0.9 + 0.1 * Math.exp(deltaY));
78 | mImageView.setScaleX(scale);
79 | mImageView.setScaleY(scale);
80 | } else if (deltaY > 0) {
81 | scale = mImageView.getScaleX() * (1.1 + 0.1 * Math.exp(-deltaY));
82 | mImageView.setScaleX(scale);
83 | mImageView.setScaleY(scale);
84 | }
85 |
86 | // Move imageview such that the zoom is centered on the mouse cursor
87 | double newTranslateX = screenX - (imageX - width / 2) * scale - width / 2;
88 | double newTranslateY = screenY - (imageY - height / 2) * scale - height / 2;
89 | mImageView.setTranslateX(newTranslateX);
90 | mImageView.setTranslateY(newTranslateY);
91 |
92 | });
93 |
94 | return mImageView;
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/src/map/Map.java:
--------------------------------------------------------------------------------
1 | package map;
2 | import model.Terrain;
3 | import noise.Noise;
4 |
5 | public abstract class Map {
6 |
7 | protected int mWidth;
8 |
9 | protected int mHeight;
10 |
11 | protected double mSeed;
12 |
13 | protected double mSeedForest;
14 |
15 | protected double mLandGen;
16 |
17 | protected double mWaterGen;
18 |
19 | protected double mMountainGen;
20 |
21 | protected double mHillGen;
22 |
23 | protected double mBeachGen;
24 |
25 | protected double mForestGen;
26 |
27 | protected int mCityGen;
28 |
29 | protected Noise mNoise;
30 |
31 | protected Noise mForestNoise;
32 |
33 | protected boolean mLandEnabled = true;
34 |
35 | protected boolean mHillsEnabled = true;
36 |
37 | protected boolean mMountainsEnabled = true;
38 |
39 | protected boolean mRiversEnabled = true;
40 |
41 | protected boolean mCitiesEnabled = true;
42 |
43 | protected boolean mNamesEnabled = true;
44 |
45 | protected boolean mContinentsEnabled = true;
46 |
47 | protected boolean mTerritoriesEnabled = true;
48 |
49 | protected boolean mBiomesEnabled = true;
50 |
51 | public abstract void generateMap();
52 |
53 | public int getWidth() {
54 | return mWidth;
55 | }
56 |
57 | public int getHeight() {
58 | return mHeight;
59 | }
60 |
61 | public Noise getNoise() {
62 | return mNoise;
63 | }
64 |
65 | public double getSeed() {
66 | return mSeed;
67 | }
68 |
69 | public double getSeedForest() {
70 | return mSeedForest;
71 | }
72 |
73 | public double getLandGen() {
74 | return mLandGen;
75 | }
76 |
77 | public double getWaterGen() {
78 | return mWaterGen;
79 | }
80 |
81 | public double getMountainGen() {
82 | return mMountainGen;
83 | }
84 |
85 | public double getHillGen() {
86 | return mHillGen;
87 | }
88 |
89 | public double getBeachGen() {
90 | return mBeachGen;
91 | }
92 |
93 | public double getForestGen() {
94 | return mForestGen;
95 | }
96 |
97 | public int getCityGen() {
98 | return mCityGen;
99 | }
100 |
101 | public Noise getForestNoise() {
102 | return mForestNoise;
103 | }
104 |
105 | public boolean isContinentsEnabled() {
106 | return mContinentsEnabled;
107 | }
108 |
109 | public boolean isLandEnabled() {
110 | return mLandEnabled;
111 | }
112 |
113 | public boolean isHillsEnabled() {
114 | return mHillsEnabled;
115 | }
116 |
117 | public boolean isMountainsEnabled() {
118 | return mMountainsEnabled;
119 | }
120 |
121 | public boolean isRiversEnabled() {
122 | return mRiversEnabled;
123 | }
124 |
125 | public boolean isCitiesEnabled() {
126 | return mCitiesEnabled;
127 | }
128 |
129 | public boolean isNamesEnabled() {
130 | return mNamesEnabled;
131 | }
132 |
133 | public boolean isTerritoriesEnabled() {
134 | return mTerritoriesEnabled;
135 | }
136 |
137 | public boolean isBiomesEnabled() {
138 | return mBiomesEnabled;
139 | }
140 |
141 | public abstract Terrain getTerrain(int x, int y);
142 |
143 | protected abstract Terrain determineTerrainTypeBasedOnElevation(Terrain terrain, double elevation);
144 |
145 | }
146 |
--------------------------------------------------------------------------------
/src/map/PerlinMap.java:
--------------------------------------------------------------------------------
1 | package map;
2 |
3 | import metrics.Metric;
4 | import metrics.MetricKey;
5 | import model.LocationType;
6 | import model.Terrain;
7 | import model.TerrainType;
8 | import noise.PerlinNoise;
9 | import procedural.*;
10 |
11 | public class PerlinMap extends RandomMap {
12 |
13 | protected Double mPersistence;
14 |
15 | protected Integer mOctaves;
16 |
17 | public PerlinMap(int width,
18 | int height,
19 | double seed,
20 | double seedForest,
21 | double landGen,
22 | double waterGen,
23 | double mountainGen,
24 | double hillGen,
25 | double beachGen,
26 | double forestGen,
27 | int cityGen) {
28 | super(width, height, seed, seedForest, landGen, waterGen, mountainGen, hillGen, beachGen, forestGen, cityGen);
29 | }
30 |
31 | public PerlinMap(int width,
32 | int height,
33 | double seed,
34 | double seedForest,
35 | double landGen,
36 | double waterGen,
37 | double mountainGen,
38 | double hillGen,
39 | double beachGen,
40 | double forestGen,
41 | int cityGen,
42 | double persistence,
43 | int octaves,
44 | boolean landEnabled,
45 | boolean hillsEnabled,
46 | boolean mountainsEnabled,
47 | boolean riversEnabled,
48 | boolean citiesEnabled,
49 | boolean namesEnabled,
50 | boolean continentsEnabled,
51 | boolean territoriesEnabled,
52 | boolean biomesEnabled) {
53 | super(width, height, seed, seedForest, landGen, waterGen, mountainGen, hillGen, beachGen, forestGen, cityGen);
54 | mPersistence = persistence;
55 | mOctaves = octaves;
56 | mLandEnabled = landEnabled;
57 | mHillsEnabled = hillsEnabled;
58 | mMountainsEnabled = mountainsEnabled;
59 | mRiversEnabled = riversEnabled;
60 | mCitiesEnabled = citiesEnabled;
61 | mNamesEnabled = namesEnabled;
62 | mContinentsEnabled = continentsEnabled;
63 | mTerritoriesEnabled = territoriesEnabled;
64 | mBiomesEnabled = biomesEnabled;
65 | }
66 |
67 | @Override
68 | public void generateMap() {
69 | mNoise = new PerlinNoise(mWidth, mHeight, mSeed, mPersistence, mOctaves);
70 | mNoise.initializeMapGrid();
71 |
72 | if (mContinentsEnabled) {
73 | generateContinents();
74 | }
75 |
76 | //generateForests();
77 |
78 | for (int y = 0; y < mHeight; y++) {
79 | for (int x = 0; x < mWidth; x++) {
80 | getTerrain(x, y).setLocationType(LocationType.EMPTY);
81 | }
82 | }
83 |
84 | if (mRiversEnabled) {
85 | generateLakesAndRivers();
86 | }
87 |
88 | // We need to generate cities if territories are enabled since
89 | // they're used to create territory starting points
90 | if (mCitiesEnabled || mTerritoriesEnabled) {
91 | generateCities();
92 | }
93 |
94 | if (mCitiesEnabled && mNamesEnabled) {
95 | generateNames();
96 | }
97 |
98 | if (mCitiesEnabled && mTerritoriesEnabled) {
99 | generateTerritories();
100 | }
101 |
102 | if (mBiomesEnabled) {
103 | generateBiomes();
104 | }
105 | }
106 |
107 | @Override
108 | public Terrain getTerrain(int x, int y) {
109 | Terrain terrain = (Terrain) mNoise.getGrid().getPoint(x, y);
110 |
111 | TerrainType terrainType = terrain.getTerrainType();
112 | if (terrainType == null) {
113 | if (mForestNoise != null && mForestNoise.getGrid().getPoint(x, y).getElevation() >= mForestGen &&
114 | determineTerrainTypeBasedOnElevation(terrain, terrain.getElevation()).getTerrainType()
115 | == TerrainType.LAND) {
116 | terrain.setTerrainType(TerrainType.FOREST);
117 | } else {
118 | return determineTerrainTypeBasedOnElevation(terrain, terrain.getElevation());
119 | }
120 | }
121 |
122 | return terrain;
123 | }
124 |
125 | protected void generateForests() {
126 | mForestNoise = new PerlinNoise(mWidth, mHeight, mSeedForest, mPersistence, 6);
127 | mForestNoise.initializeMapGrid();
128 | }
129 |
130 | protected void generateTemperature() {
131 | TemperatureGeneration temperatureGeneration = new TemperatureGeneration(this);
132 | temperatureGeneration.generate();
133 | }
134 |
135 | protected void generateHumidity() {
136 | HumidityGeneration humidityGeneration = new HumidityGeneration(this);
137 | humidityGeneration.generate();
138 | }
139 |
140 | protected void generateBiomes() {
141 | BiomeGeneration biomeGeneration = new BiomeGeneration(this);
142 | biomeGeneration.generate();
143 | }
144 |
145 | protected void generateContinents() {
146 | Metric.start(MetricKey.CONTINENTGENERATION);
147 | ContinentGeneration continentGeneration = new ContinentGeneration(this);
148 | continentGeneration.generate();
149 | Metric.record(MetricKey.CONTINENTGENERATION);
150 | }
151 |
152 | protected void generateLakesAndRivers() {
153 | Metric.start(MetricKey.RIVERGENERATION);
154 | LakesAndRiversGeneration lakesAndRiversGeneration = new LakesAndRiversGeneration(this);
155 | lakesAndRiversGeneration.generate();
156 | Metric.record(MetricKey.RIVERGENERATION);
157 | }
158 |
159 | protected void generateCities() {
160 | Metric.start(MetricKey.CITYGENERATION);
161 | CityGeneration cityGeneration = new CityGeneration(this, mCityGen);
162 | cityGeneration.generate();
163 | Metric.record(MetricKey.CITYGENERATION);
164 | }
165 |
166 | protected void generateNames() {
167 | Metric.start(MetricKey.NAMEGENERATION);
168 | NameGeneration nameGeneration = new NameGeneration(this, mCityGen);
169 | nameGeneration.generate();
170 | Metric.record(MetricKey.NAMEGENERATION);
171 | }
172 |
173 | protected void generateTerritories() {
174 | Metric.start(MetricKey.TERRITORYGENERATION);
175 | TerritoryGeneration territoryGeneration = new TerritoryGeneration(this);
176 | territoryGeneration.generate();
177 | Metric.record(MetricKey.TERRITORYGENERATION);
178 | }
179 |
180 | public Double getPersistence() {
181 | return mPersistence;
182 | }
183 |
184 | public Integer getOctaves() {
185 | return mOctaves;
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/src/map/RandomMap.java:
--------------------------------------------------------------------------------
1 | package map;
2 |
3 | import model.Terrain;
4 | import model.TerrainType;
5 | import noise.RandomNoise;
6 |
7 | public class RandomMap extends Map {
8 |
9 | public RandomMap(int width,
10 | int height,
11 | double seed,
12 | double seedForest,
13 | double landGen,
14 | double waterGen,
15 | double mountainGen,
16 | double hillGen,
17 | double beachGen,
18 | double forestGen,
19 | int cityGen) {
20 |
21 | mWidth = width;
22 | mHeight = height;
23 | mSeed = seed;
24 | mSeedForest = seedForest;
25 | mLandGen = landGen;
26 | mWaterGen = waterGen;
27 | mMountainGen = mountainGen;
28 | mHillGen = hillGen;
29 | mBeachGen = beachGen;
30 | mForestGen = forestGen;
31 | mCityGen = cityGen;
32 | }
33 |
34 | @Override
35 | public void generateMap() {
36 | mNoise = new RandomNoise(mWidth, mHeight, mSeed);
37 | mNoise.initializeMapGrid();
38 | }
39 |
40 | @Override
41 | public Terrain getTerrain(int x, int y) {
42 | Terrain terrain = (Terrain) mNoise.getGrid().getPoint(x, y);
43 |
44 | if (terrain.getTerrainType() == null) {
45 | return determineTerrainTypeBasedOnElevation(terrain, terrain.getElevation());
46 | }
47 |
48 | return terrain;
49 | }
50 |
51 | @Override
52 | protected Terrain determineTerrainTypeBasedOnElevation(Terrain terrain, double elevation) {
53 | TerrainType terrainType;
54 |
55 | if (elevation >= mMountainGen && mMountainsEnabled) {
56 | terrainType = TerrainType.MOUNTAIN;
57 | } else if (elevation >= mHillGen && mHillsEnabled) {
58 | terrainType = TerrainType.HILL;
59 | } else if (elevation >= mLandGen && mLandEnabled) {
60 | terrainType = TerrainType.LAND;
61 | } else if (elevation >= mLandGen + mBeachGen) {
62 | terrainType = TerrainType.BEACH;
63 | } else {
64 | terrainType = TerrainType.WATER;
65 | }
66 |
67 | terrain.setTerrainType(terrainType);
68 |
69 | return terrain;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/map/RevisedSmoothMap.java:
--------------------------------------------------------------------------------
1 | package map;
2 |
3 |
4 | import noise.RevisedSmoothNoise;
5 |
6 | public class RevisedSmoothMap extends RandomMap {
7 |
8 | public RevisedSmoothMap(int width, int height, double seed, double seedForest, double landGen, double waterGen,
9 | double mountainGen, double hillGen, double beachGen, double forestGen, int cityGen) {
10 | super(width, height, seed, seedForest, landGen, waterGen, mountainGen, hillGen, beachGen, forestGen, cityGen);
11 | }
12 |
13 | @Override
14 | public void generateMap() {
15 | mNoise = new RevisedSmoothNoise(mWidth, mHeight, mSeed);
16 | mNoise.initializeMapGrid();
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/map/SmoothMap.java:
--------------------------------------------------------------------------------
1 | package map;
2 |
3 | import noise.SmoothNoise;
4 |
5 | public class SmoothMap extends RandomMap {
6 |
7 | protected int mDegrees;
8 |
9 | public SmoothMap(int width, int height, double seed, double seedForest, int degrees, double landGen,
10 | double waterGen, double mountainGen, double hillGen, double beachGen, double forestGen,
11 | int cityGen) {
12 | super(width, height, seed, seedForest, landGen, waterGen, mountainGen, hillGen, beachGen, forestGen, cityGen);
13 |
14 | mDegrees = degrees;
15 | }
16 |
17 | @Override
18 | public void generateMap() {
19 | mNoise = new SmoothNoise(mWidth, mHeight, mSeed, mDegrees);
20 | mNoise.initializeMapGrid();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/metrics/Metric.java:
--------------------------------------------------------------------------------
1 | package metrics;
2 |
3 | import java.util.EnumMap;
4 | import java.util.Map;
5 | import java.util.logging.Level;
6 | import java.util.logging.Logger;
7 |
8 | public class Metric {
9 |
10 | private static final String TAG = Metric.class.getSimpleName();
11 |
12 | private static Map metrics = new EnumMap<>(MetricKey.class);
13 |
14 | public static void start(MetricKey metricKey) {
15 | metrics.put(metricKey, System.currentTimeMillis());
16 | }
17 |
18 | public static void record(MetricKey metricKey) {
19 | if (!metrics.containsKey(metricKey)) {
20 | Logger.getLogger(TAG).log(Level.WARNING, "Metric " + metricKey.name() + " not started.");
21 | return;
22 | }
23 |
24 | long difference = System.currentTimeMillis() - metrics.get(metricKey);
25 | Logger.getLogger(TAG).log(Level.INFO, metricKey.name() + ": " + (double) difference / 1000 + " seconds");
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/metrics/MetricKey.java:
--------------------------------------------------------------------------------
1 | package metrics;
2 |
3 | public enum MetricKey {
4 |
5 | NOISEGENERATION,
6 | CONTINENTGENERATION,
7 | RIVERGENERATION,
8 | CITYGENERATION,
9 | NAMEGENERATION,
10 | TERRITORYGENERATION,
11 | TEMPERATUREGENERATION,
12 | HUMIDITYGENERATION,
13 | SHADEMAP,
14 | FANTASYCOLORMAP
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/model/BiomeType.java:
--------------------------------------------------------------------------------
1 | package model;
2 |
3 | public enum BiomeType {
4 |
5 | TROPICALRAINFOREST,
6 | SAVANNA,
7 | SUBTROPICALDESERT,
8 | TEMPERATERAINFOREST,
9 | TEMPERATESEASONALFOREST,
10 | SHRUBLAND,
11 | COLDDESERT,
12 | BOREALFOREST,
13 | TUNDRA;
14 |
15 | /*public static BiomeType getBiomeTypeByTempAndHumidity(double temperature, double humidity) {
16 | if (temperature > 0.75) {
17 | if (humidity > 0.66) {
18 | return TROPICALRAINFOREST;
19 | } else if (humidity > 0.3) {
20 | return SAVANNA;
21 | } else {
22 | return SUBTROPICALDESERT;
23 | }
24 | } else if (temperature > 0.5) {
25 | if (humidity > 0.25) {
26 | return TEMPERATERAINFOREST;
27 | } else if (humidity > 0.125) {
28 | return TEMPERATESEASONALFOREST;
29 | } else if (humidity > 0.0625) {
30 | return SHRUBLAND;
31 | } else {
32 | return COLDDESERT;
33 | }
34 | } else if (temperature > 0.25) {
35 | if (humidity > 0.125) {
36 | return BOREALFOREST;
37 | } else if (humidity > 0.9) {
38 | return SHRUBLAND;
39 | } else {
40 | return COLDDESERT;
41 | }
42 | } else {
43 | return TUNDRA;
44 | }
45 | }*/
46 |
47 | public static BiomeType getBiomeTypeByTempAndHumidity(double temperature, double humidity) {
48 | if (temperature > 0.65) {
49 | if (humidity > 0.5) {
50 | return TROPICALRAINFOREST;
51 | } else if (humidity > 0.25) {
52 | return SAVANNA;
53 | } else {
54 | return SUBTROPICALDESERT;
55 | }
56 | } else if (temperature > 0.25) {
57 | if (humidity > 0.5) {
58 | return TEMPERATERAINFOREST;
59 | } else if (humidity > 0.25) {
60 | return SHRUBLAND;
61 | } else {
62 | return COLDDESERT;
63 | }
64 | } else if (temperature > 0.125) {
65 | return BOREALFOREST;
66 | } else {
67 | return TUNDRA;
68 | }
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/src/model/City.java:
--------------------------------------------------------------------------------
1 | package model;
2 |
3 | public class City extends Location {
4 |
5 | public City() {
6 | super();
7 | }
8 |
9 | public City(String name) {
10 | super(name);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/model/Direction.java:
--------------------------------------------------------------------------------
1 | package model;
2 |
3 | public enum Direction {
4 | NORTH,
5 | NORTHEAST,
6 | EAST,
7 | SOUTHEAST,
8 | SOUTH,
9 | SOUTHWEST,
10 | WEST,
11 | NORTHWEST
12 | }
13 |
--------------------------------------------------------------------------------
/src/model/Grid.java:
--------------------------------------------------------------------------------
1 | package model;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashSet;
5 | import java.util.List;
6 | import java.util.Set;
7 |
8 | public class Grid {
9 |
10 | protected int width;
11 |
12 | protected int height;
13 |
14 | protected List> grid;
15 |
16 | public Grid(int width, int height) {
17 | this.width = width;
18 | this.height = height;
19 | }
20 |
21 | public void initializeGrid() {
22 |
23 | grid = new ArrayList<>();
24 |
25 | for (int y = 0; y < height; y++) {
26 | grid.add(new ArrayList<>());
27 | for (int x = 0; x < width; x++) {
28 | grid.get(y).add(new Point(x, y));
29 | }
30 | }
31 | }
32 |
33 | public void initializeGridWithTerrain() {
34 |
35 | grid = new ArrayList<>();
36 |
37 | for (int y = 0; y < height; y++) {
38 | grid.add(new ArrayList<>());
39 | for (int x = 0; x < width; x++) {
40 | grid.get(y).add(new Terrain(x, y));
41 | }
42 | }
43 | }
44 |
45 | public List> getGrid() {
46 | return grid;
47 | }
48 |
49 | public Point getPoint(int x, int y) {
50 | return grid.get(y).get(x);
51 | }
52 |
53 | public List getAdjacentPoints(Point point, int degrees) {
54 | return getAdjacentPoints(point.getX(), point.getY(), degrees);
55 | }
56 |
57 | public List getAdjacentPoints(int x, int y, int degrees) {
58 | List adjacentPoints = new ArrayList<>();
59 |
60 | for (int dy = degrees * -1; dy <= degrees; dy++) {
61 | for (int dx = degrees * -1; dx <= degrees; dx++) {
62 | if ((dx != 0 || dy != 0) &&
63 | x + dx >= 0 && x + dx < width &&
64 | y + dy >= 0 && y + dy < height) {
65 | adjacentPoints.add(grid.get(y + dy).get(x + dx));
66 | }
67 | }
68 | }
69 |
70 | return adjacentPoints;
71 | }
72 |
73 | public Set getAdjacentTerrainTypes(Terrain terrain, int degrees) {
74 | Set adjacentTerrain = new HashSet<>();
75 | int x = terrain.getX();
76 | int y = terrain.getY();
77 |
78 | for (int dy = degrees * -1; dy <= degrees; dy++) {
79 | for (int dx = degrees * -1; dx <= degrees; dx++) {
80 | if ((dx != 0 || dy != 0) &&
81 | x + dx >= 0 && x + dx < width &&
82 | y + dy >= 0 && y + dy < height) {
83 | adjacentTerrain.add(((Terrain) grid.get(y + dy).get(x + dx)).getTerrainType());
84 | }
85 | }
86 | }
87 |
88 | return adjacentTerrain;
89 | }
90 |
91 | public List getAdjacentTerrain(Terrain terrain, int degrees) {
92 | return getAdjacentTerrain(terrain.getX(), terrain.getY(), degrees);
93 | }
94 |
95 | public List getAdjacentTerrain(int x, int y, int degrees) {
96 | List adjacentTerrain = new ArrayList<>();
97 |
98 | for (int dy = degrees * -1; dy <= degrees; dy++) {
99 | for (int dx = degrees * -1; dx <= degrees; dx++) {
100 | if ((dx != 0 || dy != 0) &&
101 | x + dx >= 0 && x + dx < width &&
102 | y + dy >= 0 && y + dy < height) {
103 | adjacentTerrain.add((Terrain) grid.get(y + dy).get(x + dx));
104 | }
105 | }
106 | }
107 |
108 | return adjacentTerrain;
109 | }
110 |
111 | // direction is -1 for left, 1 for right
112 | public List getAdjacentTerrainByDirection(int x, int y, int degrees, int dir) {
113 | List adjacentTerrain = new ArrayList<>();
114 |
115 | // left
116 | if (dir == -1) {
117 | for (int dy = -15; dy <= 15; dy++) {
118 | for (int dx = degrees * -1; dx <= 0; dx++) {
119 | if ((dx != 0 || dy != 0) &&
120 | x + dx >= 0 && x + dx < width &&
121 | y + dy >= 0 && y + dy < height) {
122 | adjacentTerrain.add((Terrain) grid.get(y + dy).get(x + dx));
123 | }
124 | }
125 | }
126 | }
127 |
128 | else if (dir == 1) {
129 | for (int dy = -15; dy <= 15; dy++) {
130 | for (int dx = 0; dx <= degrees; dx++) {
131 | if ((dx != 0 || dy != 0) &&
132 | x + dx >= 0 && x + dx < width &&
133 | y + dy >= 0 && y + dy < height) {
134 | adjacentTerrain.add((Terrain) grid.get(y + dy).get(x + dx));
135 | }
136 | }
137 | }
138 | }
139 |
140 | return adjacentTerrain;
141 | }
142 |
143 | public List getAdjacentTerrainByDirAndStrength(int x, int y, int degrees, double strength) {
144 | List adjacentTerrain = new ArrayList<>();
145 |
146 | // left
147 | if (strength <= 0) {
148 |
149 | strength *= -1;
150 | int startPos = -1 * ((int) (strength * degrees + ((1 - strength) / 2 * degrees)));
151 | int endPos = startPos + degrees;
152 |
153 | for (int dy = -5; dy <= 5; dy++) {
154 | List adjacentTerrainForThisRow = new ArrayList<>();
155 | for (int dx = endPos; dx >= startPos; dx--) {
156 | if ((dx != 0 || dy != 0) &&
157 | x + dx >= 0 && x + dx < width &&
158 | y + dy >= 0 && y + dy < height) {
159 | if (((Terrain) grid.get(y + dy).get(x + dx)).getTerrainType().equals(TerrainType.MOUNTAIN) &&
160 | dx <= 0) {
161 | adjacentTerrainForThisRow.clear();
162 | continue;
163 | }
164 | adjacentTerrainForThisRow.add((Terrain) grid.get(y + dy).get(x + dx));
165 | }
166 | }
167 | adjacentTerrain.addAll(adjacentTerrainForThisRow);
168 | }
169 | }
170 |
171 | // right
172 | else if (strength > 0) {
173 |
174 | int endPos = ((int) (strength * degrees + ((1 - strength / 2 * degrees))));
175 | int startPos = endPos - degrees;
176 |
177 | for (int dy = -5; dy <= 5; dy++) {
178 | List adjacentTerrainForThisRow = new ArrayList<>();
179 | for (int dx = startPos; dx <= endPos; dx++) {
180 | if ((dx != 0 || dy != 0) &&
181 | x + dx >= 0 && x + dx < width &&
182 | y + dy >= 0 && y + dy < height) {
183 | if (((Terrain) grid.get(y + dy).get(x + dx)).getTerrainType().equals(TerrainType.MOUNTAIN) &&
184 | dx >= 0) {
185 | adjacentTerrainForThisRow.clear();
186 | continue;
187 | }
188 | adjacentTerrainForThisRow.add((Terrain) grid.get(y + dy).get(x + dx));
189 | }
190 | }
191 | adjacentTerrain.addAll(adjacentTerrainForThisRow);
192 | }
193 | }
194 |
195 | return adjacentTerrain;
196 | }
197 |
198 | public double getSlope(Point point) {
199 | return getSlope(point.getX(), point.getY());
200 | }
201 |
202 | public double getSlope(int x, int y) {
203 | if (x - 1 < 0 || y - 1 < 0) {
204 | return 0;
205 | }
206 |
207 | return grid.get(y - 1).get(x - 1).getElevation() - grid.get(y).get(x).getElevation();
208 | }
209 |
210 | public int getWidth() {
211 | return width;
212 | }
213 |
214 | public int getHeight() {
215 | return height;
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/src/model/Location.java:
--------------------------------------------------------------------------------
1 | package model;
2 |
3 | public class Location {
4 |
5 | protected String name;
6 |
7 | public Location() {}
8 |
9 | public Location(String name) {
10 | this.name = name;
11 | }
12 |
13 | public String getName() {
14 | return name;
15 | }
16 |
17 | public void setName(String name) {
18 | this.name = name;
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/model/LocationType.java:
--------------------------------------------------------------------------------
1 | package model;
2 |
3 | public enum LocationType {
4 | CITY,
5 | EMPTY
6 | }
7 |
--------------------------------------------------------------------------------
/src/model/Point.java:
--------------------------------------------------------------------------------
1 | package model;
2 |
3 | public class Point {
4 |
5 | private int x;
6 |
7 | private int y;
8 |
9 | protected double elevation;
10 |
11 | public Point(int x, int y) {
12 | this.x = x;
13 | this.y = y;
14 | }
15 |
16 | public Point(double elevation) {
17 | this.elevation = elevation;
18 | }
19 |
20 | public void setX(int x) {
21 | this.x = x;
22 | }
23 |
24 | public void setY(int y) {
25 | this.y = y;
26 | }
27 |
28 | public void setElevation(double elevation) {
29 | this.elevation = elevation;
30 | }
31 |
32 | public int getX() {
33 | return x;
34 | }
35 |
36 | public int getY() {
37 | return y;
38 | }
39 |
40 | public double getElevation() {
41 | return elevation;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/model/PointComparator.java:
--------------------------------------------------------------------------------
1 | package model;
2 |
3 | import java.util.Comparator;
4 |
5 | public class PointComparator implements Comparator {
6 |
7 | @Override
8 | public int compare(Point a, Point b) {
9 | if (a.getElevation() < b.getElevation()) {
10 | return -1;
11 | } else if (a.getElevation() > b.getElevation()) {
12 | return 1;
13 | }
14 | return 0;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/model/Terrain.java:
--------------------------------------------------------------------------------
1 | package model;
2 |
3 | public class Terrain extends Point {
4 |
5 | protected TerrainType terrainType;
6 |
7 | protected BiomeType biomeType;
8 |
9 | protected LocationType locationType;
10 |
11 | protected Location location;
12 |
13 | protected double score;
14 |
15 | protected int territory;
16 |
17 | protected double temperature;
18 |
19 | protected double humidity;
20 |
21 | public Terrain(int x, int y) {
22 | super(x, y);
23 | score = 0;
24 | territory = -1;
25 | }
26 |
27 | public void setTerrainType(TerrainType terrainType) {
28 | this.terrainType = terrainType;
29 | }
30 |
31 | public void setBiomeType(BiomeType biomeType) {
32 | this.biomeType = biomeType;
33 | }
34 |
35 | public void setLocationType(LocationType locationType) {
36 | this.locationType = locationType;
37 | }
38 |
39 | public void setLocation(Location location) {
40 | this.location = location;
41 | }
42 |
43 | public void setScore(double amt) {
44 | score = amt;
45 | }
46 |
47 | public void setTerritory(int num) {
48 | territory = num;
49 | }
50 |
51 | public void setTemperature(double temp) {
52 | temperature = temp;
53 | }
54 |
55 | public void setHumidity(double humidity) {
56 | this.humidity = humidity;
57 | }
58 |
59 | public TerrainType getTerrainType() {
60 | return terrainType;
61 | }
62 |
63 | public BiomeType getBiomeType() {
64 | return biomeType;
65 | }
66 |
67 | public LocationType getLocationType() {
68 | return locationType;
69 | }
70 |
71 | public Location getLocation() {
72 | return location;
73 | }
74 |
75 | public double getScore() {
76 | return score;
77 | }
78 |
79 | public int getTerritory() {
80 | return territory;
81 | }
82 |
83 | public double getTemperature() {
84 | return temperature;
85 | }
86 |
87 | public double getHumidity() {
88 | return humidity;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/model/TerrainType.java:
--------------------------------------------------------------------------------
1 | package model;
2 |
3 | public enum TerrainType {
4 |
5 | MOUNTAIN,
6 | HILL,
7 | FOREST,
8 | LAND,
9 | BEACH,
10 | RIVER,
11 | RIVER_BANK,
12 | WATER
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/src/noise/Noise.java:
--------------------------------------------------------------------------------
1 | package noise;
2 |
3 | import model.Grid;
4 |
5 | public abstract class Noise {
6 |
7 | protected int mWidth;
8 |
9 | protected int mHeight;
10 |
11 | protected Grid mGrid;
12 |
13 | protected double mSeed;
14 |
15 | public abstract void initializeNoiseGrid();
16 |
17 | public abstract void initializeMapGrid();
18 |
19 | protected abstract void genNoise();
20 |
21 | public int getWidth() {
22 | return mWidth;
23 | }
24 |
25 | public int getHeight() {
26 | return mHeight;
27 | }
28 |
29 | public Grid getGrid() {
30 | return mGrid;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/noise/PerlinNoise.java:
--------------------------------------------------------------------------------
1 | package noise;
2 |
3 | import metrics.Metric;
4 | import metrics.MetricKey;
5 | import model.Point;
6 |
7 | public class PerlinNoise extends RevisedSmoothNoise {
8 |
9 | protected double persistence;
10 |
11 | protected int octaves;
12 |
13 | //private final double ZOOM = 80;
14 |
15 | private final double ZOOM = 200;
16 |
17 | public PerlinNoise(int width, int height, double seed, double persistence, int octaves) {
18 | super(width, height, seed);
19 |
20 | this.persistence = persistence;
21 | this.octaves = octaves;
22 |
23 | }
24 |
25 | @Override
26 | public void initializeNoiseGrid() {
27 | super.initializeNoiseGrid();
28 |
29 | perlinElevation();
30 | }
31 |
32 | @Override
33 | public void initializeMapGrid() {
34 | Metric.start(MetricKey.NOISEGENERATION);
35 | super.initializeMapGrid();
36 |
37 | perlinElevation();
38 | Metric.record(MetricKey.NOISEGENERATION);
39 | }
40 |
41 | private void perlinElevation() {
42 | for (int y = 0; y < mHeight; y++) {
43 | for (int x = 0; x < mWidth; x++) {
44 | perlinPoint(mGrid.getPoint(x, y));
45 | }
46 | }
47 | }
48 |
49 | protected void perlinPoint(Point point) {
50 |
51 | double elevation = 0;
52 |
53 | for (int i = 0; i < octaves - 1; i++) {
54 | double frequency = Math.pow(2, i);
55 | double amplitude = Math.pow(persistence, i);
56 |
57 | elevation += interpolatedNoise2(point.getX() / ZOOM * frequency, point.getY() / ZOOM * frequency) * amplitude;
58 | }
59 |
60 | point.setElevation(elevation);
61 | }
62 |
63 |
64 | // DEPRECTED - Original perlin noise algorithm, suffers from square artifacting when shading
65 | private double interpolatedNoise(double x, double y) {
66 | int xCoord = (int) x;
67 | int yCoord = (int) y;
68 | double xFract = x - xCoord;
69 | double yFract = y - yCoord;
70 |
71 | double gradient1 = noise(xCoord, yCoord);
72 | double gradient2 = noise(xCoord + 1, yCoord);
73 | double gradient3 = noise(xCoord, yCoord + 1);
74 | double gradient4 = noise(xCoord + 1, yCoord + 1);
75 |
76 | double interpolation1 = linearInterpolate(gradient1, gradient2, xFract);
77 | double interpolation2 = linearInterpolate(gradient3, gradient4, xFract);
78 |
79 | return linearInterpolate(interpolation1, interpolation2, yFract);
80 | }
81 |
82 | // Improved perlin noise algorithm, solves the issue of square artifacts when shading
83 | private double interpolatedNoise2(double x, double y) {
84 | int xCoord = (int) x;
85 | int yCoord = (int) y;
86 | double xFract = x - xCoord;
87 | double yFract = y - yCoord;
88 |
89 | double u = fade(xFract);
90 | double v = fade(yFract);
91 |
92 | return linearInterpolate(
93 | linearInterpolate(noise(xCoord, yCoord), noise(xCoord + 1, yCoord), u),
94 | linearInterpolate(noise(xCoord, yCoord + 1), noise(xCoord + 1, yCoord + 1), u),
95 | v);
96 | }
97 |
98 | private double fade(double t) {
99 | return t * t * t * (t * (t * 6 - 15) + 10);
100 | }
101 |
102 | private double linearInterpolate(double a, double b, double x) {
103 | return a * (1 - x) + b * x;
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/src/noise/RandomNoise.java:
--------------------------------------------------------------------------------
1 | package noise;
2 |
3 | import java.util.List;
4 |
5 | import model.Grid;
6 | import model.Point;
7 |
8 | import static java.lang.Math.abs;
9 |
10 | public class RandomNoise extends Noise {
11 |
12 | public RandomNoise(int width, int height, double seed) {
13 | mWidth = width;
14 | mHeight = height;
15 | mSeed = seed;
16 | }
17 |
18 | @Override
19 | public void initializeNoiseGrid() {
20 | mGrid = new Grid(mWidth, mHeight);
21 | mGrid.initializeGrid();
22 | genNoise();
23 | }
24 |
25 | @Override
26 | public void initializeMapGrid() {
27 | mGrid = new Grid(mWidth, mHeight);
28 | mGrid.initializeGridWithTerrain();
29 | genNoise();
30 | }
31 |
32 | @Override
33 | protected void genNoise() {
34 | for (List row : mGrid.getGrid()) {
35 | for (Point point : row) {
36 | point.setElevation(noise(point.getX(), point.getY()));
37 | }
38 | }
39 | }
40 |
41 | // credit to http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
42 | protected double noise(int x, int y) {
43 | int n = x + y * 75326 + ((int) (mSeed * 15485867));
44 | n = (n<<13) ^ n;
45 |
46 | return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/noise/RevisedSmoothNoise.java:
--------------------------------------------------------------------------------
1 | package noise;
2 |
3 | import model.Point;
4 |
5 | public class RevisedSmoothNoise extends RandomNoise {
6 |
7 | public RevisedSmoothNoise(int width, int height, double seed) {
8 | super(width, height, seed);
9 | }
10 |
11 | @Override
12 | public void initializeNoiseGrid() {
13 | super.initializeNoiseGrid();
14 |
15 | smoothElevation();
16 | }
17 |
18 | @Override
19 | public void initializeMapGrid() {
20 | super.initializeMapGrid();
21 |
22 | //smoothElevation();
23 | }
24 |
25 | private void smoothElevation() {
26 | for (int y = 0; y < mHeight; y++) {
27 | for (int x = 0; x < mWidth; x++) {
28 | smoothPoint(mGrid.getPoint(x, y));
29 | }
30 | }
31 | }
32 |
33 | // Smooth a point by averaging its elevation with adjacent points, weighted
34 | private void smoothPoint(Point point) {
35 | int x = point.getX();
36 | int y = point.getY();
37 |
38 | point.setElevation(smoothNoise((double) x, (double) y));
39 | }
40 |
41 | protected double smoothNoise(double xDoub, double yDoub) {
42 |
43 | int x = (int) xDoub;
44 | int y = (int) yDoub;
45 |
46 | // weight edges at half
47 | double edgeNeighborElevations = noise(x - 1, y) +
48 | noise(x + 1, y) +
49 | noise(x, y - 1) +
50 | noise(x, y + 1);
51 |
52 | // weight corners at a quarter
53 | double cornerNeighborElevations = noise(x - 1, y - 1) +
54 | noise(x - 1, y + 1) +
55 | noise(x + 1, y + 1) +
56 | noise(x + 1, y - 1);
57 |
58 | return noise(x, y) / 4 + edgeNeighborElevations / 8 + cornerNeighborElevations / 16;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/noise/SmoothNoise.java:
--------------------------------------------------------------------------------
1 | package noise;
2 |
3 | import java.util.List;
4 |
5 | import model.Point;
6 |
7 | public class SmoothNoise extends RandomNoise {
8 |
9 | protected int degrees;
10 |
11 | public SmoothNoise(int width, int height, double seed,int degrees) {
12 | super(width, height, seed);
13 |
14 | this.degrees = degrees;
15 | }
16 |
17 | @Override
18 | public void initializeNoiseGrid() {
19 | super.initializeNoiseGrid();
20 |
21 | smoothElevation();
22 | }
23 |
24 | @Override
25 | public void initializeMapGrid() {
26 | super.initializeMapGrid();
27 |
28 | smoothElevation();
29 | }
30 |
31 | private void smoothElevation() {
32 | for (int y = 0; y < mHeight; y++) {
33 | for (int x = 0; x < mWidth; x++) {
34 | smoothPoint(mGrid.getPoint(x, y));
35 | }
36 | }
37 | }
38 |
39 | // Smooth a point by averaging its elevation with all adjacent points
40 | private void smoothPoint(Point point) {
41 | List adjacentPoints = mGrid.getAdjacentPoints(point, degrees);
42 |
43 | double elevation = point.getElevation();
44 | double sum = elevation;
45 |
46 | for (Point adjacentPoint : adjacentPoints) {
47 | sum += adjacentPoint.getElevation();
48 | }
49 |
50 | point.setElevation(sum / (adjacentPoints.size() + 1));
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/noise/SphericalNoise.java:
--------------------------------------------------------------------------------
1 | package noise;
2 |
3 | import model.Grid;
4 | import model.Point;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * Generates an N x N grid where points closer to the edges have lower elevations and points closer to the center have
10 | * higher elevations
11 | */
12 | public class SphericalNoise extends Noise {
13 |
14 | private final double MIN_ELEVATION = -1.0;
15 |
16 | private final double MAX_ELEVATION = 0.5;
17 |
18 | private int mMaxDistance;
19 |
20 | public SphericalNoise(int width, int height) {
21 | mWidth = width;
22 | mHeight = height;
23 | mMaxDistance = mWidth / 2 < mHeight / 2 ? mWidth / 2 - 1 : mHeight / 2 - 1;
24 | }
25 |
26 | @Override
27 | public void initializeNoiseGrid() {
28 | mGrid = new Grid(mWidth, mHeight);
29 | mGrid.initializeGrid();
30 | genNoise();
31 | }
32 |
33 | @Override
34 | public void initializeMapGrid() {
35 | mGrid = new Grid(mWidth, mHeight);
36 | mGrid.initializeGridWithTerrain();
37 | genNoise();
38 | }
39 |
40 | @Override
41 | protected void genNoise() {
42 | for (List row : mGrid.getGrid()) {
43 | for (Point point : row) {
44 | point.setElevation(determineElevation(point.getX(), point.getY()));
45 | }
46 | }
47 | }
48 |
49 | protected double determineElevation(int x, int y) {
50 | int minDistFromEdge = minDistanceFromEdge(x, y);
51 |
52 | return (MAX_ELEVATION - MIN_ELEVATION) * minDistFromEdge / mMaxDistance + MIN_ELEVATION;
53 | }
54 |
55 | protected int minDistanceFromEdge(int x, int y) {
56 | int distX = getDistanceFromEdgeX(x);
57 | int distY = getDistanceFromEdgeY(y);
58 | return distX < distY ? distX : distY;
59 | }
60 |
61 | private int getDistanceFromEdgeX(int x) {
62 | return mWidth - x - 1 < x ? mWidth - x - 1 : x;
63 | }
64 |
65 | private int getDistanceFromEdgeY(int y) {
66 | return mHeight - y - 1 < y ? mHeight - y - 1 : y;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/packages/bundles/daddy.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
36 |
37 |
38 | Test page for MapEditor
39 | Webstart: click to launch this app as webstart
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/packages/bundles/daddy.jnlp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | MapEditor Demo
5 | Unknown
6 | MapEditor
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/packages/daddy.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
36 |
37 |
38 | Test page for MapEditor
39 | Webstart: click to launch this app as webstart
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/packages/daddy.jnlp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | MapEditor Demo
5 | Unknown
6 | MapEditor
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/procedural/BiomeGeneration.java:
--------------------------------------------------------------------------------
1 | package procedural;
2 |
3 | import map.PerlinMap;
4 | import metrics.Metric;
5 | import metrics.MetricKey;
6 | import model.BiomeType;
7 | import model.Terrain;
8 | import model.TerrainType;
9 |
10 | public class BiomeGeneration {
11 |
12 | private PerlinMap mMap;
13 |
14 | private TemperatureGeneration mTemperatureGeneration;
15 |
16 | private HumidityGenerationV2 mHumidityGeneration;
17 |
18 | public BiomeGeneration(PerlinMap map) {
19 | mMap = map;
20 | mTemperatureGeneration = new TemperatureGeneration(mMap);
21 | mHumidityGeneration = new HumidityGenerationV2(mMap);
22 | }
23 |
24 | public void generate() {
25 | Metric.start(MetricKey.TEMPERATUREGENERATION);
26 | mTemperatureGeneration.generate();
27 | Metric.record(MetricKey.TEMPERATUREGENERATION);
28 | Metric.start(MetricKey.HUMIDITYGENERATION);
29 | mHumidityGeneration.generate();
30 | Metric.record(MetricKey.HUMIDITYGENERATION);
31 |
32 | for (int y = 0; y < mMap.getHeight(); y++) {
33 | for (int x = 0; x < mMap.getWidth(); x++) {
34 | Terrain terrain = mMap.getTerrain(x, y);
35 |
36 | if (terrain.getTerrainType().equals(TerrainType.WATER) ||
37 | terrain.getTerrainType().equals(TerrainType.RIVER) ||
38 | terrain.getTerrainType().equals(TerrainType.BEACH) ||
39 | terrain.getTerrainType().equals(TerrainType.RIVER_BANK) ||
40 | terrain.getTerrainType().equals(TerrainType.MOUNTAIN)) {
41 | continue;
42 | }
43 |
44 | terrain.setBiomeType(BiomeType.getBiomeTypeByTempAndHumidity(terrain.getTemperature(),
45 | terrain.getHumidity()));
46 | }
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/procedural/CityGeneration.java:
--------------------------------------------------------------------------------
1 | package procedural;
2 |
3 | import map.Map;
4 | import model.*;
5 |
6 | import java.util.*;
7 |
8 | public class CityGeneration {
9 |
10 | private Map mMap;
11 |
12 | private Grid cityScoresGrid;
13 |
14 | private List citiesPlaced;
15 |
16 | private int numCities;
17 |
18 | private final double RIVER_SCORE = 1;
19 |
20 | private final double SHORE_SCORE = 0.75;
21 |
22 | private final double HIGH_GROUND_SCORE = 0.3;
23 |
24 | private final int DEGREES = 3;
25 |
26 | private final int MIN_CITY_DISTANCE = 75;
27 |
28 | PriorityQueue cities;
29 |
30 | public CityGeneration(Map map, int numCities) {
31 | mMap = map;
32 | this.numCities = numCities;
33 | cities = new PriorityQueue<>(numCities, new CityComparator());
34 |
35 | cityScoresGrid = new Grid(map.getWidth(), map.getHeight());
36 | cityScoresGrid.initializeGridWithTerrain();
37 | citiesPlaced = new ArrayList<>();
38 | }
39 |
40 | public void generate() {
41 |
42 | for (List row : mMap.getNoise().getGrid().getGrid()) {
43 | for (Point point : row) {
44 | if (!isValidTerrainType((Terrain) point)) {
45 | continue;
46 | }
47 |
48 | List adjacentPoints = mMap.getNoise().getGrid().getAdjacentPoints(point, DEGREES);
49 |
50 | Set adjacentTerrainTypes = new HashSet<>();
51 |
52 | for (Point adjPoint : adjacentPoints) {
53 | Terrain terrain = (Terrain) adjPoint;
54 | adjacentTerrainTypes.add(terrain.getTerrainType());
55 | }
56 |
57 | ((Terrain) cityScoresGrid.getPoint(point.getX(), point.getY())).setScore(getScore(adjacentTerrainTypes));
58 |
59 | cities.add((Terrain) cityScoresGrid.getPoint(point.getX(), point.getY()));
60 | }
61 | }
62 |
63 | placeCities();
64 | }
65 |
66 | // rank a location's suitability to be a city based on weights assigned to
67 | // terrain types and some randomness sprinkled in
68 | private double getScore(Set adjacentTerrainTypes) {
69 | double score = 0;
70 |
71 | if (adjacentTerrainTypes.contains(TerrainType.RIVER) ||
72 | adjacentTerrainTypes.contains((TerrainType.RIVER_BANK))) {
73 | score += RIVER_SCORE * Math.random();
74 | }
75 | if (adjacentTerrainTypes.contains(TerrainType.WATER)) {
76 | score += SHORE_SCORE * Math.random();
77 | }
78 | if (adjacentTerrainTypes.contains(TerrainType.MOUNTAIN) ||
79 | adjacentTerrainTypes.contains(TerrainType.HILL)) {
80 | score += HIGH_GROUND_SCORE * Math.random();
81 | }
82 |
83 | score += Math.random();
84 |
85 | return score;
86 | }
87 |
88 | // place x number of cities based on rank and proximity
89 | private void placeCities() {
90 | int numCitiesToBePlaced = numCities;
91 | while (numCitiesToBePlaced > 0 && cities.size() > 0) {
92 | Terrain location = cities.poll();
93 | if (nearCity(location)) {
94 | continue;
95 | }
96 |
97 | Terrain city = mMap.getTerrain(location.getX(), location.getY());
98 | city.setLocationType(LocationType.CITY);
99 | city.setLocation(new City());
100 | citiesPlaced.add(city);
101 | numCitiesToBePlaced--;
102 | }
103 | }
104 |
105 | // return true if within certain distance of an already placed city
106 | private boolean nearCity(Terrain location) {
107 | for (Terrain city : citiesPlaced) {
108 | if (Math.sqrt(Math.pow(location.getX() - city.getX(), 2) +
109 | Math.pow(location.getY() - city.getY(), 2)) <= MIN_CITY_DISTANCE) {
110 | return true;
111 | }
112 | }
113 |
114 | return false;
115 | }
116 |
117 | // returns true if terrain type is valid for a city to be placed
118 | private boolean isValidTerrainType(Terrain terrain) {
119 | return !(terrain.getTerrainType().equals(TerrainType.WATER) ||
120 | terrain.getTerrainType().equals(TerrainType.RIVER) ||
121 | terrain.getTerrainType().equals(TerrainType.RIVER_BANK) ||
122 | terrain.getTerrainType().equals(TerrainType.BEACH) ||
123 | terrain.getTerrainType().equals(TerrainType.MOUNTAIN));
124 | }
125 |
126 | private class CityComparator implements Comparator {
127 |
128 | @Override
129 | public int compare(Terrain a, Terrain b) {
130 | if (a.getScore() < b.getScore()) {
131 | return 1;
132 | } else if (a.getScore() > b.getScore()) {
133 | return -1;
134 | }
135 |
136 | return 0;
137 | }
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/src/procedural/ContinentGeneration.java:
--------------------------------------------------------------------------------
1 | package procedural;
2 |
3 | import map.Map;
4 | import noise.SphericalNoise;
5 |
6 | /**
7 | * Modifies the map to have continental landmasses. This is done by combining elevations from the map with continent
8 | * noise, thereby increasing the elevations of points in the center of the map and decreasing the elevations of points
9 | * near the edges of the map. This has the effect of making points near the center more likely to be land and
10 | * points near the edges more likely to be water
11 | */
12 | public class ContinentGeneration {
13 |
14 | private Map mMap;
15 |
16 | private SphericalNoise mSphericalNoise;
17 |
18 | public ContinentGeneration(Map map) {
19 | mMap = map;
20 | }
21 |
22 | public void generate() {
23 | mSphericalNoise = new SphericalNoise(mMap.getWidth(), mMap.getHeight());
24 | mSphericalNoise.initializeNoiseGrid();
25 |
26 | for (int y = 0; y < mMap.getHeight(); y++) {
27 | for (int x = 0; x < mMap.getWidth(); x++) {
28 | double elevation = mMap.getNoise().getGrid().getPoint(x, y).getElevation();
29 | mMap.getNoise().getGrid().getPoint(x, y).setElevation(
30 | elevation + mSphericalNoise.getGrid().getPoint(x, y).getElevation());
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/procedural/HumidityGeneration.java:
--------------------------------------------------------------------------------
1 | package procedural;
2 |
3 | import map.Map;
4 | import model.Point;
5 | import model.Terrain;
6 |
7 | import java.util.List;
8 |
9 | public class HumidityGeneration {
10 |
11 | private Map mMap;
12 |
13 | private WindCurrents mWindCurrents;
14 |
15 | private final double MIN_HUMIDITY = 0.0;
16 |
17 | private final double MAX_HUMIDITY = 1.0;
18 |
19 | private final int WATER_RADIUS = 300;
20 |
21 | public HumidityGeneration(Map map) {
22 | mMap = map;
23 | mWindCurrents = new WindCurrents(mMap.getHeight());
24 | }
25 |
26 | public void generate() {
27 |
28 | mWindCurrents.generate();
29 |
30 | for (List row : mMap.getNoise().getGrid().getGrid()) {
31 | for (Point point : row) {
32 | Terrain terrain = (Terrain) point;
33 |
34 | switch (terrain.getTerrainType()) {
35 | case WATER:
36 | case RIVER:
37 | case RIVER_BANK:
38 | continue;
39 | }
40 |
41 | if (terrain.getTemperature() > 0.25) {
42 | terrain.setHumidity(determineHumidity(terrain));
43 | } else {
44 | terrain.setHumidity(0);
45 | }
46 | }
47 | }
48 | }
49 |
50 | private double determineHumidity(Terrain terrain) {
51 |
52 | double humidity = 0.0;
53 |
54 | /*List adjacentTerrains = mMap.getNoise().getGrid().getAdjacentTerrainByDirection(
55 | terrain.getX(),
56 | terrain.getY(),
57 | WATER_RADIUS,
58 | mWindCurrents.getDirection((terrain.getY()));*/
59 |
60 | List adjacentTerrains = mMap.getNoise().getGrid().getAdjacentTerrainByDirAndStrength(
61 | terrain.getX(),
62 | terrain.getY(),
63 | WATER_RADIUS,
64 | mWindCurrents.getDirection(terrain.getY()));
65 |
66 | for (Terrain adjacentTerrain : adjacentTerrains) {
67 | switch (adjacentTerrain.getTerrainType()) {
68 | case WATER:
69 | case RIVER:
70 | case RIVER_BANK:
71 | case BEACH:
72 | humidity++;
73 | break;
74 | case MOUNTAIN:
75 | //humidity -= 20;
76 | break;
77 | }
78 | }
79 |
80 | humidity = humidity < 0 ? 0 : humidity;
81 |
82 | return normalize(humidity);
83 | }
84 |
85 | private double normalize(double value) {
86 | double maxHumid = Math.pow(((double) (2 * WATER_RADIUS + 1)), 2) - 1;
87 | assert(maxHumid == 3721);
88 | return (MAX_HUMIDITY - MIN_HUMIDITY) / /*maxHumid*/WATER_RADIUS * value;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/procedural/HumidityGenerationV2.java:
--------------------------------------------------------------------------------
1 | package procedural;
2 |
3 | import map.PerlinMap;
4 | import model.Direction;
5 | import model.Point;
6 | import model.Terrain;
7 | import model.TerrainType;
8 |
9 | import java.util.List;
10 |
11 | public class HumidityGenerationV2 {
12 |
13 | private PerlinMap mMap;
14 |
15 | private WindCurrentsV2 mWindCurrents;
16 |
17 | private final double MIN_HUMIDITY = 0.0;
18 |
19 | private final double MAX_HUMIDITY = 1.0;
20 |
21 | private final int OCEAN_SCORE = 10;
22 |
23 | private final int RIVER_SCORE = 0;
24 |
25 | private final int MOUNTAIN_SCORE = -1;
26 |
27 | public HumidityGenerationV2(PerlinMap map) {
28 | mMap = map;
29 | mWindCurrents = new WindCurrentsV2(mMap.getHeight());
30 | }
31 |
32 | public void generate() {
33 |
34 | mWindCurrents.generate();
35 |
36 | for (List row : mMap.getNoise().getGrid().getGrid()) {
37 | for (Point point : row) {
38 | Terrain terrain = (Terrain) point;
39 |
40 | switch (terrain.getTerrainType()) {
41 | case WATER:
42 | case RIVER:
43 | case RIVER_BANK:
44 | case BEACH:
45 | case MOUNTAIN:
46 | continue;
47 | }
48 |
49 | if (terrain.getTemperature() > 0.25) {
50 | terrain.setHumidity(determineHumidity(terrain));
51 | } else {
52 | terrain.setHumidity(0);
53 | }
54 | }
55 | }
56 | }
57 |
58 | private double determineHumidity(Terrain terrain) {
59 |
60 | double humidity = 0.0;
61 |
62 | List directions = mWindCurrents.getDirection(terrain.getY());
63 |
64 | double humidityDir = 0.0;
65 | for (Direction dir : directions) {
66 | switch (dir) {
67 | case NORTH:
68 | humidityDir = travelY(terrain, -1);
69 | break;
70 | case NORTHEAST:
71 | humidityDir = travelDiagonal(terrain, 1, -1);
72 | break;
73 | case EAST:
74 | humidityDir = travelX(terrain, 1);
75 | break;
76 | case SOUTHEAST:
77 | humidityDir = travelDiagonal(terrain, 1, 1);
78 | break;
79 | case SOUTH:
80 | humidityDir = travelY(terrain, 1);
81 | break;
82 | case SOUTHWEST:
83 | humidityDir = travelDiagonal(terrain, -1, 1);
84 | break;
85 | case WEST:
86 | humidityDir = travelX(terrain, -1);
87 | break;
88 | case NORTHWEST:
89 | humidityDir = travelDiagonal(terrain, -1, -1);
90 | break;
91 | default:
92 | throw new IllegalArgumentException();
93 | }
94 | //humidity = humidityDir > humidity ? humidityDir : humidity;
95 | humidity = (humidityDir + humidity) / 2;
96 | }
97 |
98 | return normalize(humidity);
99 | }
100 |
101 | private double travelDiagonal(Terrain terrain, int dx, int dy) {
102 | double humidity = 0.0;
103 |
104 | int x = terrain.getX() + dx;
105 | int y = terrain.getY() + dy;
106 | while (x >= 0 && x < mMap.getWidth() && y >= 0 && y < mMap.getHeight()) {
107 | humidity += getHumidity(mMap.getTerrain(x, y).getTerrainType());
108 |
109 | if (humidity < MOUNTAIN_SCORE * 30 || humidity > OCEAN_SCORE * 5) {
110 | break;
111 | }
112 |
113 | x += dx;
114 | y += dy;
115 | }
116 |
117 | return humidity;
118 | }
119 |
120 | private double travelX(Terrain terrain, int dx) {
121 | double humidity = 0.0;
122 |
123 | int x = terrain.getX() + dx;
124 | while (x >= 0 && x < mMap.getWidth()) {
125 | humidity += getHumidity(mMap.getTerrain(x, terrain.getY()).getTerrainType());
126 |
127 | if (humidity < MOUNTAIN_SCORE * 30 || humidity > OCEAN_SCORE * 5) {
128 | break;
129 | }
130 |
131 | x += dx;
132 | }
133 |
134 | return humidity;
135 | }
136 |
137 | private double travelY(Terrain terrain, int dy) {
138 | double humidity = 0.0;
139 |
140 | int y = terrain.getY() + dy;
141 | while (y >= 0 && y < mMap.getHeight()) {
142 | humidity += getHumidity(mMap.getTerrain(terrain.getX(), y).getTerrainType());
143 |
144 | if (humidity < MOUNTAIN_SCORE * 30 || humidity > OCEAN_SCORE * 5) {
145 | break;
146 | }
147 |
148 | y += dy;
149 | }
150 |
151 | return humidity;
152 | }
153 |
154 | private double getHumidity(TerrainType terrainType) {
155 | double humidity = 0.0;
156 |
157 | if (terrainType.equals(TerrainType.MOUNTAIN)) {
158 | humidity += MOUNTAIN_SCORE;
159 | } else if (terrainType.equals(TerrainType.RIVER) ||
160 | terrainType.equals(terrainType.RIVER_BANK)) {
161 | humidity += RIVER_SCORE;
162 | } else if (terrainType.equals(TerrainType.WATER) ||
163 | terrainType.equals(TerrainType.BEACH)) {
164 | humidity += OCEAN_SCORE;
165 | }
166 |
167 | return humidity;
168 | }
169 |
170 | private double normalize(double value) {
171 | double maxHumid = OCEAN_SCORE * 5;
172 | double minHumid = MOUNTAIN_SCORE * 30;
173 | return (MAX_HUMIDITY - MIN_HUMIDITY) / (maxHumid - minHumid) * value;
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/src/procedural/LakesAndRiversGeneration.java:
--------------------------------------------------------------------------------
1 | package procedural;
2 |
3 | import map.PerlinMap;
4 | import model.*;
5 |
6 | import java.util.PriorityQueue;
7 | import java.util.Stack;
8 |
9 | public class LakesAndRiversGeneration {
10 |
11 | private PerlinMap map;
12 |
13 | private final int QUADRANTS = 200;
14 |
15 | private Stack riverStartingPoints = new Stack<>();
16 |
17 | public LakesAndRiversGeneration(PerlinMap map) {
18 | this.map = map;
19 | }
20 |
21 | public void generate() {
22 |
23 | PriorityQueue highestPoints = new PriorityQueue<>(new PointComparator());
24 |
25 | // get highest elevation points per quadrant
26 | for (int yQuadrant = 0; yQuadrant < map.getHeight() / QUADRANTS; yQuadrant++) {
27 | for (int xQuadrant = 0; xQuadrant < map.getWidth() / QUADRANTS; xQuadrant++) {
28 |
29 | highestPoints.add(new Point(-2.0));
30 | for (int y = yQuadrant * QUADRANTS; y < yQuadrant * QUADRANTS + QUADRANTS; y++) {
31 | for (int x = xQuadrant * QUADRANTS; x < xQuadrant * QUADRANTS + QUADRANTS; x++) {
32 | highestPoints.add(map.getNoise().getGrid().getPoint(x, y));
33 | highestPoints.poll();
34 | }
35 | }
36 | riverStartingPoints.add(highestPoints.poll());
37 | }
38 | }
39 |
40 | flowDownhill();
41 | }
42 |
43 | private void flowDownhill() {
44 | Point currentPoint;
45 |
46 | PriorityQueue adjacentPoints = new PriorityQueue<>(new PointComparator());
47 |
48 | while (!riverStartingPoints.isEmpty()) {
49 | currentPoint = riverStartingPoints.pop();
50 | setRiver(currentPoint);
51 |
52 | while (true) {
53 | adjacentPoints.addAll(map.getNoise().getGrid().getAdjacentPoints(currentPoint, 1));
54 | if (isWater(adjacentPoints.peek())) {
55 | adjacentPoints.clear();
56 | break;
57 | }
58 |
59 | while (isRiver(adjacentPoints.peek())) {
60 | adjacentPoints.poll();
61 | }
62 |
63 | if (adjacentPoints.isEmpty()) {
64 | break;
65 | }
66 |
67 | currentPoint = adjacentPoints.peek();
68 | setRiver(currentPoint);
69 | adjacentPoints.clear();
70 | }
71 | }
72 |
73 | }
74 |
75 | private void setRiver(Point point) {
76 | map.getTerrain(point.getX(), point.getY()).setTerrainType(TerrainType.RIVER);
77 | }
78 |
79 | private boolean isWater(Point point) {
80 | return map.getTerrain(point.getX(), point.getY()).getTerrainType() == TerrainType.WATER;
81 | }
82 |
83 | private boolean isRiver(Point point) {
84 | Terrain terrain = (Terrain) point;
85 | if (terrain != null && terrain.getTerrainType() != null && terrain.getTerrainType().equals(TerrainType.RIVER)) {
86 | return true;
87 | }
88 |
89 | return false;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/procedural/NameGeneration.java:
--------------------------------------------------------------------------------
1 | package procedural;
2 |
3 | import model.City;
4 | import model.LocationType;
5 | import model.Terrain;
6 |
7 | import java.util.*;
8 | import java.util.Map;
9 |
10 | public class NameGeneration {
11 |
12 | private final int MIN_NAME_LENGTH = 5;
13 |
14 | private final int MAX_NAME_LENGTH = 10;
15 |
16 | private List mNames = new ArrayList() {{
17 | add("china");
18 | add("india");
19 | add("unitedstates");
20 | add("indonesia");
21 | add("brazil");
22 | add("pakistan");
23 | add("nigeria");
24 | add("bangladesh");
25 | add("russia");
26 | add("japan");
27 | add("mexico");
28 | add("philippines");
29 | add("ethiopia");
30 | add("vietnam");
31 | add("egypt");
32 | add("iran");
33 | add("germany");
34 | add("turkey");
35 | add("congodemrep");
36 | add("thailand");
37 | }};
38 |
39 | private Map> mTransitions;
40 |
41 | private List mRandomNames;
42 |
43 | private map.Map mMap;
44 |
45 | private int numNames;
46 |
47 | public NameGeneration(map.Map map, int amount) {
48 | mMap = map;
49 | numNames = amount;
50 | }
51 |
52 | public void generate() {
53 | mTransitions = new HashMap<>();
54 |
55 | for (String name : mNames) {
56 | addToTransitions(name);
57 | }
58 |
59 | generateRandomNames();
60 | assignNamesToCities();
61 | }
62 |
63 | private void addToTransitions(String name) {
64 | for (int i = 0; i < name.length() - 1; i++) {
65 | if (mTransitions.containsKey(name.charAt(i))) {
66 | mTransitions.get(name.charAt(i)).add(name.charAt(i + 1));
67 | } else {
68 | mTransitions.put(name.charAt(i), new ArrayList<>(Collections.singletonList(name.charAt(i + 1))));
69 | }
70 | }
71 | }
72 |
73 | private void generateRandomNames() {
74 | mRandomNames = new ArrayList<>();
75 |
76 | for (int i = 0; i < numNames; i++) {
77 | mRandomNames.add(generateRandomName());
78 | }
79 | }
80 |
81 | private void assignNamesToCities() {
82 | Queue queue = new LinkedList<>(mRandomNames);
83 | for (int y = 0; y < mMap.getHeight(); y++) {
84 | for (int x = 0; x< mMap.getWidth(); x++) {
85 | Terrain terrain = mMap.getTerrain(x, y);
86 | if (terrain.getLocationType().equals(LocationType.CITY)) {
87 | terrain.setLocation(new City(queue.poll()));
88 | }
89 | }
90 | }
91 | }
92 |
93 | private String generateRandomName() {
94 | StringBuilder sb = new StringBuilder();
95 | char firstCharacter = randomCharacter();
96 | sb.append(Character.toUpperCase(firstCharacter));
97 |
98 | int nameLength = new Random().nextInt(MAX_NAME_LENGTH - MIN_NAME_LENGTH) + MIN_NAME_LENGTH;
99 | char currentCharacter = firstCharacter;
100 | while (hasNextCharacter(currentCharacter) && sb.length() < nameLength) {
101 | currentCharacter = generateNextCharacter(currentCharacter);
102 | sb.append(currentCharacter);
103 | }
104 |
105 | return sb.toString();
106 | }
107 |
108 | private char randomCharacter() {
109 | List allCharacters = new ArrayList<>(mTransitions.keySet());
110 | Collections.shuffle(allCharacters);
111 | return allCharacters.get(0);
112 | }
113 |
114 | private char generateNextCharacter(char c) {
115 |
116 | Collections.shuffle(mTransitions.get(c));
117 | return mTransitions.get(c).get(0);
118 | }
119 |
120 | private boolean hasNextCharacter(char c) {
121 | return mTransitions.containsKey(c);
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/procedural/TemperatureGeneration.java:
--------------------------------------------------------------------------------
1 | package procedural;
2 |
3 | import map.Map;
4 | import model.Point;
5 | import model.Terrain;
6 | import model.TerrainType;
7 |
8 | import java.util.List;
9 |
10 | public class TemperatureGeneration {
11 |
12 | private Map mMap;
13 |
14 | private final double MIN_TEMPERATURE = 0.0;
15 |
16 | private final double MAX_TEMPERATURE = 1.0;
17 |
18 | public TemperatureGeneration(Map map) {
19 | mMap = map;
20 | }
21 |
22 | public void generate() {
23 |
24 | for (List row : mMap.getNoise().getGrid().getGrid()) {
25 | for (Point point : row) {
26 | Terrain terrain = (Terrain) point;
27 | terrain.setTemperature(determineTemperature(terrain));
28 | }
29 | }
30 | }
31 |
32 | private double determineTemperature(Terrain terrain) {
33 | double temperature = (MAX_TEMPERATURE - MIN_TEMPERATURE) * getDistanceFromEdgeY(terrain.getY()) /
34 | (mMap.getHeight() / 2 - 1) + MIN_TEMPERATURE;
35 |
36 | if (!(terrain.getTerrainType().equals(TerrainType.WATER) ||
37 | terrain.getTerrainType().equals(TerrainType.RIVER) ||
38 | terrain.getTerrainType().equals(TerrainType.RIVER_BANK))) {
39 | temperature -= terrain.getElevation() / 3;
40 | }
41 |
42 | return temperature;
43 | }
44 |
45 | private int getDistanceFromEdgeY(int y) {
46 | return mMap.getHeight() - y - 1 < y ? mMap.getHeight() - y - 1 : y;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/procedural/TerritoryGeneration.java:
--------------------------------------------------------------------------------
1 | package procedural;
2 |
3 | import map.Map;
4 | import model.LocationType;
5 | import model.Terrain;
6 |
7 | import java.util.Collections;
8 | import java.util.LinkedList;
9 | import java.util.List;
10 |
11 | public class TerritoryGeneration {
12 |
13 | private Map mMap;
14 |
15 | private int mTerritoryNum;
16 |
17 | private List mTerrainToBePlaced;
18 |
19 | public TerritoryGeneration(Map map) {
20 | mMap = map;
21 | mTerritoryNum = 0;
22 | mTerrainToBePlaced = new LinkedList<>();
23 | }
24 |
25 | public void generate() {
26 | for (int y = 0; y < mMap.getHeight(); y++) {
27 | for (int x = 0; x < mMap.getWidth(); x++) {
28 | Terrain terrain = mMap.getTerrain(x, y);
29 | if (terrain.getLocationType().equals(LocationType.CITY)) {
30 | terrain.setTerritory(mTerritoryNum);
31 | mTerrainToBePlaced.add(terrain);
32 | mTerritoryNum++;
33 | }
34 | }
35 | }
36 |
37 | expandTerritories();
38 | }
39 |
40 | private void expandTerritories() {
41 |
42 | while (!mTerrainToBePlaced.isEmpty()) {
43 |
44 | if (Math.random() > 0.95)
45 | Collections.shuffle(mTerrainToBePlaced);
46 |
47 | Terrain terrain = mTerrainToBePlaced.remove(0);
48 | List adjacentTerrains = mMap.getNoise().getGrid().getAdjacentTerrain(terrain, 1);
49 | for (Terrain adjacentTerrain : adjacentTerrains) {
50 | if (adjacentTerrain.getElevation() > mMap.getLandGen() - 0.1 &&
51 | adjacentTerrain.getTerritory() == -1) {
52 |
53 | adjacentTerrain.setTerritory(terrain.getTerritory());
54 | if (Math.random() > 0.2)
55 | mTerrainToBePlaced.add(adjacentTerrain);
56 | }
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/procedural/TerritoryGenerationV2.java:
--------------------------------------------------------------------------------
1 | package procedural;
2 |
3 | import map.Map;
4 | import model.LocationType;
5 | import model.Terrain;
6 | import model.TerrainType;
7 |
8 | import java.util.ArrayList;
9 | import java.util.HashSet;
10 | import java.util.List;
11 | import java.util.Set;
12 | import java.util.logging.Level;
13 | import java.util.logging.Logger;
14 |
15 | public class TerritoryGenerationV2 {
16 |
17 | private static final String TAG = TerritoryGenerationV2.class.getSimpleName();
18 |
19 | private Map mMap;
20 |
21 | private int mTerritoryNum;
22 |
23 | private List mCities;
24 |
25 | private Set mRivers;
26 |
27 | public TerritoryGenerationV2(Map map) {
28 | mMap = map;
29 | mTerritoryNum = 0;
30 | mCities = new ArrayList<>();
31 | mRivers = new HashSet<>();
32 | }
33 |
34 | public void generate() {
35 | for (int y = 0; y < mMap.getHeight(); y++) {
36 | for (int x = 0; x < mMap.getWidth(); x++) {
37 | Terrain terrain = mMap.getTerrain(x, y);
38 | if (terrain.getLocationType().equals(LocationType.CITY)) {
39 | terrain.setTerritory(mTerritoryNum);
40 | mCities.add(terrain);
41 | mTerritoryNum++;
42 | } else if (terrain.getTerrainType().equals(TerrainType.RIVER)) {
43 | mRivers.add(new Coords(terrain.getX(), terrain.getY()));
44 | }
45 | }
46 | }
47 |
48 | determineVoronoiTerritories();
49 | }
50 |
51 | private void determineVoronoiTerritories() {
52 | for (int y = 0; y < mMap.getHeight(); y++) {
53 | for (int x = 0; x < mMap.getWidth(); x++) {
54 | Terrain terrain = mMap.getTerrain(x, y);
55 | if (terrain.getTerrainType().equals(TerrainType.LAND) ||
56 | terrain.getTerrainType().equals(TerrainType.MOUNTAIN) ||
57 | terrain.getTerrainType().equals(TerrainType.HILL)) {
58 | terrain.setTerritory(getClosestCityTerritory(terrain));
59 | }
60 | }
61 | }
62 | }
63 |
64 | private int getClosestCityTerritory(Terrain terrain) {
65 | double min = mMap.getHeight() > mMap.getWidth() ? mMap.getHeight() : mMap.getWidth();
66 | Terrain closestCity = null;
67 | for (Terrain city : mCities) {
68 | double dist = getDistanceRivers(city, terrain);
69 | if (dist < min) {
70 | min = dist;
71 | closestCity = city;
72 | }
73 | }
74 |
75 | if (closestCity == null) {
76 | Logger.getLogger(TAG).log(Level.SEVERE, "No closest city found.");
77 | System.exit(0);
78 | }
79 |
80 | return closestCity.getTerritory();
81 | }
82 |
83 | private double getDistance(Terrain city, Terrain terrain) {
84 | //return Math.sqrt(Math.pow(terrain.getX() - city.getX(), 2) + Math.pow(terrain.getY() - city.getY(), 2));
85 | return Math.abs(terrain.getX() - city.getX()) + Math.abs(terrain.getY() - city.getY());
86 | }
87 |
88 | private double getDistanceRivers(Terrain city, Terrain terrain) {
89 | double riverScore = 0;
90 |
91 | // check if we intersect a river point
92 | int dx = terrain.getX() - city.getX();
93 | int dy = terrain.getY() - city.getY();
94 | int distance = dy - dx;
95 | int y = city.getY();
96 |
97 | for (int x = city.getX(); x < terrain.getX(); x++) {
98 |
99 | if (mRivers.contains(new Coords(x, y))) {
100 | riverScore = 500;
101 | break;
102 | }
103 |
104 | if (distance >= 0) {
105 | y++;
106 | distance = distance - dx;
107 | }
108 | distance = distance + dy;
109 | }
110 |
111 | return Math.abs(terrain.getX() - city.getX()) + Math.abs(terrain.getY() - city.getY()) + riverScore;
112 | }
113 |
114 | private class Coords {
115 | int x;
116 | int y;
117 |
118 | public boolean equals(Object o) {
119 | Coords coords = (Coords) o;
120 | return coords.x == x && coords.y == y;
121 | }
122 |
123 | public Coords(int x, int y) {
124 | super();
125 | this.x = x;
126 | this.y = y;
127 | }
128 |
129 | public int hashCode() {
130 | return new Integer(x + "0" + y);
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/src/procedural/WindCurrents.java:
--------------------------------------------------------------------------------
1 | package procedural;
2 |
3 | /**
4 | * Model wind currents. Chooses a random spin direction, and separates wind into 12 zones
5 | */
6 | public class WindCurrents {
7 |
8 | private int mHeight;
9 |
10 | private int mSpin = 1; // 1 for west to east (earth), -1 for east to west
11 |
12 | private final double ZONES = 12.0;
13 |
14 | private double mWindCurrentMidpoint;
15 |
16 | public WindCurrents(int height) {
17 | mHeight = height;
18 | mWindCurrentMidpoint = height / 12.0;
19 | }
20 |
21 | public void generate() {
22 | mSpin = Math.random() > 0.5 ? -1 : 1;
23 | }
24 |
25 | // give wind direction and strength
26 | // direction based on spin, strength based on closeness to center of wind current
27 | public double getDirection(int y) {
28 | switch (normalizeZones(y)) {
29 | case 0:
30 | return normalizeToMidpoint(mWindCurrentMidpoint - y) * -1 * mSpin;
31 | case 1:
32 | return normalizeToMidpoint(y - mWindCurrentMidpoint) * -1 * mSpin;
33 | case 4:
34 | return normalizeToMidpoint(mWindCurrentMidpoint*5 - y) * -1 * mSpin;
35 | case 5:
36 | return normalizeToMidpoint(y - mWindCurrentMidpoint*5) * -1 * mSpin;
37 | case 6:
38 | return normalizeToMidpoint(mWindCurrentMidpoint*7 - y) * -1 * mSpin;
39 | case 7:
40 | return normalizeToMidpoint(y - mWindCurrentMidpoint*7) * -1 * mSpin;
41 | case 10:
42 | return normalizeToMidpoint(mWindCurrentMidpoint*11 - y) * -1 * mSpin;
43 | case 11:
44 | return normalizeToMidpoint(y - mWindCurrentMidpoint*11) * -1 * mSpin;
45 | case 2:
46 | return normalizeToMidpoint(mWindCurrentMidpoint*3 - y) * mSpin;
47 | case 3:
48 | return normalizeToMidpoint(y - mWindCurrentMidpoint*3) * mSpin;
49 | case 8:
50 | return normalizeToMidpoint(mWindCurrentMidpoint*9 - y) * mSpin;
51 | case 9:
52 | return normalizeToMidpoint(y - mWindCurrentMidpoint*9) * mSpin;
53 | default:
54 | throw new IllegalArgumentException();
55 | }
56 | }
57 |
58 | /*private double getDistanceToNearestMidPoint(int y) {
59 |
60 | }*/
61 |
62 | private double normalizeToMidpoint(double value) {
63 | return 1 - 1 / mWindCurrentMidpoint * value;
64 | }
65 |
66 | private int normalizeZones(int value) {
67 | return (int) (ZONES / mHeight * value);
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/src/procedural/WindCurrentsV2.java:
--------------------------------------------------------------------------------
1 | package procedural;
2 |
3 | import model.Direction;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | /**
9 | * Model wind currents. Chooses a random spin direction, and separates wind into 12 zones
10 | */
11 | public class WindCurrentsV2 {
12 |
13 | private int mHeight;
14 |
15 | private int mSpin = 1; // 1 for west to east (earth), -1 for east to west
16 |
17 | private final double ZONES = 12.0;
18 |
19 | private double mWindCurrentMidpoint;
20 |
21 | public WindCurrentsV2(int height) {
22 | mHeight = height;
23 | mWindCurrentMidpoint = height / 12.0;
24 | }
25 |
26 | public void generate() {
27 | mSpin = Math.random() > 0.5 ? -1 : 1;
28 | }
29 |
30 | // give wind direction
31 | public List getDirection(int y) {
32 | List directions = new ArrayList<>();
33 |
34 | switch (normalizeZones(y)) {
35 | case 0:
36 | case 1:
37 | directions.add(Direction.NORTH);
38 | directions.add(Direction.NORTHEAST);
39 | directions.add(Direction.EAST);
40 | break;
41 | case 2:
42 | case 3:
43 | directions.add(Direction.NORTH);
44 | directions.add(Direction.NORTHWEST);
45 | directions.add(Direction.WEST);
46 | break;
47 | case 4:
48 | case 5:
49 | directions.add(Direction.NORTH);
50 | directions.add(Direction.NORTHEAST);
51 | directions.add(Direction.EAST);
52 | break;
53 | case 6:
54 | case 7:
55 | directions.add(Direction.SOUTH);
56 | directions.add(Direction.SOUTHEAST);
57 | directions.add(Direction.EAST);
58 | break;
59 | case 8:
60 | case 9:
61 | directions.add(Direction.SOUTH);
62 | directions.add(Direction.SOUTHWEST);
63 | directions.add(Direction.WEST);
64 | break;
65 | case 10:
66 | case 11:
67 | directions.add(Direction.SOUTH);
68 | directions.add(Direction.SOUTHEAST);
69 | directions.add(Direction.EAST);
70 | break;
71 | default:
72 | throw new IllegalArgumentException();
73 | }
74 |
75 | return directions;
76 | }
77 |
78 | private int normalizeZones(int value) {
79 | return (int) (ZONES / mHeight * value);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/test/ImageManagerTester.java:
--------------------------------------------------------------------------------
1 | package test;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 | import java.awt.image.BufferedImage;
6 |
7 | public class ImageManagerTester {
8 |
9 | /*public static void main(String[] arg) {
10 | PerlinMap map = new PerlinMap(1000,
11 | 1000,
12 | Math.random(),
13 | Math.random(),
14 | 0.0,
15 | 34,
16 | 0.6,
17 | 0.5,
18 | -0.0125,
19 | 3,
20 | 50,
21 | 0.5,
22 | 8,
23 | true,
24 | true,
25 | true,
26 | true,
27 | false,
28 | false,
29 | true,
30 | false,
31 | true);
32 |
33 | HeatmapImageManager heatmapImageManager = new HeatmapImageManager(map);
34 | heatmapImageManager.generateImage();
35 | createFrame(heatmapImageManager.getImage());
36 | }*/
37 |
38 | public static void createFrame(BufferedImage image) {
39 | JFrame frame = new JFrame();
40 | frame.getContentPane().setLayout(new FlowLayout());
41 | frame.getContentPane().add(new JLabel(new ImageIcon(image)));
42 | frame.pack();
43 | frame.setLocationRelativeTo(null);
44 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
45 | frame.setVisible(true);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/view/BasicNoiseDialog.java:
--------------------------------------------------------------------------------
1 | package view;
2 |
3 | import java.awt.Color;
4 | import java.awt.FlowLayout;
5 | import java.awt.image.BufferedImage;
6 |
7 | import javax.swing.ImageIcon;
8 | import javax.swing.JFrame;
9 | import javax.swing.JLabel;
10 |
11 | import noise.Noise;
12 |
13 | public class BasicNoiseDialog {
14 |
15 | public static void plotNoise(Noise noise) {
16 | BufferedImage image = new BufferedImage(noise.getWidth(), noise.getHeight(),
17 | BufferedImage.TYPE_INT_ARGB);
18 |
19 | for (int y = 0; y < noise.getHeight(); y++) {
20 | for (int x = 0; x < noise.getWidth(); x++) {
21 |
22 | double elevation = noise.getGrid().getPoint(x, y).getElevation();
23 | int colorValue = (int) ((elevation * 128.0) + 128);
24 | if (colorValue > 255) {
25 | colorValue = 255;
26 | } else if (colorValue < 0) {
27 | colorValue = 0;
28 | }
29 | Color elevationColor = null;
30 | try {
31 | elevationColor = new Color(colorValue, colorValue, colorValue);
32 | } catch (IllegalArgumentException e) {
33 | System.out.println("elevation: " + elevation);
34 | System.out.println("colorValue: " + colorValue);
35 | e.printStackTrace();
36 | System.exit(1);
37 | }
38 | image.setRGB(x, y, elevationColor.getRGB());
39 | }
40 | }
41 |
42 | createFrame(image);
43 | }
44 |
45 | public static void createFrame(BufferedImage image) {
46 | JFrame frame = new JFrame();
47 | frame.getContentPane().setLayout(new FlowLayout());
48 | frame.getContentPane().add(new JLabel(new ImageIcon(image)));
49 | frame.pack();
50 | frame.setLocationRelativeTo(null);
51 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
52 | frame.setVisible(true);
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/view/ColorMapDialog.java:
--------------------------------------------------------------------------------
1 | package view;
2 |
3 | import java.awt.*;
4 | import java.awt.image.BufferedImage;
5 |
6 | import javax.swing.ImageIcon;
7 | import javax.swing.JFrame;
8 | import javax.swing.JLabel;
9 |
10 | import map.Map;
11 | import model.LocationType;
12 | import model.Terrain;
13 | import model.TerrainType;
14 |
15 | public class ColorMapDialog {
16 |
17 | protected final int OVAL_WIDTH = 7;
18 |
19 | protected final int OVAL_HEIGHT = 7;
20 |
21 | public void plotMap(Map map) {
22 | BufferedImage image = new BufferedImage(map.getWidth(), map.getHeight(),
23 | BufferedImage.TYPE_INT_ARGB);
24 |
25 | for (int y = 0; y < map.getHeight(); y++) {
26 | for (int x = 0; x < map.getWidth(); x++) {
27 | image.setRGB(x, y, getColorByTerrain(map.getTerrain(x, y)).getRGB());
28 | }
29 | }
30 |
31 | Graphics2D graph = image.createGraphics();
32 | graph.setColor(Color.red);
33 |
34 | for (int y = 0; y < map.getHeight(); y++) {
35 | for (int x = 0; x < map.getWidth(); x++) {
36 | Terrain terrain = map.getTerrain(x, y);
37 | if (terrain.getLocationType() != null && terrain.getLocationType().equals(LocationType.CITY)) {
38 | graph.fillOval(x - OVAL_WIDTH / 2, y - OVAL_HEIGHT / 2, OVAL_WIDTH, OVAL_HEIGHT);
39 | graph.setColor(Color.black);
40 | graph.drawString(terrain.getLocation().getName(), x - OVAL_WIDTH * 4, y - OVAL_HEIGHT);
41 | graph.setColor(Color.red);
42 | }
43 | }
44 | }
45 |
46 | graph.dispose();
47 |
48 | createFrame(image);
49 | }
50 |
51 | protected Color getColorByTerrain(Terrain terrain) {
52 | TerrainType terrainType = terrain.getTerrainType();
53 |
54 | Color terrainColor;
55 | switch (terrainType) {
56 | case MOUNTAIN:
57 | //terrainColor = Color.gray;
58 | terrainColor = Color.green;
59 | break;
60 | case HILL:
61 | terrainColor = Color.green;
62 | break;
63 | case FOREST:
64 | terrainColor = Color.orange;
65 | break;
66 | case LAND:
67 | terrainColor = Color.green;
68 | break;
69 | case BEACH:
70 | //terrainColor = Color.yellow;
71 | terrainColor = Color.green;
72 | break;
73 | case WATER:
74 | terrainColor = Color.blue;
75 | break;
76 | default:
77 | terrainColor = Color.white;
78 | break;
79 | }
80 |
81 | return terrainColor;
82 | }
83 |
84 | public void createFrame(BufferedImage image) {
85 | JFrame frame = new JFrame();
86 | frame.getContentPane().setLayout(new FlowLayout());
87 | frame.getContentPane().add(new JLabel(new ImageIcon(image)));
88 | frame.pack();
89 | frame.setLocationRelativeTo(null);
90 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
91 | frame.setVisible(true);
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/view/MapEditorDialog.java:
--------------------------------------------------------------------------------
1 | package view;
2 |
3 | import controller.UiController;
4 | import javafx.application.Application;
5 | import javafx.application.Platform;
6 | import javafx.beans.InvalidationListener;
7 | import javafx.beans.Observable;
8 | import javafx.beans.property.DoubleProperty;
9 | import javafx.beans.property.SimpleDoubleProperty;
10 | import javafx.event.EventHandler;
11 | import javafx.fxml.FXMLLoader;
12 | import javafx.scene.Scene;
13 | import javafx.scene.control.MenuBar;
14 | import javafx.scene.control.ScrollPane;
15 | import javafx.scene.layout.AnchorPane;
16 | import javafx.stage.Stage;
17 | import javafx.stage.WindowEvent;
18 |
19 | import java.io.IOException;
20 | import java.util.logging.Level;
21 | import java.util.logging.Logger;
22 |
23 | public class MapEditorDialog extends Application {
24 |
25 | private static final String TAG = MapEditorDialog.class.getSimpleName();
26 |
27 | private final String TITLE = "MapMaker";
28 |
29 | @Override
30 | public void start(Stage primaryStage) {
31 | try {
32 | FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml"));
33 | AnchorPane page = loader.load();
34 | UiController uiController = loader.getController();
35 | uiController.setStageAndSetupListeners(primaryStage);
36 |
37 | ScrollPane toolPane = (ScrollPane) page.lookup("#mToolPane");
38 | toolPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
39 | double width = toolPane.getPrefWidth();
40 | double height = toolPane.getPrefHeight();
41 | MenuBar menuBar = (MenuBar) page.lookup("#mMenuBar");
42 | menuBar.prefWidthProperty().bind(primaryStage.widthProperty());
43 | double menuHeight = 25;
44 |
45 | toolPane.setPrefHeight(1000 > height ? 1000:height);
46 | Scene scene = new Scene(page, width + 1000, 1000 > height ? 1000 + menuHeight : height + menuHeight);
47 |
48 | primaryStage.setScene(scene);
49 | primaryStage.setTitle(TITLE);
50 | primaryStage.show();
51 |
52 | primaryStage.setOnCloseRequest(new EventHandler() {
53 | @Override
54 | public void handle(WindowEvent event) {
55 | Platform.exit();
56 | System.exit(0);
57 | }
58 | });
59 | } catch (IOException ioe) {
60 | Logger.getLogger(TAG).log(Level.SEVERE, null, ioe);
61 | }
62 |
63 | }
64 |
65 | public static void main(String args[]) {
66 | launch(args);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/view/SmoothColorMapDialog.java:
--------------------------------------------------------------------------------
1 | package view;
2 |
3 | import java.awt.Color;
4 |
5 | import model.Terrain;
6 |
7 | public class SmoothColorMapDialog extends ColorMapDialog {
8 |
9 | @Override
10 | protected Color getColorByTerrain(Terrain terrain) {
11 | double elevation = terrain.getElevation(); // number between -1 and 1 roughly
12 | double percent = (elevation + 1) / 2;
13 |
14 | switch (terrain.getLocationType()) {
15 | case CITY:
16 | return Color.pink;
17 | }
18 |
19 | switch (terrain.getTerrainType()) {
20 | case WATER:
21 | return averageColors(Color.cyan, Color.blue, percent);
22 | case RIVER:
23 | return averageColors(Color.blue, Color.cyan, percent);
24 | case BEACH:
25 | return averageColors(new Color(209, 199, 119), new Color(227, 221, 175), percent);
26 | case LAND:
27 | return averageColors(Color.green, new Color(44, 125, 30), percent);
28 | case FOREST:
29 | return averageColors(new Color(5, 102, 0), new Color(7, 170, 0), percent);
30 | case MOUNTAIN:
31 | return averageColors(new Color(87, 87, 87), new Color(150, 150, 150), percent);
32 | default:
33 | return averageColors(new Color(179, 124, 21), new Color(140, 98, 18), percent);
34 |
35 | }
36 | }
37 |
38 | protected Color averageColors(Color color1, Color color2, double percent) {
39 | double red = color1.getRed() * percent + color2.getRed() * (1.0 - percent);
40 | double green = color1.getGreen() * percent + color2.getGreen() * (1.0 - percent);
41 | double blue = color1.getBlue() * percent + color2.getBlue() * (1.0 - percent);
42 |
43 | try {
44 | return new Color((int) red, (int) green, (int) blue);
45 | } catch (IllegalArgumentException e) {
46 | System.out.println("Color out of range");
47 | System.out.println("red: " + red);
48 | System.out.println("green: " + green);
49 | System.out.println("blue: " + blue);
50 | System.exit(0);
51 | }
52 |
53 | return Color.white;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/view/main.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
96 |
102 |
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/src/view/main.fxml~:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
90 |
95 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/src/view/test.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
106 |
112 |
117 |
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------