Last active
July 7, 2020 19:27
-
-
Save mathdoodle/e176de7beb85f36df721954ea81ab65f to your computer and use it in GitHub Desktop.
Bacon.js Snake Tutorial
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default function() { | |
describe("...", function() { | |
it("should ...", function() { | |
expect(true).toBeTruthy() | |
}) | |
}) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<!-- STYLES-MARKER --> | |
<style> | |
/* STYLE-MARKER */ | |
</style> | |
<script src='https://jspm.io/system.js'></script> | |
<!-- SHADERS-MARKER --> | |
<!-- SCRIPTS-MARKER --> | |
</head> | |
<body> | |
<button id='clickMe'>Click me!</button> | |
<div id='output'></div> | |
<button class='left'>Left</button> | |
<button class='right'>Right</button> | |
<button class='tick'>Tick</button> | |
<div> | |
"Direction: " | |
<span id='direction'></span> | |
</div> | |
<div> | |
"Position: " | |
<span id='position'></span> | |
</div> | |
<div id='game' class='game'> | |
</div> | |
<script> | |
// CODE-MARKER | |
</script> | |
<script> | |
System.import('./index.js') | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Vector2 from './Vector2'; | |
const gameX = 7; | |
const gameY = 7; | |
DomReady.ready(function() { | |
const clicks = $('#clickMe').asEventStream('click') | |
// scan is a combinator | |
const counter = clicks.map(1).scan(0, (x, y)=> x + y) | |
counter.onValue(x => $('#output').html(`${x}`)) | |
/////////////////////// | |
const lefts = $("button.left").asEventStream('click'); | |
const rights = $("button.right").asEventStream('click'); | |
const tick = $("button.tick").asEventStream('click'); | |
const actions = lefts.map(() => rotateLeft).merge(rights.map(() => rotateRight)); | |
// We start by heading upwards | |
const startDirection = new Vector2(0, 1); | |
const direction = actions.scan(startDirection, (x, f) => f(x)); | |
const currentDirection = direction.sampledBy(tick); | |
const startPosition = new Vector2(0, 0) | |
const position = currentDirection.scan(startPosition, (x, y) => x.add(y)) | |
direction.onValue(function(x) { $("#direction").html(`${x}`)}) | |
position.onValue(function(x) { $("#position").html(`${x}`)}) | |
drawGame('#game') | |
position.map(Array).onValue(drawSnake("#game")) | |
}) | |
function rotateLeft(pos: Vector2) { | |
return new Vector2(pos.y, -pos.x) | |
} | |
function rotateRight(pos: Vector2) { | |
return new Vector2(-pos.y, pos.x) | |
} | |
function and(a: boolean, b: boolean): boolean { | |
return a && b; | |
} | |
function nonEmpty(x: {length: number}): boolean { | |
return x.length > 0 | |
} | |
/** | |
* This helper function also exusts in Bacon.UI, but we don't have that loaded. | |
*/ | |
function textFieldValue(textField: JQuery): Bacon.Property<ErrorEvent, string> { | |
function value(): string { | |
return textField.val() | |
} | |
return textField.asEventStream('keyup').map(value).toProperty(value()) | |
} | |
function drawGame(sel) { | |
var game = $(sel) | |
for (var i = 0; i < gameX; i++) { | |
var row = $('<div/>').addClass('row') | |
game.append(row) | |
for (var j = 0; j < gameY; j++) | |
row.append($('<div/>').addClass('cell')) | |
} | |
} | |
function drawSnake(sel) { | |
var game = $(sel) | |
return function(ps) { | |
game.find('.cell').removeClass('snake') | |
for (var i in ps) { | |
game.find('.row:eq('+ps[i].y+')').find('.cell:eq('+ps[i].x+')').addClass('snake') | |
} | |
} | |
} | |
function drawApple(sel) { | |
var game = $(sel) | |
return function(p) { | |
game.find('.cell').removeClass('apple') | |
game.find('.row:eq('+p.y+')').find('.cell:eq('+p.x+')').addClass('apple') | |
} | |
} | |
/* | |
function Vector2(x, y) { | |
this.x = x; this.y = y; | |
this.describe = x + ', ' + y | |
this.equals = function(p) { return this.x === p.x && this.y === p.y } | |
this.add = function(p) { return new Vector2((this.x + p.x + gameX) % gameX, (this.y + p.y + gameX) % gameX) } | |
} | |
*/ | |
const randomPos = function() { | |
return new Vector2(Math.floor(Math.random() * 5), Math.floor(Math.random() * 5)) | |
} | |
/* | |
function rotateRight(pos) { | |
return new Vector2(-pos.y, pos.x) | |
} | |
function rotateLeft(pos) { | |
return new Vector2(pos.y, -pos.x) | |
} | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"description": "Bacon.js Snake Tutorial", | |
"dependencies": { | |
"DomReady": "1.0.0", | |
"jquery": "2.1.4", | |
"jasmine": "3.4.0", | |
"baconjs": "0.7.89" | |
}, | |
"name": "baconjs-snake-tutorial", | |
"version": "0.1.0", | |
"keywords": [ | |
"Bacon", | |
"baconjs", | |
"bacon.js", | |
"Snake", | |
"Tutorial" | |
], | |
"author": "David Geo Holmes" | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
background-color: white; | |
font-family: 'Comic Sans MS', sans-serif; | |
} | |
.row { padding: 0; margin: 0; height: 12px} | |
.cell { | |
width: 10px; | |
height: 10px; | |
padding: 0; | |
margin: 1px; | |
display: inline-block; | |
background-color: white; | |
} | |
.snake { background-color: green } | |
.apple { background-color: red } | |
.game { | |
padding: 5px; | |
box-shadow: 0 0 5px lightgray; | |
display: inline-block; | |
clear: both; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<!-- STYLES-MARKER --> | |
<style> | |
/* STYLE-MARKER */ | |
</style> | |
<script src='https://jspm.io/system.js'></script> | |
<!-- SCRIPTS-MARKER --> | |
</head> | |
<body> | |
<script> | |
// CODE-MARKER | |
</script> | |
<script> | |
System.import('./tests.js') | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Example from './Example.spec' | |
window['jasmine'] = jasmineRequire.core(jasmineRequire) | |
jasmineRequire.html(window['jasmine']) | |
const env = jasmine.getEnv() | |
const jasmineInterface = jasmineRequire.interface(window['jasmine'], env) | |
extend(window, jasmineInterface) | |
const htmlReporter = new jasmine.HtmlReporter({ | |
env: env, | |
getContainer: function() { return document.body }, | |
createElement: function() { return document.createElement.apply(document, arguments) }, | |
createTextNode: function() { return document.createTextNode.apply(document, arguments) }, | |
timer: new jasmine.Timer() | |
}) | |
env.addReporter(htmlReporter) | |
DomReady.ready(function() { | |
htmlReporter.initialize() | |
describe("Example", Example) | |
env.execute() | |
}) | |
/* | |
* Helper function for extending the properties on objects. | |
*/ | |
export default function extend<T>(destination: T, source: any): T { | |
for (let property in source) { | |
destination[property] = source[property] | |
} | |
return destination | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
{ | |
"allowJs": true, | |
"checkJs": true, | |
"declaration": true, | |
"emitDecoratorMetadata": true, | |
"experimentalDecorators": true, | |
"jsx": "react", | |
"module": "system", | |
"noImplicitAny": true, | |
"noImplicitReturns": true, | |
"noImplicitThis": true, | |
"noUnusedLocals": true, | |
"noUnusedParameters": true, | |
"preserveConstEnums": true, | |
"removeComments": false, | |
"skipLibCheck": true, | |
"sourceMap": true, | |
"strictNullChecks": true, | |
"suppressImplicitAnyIndexErrors": true, | |
"target": "es5", | |
"traceResolution": true | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default class Vector2 { | |
constructor(public x: number, public y: number) { | |
} | |
add(rhs: Vector2): Vector2 { | |
return new Vector2(this.x + rhs.x, this.y + rhs.y); | |
} | |
toString(): string { | |
return `[${this.x}, ${this.y}]` | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment