Initialize Game
let FONT: Font;
let SPRITES:ImageSpriteSheet;
function main() {
APP = new App(320, 240);
FONT = new Font(APP.images['font'], 'white');
SPRITES = new ImageSpriteSheet(
APP.images['sprites'], new Vec2(16,16), new Vec2(8,8));
APP.init(new Game());
}
Basic Player Control
class Player extends Entity {
usermove: Vec2;
constructor(pos: Vec2) {
super(pos);
let sprite = new RectSprite('green', new Rect(-10,-10,20,20));
this.sprites = [sprite];
this.collider = sprite.getBounds();
}
onStart() {
super.onStart();
this.usermove = new Vec2();
}
onTick() {
super.onTick();
this.moveIfPossible(this.usermove);
}
}
class Game extends GameScene {
player: Player;
onStart() {
super.onStart();
this.player = new Player(this.world.area.center());
this.world.add(this.player);
}
onDirChanged(v: Vec2) {
this.player.usermove = v;
}
}
Restrict Entity within Bounds
class Player extends Entity {
getFencesFor(range: Rect, v: Vec2, context: string): Rect[] {
return [this.world.area];
}
}
Spawn Another Entity
class Bullet extends Particle {
constructor(pos: Vec2) {
super(pos);
let bounds = new Rect(-2, -2, 4, 4);
let sprite = new RectSprite('white', bounds)
this.sprites = [sprite];
this.collider = bounds;
this.movement = new Vec2(8, 0);
}
getFrame() {
return this.world.area;
}
}
class Player extends Entity {
...
fire() {
let bullet = new Bullet(this.pos);
this.world.add(bullet);
}
}
Schedule Delayed Action
let task = new Task();
task.lifetime = 2;
task.stopped.subscribe(() => { info("foo"); });
this.world.add(task);
Signal Subscription/Firing
class Player extends Entity {
happened: Signal;
constructor(pos: Vec2) {
super(pos);
this.happened = new Signal(this);
}
somethingHappened() {
this.happened.fire('holy!');
}
}
let player = new Player();
player.happened.subscribe((e:Entity, value:string) => {
info(value);
});
Change Scene
class Game extends GameScene {
...
gameover() {
APP.lockKeys();
this.changeScene(new GameOver());
}
}
Show Explosion Effect
class Explosion extends Entity {
constructor(pos: Vec2) {
super(pos);
this.sprites = [new RectSprite('yellow, new Rect(-10,-10,20,20))];
this.lifetime = 0.5;
}
}
class Player extends Entity {
...
die() {
this.chain(new Explosion(this.pos));
this.stop();
}
}
Create TileMap
class Game extends GameScene {
...
onStart() {
const MAP = [
"0010010000",
"0222022002",
...
"0000010030",
];
this.tilemap = new TileMap(16, 10, 10, MAP.map(
(v:string) => { return str2array(v); }
));
let p = this.tilemap.findTile((c:number) => { return c == 3; });
this.player = new Player(this, this.tilemap.map2coord(p).center());
}
render(ctx: CanvasRenderingContext2D) {
super.render(ctx);
this.tilemap.renderWindowFromBottomLeft(
ctx, this.world.window,
(x,y,c) => { return TILES.get(c); });
}
}
Collision with TileMap
class Player extends Entity {
tilemap: TileMap;
getObstaclesFor(range: Rect, v: Vec2, context=null as string): Rect[] {
let f = ((c:number) => { return (c == 1 || c == 3); });
return this.tilemap.getTileRects(f, range);
}
}
Collision with Other Entities
class Player extends Entity {
getObstaclesFor(range: Rect, v: Vec2, context=null as string): Rect[] {
let f = ((e:Entity) => { return (e instanceof Enemy); });
return this.world.getEntityColliders(f, range);
}
}
Draw Rectangle
ctx.strokeStyle = 'white';
ctx.lineWidth = 2;
strokeRect(ctx, rect);
Display Text
let glyphs = APP.images['font'];
let font = new Font(glyphs, 'white');
let textbox = new TextBox(new Rect(0, 0, 300, 200), font);
textbox.borderWidth = 2;
textbox.borderColor = 'white';
textbox.clear();
textbox.putText(['HELLO', 'WORLD'], 'center', 'center');
textbox.render(ctx);
Blinking Banner
let banner = new BannerBox(
this.screen, font,
['COLLECT ALL TEH THINGS!']);
banner.lifetime = 2.0;
banner.interval = 0.5;
this.world.add(banner);
Text Particle
let yay = new TextParticle(entity.pos, font, 'YAY!');
yay.movement = new Vec2(0,-4);
yay.lifetime = 1.0;
this.world.add(yay);
Typewriter Effect
let textbox = new TextBox(new Rect(0, 0, 300, 200), font);
let dialog = new DialogBox(textbox);
dialog.addDisplay('Hello, this is a test.', 12);
let glyphs = APP.images['font'];
let font = new Font(glyphs, 'white');
let invfont = new InvertedFont(glyphs, 'white');
let textbox = new TextBox(new Rect(0, 0, 300, 200), font);
let dialog = new DialogBox(textbox, invfont);
dialog.addDisplay('What to do?');
let menu = this.dialogBox.addMenu();
menu.addItem(new Vec2(20,20), 'Foo');
menu.addItem(new Vec2(20,30), 'Bar');
menu.addItem(new Vec2(20,40), 'Bzzz');
menu.selected.subscribe((value) => {
info(value);
});
Mouse/Touchscreen Control
class Button extends Entity {
constructor(pos: Vec2) {
super(pos);
this.sprites = [new RectSprite('white', new Rect(-10,-10,20,20))];
}
}
class Game extends GameScene {
onStart() {
this.world.add(new Button(new Vec2(100,100)));
this.world.mouseDown.subscribe((world:World, entity:Entity) => {
info(entity);
}
}
}
Text Button
class TextButton extends Entity {
constructor(frame: Rect, text: string) {
super(frame.center());
frame = frame.move(-this.pos.x, -this.pos.y);
let textbox = new TextBox(frame, font);
textbox.putText([text], 'center', 'center');
this.sprites = [textbox];
this.collider = frame;
}
isFocused() {
return (this.world !== null &&
this.world.mouseFocus === this);
}
renderExtra(ctx: CanvasRenderingContext2D) {
if (this.isFocused()) {
let rect = this.sprite.getBounds();
ctx.strokeStyle = 'white';
ctx.lineWidth = 2;
strokeRect(ctx, rect.inflate(4,4));
}
}
}