refactoring and some cleanup...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2017-04-12 16:50:13 +03:00
parent 5b5d3ad8b9
commit 03ebf5f301

View File

@ -2,13 +2,13 @@
<html> <html>
<style> <style>
.snake.field { .simplesnake .field {
position: relative; position: relative;
left: 50%; left: 50%;
margin-left: -250px; margin-left: -45vmin;
width: 500px; width: 90vmin;
height: 500px; height: 90vmin;
border: solid 1px silver; border: solid 1px silver;
} }
@ -36,8 +36,9 @@ function makeEvent(handler_attr){
var Snake = { var Snake = {
config: { config: {
field_size: 32,
apple_color: 'red', apple_color: 'red',
wall_color: 'gray', wall_color: 'silver',
interval: 200, interval: 200,
}, },
@ -46,6 +47,23 @@ var Snake = {
players: null, players: null,
field_size: null, field_size: null,
get random_point(){
var cells = this._cells
var l = cells.length
var w = this.field_size.width
do {
var i = Math.floor(Math.random() * l)
} while(cells[i].style.backgroundColor != '')
return {
x: i%w,
y: Math.floor(i/w),
}
},
get random_direction(){
return ('nesw')[Math.floor(Math.random() * 4)] },
// utils... // utils...
normalize_point: function(point){ normalize_point: function(point){
point = point || {} point = point || {}
@ -60,22 +78,18 @@ var Snake = {
return { x: x, y: y } return { x: x, y: y }
}, },
random_point: function(){ _make_field: function(w){
var cells = this._cells var l = []
var l = cells.length l.length = w || this.config.field_size
var w = this.field_size.width l.fill('<td/>')
this._field.innerHTML =
do { `<table class="field" cellspacing="0">\n${
var i = Math.floor(Math.random() * l) l.map(function(){
} while(cells[i].style.backgroundColor != '') return ` <tr> ${ l.join('') } </tr>`
}).join('\n')
return { }\n</table>`
x: i%w,
y: Math.floor(i/w),
}
}, },
_step: function(){
_tick: function(){
var that = this var that = this
var l = this._cells.length var l = this._cells.length
var w = this.field_size.width var w = this.field_size.width
@ -172,35 +186,12 @@ var Snake = {
}) })
}, },
setup: function(field){
field = field || this._field
field = this._field = typeof(field) == typeof('str') ? document.querySelector(field)
: field
this._cells = [].slice.call(field.querySelectorAll('td'))
this.field_size = {
width: field.querySelector('tr').querySelectorAll('td').length,
height: field.querySelectorAll('tr').length,
}
this.players = {}
return this
},
clear: function(){
// this resets the cell object attrs...
this.setup()
// reset the actual cells...
this._cells.forEach(function(c){ c.style.backgroundColor = '' })
this.players = {}
delete this.__appleEatenHandlers
delete this.__killHandlers
return this
},
// constructors... // constructors...
snake: function(color, point, direction, age){ snake: function(color, point, direction, age){
point = this.normalize_point(point || this.random_point()) point = this.normalize_point(point || this.random_point)
var head = this._cells[point.x + point.y * this.field_size.width] var head = this._cells[point.x + point.y * this.field_size.width]
head.style.backgroundColor = color head.style.backgroundColor = color
head.direction = direction head.direction = direction || this.random_direction
head.age = (age || 5) - 1 head.age = (age || 5) - 1
this.players[color] = '' this.players[color] = ''
@ -208,13 +199,14 @@ var Snake = {
return this return this
}, },
apple: function(point){ apple: function(point){
point = this.normalize_point(point || this.random_point()) point = this.normalize_point(point || this.random_point)
this._cells[point.x + point.y * this.field_size.width] this._cells[point.x + point.y * this.field_size.width]
.style.backgroundColor = this.config.apple_color .style.backgroundColor = this.config.apple_color
return this return this
}, },
wall: function(point, direction, length){ wall: function(point, direction, length){
point = this.normalize_point(point || this.random_point()) direction = direction || this.random_direction
point = this.normalize_point(point || this.random_point)
var x = point.x var x = point.x
var y = point.y var y = point.y
length = length || 1 length = length || 1
@ -244,9 +236,34 @@ var Snake = {
snakeKilled: makeEvent('__killHandlers'), snakeKilled: makeEvent('__killHandlers'),
// actions... // actions...
setup: function(field, size){
this.config.field_size = size || this.config.field_size
field = field || this._field
field = this._field = typeof(field) == typeof('str') ? document.querySelector(field)
: field
// XXX is it a good idea to re-make the field on every start???
this._make_field()
this._cells = [].slice.call(field.querySelectorAll('td'))
this.field_size = {
width: field.querySelector('tr').querySelectorAll('td').length,
height: field.querySelectorAll('tr').length,
}
this.players = {}
return this
},
clear: function(){
// this resets the cell object attrs...
this.setup()
// reset the actual cells...
//this._cells.forEach(function(c){ c.style.backgroundColor = '' })
this.players = {}
delete this.__appleEatenHandlers
delete this.__killHandlers
return this
},
start: function(t){ start: function(t){
this.__timer = this.__timer this.__timer = this.__timer
|| setInterval(this._tick.bind(this), t || this.config.interval || 200) || setInterval(this._step.bind(this), t || this.config.interval || 200)
return this return this
}, },
stop: function(){ stop: function(){
@ -274,15 +291,13 @@ var Snake = {
.wall({x:a*3, y:a*3}, 'e', a*2) .wall({x:a*3, y:a*3}, 'e', a*2)
.wall({x:a*5, y:a*3}, 's', a*2) .wall({x:a*5, y:a*3}, 's', a*2)
.wall({x:a*5, y:a*5}, 'e', a*6) }, .wall({x:a*5, y:a*5}, 'e', a*6) },
// XXX need to avoid blocked sections...
randomLevel: function(){ randomLevel: function(){
var a = Math.round(this.field_size.width/8) var a = Math.round(this.field_size.width/8)
var b = Math.round(this.field_size.height/8) var b = Math.round(this.field_size.height/8)
return this return this
.wall(null, 's', b*6) .wall(null, null, b*6)
.wall(null, 's', b*6) .wall(null, null, b*6)
.wall(null, 'e', a*6) .wall(null, null, b*6) },
.wall(null, 'e', a*6) },
} }
@ -312,46 +327,28 @@ function tapHandler(event){
//--------------------------------------------------------------------- //---------------------------------------------------------------------
function makeFiled(w){ function setup(snake){
var l = [] snake = (snake || Snake)
l.length = w .setup('.simplesnake')
l.fill('<td/>')
return `<table class="snake field" cellspacing="0">\n${
l.map(function(){
return ` <tr> ${ l.join('') } </tr>`
}).join('\n')
}\n</table>`
}
//---------------------------------------------------------------------
function setup(){
document.querySelector('.simplesnake').innerHTML = makeFiled(32)
Snake
.setup('.snake')
// make setup(..) re-enterable..
.stop()
.clear()
.randomLevel()
//.basicLevel() //.basicLevel()
.randomLevel()
.appleEaten(function(){ this.apple() }) .appleEaten(function(){ this.apple() })
.apple() .apple()
.apple() .apple()
// XXX do something better with direction... // XXX need to place the snake with some headroom in the
// direction of travel...
.snakeKilled(function(color){ .snakeKilled(function(color){
this this
.pause() .pause()
.snake(color, null, 's', 3) .snake(color, null, null, 3)
}) })
.snake('blue', null, 's', 3) .snake('blue', null, null, 3)
.start(150) .start(150)
.pause()
// setup kb handler (only once)... // setup kb handler (only once)...
if(!HANDLER_SET){ if(!HANDLER_SET){
@ -360,6 +357,8 @@ function setup(){
document.addEventListener('touchstart', tapHandler) document.addEventListener('touchstart', tapHandler)
HANDLER_SET = true HANDLER_SET = true
} }
return snake
} }