diff --git a/Airport.vcxproj b/Airport.vcxproj
index 9dbfdac..d0a5119 100644
--- a/Airport.vcxproj
+++ b/Airport.vcxproj
@@ -28,6 +28,7 @@
+
@@ -125,10 +126,10 @@
SDL2main.lib;SDL2.lib;SDL2_image.lib;Toy.lib;Box.lib;%(AdditionalDependencies)
- $(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SolutionDir)out\$(Configuration);%(AdditionalLibraryDirectories)
+ $(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration);%(AdditionalLibraryDirectories)
- $(SDL2Dir)\include;$(SDL2ImageDir)\include;%(SolutionDir)Toy\source;$(SolutionDir)box;%(AdditionalIncludeDirectories)
+ $(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;$(SolutionDir)box;%(AdditionalIncludeDirectories)
stdc17
@@ -143,10 +144,10 @@
stdc17
- $(SDL2Dir)\include;$(SDL2ImageDir)\include;%(SolutionDir)Toy\source;$(SolutionDir)box;%(AdditionalIncludeDirectories)
+ $(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;$(SolutionDir)box;%(AdditionalIncludeDirectories)
- $(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SolutionDir)out\$(Configuration);%(AdditionalLibraryDirectories)
+ $(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration);%(AdditionalLibraryDirectories)
SDL2main.lib;SDL2.lib;SDL2_image.lib;Toy.lib;Box.lib;%(AdditionalDependencies)
diff --git a/Box.vcxproj b/Box.vcxproj
index ecd740c..5d353f9 100644
--- a/Box.vcxproj
+++ b/Box.vcxproj
@@ -110,11 +110,11 @@
stdc17
BOX_EXPORT;LIB_RUNNER_EXPORT;%(PreprocessorDefinitions)
- $(SDL2Dir)\include;$(SDL2ImageDir)\include;%(SolutionDir)Toy\source;%(AdditionalIncludeDirectories)
+ $(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;%(AdditionalIncludeDirectories)
- $(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SolutionDir)out\$(Configuration)\;%(AdditionalLibraryDirectories)
- SDL2.lib;SDL2_image.lib;Toy.lib;%(AdditionalDependencies)
+ $(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration)\;%(AdditionalLibraryDirectories)
+ SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;Toy.lib;%(AdditionalDependencies)
xcopy "$(SolutionDir)Toy\repl\lib*.*" "$(SolutionDir)box" /Y /I /E
@@ -125,11 +125,11 @@ xcopy "$(SolutionDir)Toy\repl\repl_tools.*" "$(SolutionDir)box" /Y /I /E
stdc17
BOX_EXPORT;LIB_RUNNER_EXPORT;%(PreprocessorDefinitions)
- $(SDL2Dir)\include;$(SDL2ImageDir)\include;%(SolutionDir)Toy\source;%(AdditionalIncludeDirectories)
+ $(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;%(AdditionalIncludeDirectories)
- $(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SolutionDir)out\$(Configuration)\;%(AdditionalLibraryDirectories)
- SDL2.lib;SDL2_image.lib;Toy.lib;%(AdditionalDependencies)
+ $(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration)\;%(AdditionalLibraryDirectories)
+ SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;Toy.lib;%(AdditionalDependencies)
xcopy "$(SolutionDir)Toy\repl\lib*.*" "$(SolutionDir)box" /Y /I /E
diff --git a/README.md b/README.md
index 091709b..b38ba00 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,9 @@
The best way to build a game engine, is to build a game first.
-This game utilizes the [Toy programming langauge](https://toylang.com).
+This project has now been adapted into a roguelike for the 7 day roguelike jam.
+
+This game/engine utilizes the [Toy programming langauge](https://toylang.com).
## Cloning
@@ -10,13 +12,25 @@ Either clone recursively, or run `git submodule update --init` after cloning.
## Building
-Simply run `make` in the root directory.
+We're now using Visual Studio - define the following environment variables to point to the root of each SDL2 lib:
+
+* `SDL2Dir`
+* `SDL2ImageDir`
+* `SDL2TTFDir`
## Running
-Make sure the program can see the `assets` folder (symbolic links can help).
+Make sure the program can see the `assets` folder (symbolic links can help), and all of the required DLLs are present.
## Dependencies
* SDL2
* SDL2_image
+* SDL2_ttf
+
+## Credits
+
+* Art - Evan Hartshorn
+* Coding - Kayne Ruse
+* Font - Ancient God (Koczman Bálint)
+
diff --git a/Toy b/Toy
index 76ddd57..f869c94 160000
--- a/Toy
+++ b/Toy
@@ -1 +1 @@
-Subproject commit 76ddd5703e73cc7435595f7b38c8d8a1c63a80d0
+Subproject commit f869c9425a9070e243d975f4fe7748662ce27f6b
diff --git a/assets/fonts/Ancient God.ttf b/assets/fonts/Ancient God.ttf
new file mode 100644
index 0000000..41467b4
Binary files /dev/null and b/assets/fonts/Ancient God.ttf differ
diff --git a/assets/scripts/gameplay/drone.toy b/assets/scripts/gameplay/drone.toy
new file mode 100644
index 0000000..7d8dfd7
--- /dev/null
+++ b/assets/scripts/gameplay/drone.toy
@@ -0,0 +1,186 @@
+import standard;
+import node;
+
+//constants
+var SPEED: int const = 4;
+
+var SPRITE_WIDTH: int const = 64;
+var SPRITE_HEIGHT: int const = 64;
+
+var TILE_WIDTH: int const = 32;
+var TILE_HEIGHT: int const = 32;
+
+
+//variables
+var parent: opaque = null; //cache the parent for quick access
+
+var gridX: int = 1; //position on the game grid
+var gridY: int = 1;
+
+var realX: int = 0; //will change until realX = gridX * SPRITE_WIDTH
+var realY: int = 0;
+
+var motionX: int = 0; //normalized movement direction
+var motionY: int = 0;
+
+var direction: int = null; //BUGFIX: animation not looping properly
+
+var stepAI: int = 0;
+
+//polyfills - animating different cycles on one image
+var stepCount: int = 0;
+
+fn faceDown(node: opaque) {
+ if (direction == 0) return;
+ direction = 0;
+ node.setNodeRect(0, 0, 32, 32);
+ node.setNodeFrames(2);
+}
+
+fn faceUp(node: opaque) {
+ if (direction == 1) return;
+ direction = 1;
+ node.setNodeRect(32 * 2, 0, 32, 32);
+ node.setNodeFrames(2);
+}
+
+fn faceRight(node: opaque) {
+ if (direction == 2) return;
+ direction = 2;
+ node.setNodeRect(32 * 4, 0, 32, 32);
+ node.setNodeFrames(2);
+}
+
+fn faceLeft(node: opaque) {
+ if (direction == 3) return;
+ direction = 3;
+ node.setNodeRect(32 * 6, 0, 32, 32);
+ node.setNodeFrames(2);
+}
+
+
+//accessors & mutators
+fn setGridPos(node: opaque, x: int, y: int) {
+ gridX = x;
+ gridY = y;
+
+ if (realX == null) {
+ realX = gridX * TILE_WIDTH;
+ }
+
+ if (realY == null) {
+ realY = gridY * TILE_HEIGHT;
+ }
+}
+
+fn setRealPos(node: opaque, x: int, y: int) {
+ realX = x;
+ realY = y;
+}
+
+fn getGridPos(node: opaque) {
+ return [gridX, gridY];
+}
+
+fn getRealPos(node: opaque) {
+ return [realX, realY];
+}
+
+
+//lifecycle functions
+fn onLoad(node: opaque) {
+ node.loadTexture("sprites:/drone.png");
+ node.faceDown();
+}
+
+fn onInit(node: opaque) {
+ parent = node.getParentNode();
+}
+
+fn onStep(node: opaque) {
+ if (++stepCount >= 5) {
+ node.incrementCurrentNodeFrame();
+ stepCount = 0;
+ }
+
+ //calc movement
+ var distX = gridX * TILE_WIDTH - realX;
+ var distY = gridY * TILE_HEIGHT - realY;
+
+ motionX = normalize(distX);
+ motionY = normalize(distY);
+
+ //make movement
+ realX += abs(distX) > SPEED ? SPEED * motionX : distX;
+ realY += abs(distY) > SPEED ? SPEED * motionY : distY;
+}
+
+fn onFree(node: opaque) {
+ node.freeTexture();
+}
+
+fn customOnDraw(node: opaque) {
+ var px = 0;
+ var py = 0;
+
+ if (parent != null) {
+ px = parent.callNodeFn("getX");
+ py = parent.callNodeFn("getY");
+
+ px = px != null ? px : 0;
+ py = py != null ? py : 0;
+ }
+
+ node.drawNode(realX + px - SPRITE_WIDTH / 4, realY + py - SPRITE_HEIGHT / 2, SPRITE_WIDTH, SPRITE_HEIGHT);
+}
+
+
+//gameplay functions
+fn runAI(node: opaque, rng: opaque) {
+ if ((stepAI++) >= 1) { //TODO: Toy bug here, something to do with precedence of postfix++?
+ stepAI = 0;
+
+ import random;
+
+ 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 (parent.callNodeFn("getCollisionAt", gridX + moveX, gridY + moveY)) {
+ gridX += moveX;
+ gridY += moveY;
+ }
+ }
+}
+
+
+//polyfills - move these to standard
+fn normalize(x): int {
+ if (x > 0) {
+ return 1;
+ }
+ if (x < 0) {
+ return -1;
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/assets/scripts/gameplay/lejana.toy b/assets/scripts/gameplay/lejana.toy
index 56887e7..0c6d387 100644
--- a/assets/scripts/gameplay/lejana.toy
+++ b/assets/scripts/gameplay/lejana.toy
@@ -2,11 +2,14 @@ import standard;
import node;
//constants
-var SPEED: int const = 3;
+var SPEED: int const = 4;
var SPRITE_WIDTH: int const = 64;
var SPRITE_HEIGHT: int const = 64;
+var TILE_WIDTH: int const = 32;
+var TILE_HEIGHT: int const = 32;
+
//variables
var parent: opaque = null; //cache the parent for quick access
@@ -14,8 +17,8 @@ var parent: opaque = null; //cache the parent for quick access
var gridX: int = 1; //position on the game grid
var gridY: int = 1;
-var realX: int = 0; //will change until realX = gridX * SPRITE_WIDTH
-var realY: int = 0;
+var realX: int = null; //will change until realX = gridX * SPRITE_WIDTH
+var realY: int = null;
var motionX: int = 0; //normalized movement direction
var motionY: int = 0;
@@ -23,39 +26,67 @@ var motionY: int = 0;
var inputX: int = 0; //cache the keyboard input
var inputY: int = 0;
+var direction: int = null; //BUGFIX: animation not looping properly
+var enableMovementCounter: int = 30 * 3; //BUGFIX: freeze while drones reach their starting spot
+
//polyfills - animating different cycles on one image
var stepCount: int = 0;
fn faceDown(node: opaque) {
+ if (direction == 0) return;
+ direction = 0;
node.setNodeRect(0, 0, 32, 32);
node.setNodeFrames(4);
}
fn faceUp(node: opaque) {
+ if (direction == 1) return;
+ direction = 1;
node.setNodeRect(32 * 4, 0, 32, 32);
node.setNodeFrames(4);
}
-fn faceLeft(node: opaque) {
- node.setNodeRect(32 * 12, 0, 32, 32);
- node.setNodeFrames(4);
-}
-
fn faceRight(node: opaque) {
+ if (direction == 2) return;
+ direction = 2;
node.setNodeRect(32 * 8, 0, 32, 32);
node.setNodeFrames(4);
}
-//polyfills - move these to standard
-fn normalize(x): int {
- if (x > 0) {
- return 1;
+fn faceLeft(node: opaque) {
+ if (direction == 3) return;
+ direction = 3;
+ node.setNodeRect(32 * 12, 0, 32, 32);
+ node.setNodeFrames(4);
+}
+
+
+//accessors & mutators
+fn setGridPos(node: opaque, x: int, y: int) {
+ gridX = x;
+ gridY = y;
+
+ if (realX == null) {
+ realX = gridX * TILE_WIDTH;
}
- if (x < 0) {
- return -1;
+
+ if (realY == null) {
+ realY = gridY * TILE_HEIGHT;
}
- return 0;
+}
+
+fn setRealPos(node: opaque, x: int, y: int) {
+ realX = x;
+ realY = y;
+}
+
+fn getGridPos(node: opaque) {
+ return [gridX, gridY];
+}
+
+fn getRealPos(node: opaque) {
+ return [realX, realY];
}
@@ -70,14 +101,20 @@ fn onInit(node: opaque) {
}
fn onStep(node: opaque) {
+ //initial freeze
+ if (enableMovementCounter > 0) {
+ enableMovementCounter--;
+ return;
+ }
+
//process input when aligned to a grid
- if (realX / SPRITE_WIDTH == gridX && realY / SPRITE_HEIGHT == gridY && motionX == 0 && motionY == 0) {
+ if (realX / TILE_WIDTH == gridX && realY / TILE_HEIGHT == gridY && motionX == 0 && motionY == 0) {
//disallow wall phasing
- if (parent.callNodeFn("getCollisionAt", gridX + inputX, gridY) != true) {
+ if (inputX != 0 && parent.callNodeFn("getCollisionAt", gridX + inputX, gridY) != true) {
inputX = 0;
}
- if (parent.callNodeFn("getCollisionAt", gridX, gridY + inputY) != true) {
+ if (inputY != 0 && parent.callNodeFn("getCollisionAt", gridX, gridY + inputY) != true) {
inputY = 0;
}
@@ -105,22 +142,27 @@ fn onStep(node: opaque) {
if (inputX < 0) {
node.faceLeft();
}
+
+ //trigger the world
+ if (inputX != 0 || inputY != 0) {
+ parent.callNodeFn("runAI");
+ }
}
//animation
- if (motionX == 0 && motionY == 0) {
+ if (motionX == 0 && motionY == 0 && inputX == 0 && inputY == 0) {
stepCount = 0;
node.setCurrentNodeFrame(0);
}
- if (++stepCount >= 10) {
+ if (++stepCount >= 5) {
node.incrementCurrentNodeFrame();
stepCount = 0;
}
//calc movement
- var distX = gridX * SPRITE_WIDTH - realX;
- var distY = gridY * SPRITE_HEIGHT - realY;
+ var distX = gridX * TILE_WIDTH - realX;
+ var distY = gridY * TILE_HEIGHT - realY;
motionX = normalize(distX);
motionY = normalize(distY);
@@ -134,7 +176,7 @@ fn onFree(node: opaque) {
node.freeTexture();
}
-fn onDraw(node: opaque) {
+fn customOnDraw(node: opaque) {
var px = 0;
var py = 0;
@@ -146,9 +188,10 @@ fn onDraw(node: opaque) {
py = py != null ? py : 0;
}
- node.drawNode(realX + px, realY + py, SPRITE_WIDTH, SPRITE_HEIGHT);
+ node.drawNode(realX + px - SPRITE_WIDTH / 4, realY + py - SPRITE_HEIGHT / 2, SPRITE_WIDTH, SPRITE_HEIGHT);
}
+
//event functions
fn onKeyDown(node: opaque, event: string) {
if (event == "character_up") {
@@ -192,4 +235,16 @@ fn onKeyUp(node: opaque, event: string) {
inputX = 0;
return;
}
+}
+
+
+//polyfills - move these to standard
+fn normalize(x): int {
+ if (x > 0) {
+ return 1;
+ }
+ if (x < 0) {
+ return -1;
+ }
+ return 0;
}
\ No newline at end of file
diff --git a/assets/scripts/gameplay/scene.toy b/assets/scripts/gameplay/scene.toy
index 6a9b7a5..92184d7 100644
--- a/assets/scripts/gameplay/scene.toy
+++ b/assets/scripts/gameplay/scene.toy
@@ -1,11 +1,25 @@
import standard;
import node;
+//consts
+var TILE_WIDTH: int const = 32;
+var TILE_HEIGHT: int const = 32;
+
+
var tilemap: opaque = null;
var player: 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 stepCounter: int = 0;
+var drawCounter: int = 0;
+
//lifecycle functions
fn onLoad(node: opaque) {
tilemap = node.loadChild("scripts:/gameplay/tilemap.toy");
@@ -13,8 +27,27 @@ fn onLoad(node: opaque) {
}
fn onInit(node: opaque) {
- tilemap.callNodeFn("generateFromSeed", clock().hash(), 8, 8);
- collisionMap = tilemap.callNodeFn("getCollisionMap");
+ node.generateLevel(clock().hash(), 16, 16);
+}
+
+fn onStep(node: opaque) {
+ if (++stepCounter >= 30) {
+ print "FPS: " + string drawCounter + " / 30";
+ stepCounter = 0;
+ drawCounter = 0;
+ }
+
+ entities = entities.sort(depthComparator);
+}
+
+fn onDraw(node: opaque) {
+ drawCounter++;
+
+ //call each child's custom sort fn
+ tilemap.callNodeFn("customOnDraw");
+ for (var i = 0; i < entities.length(); i++) {
+ entities[i].callNodeFn("customOnDraw");
+ }
}
//utils - polyfills
@@ -24,11 +57,78 @@ fn loadChild(parent: opaque, fname: string) {
return child;
}
-//connective functions
+//gameplay functions
+fn generateLevel(node: opaque, seed: int, width: int, height: int) {
+ //reset the array
+ enemies = [];
+ entities = [player]; //assume the player exists already
+
+ import random;
+
+ 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 + 2;
+ 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 / 2) && y < (height / 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) {
+ 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[x][y];
}
+
+fn runAI(node: opaque) {
+ for (var i = 0; i < enemies.length(); i++) {
+ enemies[i].callNodeFn("runAI", rng);
+ }
+}
+
+fn depthComparator(lhs: opaque, rhs: opaque) { //for sorting by depth
+ var lhsPos = lhs.callNodeFn("getRealPos");
+ var rhsPos = rhs.callNodeFn("getRealPos");
+
+ return lhsPos[1] < rhsPos[1];
+}
\ No newline at end of file
diff --git a/assets/scripts/gameplay/tilemap.toy b/assets/scripts/gameplay/tilemap.toy
index e41ab50..e143283 100644
--- a/assets/scripts/gameplay/tilemap.toy
+++ b/assets/scripts/gameplay/tilemap.toy
@@ -2,11 +2,13 @@ import standard;
import node;
//consts
-var TILE_WIDTH: int const = 64;
-var TILE_HEIGHT: int const = 64;
+var TILE_WIDTH: int const = 32;
+var TILE_HEIGHT: int const = 32;
//map between the identity and position on the sprite sheet
-var tilemap: [[string]] = null;
+var rawmap: [[string]] = null;
+
+var tilemap: [[[int]]] = null;
var collisions: [[bool]] = null;
var tileset: [string : [int]] = [
@@ -46,7 +48,7 @@ fn onLoad(node: opaque) {
node.loadTexture("sprites:/tileset.png");
}
-fn onDraw(node: opaque) {
+fn customOnDraw(node: opaque) {
if (tilemap == null) {
return;
}
@@ -77,7 +79,7 @@ fn onDraw(node: opaque) {
//draw the tilemap
for (var j = lowerY; j < upperY; j++) {
for (var i = lowerX; i < upperX; i++) {
- var pos = tileset[tilemap[i][j]];
+ var pos = tileset[ rawmap[i][j] ];
node.setNodeRect(pos[0] * 16, pos[1] * 16, 16, 16);
node.drawNode(i * TILE_WIDTH, j * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT);
@@ -87,17 +89,18 @@ fn onDraw(node: opaque) {
//utils functions for map generation
-fn generateFromSeed(node: opaque, seed: int, width: int, height: int) {
- tilemap = generateTilemap(seed, width, height);
- collisions = bakeCollisionMap(tilemap, width, height);
+fn generateFromRng(node: opaque, rng: opaque, width: int, height: int) {
+ rawmap = generateRawTilemap(rng, width, height);
+
+ tilemap = bakeTilemap(rawmap, width, height);
+ collisions = bakeCollisionMap(rawmap, width, height);
print tilemap;
print collisions;
}
-fn generateTilemap(seed: int, width: int, height: int) {
+fn generateRawTilemap(rng: opaque, width: int, height: int) {
import random;
- var rng: opaque = createRandomGenerator(seed);
//generate an empty grid
var result: [[string]] = [];
@@ -165,6 +168,30 @@ fn bakeCollisionMap(tilemap: [[string]], width: int, height: int) {
return result;
}
+fn bakeTilemap(tilemap: [[string]], width: int, height: int) {
+ //generate an empty grid
+ var result: [[[int]]] = [];
+ var row: [[int]] = [];
+ for (var j: int = 0; j < height; j++) {
+ row.push([0,0]);
+ }
+
+ for (var i: int = 0; i < width; i++) {
+ result.push(row);
+ }
+
+ //extract the collision map
+ for (var j: int = 0; j < height; j++) {
+ for (var i: int = 0; i < width; i++) {
+ //almost - you still need one pair of parentheses
+ result[i][j][0] = (tileset[ tilemap[i][j] ][0]);
+ result[i][j][1] = (tileset[ tilemap[i][j] ][1]);
+ }
+ }
+
+ return result;
+}
+
fn getCollisionMap(node: opaque) {
return collisions;
}
\ No newline at end of file
diff --git a/assets/scripts/init.toy b/assets/scripts/init.toy
index 6204726..cf15d34 100644
--- a/assets/scripts/init.toy
+++ b/assets/scripts/init.toy
@@ -27,8 +27,11 @@
mapInputEventToKeyUp("character_right", "right"); //event, keysym
+ //TODO: escape to kill the game
+
+
//this function must always be called, or the engine won't run
- initWindow("Skyland", 1080, 720, false);
+ initWindow("Skyland", 32*16, 32*16, false); //TODO: custom FPS setting
//kick off the logic of the scene graph
loadRootNode("scripts:/gameplay/scene.toy");
diff --git a/assets/sprites/drone.png b/assets/sprites/drone.png
new file mode 100644
index 0000000..b079618
Binary files /dev/null and b/assets/sprites/drone.png differ
diff --git a/box/box_common.h b/box/box_common.h
index 39a1e9e..363c004 100644
--- a/box/box_common.h
+++ b/box/box_common.h
@@ -14,6 +14,7 @@
#include
#include
+#include
#include
#define BOX_API extern
@@ -22,6 +23,7 @@
#include
#include
+#include
#include
#include
diff --git a/box/box_engine.c b/box/box_engine.c
index 55d0a84..d12a200 100644
--- a/box/box_engine.c
+++ b/box/box_engine.c
@@ -51,6 +51,11 @@ void Box_initEngine() {
fatalError("Failed to initialize SDL2_image");
}
+ //init SDL_ttf
+ if (TTF_Init() == -1) {
+ fatalError("Failed to initialize SDL2_ttf");
+ }
+
//init events
Toy_initLiteralDictionary(&engine.symKeyDownEvents);
Toy_initLiteralDictionary(&engine.symKeyUpEvents);
@@ -412,7 +417,7 @@ void Box_execEngine() {
//set up time
engine.realTime = clock();
engine.simTime = engine.realTime;
- clock_t delta = (double) CLOCKS_PER_SEC / 60.0;
+ clock_t delta = (double) CLOCKS_PER_SEC / 30.0;
while (engine.running) {
execLoadRootNode();
@@ -432,8 +437,8 @@ void Box_execEngine() {
}
//render the world
- SDL_SetRenderDrawColor(engine.renderer, 128, 128, 128, 255); //NOTE: This line can be disabled later
- SDL_RenderClear(engine.renderer); //NOTE: This line can be disabled later
+ //SDL_SetRenderDrawColor(engine.renderer, 128, 128, 128, 255); //NOTE: This line can be disabled later
+ //SDL_RenderClear(engine.renderer); //NOTE: This line can be disabled later
Box_callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onDraw", NULL);
diff --git a/source/main.c b/source/main.c
index b4c4b2c..cbd7f7b 100644
--- a/source/main.c
+++ b/source/main.c
@@ -42,6 +42,19 @@ int main(int argc, char* argv[]) {
Toy_freeLiteral(pathLiteral);
}
+ {
+ //create a pair of literals, the first for the drive name, the second for the path
+ Toy_Literal driveLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("fonts"));
+ Toy_Literal pathLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("assets/fonts"));
+
+ //set these within the drive dictionary
+ Toy_setLiteralDictionary(Toy_getDriveDictionary(), driveLiteral, pathLiteral);
+
+ //these literals are no longer needed
+ Toy_freeLiteral(driveLiteral);
+ Toy_freeLiteral(pathLiteral);
+ }
+
//run the rest of your program
Box_initEngine();
Box_execEngine();