Skip to content

Commit

Permalink
merge new game button
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielecirulli committed Mar 22, 2014
2 parents 6c8d94c + 17fe360 commit 5afb368
Show file tree
Hide file tree
Showing 13 changed files with 284 additions and 124 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ Many thanks to [rayhaanj](https://github.com/rayhaanj), [Mechazawa](https://gith

### Screenshot

[![Screenshot](http://pictures.gabrielecirulli.com/2048-20140309-234100.png)](http://pictures.gabrielecirulli.com/2048-20140309-234100.png)
<p align="center">
<img src="http://pictures.gabrielecirulli.com/2048-20140309-234100.png" alt="Screenshot"/>
</p>

That screenshot is fake, by the way. I never reached 2048 :smile:

Expand Down
4 changes: 2 additions & 2 deletions cache.appcache
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ CACHE MANIFEST
# Adds the ability to play the game online.
# The following comment needs to be updated whenever a change is made.
# Run `rake appcache:update` to do so
# Updated: 2014-03-21T13:04:30+01:00
# Updated: 2014-03-22T17:11:53+01:00

# Main page
index.html
Expand Down Expand Up @@ -36,7 +36,7 @@ js/game_manager.js
js/grid.js
js/html_actuator.js
js/keyboard_input_manager.js
js/local_score_manager.js
js/local_storage_manager.js
js/tile.js

favicon.ico
Expand Down
8 changes: 6 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ <h1 class="title">2048</h1>
<div class="best-container">0</div>
</div>
</div>
<p class="game-intro">Join the numbers and get to the <strong>2048 tile!</strong></p>

<div class="above-game">
<p class="game-intro">Join the numbers and get to the <strong>2048 tile!</strong></p>
<a class="restart-button">New Game</a>
</div>

<div class="game-container">
<div class="game-message">
Expand Down Expand Up @@ -109,7 +113,7 @@ <h1 class="title">2048</h1>
<script src="js/html_actuator.js"></script>
<script src="js/grid.js"></script>
<script src="js/tile.js"></script>
<script src="js/local_score_manager.js"></script>
<script src="js/local_storage_manager.js"></script>
<script src="js/game_manager.js"></script>
<script src="js/application.js"></script>

Expand Down
2 changes: 1 addition & 1 deletion js/application.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Wait till the browser is ready to render the game (avoids glitches)
window.requestAnimationFrame(function () {
new GameManager(4, KeyboardInputManager, HTMLActuator, LocalScoreManager);
new GameManager(4, KeyboardInputManager, HTMLActuator, LocalStorageManager);
});
59 changes: 41 additions & 18 deletions js/game_manager.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
function GameManager(size, InputManager, Actuator, ScoreManager) {
this.size = size; // Size of the grid
this.inputManager = new InputManager;
this.scoreManager = new ScoreManager;
this.actuator = new Actuator;
function GameManager(size, InputManager, Actuator, StorageManager) {
this.size = size; // Size of the grid
this.inputManager = new InputManager;
this.storageManager = new StorageManager;
this.actuator = new Actuator;

this.startTiles = 2;
this.startTiles = 2;

this.inputManager.on("move", this.move.bind(this));
this.inputManager.on("restart", this.restart.bind(this));
Expand All @@ -15,6 +15,7 @@ function GameManager(size, InputManager, Actuator, ScoreManager) {

// Restart the game
GameManager.prototype.restart = function () {
this.storageManager.clearGameState();
this.actuator.continue();
this.setup();
};
Expand All @@ -35,15 +36,25 @@ GameManager.prototype.isGameTerminated = function () {

// Set up the game
GameManager.prototype.setup = function () {
this.grid = new Grid(this.size);

this.score = 0;
this.over = false;
this.won = false;
this.keepPlaying = false;

// Add the initial tiles
this.addStartTiles();
var previousState = this.storageManager.getGameState();

if (previousState) {
this.grid = new Grid(previousState.grid.size,
previousState.grid.cells); // Reload grid
this.score = previousState.score;
this.over = previousState.over;
this.won = previousState.won;
this.keepPlaying = previousState.keepPlaying;
} else {
this.grid = new Grid(this.size);
this.score = 0;
this.over = false;
this.won = false;
this.keepPlaying = false;

// Add the initial tiles
this.addStartTiles();
}

// Update the actuator
this.actuate();
Expand All @@ -68,20 +79,32 @@ GameManager.prototype.addRandomTile = function () {

// Sends the updated grid to the actuator
GameManager.prototype.actuate = function () {
if (this.scoreManager.get() < this.score) {
this.scoreManager.set(this.score);
if (this.storageManager.getBestScore() < this.score) {
this.storageManager.setBestScore(this.score);
}

this.storageManager.setGameState(this.serialize());

this.actuator.actuate(this.grid, {
score: this.score,
over: this.over,
won: this.won,
bestScore: this.scoreManager.get(),
bestScore: this.storageManager.getBestScore(),
terminated: this.isGameTerminated()
});

};

GameManager.prototype.serialize = function () {
return {
grid: this.grid.serialize(),
score: this.score,
over: this.over,
won: this.won,
keepPlaying: this.keepPlaying
};
};

// Save all tile positions and remove merger info
GameManager.prototype.prepareTiles = function () {
this.grid.eachCell(function (x, y, tile) {
Expand Down
47 changes: 40 additions & 7 deletions js/grid.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
function Grid(size) {
function Grid(size, previousState) {
this.size = size;

this.cells = [];

this.build();
this.cells = previousState ? this.fromState(previousState) : this.empty();
}

// Build a grid of the specified size
Grid.prototype.build = function () {
Grid.prototype.empty = function () {
var cells = [];

for (var x = 0; x < this.size; x++) {
var row = this.cells[x] = [];
var row = cells[x] = [];

for (var y = 0; y < this.size; y++) {
row.push(null);
}
}

return cells;
};

Grid.prototype.fromState = function (state) {
var cells = [];

for (var x = 0; x < this.size; x++) {
var row = cells[x] = [];

for (var y = 0; y < this.size; y++) {
var tile = state[x][y];
row.push(tile ? new Tile(tile.position, tile.value) : null);
}
}

return cells;
};

// Find the first available random position
Expand Down Expand Up @@ -82,3 +98,20 @@ Grid.prototype.withinBounds = function (position) {
return position.x >= 0 && position.x < this.size &&
position.y >= 0 && position.y < this.size;
};

Grid.prototype.serialize = function () {
var cellState = [];

for (var x = 0; x < this.size; x++) {
var row = cellState[x] = [];

for (var y = 0; y < this.size; y++) {
row.push(this.cells[x][y] ? this.cells[x][y].serialize() : null);
}
}

return {
size: this.size,
cells: cellState
};
};
68 changes: 41 additions & 27 deletions js/keyboard_input_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,17 @@ KeyboardInputManager.prototype.listen = function () {
39: 1, // Right
40: 2, // Down
37: 3, // Left
75: 0, // vim keybindings
76: 1,
74: 2,
72: 3,
75: 0, // Vim up
76: 1, // Vim right
74: 2, // Vim down
72: 3, // Vim left
87: 0, // W
68: 1, // D
83: 2, // S
65: 3 // A
};

// Respond to direction keys
document.addEventListener("keydown", function (event) {
var modifiers = event.altKey || event.ctrlKey || event.metaKey ||
event.shiftKey;
Expand All @@ -59,34 +60,37 @@ KeyboardInputManager.prototype.listen = function () {
event.preventDefault();
self.emit("move", mapped);
}
}

if (event.which === 32) self.restart.bind(self)(event);
// R key restarts the game
if (!modifiers && event.which === 82) {
self.restart.call(self, event);
}
});

var retry = document.querySelector(".retry-button");
retry.addEventListener("click", this.restart.bind(this));
retry.addEventListener(this.eventTouchend, this.restart.bind(this));

var keepPlaying = document.querySelector(".keep-playing-button");
keepPlaying.addEventListener("click", this.keepPlaying.bind(this));
keepPlaying.addEventListener("touchend", this.keepPlaying.bind(this));
// Respond to button presses
this.bindButtonPress(".retry-button", this.restart);
this.bindButtonPress(".restart-button", this.restart);
this.bindButtonPress(".keep-playing-button", this.keepPlaying);

// Listen to swipe events
// Respond to swipe events
var touchStartClientX, touchStartClientY;
var gameContainer = document.getElementsByClassName("game-container")[0];

gameContainer.addEventListener(this.eventTouchstart, function (event) {
if (( !window.navigator.msPointerEnabled && event.touches.length > 1) || event.targetTouches > 1) return;

if(window.navigator.msPointerEnabled){
touchStartClientX = event.pageX;
touchStartClientY = event.pageY;
if ((!window.navigator.msPointerEnabled && event.touches.length > 1) ||
event.targetTouches > 1) {
return; // Ignore if touching with more than 1 finger
}

if (window.navigator.msPointerEnabled) {
touchStartClientX = event.pageX;
touchStartClientY = event.pageY;
} else {
touchStartClientX = event.touches[0].clientX;
touchStartClientY = event.touches[0].clientY;
touchStartClientX = event.touches[0].clientX;
touchStartClientY = event.touches[0].clientY;
}

event.preventDefault();
});

Expand All @@ -95,15 +99,19 @@ KeyboardInputManager.prototype.listen = function () {
});

gameContainer.addEventListener(this.eventTouchend, function (event) {
if (( !window.navigator.msPointerEnabled && event.touches.length > 0) || event.targetTouches > 0) return;
if ((!window.navigator.msPointerEnabled && event.touches.length > 0) ||
event.targetTouches > 0) {
return; // Ignore if still touching with one or more fingers
}

var touchEndClientX, touchEndClientY;
if(window.navigator.msPointerEnabled){
touchEndClientX = event.pageX;
touchEndClientY = event.pageY;

if (window.navigator.msPointerEnabled) {
touchEndClientX = event.pageX;
touchEndClientY = event.pageY;
} else {
touchEndClientX = event.changedTouches[0].clientX;
touchEndClientY = event.changedTouches[0].clientY;
touchEndClientX = event.changedTouches[0].clientX;
touchEndClientY = event.changedTouches[0].clientY;
}

var dx = touchEndClientX - touchStartClientX;
Expand All @@ -128,3 +136,9 @@ KeyboardInputManager.prototype.keepPlaying = function (event) {
event.preventDefault();
this.emit("keepPlaying");
};

KeyboardInputManager.prototype.bindButtonPress = function (selector, fn) {
var button = document.querySelector(selector);
button.addEventListener("click", fn.bind(this));
button.addEventListener(this.eventTouchend, fn.bind(this));
};
48 changes: 0 additions & 48 deletions js/local_score_manager.js

This file was deleted.

Loading

0 comments on commit 5afb368

Please sign in to comment.