152 lines
3.6 KiB
Plaintext
152 lines
3.6 KiB
Plaintext
import standard;
|
|
import node;
|
|
import random;
|
|
|
|
//consts
|
|
var TILE_WIDTH: int const = 32;
|
|
var TILE_HEIGHT: int const = 32;
|
|
|
|
var MAP_WIDTH: int const = 16;
|
|
var MAP_HEIGHT: int const = 16;
|
|
|
|
|
|
var tilemap: opaque = null;
|
|
var player: opaque = null;
|
|
var stepCounter: opaque = null;
|
|
|
|
var enemies: [opaque] = [];
|
|
|
|
var entities: [opaque] = null; //full list of entities
|
|
|
|
var collisionMap: [bool] = null; //cache this, since it won't change during a level
|
|
|
|
var rng: opaque = null;
|
|
|
|
//debugging tools
|
|
var debugStepCounter: int = 0;
|
|
var debugDrawCounter: int = 0;
|
|
|
|
//lifecycle functions
|
|
fn onLoad(node: opaque) {
|
|
tilemap = node.loadChild("scripts:/gameplay/tilemap.toy");
|
|
player = node.loadChild("scripts:/gameplay/lejana.toy");
|
|
stepCounter = node.loadChild("scripts:/gameplay/step-counter.toy");
|
|
}
|
|
|
|
fn onInit(node: opaque) {
|
|
node.generateLevel(clock().hash(), MAP_WIDTH, MAP_HEIGHT);
|
|
stepCounter.callNodeFn("setMaxSteps", 100);
|
|
}
|
|
|
|
fn onFree(node: opaque) {
|
|
rng.freeRandomGenerator();
|
|
}
|
|
|
|
fn onStep(node: opaque) {
|
|
if (++debugStepCounter >= 30) {
|
|
print "FPS: " + string debugDrawCounter + " / 30";
|
|
debugStepCounter = 0;
|
|
debugDrawCounter = 0;
|
|
}
|
|
|
|
entities = entities.sort(depthComparator);
|
|
}
|
|
|
|
fn onDraw(node: opaque) {
|
|
debugDrawCounter++;
|
|
|
|
//call each child's custom draw fn (with parent shifting)
|
|
tilemap.callNodeFn("customOnDraw", 0, 32);
|
|
for (var i = 0; i < entities.length(); i++) {
|
|
entities[i].callNodeFn("customOnDraw", 0, 32);
|
|
}
|
|
|
|
stepCounter.callNodeFn("customOnDraw", 0, 0, TILE_WIDTH * MAP_WIDTH, 32);
|
|
}
|
|
|
|
//utils - polyfills
|
|
fn loadChild(parent: opaque, fname: string) {
|
|
var child: opaque = loadNode(fname);
|
|
parent.pushNode(child);
|
|
return child;
|
|
}
|
|
|
|
//gameplay functions
|
|
fn generateLevel(node: opaque, seed: int, width: int, height: int) {
|
|
//reset the array
|
|
enemies = [];
|
|
entities = [player]; //assume the player exists already
|
|
|
|
if (rng != null) rng.freeRandomGenerator();
|
|
rng = createRandomGenerator(seed);
|
|
|
|
//place player
|
|
player.callNodeFn("setGridPos", 1, 1);
|
|
|
|
//generate map
|
|
tilemap.callNodeFn("generateFromRng", rng, 16, 16);
|
|
collisionMap = tilemap.callNodeFn("getCollisionMap");
|
|
|
|
//generate drones
|
|
var droneCount: int const = rng.generateRandomNumber() % 2 + 20;
|
|
for (var i = 0; i < droneCount; i++) {
|
|
var d = node.loadChild("scripts:/gameplay/drone.toy");
|
|
d.initNode();
|
|
|
|
enemies.push(d);
|
|
entities.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.getCollisionAt(x, y) == false || (x < (width / 6 * 2) && y < (height / 6 * 2))) { //TODO: toy bug - no short-circuiting?
|
|
x = rng.generateRandomNumber() % width;
|
|
y = rng.generateRandomNumber() % height;
|
|
}
|
|
|
|
d.callNodeFn("setGridPos", x, y);
|
|
d.callNodeFn("setRealPos", (width -1) * TILE_WIDTH, (height - 1) * TILE_HEIGHT);
|
|
}
|
|
}
|
|
|
|
fn getCollisionAt(node: opaque, x: int, y: int) {
|
|
if (collisionMap == null || x == null || y == null) {
|
|
return false;
|
|
}
|
|
|
|
//entities
|
|
var pos = player.callNodeFn("getGridPos");
|
|
if (x == pos[0] && y == pos[1]) {
|
|
return false;
|
|
}
|
|
|
|
for (var i = 0; i < enemies.length(); i++) {
|
|
var pos = enemies[i].callNodeFn("getGridPos");
|
|
if (x == pos[0] && y == pos[1]) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//default
|
|
return collisionMap[y * MAP_WIDTH + x];
|
|
}
|
|
|
|
fn runAI(node: opaque) {
|
|
for (var i = 0; i < enemies.length(); i++) {
|
|
enemies[i].callNodeFn("runAI", rng);
|
|
}
|
|
|
|
stepCounter.callNodeFn("alterRemainingSteps", -1);
|
|
}
|
|
|
|
fn depthComparator(lhs: opaque, rhs: opaque) { //for sorting by depth
|
|
var lhsPos = lhs.callNodeFn("getRealPos");
|
|
var rhsPos = rhs.callNodeFn("getRealPos");
|
|
|
|
if (lhsPos[1] == rhsPos[1]) { //BUGFIX: prevent z-fighting
|
|
return lhsPos[0] < rhsPos[0];
|
|
}
|
|
|
|
return lhsPos[1] < rhsPos[1];
|
|
} |