Room generation looks good
This commit is contained in:
@@ -1,163 +0,0 @@
|
||||
import standard;
|
||||
import node;
|
||||
import random;
|
||||
|
||||
//variables
|
||||
var gridPositionX: int = 1;
|
||||
var gridPositionY: int = 1;
|
||||
|
||||
var direction: int = null; //BUGFIX: animation not looping properly
|
||||
|
||||
var stepAI: int = 0;
|
||||
|
||||
//polyfills - animating different cycles on one image
|
||||
var walkAnimationCounter: int = 0;
|
||||
|
||||
fn faceDown(node: opaque) {
|
||||
if (direction == 0) return;
|
||||
direction = 0;
|
||||
node.setNodeRect(0, 0, 32, 32);
|
||||
node.setNodeFrames(2);
|
||||
walkAnimationCounter = 12;
|
||||
}
|
||||
|
||||
fn faceUp(node: opaque) {
|
||||
if (direction == 1) return;
|
||||
direction = 1;
|
||||
node.setNodeRect(32 * 2, 0, 32, 32);
|
||||
node.setNodeFrames(2);
|
||||
walkAnimationCounter = 12;
|
||||
}
|
||||
|
||||
fn faceRight(node: opaque) {
|
||||
if (direction == 2) return;
|
||||
direction = 2;
|
||||
node.setNodeRect(32 * 4, 0, 32, 32);
|
||||
node.setNodeFrames(2);
|
||||
walkAnimationCounter = 12;
|
||||
}
|
||||
|
||||
fn faceLeft(node: opaque) {
|
||||
if (direction == 3) return;
|
||||
direction = 3;
|
||||
node.setNodeRect(32 * 6, 0, 32, 32);
|
||||
node.setNodeFrames(2);
|
||||
walkAnimationCounter = 12;
|
||||
}
|
||||
|
||||
|
||||
//accessors & mutators
|
||||
fn setGridPosition(node: opaque, x: int, y: int) {
|
||||
gridPositionX = x;
|
||||
gridPositionY = y;
|
||||
|
||||
node.setNodePositionX(floor( gridPositionX * node.getNodeRectW() / node.getNodeScaleX() ));
|
||||
node.setNodePositionY(floor( gridPositionY * node.getNodeRectH() / node.getNodeScaleY() ));
|
||||
}
|
||||
|
||||
fn getGridPositionX(node: opaque) {
|
||||
return gridPositionX;
|
||||
}
|
||||
|
||||
fn getGridPositionY(node: opaque) {
|
||||
return gridPositionY;
|
||||
}
|
||||
|
||||
|
||||
//lifecycle functions
|
||||
fn onLoad(node: opaque) {
|
||||
node.loadNodeTexture("sprites:/drone.png");
|
||||
node.faceDown();
|
||||
|
||||
node.setNodeScaleX(CAMERA_SCALE_X);
|
||||
node.setNodeScaleY(CAMERA_SCALE_Y);
|
||||
}
|
||||
|
||||
//fn onUpdate(node: opaque, delta: int) {
|
||||
// //
|
||||
//}
|
||||
|
||||
fn onStep(node: opaque) {
|
||||
if (++walkAnimationCounter >= 12) {
|
||||
node.incrementCurrentNodeFrame();
|
||||
walkAnimationCounter = 0;
|
||||
}
|
||||
|
||||
//move in realspace
|
||||
var distX = gridPositionX * TILE_PIXEL_WIDTH - node.getNodePositionX();
|
||||
var distY = gridPositionY * TILE_PIXEL_HEIGHT - node.getNodePositionY();
|
||||
|
||||
node.setNodeMotionX( normalize(distX) );
|
||||
node.setNodeMotionY( normalize(distY) );
|
||||
}
|
||||
|
||||
fn onFree(node: opaque) {
|
||||
node.freeNodeTexture();
|
||||
}
|
||||
|
||||
fn onDraw(node: opaque) {
|
||||
var posX: int = node.getNodeWorldPositionX();
|
||||
var posY: int = node.getNodeWorldPositionY();
|
||||
|
||||
var scaleX: float = node.getNodeWorldScaleX();
|
||||
var scaleY: float = node.getNodeWorldScaleY();
|
||||
|
||||
//this offset is because the sprite cell for lejana is twice as big as the sprite cell for the floor tiles
|
||||
var originOffsetX: int = node.getNodeRectW() * int scaleX / 4;
|
||||
var originOffsetY: int = node.getNodeRectH() * int scaleY / 2;
|
||||
|
||||
node.drawNode(
|
||||
floor(posX * scaleX) - originOffsetX + globalCameraX,
|
||||
floor(posY * scaleY) - originOffsetY + globalCameraY,
|
||||
floor(node.getNodeRectW() * scaleX),
|
||||
floor(node.getNodeRectH() * scaleY)
|
||||
);
|
||||
}
|
||||
|
||||
//gameplay functions
|
||||
fn runAI(node: opaque, rng: opaque) {
|
||||
if (stepAI++ >= 1) {
|
||||
stepAI = 0;
|
||||
|
||||
var dir = rng.generateRandomNumber() % 4;
|
||||
var moveX = 0;
|
||||
var moveY = 0;
|
||||
|
||||
if (dir == 0) {
|
||||
moveY += 1;
|
||||
node.faceDown();
|
||||
}
|
||||
|
||||
if (dir == 1) {
|
||||
moveY -= 1;
|
||||
node.faceUp();
|
||||
}
|
||||
|
||||
if (dir == 2) {
|
||||
moveX += 1;
|
||||
node.faceRight();
|
||||
}
|
||||
|
||||
if (dir == 3) {
|
||||
moveX -= 1;
|
||||
node.faceLeft();
|
||||
}
|
||||
|
||||
if (node.getParentNode().callNodeFn("getWalkableAt", gridPositionX + moveX, gridPositionY + moveY)) {
|
||||
gridPositionX += moveX;
|
||||
gridPositionY += moveY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//polyfills - move these to standard
|
||||
fn normalize(x): int {
|
||||
if (x > 0) {
|
||||
return 1;
|
||||
}
|
||||
if (x < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,258 +0,0 @@
|
||||
import standard;
|
||||
import node;
|
||||
|
||||
var gridPositionX: int = 1; //position on the game grid
|
||||
var gridPositionY: int = 1;
|
||||
|
||||
var inputX: int = 0; //cache the keyboard input
|
||||
var inputY: int = 0;
|
||||
|
||||
var direction: int = null; //BUGFIX: animation not looping properly
|
||||
var enableMovementCounter: int = 60 * 3; //BUGFIX: freeze while drones reach their starting spot
|
||||
|
||||
//polyfills - animating different cycles on one image
|
||||
var walkAnimationCounter: int = 0;
|
||||
var attackAnimationCounter: int = 0;
|
||||
|
||||
//utils for facing different directions (idling)
|
||||
fn faceDown(node: opaque) {
|
||||
if (direction == 0) return;
|
||||
direction = 0;
|
||||
node.setNodeRect(0, 0, 32, 32);
|
||||
node.setNodeFrames(4);
|
||||
walkAnimationCounter = 12;
|
||||
}
|
||||
|
||||
fn faceUp(node: opaque) {
|
||||
if (direction == 1) return;
|
||||
direction = 1;
|
||||
node.setNodeRect(32 * 4, 0, 32, 32);
|
||||
node.setNodeFrames(4);
|
||||
walkAnimationCounter = 12;
|
||||
}
|
||||
|
||||
fn faceRight(node: opaque) {
|
||||
if (direction == 2) return;
|
||||
direction = 2;
|
||||
node.setNodeRect(32 * 8, 0, 32, 32);
|
||||
node.setNodeFrames(4);
|
||||
walkAnimationCounter = 12;
|
||||
}
|
||||
|
||||
fn faceLeft(node: opaque) {
|
||||
if (direction == 3) return;
|
||||
direction = 3;
|
||||
node.setNodeRect(32 * 12, 0, 32, 32);
|
||||
node.setNodeFrames(4);
|
||||
walkAnimationCounter = 12;
|
||||
}
|
||||
|
||||
//accessors & mutators
|
||||
fn setGridPosition(node: opaque, x: int, y: int) {
|
||||
gridPositionX = x;
|
||||
gridPositionY = y;
|
||||
|
||||
node.setNodePositionX(floor( gridPositionX * node.getNodeRectW() / node.getNodeScaleX() ));
|
||||
node.setNodePositionY(floor( gridPositionY * node.getNodeRectH() / node.getNodeScaleY() ));
|
||||
}
|
||||
|
||||
fn getGridPositionX(node: opaque) {
|
||||
return gridPositionX;
|
||||
}
|
||||
|
||||
fn getGridPositionY(node: opaque) {
|
||||
return gridPositionY;
|
||||
}
|
||||
|
||||
//lifecycle functions
|
||||
fn onLoad(node: opaque) {
|
||||
node.loadNodeTexture("sprites:/lejana.png"); //NOTE: all of this script is mapped to this sprite sheet
|
||||
node.faceDown();
|
||||
|
||||
node.setNodeScaleX(CAMERA_SCALE_X);
|
||||
node.setNodeScaleY(CAMERA_SCALE_Y);
|
||||
}
|
||||
|
||||
//fn onUpdate(node: opaque, delta: int) {
|
||||
// //
|
||||
//}
|
||||
|
||||
fn onStep(node: opaque) {
|
||||
//initial freeze
|
||||
if (enableMovementCounter > 0) {
|
||||
enableMovementCounter--;
|
||||
return;
|
||||
}
|
||||
|
||||
//animation - start idling
|
||||
if (attackAnimationCounter == 0) {
|
||||
//move to standing state
|
||||
if (node.getNodeRectY() != 0) {
|
||||
node.setNodeRect(direction * 32 * 4, 0, 32, 32);
|
||||
node.setNodeFrames(4);
|
||||
walkAnimationCounter = 12;
|
||||
}
|
||||
}
|
||||
|
||||
//animation - start attacking
|
||||
if (--attackAnimationCounter >= 0) {
|
||||
//move to attacking state
|
||||
if (node.getNodeRectY() != 32) {
|
||||
node.setNodeRect(direction * 32 * 4, 32, 32, 32);
|
||||
node.setNodeFrames(3);
|
||||
}
|
||||
|
||||
if ((attackAnimationCounter+1) % 4 == 0) { //+1 for a bugfix
|
||||
node.incrementCurrentNodeFrame();
|
||||
}
|
||||
|
||||
//skip out
|
||||
return;
|
||||
}
|
||||
|
||||
//facing
|
||||
if (inputY > 0) {
|
||||
node.faceDown();
|
||||
}
|
||||
|
||||
else if (inputY < 0) {
|
||||
node.faceUp();
|
||||
}
|
||||
|
||||
else if (inputX > 0) {
|
||||
node.faceRight();
|
||||
}
|
||||
|
||||
else if (inputX < 0) {
|
||||
node.faceLeft();
|
||||
}
|
||||
|
||||
//BUGFIX for smooth animation fo
|
||||
var lesser = 0;
|
||||
if ((inputX != 0 || inputY != 0) && attackAnimationCounter == 0) {
|
||||
lesser = 6;
|
||||
}
|
||||
|
||||
//actually animate
|
||||
if (--walkAnimationCounter <= lesser) {
|
||||
node.incrementCurrentNodeFrame();
|
||||
walkAnimationCounter = 12;
|
||||
}
|
||||
|
||||
var parent = node.getParentNode(); //check for collisions from the parent
|
||||
|
||||
if (parent.callNodeFn("getWalkableAt", gridPositionX + inputX, gridPositionY + inputY) && abs(inputX) != abs(inputY)) {
|
||||
//calc movement
|
||||
gridPositionX += inputX;
|
||||
gridPositionY += inputY;
|
||||
|
||||
parent.callNodeFn("runAI");
|
||||
}
|
||||
|
||||
//move in realspace
|
||||
var distX = gridPositionX * TILE_PIXEL_WIDTH - node.getNodePositionX();
|
||||
var distY = gridPositionY * TILE_PIXEL_HEIGHT - node.getNodePositionY();
|
||||
|
||||
node.setNodeMotionX( normalize(distX) );
|
||||
node.setNodeMotionY( normalize(distY) );
|
||||
|
||||
//reset input
|
||||
inputX = 0;
|
||||
inputY = 0;
|
||||
}
|
||||
|
||||
fn onFree(node: opaque) {
|
||||
node.freeNodeTexture();
|
||||
}
|
||||
|
||||
fn onDraw(node: opaque) {
|
||||
var posX: int = node.getNodeWorldPositionX();
|
||||
var posY: int = node.getNodeWorldPositionY();
|
||||
|
||||
var scaleX: float = node.getNodeWorldScaleX();
|
||||
var scaleY: float = node.getNodeWorldScaleY();
|
||||
|
||||
//this offset is because the sprite cell for lejana is twice as big as the sprite cell for the floor tiles
|
||||
var originOffsetX: int = player.getNodeRectW() / 2;
|
||||
var originOffsetY: int = player.getNodeRectH();
|
||||
|
||||
node.drawNode(
|
||||
floor(posX * scaleX) - originOffsetX + globalCameraX,
|
||||
floor(posY * scaleY) - originOffsetY + globalCameraY,
|
||||
floor(node.getNodeRectW() * scaleX),
|
||||
floor(node.getNodeRectH() * scaleY)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//event functions
|
||||
fn onKeyDown(node: opaque, event: string) {
|
||||
//initial freeze
|
||||
if (enableMovementCounter > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//enable attack
|
||||
if (event == "character_attack" && inputX == 0 && inputY == 0) {
|
||||
attackAnimationCounter = 12;
|
||||
return;
|
||||
}
|
||||
|
||||
//if moving, don't take any more input
|
||||
if (node.getNodeMotionX() != 0 || node.getNodeMotionY() != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == "character_up") {
|
||||
inputY -= 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == "character_down") {
|
||||
inputY += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == "character_left") {
|
||||
inputX -= 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == "character_right") {
|
||||
inputX += 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fn onKeyUp(node: opaque, event: string) {
|
||||
if (event == "character_up" && inputY < 0) {
|
||||
inputY = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == "character_down" && inputY > 0) {
|
||||
inputY = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == "character_left" && inputX < 0) {
|
||||
inputX = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == "character_right" && inputX > 0) {
|
||||
inputX = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//polyfills - move these to standard
|
||||
fn normalize(x): int {
|
||||
if (x > 0) {
|
||||
return 1;
|
||||
}
|
||||
if (x < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
import standard;
|
||||
import node;
|
||||
import random;
|
||||
|
||||
|
||||
//persistent members
|
||||
var tilemap: opaque = null;
|
||||
var stepCounter: opaque = null;
|
||||
var player: opaque = null;
|
||||
var enemies: [opaque] = null;
|
||||
|
||||
var collisionDataCache: [bool] = null;
|
||||
|
||||
var rng: opaque = null; //TODO: does this have an opaque tag?
|
||||
|
||||
//lifecycle functions
|
||||
fn onInit(node: opaque) {
|
||||
//load the map stuff
|
||||
tilemap = node.loadChild("scripts:/gameplay/tilemap.toy");
|
||||
node.generateScene(clock().hash(), MAP_GRID_WIDTH, MAP_GRID_HEIGHT);
|
||||
|
||||
//load and initialize the UI (depends on map stuff)
|
||||
stepCounter = node.loadChild("scripts:/gameplay/step-counter.toy");
|
||||
stepCounter.setNodeRect(0, 0, CAMERA_SCREEN_W, 32);
|
||||
stepCounter.callNodeFn("setMaxSteps", 100);
|
||||
stepCounter.setNodeLayer(100);
|
||||
|
||||
//offset the scene node, so it shows the map outside separate from the UI
|
||||
node.setNodePositionY(16);
|
||||
}
|
||||
|
||||
fn onFree(node: opaque) {
|
||||
//cleanup
|
||||
if (rng != null) {
|
||||
rng.freeRandomGenerator();
|
||||
}
|
||||
}
|
||||
|
||||
// fn onUpdate(node: opaque, delta: int) {
|
||||
// print "delta: " + string delta;
|
||||
// }
|
||||
|
||||
//fn onStep(node: opaque) {
|
||||
// //
|
||||
//}
|
||||
|
||||
fn onDraw(node: opaque) {
|
||||
//use the onDraw to sort - skip too many steps
|
||||
node.sortChildrenNode(depthComparator);
|
||||
|
||||
var scaleX: float = player.getNodeWorldScaleX();
|
||||
var scaleY: float = player.getNodeWorldScaleY();
|
||||
|
||||
//this offset is because the sprite cell for lejana is twice as big as the sprite cell for the floor tiles
|
||||
var originOffsetX: int = player.getNodeRectW() / 2;
|
||||
var originOffsetY: int = player.getNodeRectH() / 2;
|
||||
|
||||
//use the room scene's onDraw to set the global camera position
|
||||
globalCameraX = floor((CAMERA_SCREEN_W / 2) - (player.getNodeWorldPositionX() * scaleX)) - originOffsetX;
|
||||
globalCameraY = floor((CAMERA_SCREEN_H / 2) - (player.getNodeWorldPositionY() * scaleY)) - originOffsetY;
|
||||
}
|
||||
|
||||
//gameplay functions
|
||||
fn generateScene(node: opaque, seed: int, width: int, height: int) {
|
||||
//reset the array
|
||||
enemies = [];
|
||||
|
||||
if (rng != null) {
|
||||
rng.freeRandomGenerator();
|
||||
}
|
||||
rng = createRandomGenerator(seed);
|
||||
|
||||
//generate map
|
||||
tilemap.callNodeFn("generateFromRng", rng, width, height);
|
||||
collisionDataCache = tilemap.callNodeFn("getCollisionData");
|
||||
|
||||
//place player here, so drop dropping can avoid the player
|
||||
player = node.loadChild("scripts:/gameplay/lejana.toy");
|
||||
player.callNodeFn("setGridPosition", 1, 1);
|
||||
|
||||
//generate drones
|
||||
var droneCount: int const = rng.generateRandomNumber() % 2 + 20;
|
||||
for (var i = 0; i < droneCount; i++) {
|
||||
var d: opaque = node.loadChild("scripts:/gameplay/drone.toy");
|
||||
d.initNode();
|
||||
|
||||
enemies.push(d);
|
||||
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
|
||||
//while generated spot is a collision, or too close to the player
|
||||
while (x == 0 && y == 0 || node.getWalkableAt(x, y) == false || x < width / 6 * 2 && y < height / 6 * 2) {
|
||||
x = rng.generateRandomNumber() % width;
|
||||
y = rng.generateRandomNumber() % height;
|
||||
}
|
||||
|
||||
d.callNodeFn("setGridPosition", x, y);
|
||||
d.setNodePositionX(MAP_GRID_WIDTH * TILE_PIXEL_WIDTH);
|
||||
d.setNodePositionY(MAP_GRID_HEIGHT * TILE_PIXEL_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
fn getWalkableAt(node: opaque, x: int, y: int) {
|
||||
if (collisionDataCache == null || x == null || y == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//entities
|
||||
if (x == player.callNodeFn("getGridPositionX") && y == player.callNodeFn("getGridPositionY")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < enemies.length(); i++) {
|
||||
if (x == enemies[i].callNodeFn("getGridPositionX") && y == enemies[i].callNodeFn("getGridPositionY")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//outside the grid
|
||||
if (y * MAP_GRID_WIDTH + x < 0 || y * MAP_GRID_WIDTH + x >= collisionDataCache.length()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//default
|
||||
return collisionDataCache[y * MAP_GRID_WIDTH + x];
|
||||
}
|
||||
|
||||
fn runAI(node: opaque) {
|
||||
for (var i = 0; i < enemies.length(); i++) {
|
||||
enemies[i].callNodeFn("runAI", rng);
|
||||
}
|
||||
|
||||
stepCounter.callNodeFn("alterRemainingSteps", -1);
|
||||
}
|
||||
|
||||
//utils - polyfills
|
||||
fn loadChild(parent: opaque, fname: string) {
|
||||
//TODO: add this to the API proper
|
||||
var child: opaque = loadNode(fname);
|
||||
parent.pushNode(child);
|
||||
return child;
|
||||
}
|
||||
|
||||
fn depthComparator(lhs: opaque, rhs: opaque) { //for sorting by depth
|
||||
var lhsPositionY = lhs.getNodeWorldPositionY();
|
||||
var rhsPositionY = rhs.getNodeWorldPositionY();
|
||||
|
||||
if (lhsPositionY == null || rhsPositionY == null) { //BUGFIX: children without that function
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lhsPositionY == rhsPositionY) { //BUGFIX: prevent z-fighting
|
||||
var lhsPositionX = lhs.getNodeWorldPositionX();
|
||||
var rhsPositionX = rhs.getNodeWorldPositionX();
|
||||
|
||||
return lhsPositionX < rhsPositionX;
|
||||
}
|
||||
|
||||
return lhsPositionY < rhsPositionY;
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
import node;
|
||||
|
||||
//members
|
||||
var maxSteps: int = 0;
|
||||
var remainingSteps: int = 0;
|
||||
|
||||
//accessors
|
||||
fn getMaxSteps(node: opaque) {
|
||||
return maxSteps;
|
||||
}
|
||||
|
||||
fn getRemainingSteps(node: opaque) {
|
||||
return remainingSteps;
|
||||
}
|
||||
|
||||
//mutators
|
||||
fn setMaxSteps(node: opaque, steps: int) {
|
||||
maxSteps = steps;
|
||||
remainingSteps = steps;
|
||||
}
|
||||
|
||||
fn setRemainingSteps(node: opaque, steps: int) {
|
||||
remainingSteps = steps;
|
||||
}
|
||||
|
||||
//utility mutators
|
||||
fn alterRemainingSteps(node: opaque, increment: int) {
|
||||
remainingSteps += increment;
|
||||
if (remainingSteps > maxSteps) {
|
||||
remainingSteps = maxSteps;
|
||||
}
|
||||
|
||||
if (remainingSteps < 0) {
|
||||
remainingSteps = 0;
|
||||
}
|
||||
|
||||
return remainingSteps;
|
||||
}
|
||||
|
||||
//utils - polyfills
|
||||
fn loadChild(parent: opaque, fname: string) {
|
||||
var child: opaque = loadNode(fname);
|
||||
parent.pushNode(child);
|
||||
child.setNodeLayer(parent.getNodeLayer());
|
||||
return child;
|
||||
}
|
||||
|
||||
//lifecycle functions
|
||||
fn onLoad(node: opaque) {
|
||||
node.loadNodeTexture("sprites:/stepcounter.png");
|
||||
|
||||
node
|
||||
.loadChild("scripts:/gameplay/text.toy")
|
||||
.setNodeText("fonts:/alphbeta.ttf", 32, "Water", 0, 60, 240, 255); //rgba
|
||||
}
|
||||
|
||||
fn onFree(node: opaque) {
|
||||
node.freeNodeTexture();
|
||||
}
|
||||
|
||||
fn onDraw(node: opaque) {
|
||||
if (remainingSteps > 0 && maxSteps > 0) {
|
||||
var tmp = float remainingSteps / maxSteps * node.getNodeRectW();
|
||||
var h = node.getNodeRectH();
|
||||
|
||||
node.drawNode(node.getNodePositionX(), node.getNodePositionY(), int tmp, h);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import node;
|
||||
|
||||
//this is a child of the step counter, which simply renders text
|
||||
|
||||
fn onDraw(node: opaque) {
|
||||
var posX: int = node.getNodePositionX();
|
||||
var posY: int = node.getNodePositionY();
|
||||
var scaleX: float = node.getNodeScaleX();
|
||||
var scaleY: float = node.getNodeScaleY();
|
||||
|
||||
node.drawNode(floor(posX * scaleX), floor(posY * scaleY));
|
||||
}
|
||||
|
||||
fn onFree(node: opaque) {
|
||||
node.freeNodeTexture();
|
||||
}
|
||||
|
||||
//TODO: polyfill?
|
||||
@@ -1,187 +0,0 @@
|
||||
import standard;
|
||||
import node;
|
||||
|
||||
//constants mapped to the given file "tileset.png"
|
||||
var tileset: [string : [int]] const = [
|
||||
"empty": [-1. -1, -1],
|
||||
|
||||
"pillar": [0, 0, 0],
|
||||
|
||||
"floor-0": [0, 1, 1],
|
||||
"floor-1": [1, 1, 1],
|
||||
"floor-2": [2, 1, 1],
|
||||
"floor-3": [3, 1, 1],
|
||||
|
||||
"wall-t": [0, 2, 0],
|
||||
"wall-b": [1, 2, 0],
|
||||
"wall-l": [2, 2, 0],
|
||||
"wall-r": [3, 2, 0],
|
||||
|
||||
"corner-tl": [0, 3, 0],
|
||||
"corner-tr": [1, 3, 0],
|
||||
"corner-bl": [2, 3, 0],
|
||||
"corner-br": [3, 3, 0],
|
||||
|
||||
"edge-tl": [0, 4, 0],
|
||||
"edge-tr": [1, 4, 0],
|
||||
"edge-bl": [2, 4, 0],
|
||||
"edge-br": [3, 4, 0]
|
||||
];
|
||||
|
||||
//raw string data
|
||||
var rawmap: [[string]] = null;
|
||||
|
||||
//baked and usable blobs of data
|
||||
var tilemap: [int] = null; // [x0, y0, x1, y1, ...]
|
||||
var collisions: [bool] = null;
|
||||
|
||||
//metadata about the above blobs
|
||||
var tilemapGridWidth: int = 0;
|
||||
var tilemapGridHeight: int = 0;
|
||||
|
||||
//fast accessors
|
||||
fn getTilemapData(node: opaque) {
|
||||
return tilemap;
|
||||
}
|
||||
|
||||
fn getCollisionData(node: opaque) {
|
||||
return collisions;
|
||||
}
|
||||
|
||||
//lifecycle functions
|
||||
fn onLoad(node: opaque) {
|
||||
node.loadNodeTexture("sprites:/tileset.png");
|
||||
|
||||
node.setNodeScaleX(CAMERA_SCALE_X);
|
||||
node.setNodeScaleY(CAMERA_SCALE_Y);
|
||||
}
|
||||
|
||||
fn onDraw(node: opaque) {
|
||||
assert tilemap, "tilemap is null";
|
||||
|
||||
var posX: int const = node.getNodeWorldPositionX();
|
||||
var posY: int const = node.getNodeWorldPositionY();
|
||||
|
||||
//draw everything at twice the original size
|
||||
var scaleX: float const = node.getNodeWorldScaleX();
|
||||
var scaleY: float const = node.getNodeWorldScaleY();
|
||||
|
||||
//draw the tilemap
|
||||
for (var j = 0; j < tilemapGridHeight; j++) {
|
||||
for (var i = 0; i < tilemapGridWidth; i++) {
|
||||
//set the rect of the node on the tilesheet - the "tilemap" var is a single blob of data
|
||||
node.setNodeRect(
|
||||
tilemap[j * tilemapGridWidth * 2 + i * 2] * TILE_PIXEL_WIDTH,
|
||||
tilemap[j * tilemapGridWidth * 2 + i * 2 + 1] * TILE_PIXEL_HEIGHT,
|
||||
TILE_PIXEL_WIDTH, TILE_PIXEL_HEIGHT
|
||||
);
|
||||
|
||||
//draw to the screen
|
||||
node.drawNode(
|
||||
floor((i * TILE_PIXEL_WIDTH + posX) * scaleX) + globalCameraX,
|
||||
floor((j * TILE_PIXEL_HEIGHT + posY) * scaleY) + globalCameraY,
|
||||
floor(TILE_PIXEL_WIDTH * scaleX),
|
||||
floor(TILE_PIXEL_HEIGHT * scaleY)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//utils functions for map generation
|
||||
fn generateFromRng(node: opaque, rng: opaque, width: int, height: int) {
|
||||
//use debug room for now
|
||||
rawmap = generateRawTilemapDebugRoom(rng, width, height);
|
||||
|
||||
tilemap = bakeTilemap(rawmap, width, height);
|
||||
collisions = bakeCollisionMap(rawmap, width, height);
|
||||
|
||||
tilemapGridWidth = width;
|
||||
tilemapGridHeight = height;
|
||||
|
||||
//debugging
|
||||
print tilemap;
|
||||
print collisions;
|
||||
}
|
||||
|
||||
//"raw" tilemaps are not usable, they are just a 2d array of strings
|
||||
fn generateRawTilemapDebugRoom(rng: opaque, width: int, height: int): [[string]] const {
|
||||
import random;
|
||||
|
||||
//generate a grid filled with only pillar tiles, as a starting point
|
||||
var result: [[string]] = [];
|
||||
var row: [string] = [];
|
||||
for (var j: int = 0; j < height; j++) {
|
||||
row.push("pillar");
|
||||
}
|
||||
for (var i: int = 0; i < width; i++) {
|
||||
result.push(row);
|
||||
}
|
||||
|
||||
//generate the walkable tiles of the grid - floor tiles
|
||||
for (var j: int = 1; j < height - 1; j++) {
|
||||
for (var i: int = 1; i < width - 1; i++) {
|
||||
//select a random floor tile (graphical effect only)
|
||||
var x: int = rng.generateRandomNumber() % 4;
|
||||
var t: string = "floor-" + string x;
|
||||
|
||||
result[i][j] = t;
|
||||
}
|
||||
}
|
||||
|
||||
//draw top and bottom walls
|
||||
for (var i: int = 1; i < width - 1; i++) {
|
||||
result[i][0] = "wall-t";
|
||||
result[i][height - 1] = "wall-b";
|
||||
}
|
||||
|
||||
//draw the left and right walls
|
||||
for (var j: int = 1; j < height - 1; j++) {
|
||||
result[0][j] = "wall-l";
|
||||
result[width-1][j] = "wall-r";
|
||||
}
|
||||
|
||||
//draw the corners
|
||||
result[0][0] = "corner-tl";
|
||||
result[width - 1][0] = "corner-tr";
|
||||
result[0][height - 1] = "corner-bl";
|
||||
result[width - 1][height - 1] = "corner-br";
|
||||
|
||||
//debugging
|
||||
result[4][4] = "pillar";
|
||||
result[width - 5][4] = "pillar";
|
||||
result[4][height - 5] = "pillar";
|
||||
result[width - 5][height - 5] = "pillar";
|
||||
|
||||
//return the raw result of strings
|
||||
return result;
|
||||
}
|
||||
|
||||
//"baking" converts raw tilemaps into usable blobs of data
|
||||
fn bakeTilemap(tilemap: [[string]] const, width: int, height: int): [int] const {
|
||||
var result: [int] = [];
|
||||
|
||||
//extract the positions from the tileset
|
||||
for (var j: int = 0; j < height; j++) {
|
||||
for (var i: int = 0; i < width; i++) {
|
||||
result.push(tileset[ tilemap[i][j] ][0]);
|
||||
result.push(tileset[ tilemap[i][j] ][1]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//this bakes the collision map as a separate object
|
||||
fn bakeCollisionMap(tilemap: [[string]] const, width: int, height: int): [bool] const {
|
||||
var result: [bool] = [];
|
||||
|
||||
//extract the walkable state
|
||||
for (var j: int = 0; j < height; j++) {
|
||||
for (var i: int = 0; i < width; i++) {
|
||||
result.push(tileset[ tilemap[i][j] ][2] != 0);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -24,8 +24,8 @@ var tileset: [string : [int]] const = [
|
||||
|
||||
"temple-edge-tl": [0, 4, 0],
|
||||
"temple-edge-tr": [1, 4, 0],
|
||||
"temple-edge-bl": [2, 4, 0],
|
||||
"temple-edge-br": [3, 4, 0]
|
||||
"temple-edge-bl": [3, 4, 0], //would be great if these were the right way around...
|
||||
"temple-edge-br": [2, 4, 0]
|
||||
];
|
||||
|
||||
var themes: [string] const = [
|
||||
@@ -104,7 +104,8 @@ fn generateTilemapData(rng: opaque) {
|
||||
//etch the corridors
|
||||
etchCorridors(roomData, corridorData, rng);
|
||||
|
||||
//TODO: etch the walls with a filter, based on the room's themes
|
||||
//etch the walls with marching squares, based on the room's themes
|
||||
etchWalls(roomData);
|
||||
|
||||
//save the metadata for later retrieval
|
||||
metadata = roomData;
|
||||
@@ -153,52 +154,6 @@ fn etchRoom(rng: opaque, metadata: [string: any]) {
|
||||
tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 2] = tileset[theme + "-floor-" + string floorIndex][2];
|
||||
}
|
||||
}
|
||||
|
||||
// //create the string constants here, so refstring can do it's job
|
||||
// var T_WALL: [int] const = tileset[ theme + "-wall-t" ];
|
||||
// var B_WALL: [int] const = tileset[ theme + "-wall-b" ];
|
||||
// var L_WALL: [int] const = tileset[ theme + "-wall-l" ];
|
||||
// var R_WALL: [int] const = tileset[ theme + "-wall-r" ];
|
||||
|
||||
// //etch the walls of each room
|
||||
// for (var i: int = x; i < x + w; i++) {
|
||||
// tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 0] = T_WALL[0];
|
||||
// tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 1] = T_WALL[1];
|
||||
// tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 2] = T_WALL[2];
|
||||
|
||||
// tilemap[(h + y - 1) * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 0] = B_WALL[0];
|
||||
// tilemap[(h + y - 1) * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 1] = B_WALL[1];
|
||||
// tilemap[(h + y - 1) * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 2] = B_WALL[2];
|
||||
// }
|
||||
|
||||
// for (var j: int = y; j < y + h; j++) {
|
||||
// tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 0] = L_WALL[0];
|
||||
// tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 1] = L_WALL[1];
|
||||
// tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 2] = L_WALL[2];
|
||||
|
||||
// tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + (x + w - 1) * 3 + 0] = R_WALL[0];
|
||||
// tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + (x + w - 1) * 3 + 1] = R_WALL[1];
|
||||
// tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + (x + w - 1) * 3 + 2] = R_WALL[2];
|
||||
// }
|
||||
|
||||
// //etch the corners
|
||||
// tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 0] = tileset[ theme + "-corner-tl" ][0];
|
||||
// tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 1] = tileset[ theme + "-corner-tl" ][1];
|
||||
// tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 2] = tileset[ theme + "-corner-tl" ][2];
|
||||
|
||||
// tilemap[(h + y - 1) * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 0] = tileset[ theme + "-corner-bl" ][0];
|
||||
// tilemap[(h + y - 1) * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 1] = tileset[ theme + "-corner-bl" ][1];
|
||||
// tilemap[(h + y - 1) * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 2] = tileset[ theme + "-corner-bl" ][2];
|
||||
|
||||
|
||||
// tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + (x + w - 1) * 3 + 0] = tileset[ theme + "-corner-tr" ][0];
|
||||
// tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + (x + w - 1) * 3 + 1] = tileset[ theme + "-corner-tr" ][1];
|
||||
// tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + (x + w - 1) * 3 + 2] = tileset[ theme + "-corner-tr" ][2];
|
||||
|
||||
|
||||
// tilemap[(h + y - 1) * CELL_WIDTH * CELL_COUNT_X * 3 + (x + w - 1) * 3 + 0] = tileset[ theme + "-corner-br" ][0];
|
||||
// tilemap[(h + y - 1) * CELL_WIDTH * CELL_COUNT_X * 3 + (x + w - 1) * 3 + 1] = tileset[ theme + "-corner-br" ][1];
|
||||
// tilemap[(h + y - 1) * CELL_WIDTH * CELL_COUNT_X * 3 + (x + w - 1) * 3 + 2] = tileset[ theme + "-corner-br" ][2];
|
||||
}
|
||||
|
||||
fn generateCorridorData(rng: opaque) {
|
||||
@@ -419,6 +374,189 @@ fn etchLine(x: int, y: int, xLength: int, yLength: int, theme: string, rng: opaq
|
||||
}
|
||||
}
|
||||
|
||||
fn etchWalls(roomData) {
|
||||
//zero'd signals
|
||||
var signals: [string] = [];
|
||||
|
||||
for (var j: int = 0; j < CELL_COUNT_Y * CELL_HEIGHT; j++) {
|
||||
for (var i: int = 0; i < CELL_COUNT_X * CELL_WIDTH; i++) {
|
||||
signals.push(""); //empty
|
||||
}
|
||||
}
|
||||
|
||||
//determine the walls' layout from the tilemap
|
||||
for (var i: int = 0; i < MAP_GRID_WIDTH; i++) {
|
||||
for (var j: int = 0; j < MAP_GRID_HEIGHT; j++) {
|
||||
signals[j * MAP_GRID_WIDTH + i] = parseTilemapAt(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
//etch the walls into the tilemap, based on the room theme
|
||||
for (var i: int = 0; i < MAP_GRID_WIDTH; i++) {
|
||||
for (var j: int = 0; j < MAP_GRID_HEIGHT; j++) {
|
||||
if (signals[j * MAP_GRID_WIDTH + i] == "") {
|
||||
continue;
|
||||
}
|
||||
|
||||
var theme = roomData[floor(i / CELL_WIDTH)][floor(j / CELL_HEIGHT)]["theme"];
|
||||
tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 0] = tileset[theme + "-" + signals[j * MAP_GRID_WIDTH + i]][0];
|
||||
tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 1] = tileset[theme + "-" + signals[j * MAP_GRID_WIDTH + i]][1];
|
||||
tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 2] = tileset[theme + "-" + signals[j * MAP_GRID_WIDTH + i]][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
//lets say snapshot looks like this
|
||||
snapshot:
|
||||
|
||||
0, 0, 1
|
||||
0, 0, 1
|
||||
0, 0, 1
|
||||
|
||||
result should be "wall-l",
|
||||
|
||||
//lets say filter looks like this
|
||||
filter:
|
||||
|
||||
1 1 1 1 1
|
||||
1 0 0 0 1
|
||||
1 0 0 0 1
|
||||
1 0 0 0 1
|
||||
1 1 1 1 1
|
||||
|
||||
find the position within the filter, that gives the result "wall-l"
|
||||
|
||||
//lets say result looks like this
|
||||
|
||||
"edge-br" "wall-b" "edge-bl"
|
||||
"wall-r" "pillar" "wall-l"
|
||||
"edge-tr" "wall-t" "edge-tl"
|
||||
|
||||
let's try this...
|
||||
|
||||
*/
|
||||
|
||||
/* 9x9
|
||||
var marchingFilter: [int] const = [
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 1, 1, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 1, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 1, 1, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||
];
|
||||
|
||||
var marchingFilterResult: [string] const = [
|
||||
"", "", "", "", "", "", "", "", "",
|
||||
"", "edge-tr", "wall-b", "wall-b", "wall-b", "wall-b", "wall-b", "edge-tl", "",
|
||||
"", "wall-r", "corner-tl", "wall-t", "wall-t", "wall-t", "corner-tr", "wall-l", "",
|
||||
"", "wall-r", "wall-l", "", "", "", "wall-r", "wall-l", "",
|
||||
"", "wall-r", "wall-l", "", "", "", "wall-r", "wall-l", "",
|
||||
"", "wall-r", "wall-l", "", "", "", "wall-r", "wall-l", "",
|
||||
"", "wall-r", "corner-bl", "wall-b", "wall-b", "wall-b", "corner-br", "wall-l", "",
|
||||
"", "edge-br", "wall-t", "wall-t", "wall-t", "wall-t", "wall-t", "edge-bl", "",
|
||||
"", "", "", "", "", "", "", "", ""
|
||||
];
|
||||
*/
|
||||
|
||||
|
||||
//this is a nightmare
|
||||
var marchingFilter: [int] const = [
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||
];
|
||||
|
||||
var marchingFilterResult: [string] const = [
|
||||
"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,
|
||||
"" ,"" ,"edge-tl" ,"wall-b" ,"wall-b" ,"wall-b" ,"wall-b" ,"wall-b" ,"wall-b" ,"edge-tr" ,"" ,"" ,
|
||||
"" ,"edge-tl" ,"corner-br" ,"" ,"corner-tl" ,"wall-t" ,"wall-t" ,"corner-tr" ,"" ,"corner-bl" ,"edge-tr" ,"" ,
|
||||
"" ,"wall-r" ,"" ,"" ,"wall-l" ,"" ,"" ,"wall-r" ,"" ,"" ,"wall-l" ,"" ,
|
||||
"" ,"wall-r" ,"corner-tl" ,"wall-t" ,"edge-br" ,"" ,"" ,"edge-bl" ,"wall-t" ,"corner-tr" ,"wall-l" ,"" ,
|
||||
"" ,"wall-r" ,"wall-l" ,"" ,"" ,"" ,"" ,"" ,"" ,"wall-r" ,"wall-l" ,"" ,
|
||||
"" ,"wall-r" ,"wall-l" ,"" ,"" ,"" ,"" ,"" ,"" ,"wall-r" ,"wall-l" ,"" ,
|
||||
"" ,"wall-r" ,"corner-bl" ,"wall-b" ,"edge-tr" ,"" ,"" ,"edge-tl" ,"wall-b" ,"corner-br" ,"wall-l" ,"" ,
|
||||
"" ,"wall-r" ,"" ,"" ,"wall-l" ,"" ,"" ,"wall-r" ,"" ,"" ,"wall-l" ,"" ,
|
||||
"" ,"edge-bl" ,"corner-tr" ,"" ,"corner-bl" ,"wall-b" ,"wall-b" ,"corner-br" ,"" ,"corner-tl" ,"edge-br" ,"" ,
|
||||
"" ,"" ,"edge-bl" ,"wall-t" ,"wall-t" ,"wall-t" ,"wall-t" ,"wall-t" ,"wall-t" ,"edge-br" ,"" ,"" ,
|
||||
"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,""
|
||||
];
|
||||
|
||||
|
||||
//if walkable is below, then return top, etc.
|
||||
fn parseTilemapAt(x: int, y: int) {
|
||||
//parse based on walkability, for now
|
||||
if (tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 2] != 0) {
|
||||
return ""; //empty
|
||||
}
|
||||
|
||||
//generate the snapshot of the current position
|
||||
var snapshot = generateSnapshotAt(x, y);
|
||||
|
||||
//find the snapshot's position within the filter
|
||||
for (var i: int = 0; i < 12 -2; i++) {
|
||||
for (var j: int = 0; j < 12 -2; j++) {
|
||||
if (
|
||||
marchingFilter[(j + 0) * 12 + (i + 0)] == snapshot[0 * 3 + 0] &&
|
||||
marchingFilter[(j + 0) * 12 + (i + 1)] == snapshot[0 * 3 + 1] &&
|
||||
marchingFilter[(j + 0) * 12 + (i + 2)] == snapshot[0 * 3 + 2] &&
|
||||
|
||||
marchingFilter[(j + 1) * 12 + (i + 0)] == snapshot[1 * 3 + 0] &&
|
||||
marchingFilter[(j + 1) * 12 + (i + 1)] == snapshot[1 * 3 + 1] &&
|
||||
marchingFilter[(j + 1) * 12 + (i + 2)] == snapshot[1 * 3 + 2] &&
|
||||
|
||||
marchingFilter[(j + 2) * 12 + (i + 0)] == snapshot[2 * 3 + 0] &&
|
||||
marchingFilter[(j + 2) * 12 + (i + 1)] == snapshot[2 * 3 + 1] &&
|
||||
marchingFilter[(j + 2) * 12 + (i + 2)] == snapshot[2 * 3 + 2]
|
||||
)
|
||||
{
|
||||
return marchingFilterResult[(j+1) * 12 + (i+1)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//anything else, just plop down a pillar
|
||||
fn nonZero(key: int, value: int) {
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
if (snapshot.some(nonZero)) {
|
||||
return "pillar";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
fn generateSnapshotAt(x: int, y: int) {
|
||||
var result: [int] = [];
|
||||
|
||||
for (var j: int = -1; j < 2; j++) {
|
||||
for (var i: int = -1; i < 2; i++) {
|
||||
if (x + i < 0 || y + j < 0 || x + i >= MAP_GRID_WIDTH || y + j >= MAP_GRID_HEIGHT) {
|
||||
result.push(0);
|
||||
}
|
||||
else {
|
||||
result.push(tilemap[(y+j) * CELL_WIDTH * CELL_COUNT_X * 3 + (x+i) * 3 + 2] != 0 ? 1 : 0); //walkable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//polyfill
|
||||
fn sign(x) {
|
||||
if (x > 0) return 1;
|
||||
|
||||
Reference in New Issue
Block a user