Example #1
0
export function Tile(params) {
    // Required parameters
    if(isNone(params.cell)) {
		throw new Error('Missing Tile configuration');
	}
        
    let tile = {
        cell: withDefault(params.cell, null),
        material: withDefault(params.material, null)
    };
    
    // Check if we have a hexCell; if we do, destroy the old
    // reference and replace with this tile
    if(!isNone(tile.cell) && !isNone(tile.cell.tile)) {
        // Destroy old tile reference
        tile.cell.destroy();
    }
    // Replace tile reference in the hexCell with this tile
    tile.cell.tile = tile;
    
    // Default material
    if(isNone(tile.material)) {
        tile.material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
    }
    
    // Create mesh from geometry and material
    tile.mesh = new THREE.Mesh(tile.cell.geometry, tile.material);
    
    // Create RigidBody for physics calculations
    tile.planeShape = new Goblin.PlaneShape( 1, (tile.cell.width() / 2), (tile.cell.height() / 2) );

    // Reference the mesh position and rotation for ease of use
    tile.position = tile.mesh.position;
    tile.rotation = tile.mesh.rotation;
    
    // rotate the tile to face "up" (the threejs coordinate space is Y+)
	tile.rotation.x = -90 * DEG_TO_RAD;
	let scale = withDefault(params.scale, 1);
	tile.mesh.scale.set(scale, scale, 1);

	if (tile.material.emissive) {
		tile._emissive = tile.material.emissive.getHex();
	} else {
		tile._emissive = null;
	}
    
    return extend(tile, tileUtils);
};
Example #2
0
	generate: function(params) {
		if(isNone(params)) {
			params = {};
		}
		this.size = withDefault(params.size, this.size);
		let x, y, z;
		for (x = -this.size; x < this.size + 1; x++) {
			for (y = -this.size; y < this.size + 1; y++) {
				z = -x-y;
				if (Math.abs(x) <= this.size && Math.abs(y) <= this.size && Math.abs(z) <= this.size) {
					// Create a hexCell for the position in the grid
					let c = HexCell({
						q: x, 
						r: y, 
						s: z,
						hashDelimeter: this.hashDelimeter,
						size: this.cellSize
					});
					let t = Tile({
						cell: c,
						material: params.material
					});
					this.add(c);
				}
			}
		}
	},
