<html> | |
<head> | |
<style> | |
@-webkit-keyframes struck { | |
0% { -webkit-transform: translateX(10px); } | |
50% { -webkit-transform: translateX(0); } | |
100% { -webkit-transform: translateX(10px); } | |
} | |
html { | |
height: 100%; | |
overflow-y: hidden; | |
} | |
body { | |
background: rgba(0, 0, 0, .9); | |
color: rgba(255, 255, 255, .75); | |
font-family: sans-serif; | |
text-align: center; | |
height: 100%; | |
} | |
.game { | |
display: table; | |
width: 100%; | |
height: 100%; | |
} | |
.level { | |
display: table-cell; | |
text-align: center; | |
vertical-align: middle; | |
} | |
.cell { | |
-webkit-transition-property: transform, border; | |
-webkit-transition-timing-function: cubic-bezier(0,0,0,1); | |
-webkit-transition-duration: 250ms; | |
width: 50px; | |
height: 50px; | |
background: rgba(255, 255, 255, .075); | |
margin: 2px 4px; | |
border-radius: 50%; | |
display: inline-block; | |
border: 3px solid transparent; | |
} | |
.cell.start { | |
background: #00AAFF; | |
} | |
.cell.finish { | |
background: #8aba56; | |
} | |
.cell.wall { | |
background: rgba(255, 255, 255, .75); | |
} | |
.cell.walkedOn { | |
box-shadow: inset 0 0 0 5px #FFF; | |
} | |
.cell.walkedOnTwice { | |
box-shadow: inset 0 0 0 5px #00AAFF; | |
} | |
.cell.walkedOnThrice { | |
box-shadow: inset 0 0 0 5px #00FFAA; | |
} | |
.cell.struck { | |
-webkit-animation: struck 250ms; | |
} | |
.cell.active { | |
-webkit-transform: scale(1.25); | |
border: 3px solid #ff8833; | |
} | |
.cell.active.finish { | |
border: 3px solid transparent; | |
box-shadow: inset 0 0 0 3px rgba(0,0,0,0.25); | |
-webkit-transform: scale(1.4); | |
} | |
</style> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> | |
<script> | |
// | |
// Game | |
// | |
Game = function() { | |
this.player = null; | |
this.currentLevel = null; | |
this.levels = [ | |
{ | |
name: 'Level 1', | |
map: [ | |
[ 9, 5, 0, 5, 0, 5, 0, 0, 5, 0, 5, 0, 0, 0, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 5, 0, 5, 0, 5, 5, 0, 0, 0 ], | |
[ 0, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 5, 0, 5, 0, 5, 5, 0, 0, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 5, 0, 5, 0, 5, 5, 0, 0, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 5, 0, 5, 0, 5, 5, 0, 0, 0 ], | |
[ 0, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 5, 0, 5, 0, 5, 5, 0, 0, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 5, 0, 5, 0, 5, 5, 0, 0, 0 ], | |
[ 0, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 5, 0, 5, 0, 5, 5, 0, 0, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 5, 0, 5, 0, 5, 5, 5, 5, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 5, 0, 5, 0, 5, 5, 0, 0, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 0, 0, 5, 0, 5, 0, 0, 0, 0 ], | |
[ 0, 5, 0, 5, 0, 5, 0, 0, 5, 0, 5, 0, 0, 5, 5 ], | |
[ 0, 0, 0, 5, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 1 ], | |
], | |
playerStart: { | |
x: 14, | |
y: 20, | |
}, | |
}, | |
]; | |
}; | |
Game.prototype.renderLevel = function(level) { | |
// Create row | |
function createRow(rowIndex) { | |
$('.level').append($('<div />').addClass('row row'+rowIndex)); | |
} | |
// Create column | |
function createCell(rowIndex, columnIndex, cellValue) { | |
// Get the current row div | |
var rowDiv = $('.row'+rowIndex); | |
// Create a new cell div | |
var cellDiv = $('<div />').addClass('cell cellRow'+rowIndex+'Column'+columnIndex); | |
// Start | |
if(cellValue === 1) { | |
cellDiv.addClass('start'); | |
} | |
// Wall | |
else if(cellValue === 5) { | |
cellDiv.addClass('wall'); | |
} | |
// Finish | |
else if(cellValue === 9) { | |
cellDiv.addClass('finish'); | |
} | |
rowDiv.append(cellDiv); | |
} | |
// Create the rows and columns | |
for(var rowIndex = 0; rowIndex < level.map.length; rowIndex++) { | |
createRow(rowIndex); | |
for(var columnIndex = 0; columnIndex < level.map[rowIndex].length; columnIndex++) { | |
createCell(rowIndex, columnIndex, level.map[rowIndex][columnIndex]); | |
} | |
} | |
} | |
Game.prototype.playLevel = function(levelIndex) { | |
// Get the level | |
var level = this.levels[levelIndex]; | |
// Render the level | |
this.renderLevel(level); | |
// Create the player and play the game | |
this.player = new Player(level); | |
this.player.play(); | |
} | |
// | |
// Player | |
// | |
Player = function(level) { | |
this.moveHistory = []; | |
this.moveCount = 0; | |
this.moveLimit = 500; | |
this.level = level; | |
this.previousX = null; | |
this.previousY = null; | |
this.x = this.level.playerStart.x; | |
this.y = this.level.playerStart.y; | |
this.activeCellElement = $('.cell.cellRow'+this.y+'Column'+this.x).addClass('active'); | |
this.previousCellElement = null; | |
this.nextCellElement = null; | |
} | |
Player.prototype.canMoveTo = function(x, y) { | |
var canMoveTo = false; | |
var cellDiv = $('.cell.cellRow'+y+'Column'+x); | |
var cellValue = this.level.map[x, y]; | |
// Row exists | |
if(y >= 0 && y < this.level.map.length) { | |
//console.log('Row exists'); | |
// Cell exists | |
if(x >= 0 && x < this.level.map[y].length) { | |
//console.log('Cell exists'); | |
// Cell is not a wall | |
if(!cellDiv.is('.wall')) { | |
canMoveTo = true; | |
} | |
} | |
} | |
return canMoveTo; | |
} | |
Player.prototype.findAndExecuteNextMove = function() { | |
var canMoveUp = this.canMoveTo(this.x, this.y - 1); | |
var canMoveDown = this.canMoveTo(this.x, this.y + 1); | |
var canMoveLeft = this.canMoveTo(this.x - 1, this.y); | |
var canMoveRight = this.canMoveTo(this.x + 1, this.y); | |
var upIsWalkedOn = canMoveUp && $('.cell.cellRow'+(this.y - 1)+'Column'+this.x).is('.walkedOn'); | |
var downIsWalkedOn = canMoveDown && $('.cell.cellRow'+(this.y + 1)+'Column'+this.x).is('.walkedOn'); | |
var leftIsWalkedOn = canMoveLeft && $('.cell.cellRow'+this.y+'Column'+(this.x - 1)).is('.walkedOn'); | |
var rightIsWalkedOn = canMoveRight && $('.cell.cellRow'+this.y+'Column'+(this.x + 1)).is('.walkedOn'); | |
var upIsWalkedOnTwice = canMoveUp && $('.cell.cellRow'+(this.y - 1)+'Column'+this.x).is('.walkedOnTwice'); | |
var downIsWalkedOnTwice = canMoveDown && $('.cell.cellRow'+(this.y + 1)+'Column'+this.x).is('.walkedOnTwice'); | |
var leftIsWalkedOnTwice = canMoveLeft && $('.cell.cellRow'+this.y+'Column'+(this.x - 1)).is('.walkedOnTwice'); | |
var rightIsWalkedOnTwice = canMoveRight && $('.cell.cellRow'+this.y+'Column'+(this.x + 1)).is('.walkedOnTwice'); | |
var upIsWalkedOnThrice = canMoveUp && $('.cell.cellRow'+(this.y - 1)+'Column'+this.x).is('.walkedOnThrice'); | |
var downIsWalkedOnThrice = canMoveDown && $('.cell.cellRow'+(this.y + 1)+'Column'+this.x).is('.walkedOnThrice'); | |
var leftIsWalkedOnThrice = canMoveLeft && $('.cell.cellRow'+this.y+'Column'+(this.x - 1)).is('.walkedOnThrice'); | |
var rightIsWalkedOnThrice = canMoveRight && $('.cell.cellRow'+this.y+'Column'+(this.x + 1)).is('.walkedOnThrice'); | |
var upIsPreviousMove = this.previousX == this.x && this.previousY == this.y - 1; | |
var downIsPreviousMove = this.previousX == this.x && this.previousY == this.y + 1; | |
var leftIsPreviousMove = this.previousX == this.x - 1 && this.previousY == this.y; | |
var rightIsPreviousMove = this.previousX == this.x + 1 && this.previousY == this.y; | |
// Third preference is to move up | |
if(canMoveUp && !upIsWalkedOn) { | |
this.moveUp(); | |
} | |
// Second preference is to move right | |
else if(canMoveRight && !rightIsWalkedOn) { | |
this.moveRight(); | |
} | |
// First preference is to move down | |
else if(canMoveDown && !downIsWalkedOn) { | |
this.moveDown(); | |
} | |
// Fourth preference is to move left | |
else if(canMoveLeft && !leftIsWalkedOn) { | |
this.moveLeft(); | |
} | |
else { | |
// Third preference is to move up | |
if(canMoveUp && !upIsPreviousMove) { | |
this.moveUp(); | |
} | |
// Second preference is to move right | |
else if(canMoveRight && !rightIsPreviousMove) { | |
this.moveRight(); | |
} | |
// First preference is to move down | |
else if(canMoveDown && !downIsPreviousMove) { | |
this.moveDown(); | |
} | |
// Fourth preference is to move left | |
else if(canMoveLeft && !leftIsPreviousMove) { | |
this.moveLeft(); | |
} | |
else { | |
$('.active').addClass('struck'); | |
// Back track | |
var previousMove = this.moveHistory.pop(); | |
this.move(previousMove.x, previousMove.y); | |
} | |
} | |
} | |
Player.prototype.move = function(x, y) { | |
this.activeCellElement.removeClass('active'); | |
this.nextCellElement = $('.cell.cellRow'+y+'Column'+x); | |
this.previousCellElement = this.activeCellElement; | |
this.activeCellElement = this.nextCellElement; | |
this.activeCellElement.addClass('active'); | |
if(this.previousCellElement.is('.walkedOnTwice')) { | |
this.previousCellElement.addClass('walkedOnThrice'); | |
} | |
else if(this.previousCellElement.is('.walkedOn')) { | |
this.previousCellElement.addClass('walkedOnTwice'); | |
} | |
else { | |
this.previousCellElement.addClass('walkedOn'); | |
} | |
this.previousX = this.x; | |
this.previousY = this.y; | |
this.x = x; | |
this.y = y; | |
this.moveHistory.push({ | |
x: this.x, | |
y: this.y, | |
}); | |
console.log('Moving to', x+', '+y); | |
if(this.activeCellElement.is('.finish')) { | |
console.log('Done!'); | |
return; | |
} | |
this.moveCount++; | |
this.play(); | |
} | |
Player.prototype.moveUp = function() { | |
console.log('Up'); | |
this.move(this.x, this.y - 1); | |
} | |
Player.prototype.moveDown = function() { | |
console.log('Down'); | |
this.move(this.x, this.y + 1); | |
} | |
Player.prototype.moveLeft = function() { | |
console.log('Left'); | |
this.move(this.x - 1, this.y); | |
} | |
Player.prototype.moveRight = function() { | |
console.log('Right'); | |
this.move(this.x + 1, this.y); | |
} | |
Player.prototype.play = function() { | |
setTimeout(function() { | |
if(this.moveCount < this.moveLimit) { | |
this.findAndExecuteNextMove(); | |
} | |
else { | |
console.log('Out of moves', this.moveCount); | |
} | |
}.bind(this), 100); | |
} | |
// | |
// Start the game | |
// | |
$(document).ready(function() { | |
var game = new Game(); | |
game.playLevel(0); | |
}); | |
</script> | |
</head> | |
<body> | |
<div class="game"> | |
<div class="level"></div> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment