mirror of
https://github.com/Viglino/ol-games.git
synced 2026-01-18 15:17:17 +00:00
269 lines
9.0 KiB
HTML
269 lines
9.0 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<!--
|
|
Copyright (c) 2017 Jean-Marc VIGLINO,
|
|
released under CeCILL-B (french BSD like) licence: http://www.cecill.info/
|
|
-->
|
|
<title>ol-games: Hexmap</title>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
|
|
<meta name="description" content="Hexagonal source for openlayers maps" />
|
|
<meta name="keywords" content="ol, game, hexagon, hexagonal, source, map" />
|
|
|
|
<link rel="stylesheet" href="style.css" />
|
|
|
|
<!-- jQuery -->
|
|
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
|
|
<!-- FontAwesome -->
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
|
|
<!-- OpenLayers -->
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@latest/ol.css" />
|
|
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ol@latest/dist/ol.js"></script>
|
|
|
|
<!-- ol-ext -->
|
|
<link rel="stylesheet" href="https://rawgit.com/Viglino/ol-ext/master/dist/ol-ext.css" />
|
|
<script type="text/javascript" src="https://rawgit.com/Viglino/ol-ext/master/dist/ol-ext.js"></script>
|
|
|
|
<!-- ol-games -->
|
|
<link rel="stylesheet" href="../dist/ol-games.css" />
|
|
<script type="text/javascript" src="../dist/ol-games.js"></script>
|
|
|
|
<style>
|
|
#map
|
|
{ width:100%;
|
|
height: 600px;
|
|
margin: 0;
|
|
}
|
|
.options
|
|
{ position:absolute;
|
|
right: 1em;
|
|
}
|
|
</style>
|
|
|
|
</head>
|
|
<body >
|
|
<a href="https://github.com/Viglino/ol-games" class="icss-github-corner"><i></i></a>
|
|
|
|
<a href="../index.html">
|
|
<h1>ol-games: Hexmap</h1>
|
|
</a>
|
|
<div class="info">
|
|
<p>
|
|
hexagonal map or hex map is a game board design commonly used in wargames of all scales.
|
|
The map is subdivided into a hexagonal tiling, small regular hexagons of identical size.
|
|
<br />
|
|
<i>ol.source.HexMap</i> is an image source that render an hexagonal grid on a map.
|
|
The <i>ol.Hexgrid</i> object is used to convert from coordinate to hex or calculate lines beetween hexagons.
|
|
</p>
|
|
<p>
|
|
For more information on Hexagnol grid, I recommend this fabulous <a href="http://www.redblobgames.com/grids/hexagons/">Red Blob Games article</a>.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Map div -->
|
|
<div id="map"></div>
|
|
|
|
<div class="options" >
|
|
<h2>Options:</h2>
|
|
<div id="pattern"></div>
|
|
|
|
<ul>
|
|
<li>
|
|
layout:
|
|
<select id="layout" onchange="grid.setLayout(this.value); vector.getSource().clear();">
|
|
<option value="pointy">pointy</option>
|
|
<option value="flat">flat</option>
|
|
</select>
|
|
</li>
|
|
<li>
|
|
size:
|
|
<select id="size" onchange="grid.setSize(this.value)">
|
|
<option value="2000">small</option>
|
|
<option value="4000" selected="selected">standard</option>
|
|
<option value="6000">big</option>
|
|
</select>
|
|
</li>
|
|
<li>
|
|
actions:<br/>
|
|
<input type="radio" name="action" value="dist" /><label> distance</label>
|
|
<br/>
|
|
coords:<br/>
|
|
<input type="radio" name="action" value="axial" /><label> axial</label>
|
|
<br />
|
|
<input type="radio" name="action" value="offset" /><label> offset</label>
|
|
<br />
|
|
<input type="radio" name="action" value="cube" /><label> cube</label>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
|
|
<script type="text/javascript">
|
|
// Layers
|
|
var layers = [new ol.layer.Tile({ preload:Infinity, source: new ol.source.StadiaMaps({ layer: 'stamen_watercolor' }) })];
|
|
|
|
// Popup
|
|
var popup = new ol.Overlay.Popup (
|
|
{ popupClass: "tooltips",
|
|
positioning: 'auto'
|
|
});
|
|
|
|
// The map
|
|
var map = new ol.Map({
|
|
target: 'map',
|
|
view: new ol.View({
|
|
zoom: 11,
|
|
center: [260064, 6250762]
|
|
}),
|
|
layers: layers,
|
|
overlays: [popup]
|
|
});
|
|
|
|
var grid = new ol.HexGrid ({ size:4000, origin: map.getView().getCenter() });
|
|
var hex = new ol.source.HexMap({ hexGrid: grid });
|
|
map.addLayer ( new ol.layer.Image({ source: hex }) );
|
|
|
|
var text = false;
|
|
hex.set('text', text);
|
|
grid.setLayout($("#layout").val());
|
|
grid.setSize($("#size").val());
|
|
|
|
var vector = new ol.layer.Vector({
|
|
source: new ol.source.Vector(),
|
|
//style: new ol.style.Style ({ fill: new ol.style.Fill({ color:"red"} )})
|
|
});
|
|
map.addLayer(vector);
|
|
|
|
// Styles
|
|
var greenStyle = new ol.style.Style({
|
|
fill: new ol.style.Fill({ color: 'rgba(0,255,0,0.2)' }),
|
|
stroke: new ol.style.Stroke({ color: 'green', width: 1.25 })
|
|
});
|
|
var blueStyle = new ol.style.Style({
|
|
fill: new ol.style.Fill({ color: 'rgba(0,0,255,0.2)' }),
|
|
stroke: new ol.style.Stroke({ color: 'blue', width: 1.25 })
|
|
});
|
|
var redStyle = new ol.style.Style({
|
|
fill: new ol.style.Fill({ color: 'rgba(255,0,0,0.2)' }),
|
|
stroke: new ol.style.Stroke({ color: 'red', width: 1.25 })
|
|
});
|
|
|
|
// Pointer move
|
|
var current = [];
|
|
var start = false;
|
|
map.on(["pointermove", "click"], function(e)
|
|
{ // Coords
|
|
var h = grid.coord2hex(e.coordinate);
|
|
if (e.type!="click" && h[0]==current[0] && h[1]==current[1]) return;
|
|
current = h;
|
|
|
|
// Move
|
|
if (!text)
|
|
{ vector.getSource().clear();
|
|
var c = grid.hex2cube(grid.coord2hex(e.coordinate));
|
|
if (e.type=="click") start = c;
|
|
if (start)
|
|
{ var l = grid.cube_line(start, c);
|
|
for (var i=0; i<l.length; i++)
|
|
{ var ex = grid.getHexagon(grid.cube2hex(l[i]));
|
|
var f = new ol.Feature(new ol.geom.Polygon([ex]));
|
|
f.setStyle(redStyle);
|
|
vector.getSource().addFeature(f);
|
|
}
|
|
popup.show ( e.coordinate, "Move = "+(l.length-1)+" hexagon"+(l.length>2?"s":"") );
|
|
}
|
|
return;
|
|
}
|
|
|
|
//popup.hide();
|
|
|
|
vector.getSource().clear();
|
|
var ex = grid.getHexagon(h);
|
|
var f = new ol.Feature(new ol.geom.Polygon([ex]));
|
|
vector.getSource().addFeature(f);
|
|
|
|
var size = map.getSize();
|
|
size = Math.round( Math.max(size[0],size[1]) / grid.getSize() * map.getView().getResolution() / Math.sqrt(3) );
|
|
switch (text)
|
|
{ case 'cube':
|
|
var c = grid.hex2cube(h);
|
|
popup.show ( e.coordinate, "x: "+c[0]+", y: "+c[1]+", z: "+c[2]);
|
|
for (var x=-size; x<=size; x++)
|
|
{ if (x)
|
|
{ ex = grid.getHexagon (grid.cube2hex([c[0]+x,c[1]-x,c[2]]));
|
|
f = new ol.Feature(new ol.geom.Polygon([ex]));
|
|
f.setStyle(greenStyle);
|
|
vector.getSource().addFeature(f);
|
|
ex = grid.getHexagon (grid.cube2hex([c[0]+x,c[1],c[2]-x]));
|
|
f = new ol.Feature(new ol.geom.Polygon([ex]));
|
|
f.setStyle(blueStyle);
|
|
vector.getSource().addFeature(f);
|
|
ex = grid.getHexagon (grid.cube2hex([c[0],c[1]+x,c[2]-x]));
|
|
f = new ol.Feature(new ol.geom.Polygon([ex]));
|
|
f.setStyle(redStyle);
|
|
vector.getSource().addFeature(f);
|
|
}
|
|
}
|
|
break;
|
|
case 'axial':
|
|
popup.show ( e.coordinate, "x: "+h[0]+", y: "+h[1]);
|
|
for (var x=-size; x<=size; x++)
|
|
{ if (x)
|
|
{ ex = grid.getHexagon ([h[0]+x,h[1]]);
|
|
f = new ol.Feature(new ol.geom.Polygon([ex]));
|
|
f.setStyle(greenStyle);
|
|
vector.getSource().addFeature(f);
|
|
ex = grid.getHexagon ([h[0],h[1]+x]);
|
|
f = new ol.Feature(new ol.geom.Polygon([ex]));
|
|
f.setStyle(blueStyle);
|
|
vector.getSource().addFeature(f);
|
|
}
|
|
}
|
|
break;
|
|
case 'offset':
|
|
var o = grid.hex2offset(h);
|
|
popup.show ( e.coordinate, "x: "+o[0]+", y: "+o[1]);
|
|
for (var x=-size; x<=size; x++)
|
|
{ if (x)
|
|
{ ex = grid.getHexagon (grid.offset2hex([o[0]+x,o[1]]));
|
|
f = new ol.Feature(new ol.geom.Polygon([ex]));
|
|
f.setStyle(greenStyle);
|
|
vector.getSource().addFeature(f);
|
|
ex = grid.getHexagon (grid.offset2hex([o[0],o[1]+x]));
|
|
f = new ol.Feature(new ol.geom.Polygon([ex]));
|
|
f.setStyle(blueStyle);
|
|
vector.getSource().addFeature(f);
|
|
}
|
|
}
|
|
break;
|
|
default: break;
|
|
}
|
|
});
|
|
|
|
// Handle menu
|
|
$("label").click(function(){ $(this).prev().click(); });
|
|
$('input[name=action]').on('change', function()
|
|
{ var v = $('input[name=action]:checked').val();
|
|
vector.getSource().clear();
|
|
popup.hide();
|
|
start = false;
|
|
switch (v)
|
|
{ case 'axial':
|
|
case 'offset':
|
|
case 'cube':
|
|
text = v;
|
|
hex.showCoordiantes(v);
|
|
break;
|
|
default:
|
|
text = false;
|
|
hex.showCoordiantes(false);
|
|
break;
|
|
};
|
|
});
|
|
|
|
</script>
|
|
|
|
</body>
|
|
</html> |