Example #3
0
export function Player(params) {
    if(isNone(params)) {
        params = {};
    }
    
    let player = {
        geometry: withDefault(params.geometry, new THREE.BoxGeometry(1, 1, 1)),
        material: withDefault(params.material, new THREE.MeshBasicMaterial({color: 0xFF0000}))
    };

    player.mesh = new THREE.Mesh(player.geometry, player.material);
    
    var box_shape = new Goblin.BoxShape( 1, 1, 1), // dimensions are half width, half height, and half depth, or a box 1x1x1
        mass = 5,
        dynamic_box = new Goblin.RigidBody( box_shape, mass );
        
    player.rigidBody = dynamic_box;
    
    // Reference the mesh position and rotation for ease of use
    player.position = player.mesh.position;
    player.rotation = player.mesh.rotation;
    
    return extend(player, utils);
}
Example #4
0
export function HexGrid(params) {
	if(isNone(params)) {
		params = {};
	}
    let hexGrid = {
    	cellSize: withDefault(params.cellSize, 10),
    	cells: {},
    	hashDelimeter: withDefault(params.hashDelimeter, '-')
    };
    
    // pre-computed permutations
	hexGrid._directions = [
		HexCell({
			q: +1, 
			r: -1, 
			s: 0,
			size: hexGrid.cellSize
		}), 
		HexCell({
			q: +1, 
			r: 0, 
			s: -1,
			size: hexGrid.cellSize
		}), 
		HexCell({
			q: 0, 
			r: +1, 
			s: -1,
			size: hexGrid.cellSize
		}),				
		HexCell({
			q: -1, 
			r: +1, 
			s: 0,
			size: hexGrid.cellSize
		}), 
		HexCell({
			q: -1, 
			r: 0, 
			s: +1,
			size: hexGrid.cellSize
		}),
		HexCell({
			q: 0, 
			r: -1, 
			s: +1,
			size: hexGrid.cellSize
		})
	];
	// this._diagonals = [HexCell(+2, -1, -1), HexCell(+1, +1, -2), HexCell(-1, +2, -1),
	// 				   HexCell(-2, +1, +1), HexCell(-1, -1, +2), HexCell(+1, -2, +1)];
    
	// cached objects
	hexGrid._list = [];
	hexGrid._vec3 = new THREE.Vector3();
	hexGrid._cell = HexCell({
		q: 0, 
		r: 0, 
		s: 0,
		hashDelimeter: hexGrid.hashDelimeter,
		size: hexGrid.cellSize
	});
	hexGrid._conversionVec = new THREE.Vector3();
	hexGrid._geoCache = [];
	hexGrid._matCache = [];
    
    return extend(hexGrid, hexGridUtils);
};
Example #5
0
export function Tile(params) {
    let tileUtils = {
        inView(tile) {
            var hexsInLineToTarget = this.lineTo(tile);
            return hexsInLineToTarget
                .map(function(hex) {
                    // Map hexagons to tiles so we can access tile data
                    return this.map.getTile(hex.position);
                }.bind(this))
                .reduce(function(result, current) {
                    if(!result) {
                        return !current.blocksVisibility;
                    }
                    return result;
                }, false);
        },
        pathTo(targetTile) {
            let frontier = this.neighbors.map(function(neighbor) {
                var neighborTile = this.map.getTile(neighbor);
                return {
                    data: neighborTile,
                    priority: neighborTile.movementCost
                };
            }.bind(this));
            let visited = {};
            let cameFrom = {};
            let cost = {};
            visited[this.hash()] = null;
            cost[this.hash()] = 0;
            
            while(frontier.length > 0) {
                frontier = frontier.sort(function(a, b) {
                    return a.priority - b.priority;
                });
                // Pop off the current tile
                let current = frontier.pop().data;
                // Exit early if we found our target
                if(current.position.equals(targetTile.position)) {
                    break;
                }
                // Get the current tiles neighbors and add
                // them to the frontier if they haven't been visited
                current.neighbors
                    .map(function(neighbor) {
                        // Map neighbor hexagons to tiles so we can access tile data
                        return this.map.getTile(neighbor.position);
                    })
                    .forEach(function(neighbor) {
                        if(neighbor.passable) {
                            let newCost = cost[current.hash()] + neighbor.movementCost;
                            let neighborCost = cost[neighbor.hash()] || 0;
                            if(!visited[neighbor.hash()] || newCost < neighborCost) {
                                cost[neighbor.hash()] = newCost;
                                // Add current tile to came from so we can assemble a 
                                // path later
                                cameFrom[neighbor.hash()] = current;
                                frontier.push({
                                    data: neighbor,
                                    priority: newCost + neighbor.distanceTo(targetTile)
                                });
                            }
                        }
                    });
                // Add the current tile to visited
                visited[current.hash()] = current;
            }
            
            let path = [targetTile];
            let current = targetTile;
            let start = this.position;
            while(!current.position.equals(start)) {
               current = cameFrom[current.hash()];
               path.push(current);
            }
            path.reverse();
            return path;
        }
    };
    
    // Create our hexagon that we will be extending
    let hexagon = Hexagon(params);
    
    // Extend the hexagon and add any new properties
    let tile = extend(hexagon, {
        movementCost: withDefault(params.movementCost, 1),
        passable: withDefault(params.passable, true),
        blocksVisibility: withDefault(params.blocksVisibility, false),
        map: withDefault(params.map, Map())
    });
    
    return extend(tile, tileUtils);
};
Example #6
0
export function HexCell(params) {
	if(isNone(params)) {
        params = {};
    }
    
    let hexCell = {
        q: withDefault(params.q, 0),
        r: withDefault(params.r, 0),
        s: withDefault(params.s, 0),
        h: withDefault(params.h, 1),
        hashDelimeter: withDefault(params.hashDelimeter, '-'),
        tile: withDefault(params.tile, null),
        size: withDefault(params.size, 1),
        hexType: withDefault(fromEnum(params.hexType, HEX_TYPES), HEX_TYPES.FLAT),
    };
    
    // Calculate coordinates for the corners of the hexagon
    hexCell.corners = [];
    let offsetAngle = (hexCell.hexType === HEX_TYPES.FLAT ? 0 : 30);
    for(let i = 0; i < 6; i++) {
        hexCell.corners.push(corner(i, hexCell.size));
    }
    
    // Calculate neighbor matrix
    let x = hexCell.q;
    let y = hexCell.r;
    let z = hexCell.s;
    hexCell.neighbors = [
        new THREE.Vector3(x + 1, y - 1,  z + 0), new THREE.Vector3(x + 1, y + 0, z - 1), new THREE.Vector3(x + 0, y + 1, z - 1),
        new THREE.Vector3(x - 1, y + 1, z + 0), new THREE.Vector3(x - 1, y + 0, z + 1), new THREE.Vector3(x + 0, y - 1, z + 1)
    ];
    
    // Create geometry if we dont have one cached
    if(isNone(hexShapeGeo)) {
        hexShape = new THREE.Shape();
    	hexShape.moveTo(hexCell.corners[0].x, hexCell.corners[0].y);
    	for (let i = 1; i < 6; i++) {
    		hexShape.lineTo(hexCell.corners[i].x, hexCell.corners[i].y);
    	}
    	hexShape.lineTo(hexCell.corners[0].x, hexCell.corners[0].y);
    
    	hexGeo = new THREE.Geometry();
    	hexGeo.vertices = hexCell.corners;
    	hexGeo.verticesNeedUpdate = true;
    
    	hexShapeGeo = new THREE.ShapeGeometry(hexShape); 
    }
    
    
    
    // Add reference to the geometry on the hexagon
    hexCell.geometry = hexShapeGeo;
    
    // Extend hexCell metaobject with utils object
    hexCell = extend(hexCell, hexCellUtils);
    if(hexCell.hexType === HEX_TYPES.FLAT) {
        hexCell = extend(hexCell, flatHexagonUtils);
    } else if(hexCell.hexType === HEX_TYPES.POINTY) {
        hexCell = extend(hexCell, pointyHexagonUtils);
    }
	
	return hexCell;
};
Example #7
0
/* global THREE */
// HexCell object factory
import {extend, isNone, fromEnum, withDefault} from 'engineUtil';
import {TAU} from 'core/constants';

export let hexCellUtils = {
    set(q, r, s) {
		this.q = q;
		this.r = r;
		this.s = s;
		return this;
	},

	copy(hexCell) {
		this.q = withDefault(hexCell.q, 0);
		this.r = withDefault(hexCell.r, 0);
		this.s = withDefault(hexCell.s, 0);
		this.h = withDefault(hexCell.h, 1);
		this.tile = withDefault(hexCell.tile, null);
		return this;
	},

	add(hexCell) {
		this.q += hexCell.q;
		this.r += hexCell.r;
		this.s += hexCell.s;
		return this;
	},

	equals(hexCell) {
		return this.q === hexCell.q && this.r === hexCell.r && this.s === hexCell.s;