Skip to content

Instantly share code, notes, and snippets.

@kirkouimet kirkouimet/game.html
Created Sep 23, 2015

Embed
What would you like to do?
<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
You can’t perform that action at this time.