Created
March 23, 2018 12:54
-
-
Save zischwartz/a302e37175922d44c605a281a36236b8 to your computer and use it in GitHub Desktop.
This file contains 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> | |
<meta charset="utf-8"> | |
<title></title> | |
<style> | |
body { | |
background-color: black; | |
height: 100vh; | |
overflow: hidden; | |
} | |
#app { | |
margin-left: auto; | |
margin-right: auto; | |
width: 800px; | |
height: 800px; | |
/* margin-top: 0px; */ | |
/* background-color: black; */ | |
} | |
svg { | |
background-color: rgb(40,40,40); | |
width: 800px; | |
height: 800px; | |
} | |
svg text { | |
-webkit-user-select: none; | |
-moz-user-select: none; | |
-ms-user-select: none; | |
user-select: none; | |
} | |
svg text::selection { | |
background: none; | |
} | |
svg text { | |
fill: white; | |
} | |
rect { | |
fill: none; | |
/* fill: black; */ | |
} | |
#score { | |
color: rgb(250,250,250); | |
text-align: right; | |
font-family: sans-serif; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="app"></div> | |
</body> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<!-- For offline dev --> | |
<!-- <script src="d3.v4.min.js"></script> --> | |
<script src="tinyboard.js"></script> | |
<!-- <script src="game.js"></script> --> | |
<script src="mgame.js"></script> | |
<!-- <script src="game_examples.js"></script> --> | |
<script> | |
// XXX YOU PROBABLY DON'T NEED TO EDIT THIS FILE | |
// Go edit game.js instead | |
let wrap = d3.select( document.getElementById("app") ) | |
let score_el = wrap.append('div').attr('id', 'score') | |
let svg = wrap.append('svg') | |
let sel = svg.append('g').attr('id', 'game') | |
function render_board(data){ | |
let board = Board() | |
.tile_size(800/10) | |
sel.datum(data).call(board) | |
} | |
function set_score(score){ | |
score_el.html(score) | |
} | |
let game = new Game(render_board, set_score) | |
// register our event listener | |
document.addEventListener('keydown', (event) => { | |
if (game.keypressed){ | |
game.keypressed(event.key) | |
} | |
// console.log(event.key) | |
}) | |
// call game's do_every_second | |
if (game.do_every_second){ | |
setInterval(game.do_every_second.bind(game), 1000) | |
} | |
</script> | |
</html> |
This file contains 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
class Game { | |
constructor(render_board, set_score){ | |
this.render_board = render_board | |
this.set_score = set_score | |
this.score = 0 | |
this.board_size = 10 // 10 rows by 10 cols | |
// we use this to count the total number item's we've added, to make sure they | |
// have unique ids | |
this.all_objects_ever_count = 0 | |
this.set_score(this.score) | |
this.data = [] | |
// just add one money item to start, for easier debug. was 10 in class | |
this.add_item('💰', 1) | |
this.data.push({row:2, col: 5, icon:'🐄', id:'player' }) | |
this.add_item('👿', 1) | |
this.add_item('🌲', 3) | |
this.render_board(this.data) | |
} | |
add_item(icon, number_to_add){ | |
for (var i = 0; i < number_to_add; i++) { | |
let row = Math.floor(Math.random()*this.board_size) | |
let col = Math.floor(Math.random()*this.board_size) | |
// in class I used this.data.length for the item id here, but I realized that's | |
// a mistake and will result in duplicate ids IF we're removing items from this.data (which we are) | |
this.data.push({row, col, icon, id:`${this.all_objects_ever_count}`}) | |
// increment all_objects_ever_count so the next money id will be unique | |
this.all_objects_ever_count+=1 | |
} | |
} | |
keypressed(keyname){ | |
let player = this.get_by_id('player') | |
if (keyname == 'ArrowUp'){ | |
player['row'] = player['row']-1 | |
} | |
else if (keyname == 'ArrowDown'){ | |
player['row'] +=1 | |
} | |
else if (keyname == 'ArrowLeft'){ | |
player['col'] -=1 | |
} | |
else if (keyname == 'ArrowRight'){ | |
player['col'] +=1 | |
} | |
this.process_money(player) | |
this.process_enemies(player) | |
this.render_board(this.data) | |
} | |
// move enemies and collision detection with player | |
process_enemies(player){ | |
let all_enemies = this.data.filter( function(x){ return x.icon == '👿'}) | |
for (var i = 0; i < all_enemies.length; i++) { | |
let enemy = all_enemies[i] | |
// randomly 1 or 0 | |
let should_move = Math.round(Math.random()) | |
// if should_move is true, move this enemy towards the player, | |
// along the x axis (col number) | |
if (enemy.col > player.col && should_move){ | |
enemy.col-=1 | |
} else if (enemy.col < player.col && should_move){ | |
enemy.col+=1 | |
} | |
// did the enemy touch a player? | |
if (enemy.col == player.col && enemy.row == player.row){ | |
this.score -=1 | |
// turn the player into a hamburger | |
player['icon'] = '🍔' | |
this.set_score(this.score) | |
} | |
} | |
} | |
// collision detection for player hitting a money item | |
process_money(player){ | |
let all_money = this.data.filter( function(x){ return x.icon == '💰'}) | |
for (var i = 0; i < all_money.length; i++) { | |
let money = all_money[i] | |
if (money.col == player.col && money.row == player.row){ | |
this.score +=1 | |
this.set_score(this.score) | |
this.data = this.data.filter( function(x){ return x.id !=money.id}) | |
this.add_item('💰',2) | |
this.add_item('👿',1) | |
} | |
} | |
} | |
// helper | |
get_by_id(id){ | |
return this.data.find( x=> x.id==id) | |
} | |
// do_every_second() automatically gets called once a second in index.html | |
do_every_second(){ | |
// you can use it to move things around without user interaction | |
// change this.data and uncomment this line | |
// this.render_board(this.data) | |
} | |
} |
This file contains 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
// XXX YOU ARE NOT MEANT TO EDIT THIS FILE | |
// XXX YOU ARE NOT MEANT TO EDIT THIS FILE | |
// XXX YOU ARE NOT MEANT TO EDIT THIS FILE | |
let key_func_by_id = function(d) { | |
return d.id | |
} | |
let is_data_invalid = function(data){ | |
let have_ids = data.filter( (x) => typeof x.id != 'undefined' ) | |
if (have_ids.length >0 && have_ids.length != data.length){ | |
return true | |
} | |
else { | |
return false | |
} | |
} | |
// https://bost.ocks.org/mike/chart/ | |
// XXX meant to be used with datum(), not data() | |
// i.e. selection should just be a single g | |
function Board() { | |
// All options that should be accessible to caller | |
let tile_size = 30 | |
let margin = 1 | |
let click = () => {} | |
function board(selection) { | |
selection.each(function(data, i) { | |
if (is_data_invalid(data)){ | |
throw Error('Doh! Your data is not consistent - It looks like some of your items have the `id` property and some do not') | |
} | |
let spaces | |
if (data.filter( (x) => typeof x.id != 'undefined' ).length){ | |
spaces = d3.select(this).selectAll(".space").data(data, key_func_by_id) | |
} else { | |
spaces = d3.select(this).selectAll(".space").data(data) | |
} | |
let spacesEnter = spaces | |
.enter() | |
.append("g") | |
.attr("class", "space") | |
spacesEnter.append("rect") | |
spacesEnter.append("text") | |
spacesEnter.attr( | |
"transform", | |
(d, i) => `translate(${d.col * tile_size}, ${d.row * tile_size})` | |
) | |
// enter+update | |
let spacesMerge = spacesEnter.merge(spaces) | |
spaces.exit().remove() | |
spacesMerge | |
.transition() | |
// .duration(400) | |
.attr( | |
"transform", | |
(d, i) => `translate(${d.col * tile_size}, ${d.row * tile_size})` | |
) | |
.select("rect") | |
.attr("width", tile_size - margin) | |
.attr("height", tile_size - margin) | |
spacesMerge | |
.select("text") | |
// .attr("font-size", 13) | |
.attr("font-size", 48) | |
.text(d => { | |
return d.icon | |
}) | |
// .attr("y", ".3em") | |
.attr("y", (tile_size - margin) / 1.5) | |
.attr("x", (tile_size - margin) / 2) | |
.attr("text-anchor", "middle") | |
.attr("text-align", "center") | |
spacesMerge.on("click", click) | |
// console.log(cluesMerge) | |
}) // end selection.each | |
} // end board function we return | |
board.tile_size = function(value) { | |
if (!arguments.length) return tile_size | |
tile_size = value | |
// if (typeof updateWidth === "function") updateWidth() | |
return board | |
} | |
board.margin = function(value) { | |
if (!arguments.length) return margin | |
margin = value | |
// if (typeof updateHeight === "function") updateHeight() | |
return board | |
} | |
board.click = function(value) { | |
if (!arguments.length) return click | |
click = value | |
return board | |
} | |
return board | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment