import standard; import node; import random; //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; 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; }