merge new game button
This commit is contained in:
@@ -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)
|
<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:
|
That screenshot is fake, by the way. I never reached 2048 :smile:
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ CACHE MANIFEST
|
|||||||
# Adds the ability to play the game online.
|
# Adds the ability to play the game online.
|
||||||
# The following comment needs to be updated whenever a change is made.
|
# The following comment needs to be updated whenever a change is made.
|
||||||
# Run `rake appcache:update` to do so
|
# 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
|
# Main page
|
||||||
index.html
|
index.html
|
||||||
@@ -36,7 +36,7 @@ js/game_manager.js
|
|||||||
js/grid.js
|
js/grid.js
|
||||||
js/html_actuator.js
|
js/html_actuator.js
|
||||||
js/keyboard_input_manager.js
|
js/keyboard_input_manager.js
|
||||||
js/local_score_manager.js
|
js/local_storage_manager.js
|
||||||
js/tile.js
|
js/tile.js
|
||||||
|
|
||||||
favicon.ico
|
favicon.ico
|
||||||
|
|||||||
+6
-2
@@ -28,7 +28,11 @@
|
|||||||
<div class="best-container">0</div>
|
<div class="best-container">0</div>
|
||||||
</div>
|
</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-container">
|
||||||
<div class="game-message">
|
<div class="game-message">
|
||||||
@@ -109,7 +113,7 @@
|
|||||||
<script src="js/html_actuator.js"></script>
|
<script src="js/html_actuator.js"></script>
|
||||||
<script src="js/grid.js"></script>
|
<script src="js/grid.js"></script>
|
||||||
<script src="js/tile.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/game_manager.js"></script>
|
||||||
<script src="js/application.js"></script>
|
<script src="js/application.js"></script>
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// Wait till the browser is ready to render the game (avoids glitches)
|
// Wait till the browser is ready to render the game (avoids glitches)
|
||||||
window.requestAnimationFrame(function () {
|
window.requestAnimationFrame(function () {
|
||||||
new GameManager(4, KeyboardInputManager, HTMLActuator, LocalScoreManager);
|
new GameManager(4, KeyboardInputManager, HTMLActuator, LocalStorageManager);
|
||||||
});
|
});
|
||||||
|
|||||||
+39
-16
@@ -1,10 +1,10 @@
|
|||||||
function GameManager(size, InputManager, Actuator, ScoreManager) {
|
function GameManager(size, InputManager, Actuator, StorageManager) {
|
||||||
this.size = size; // Size of the grid
|
this.size = size; // Size of the grid
|
||||||
this.inputManager = new InputManager;
|
this.inputManager = new InputManager;
|
||||||
this.scoreManager = new ScoreManager;
|
this.storageManager = new StorageManager;
|
||||||
this.actuator = new Actuator;
|
this.actuator = new Actuator;
|
||||||
|
|
||||||
this.startTiles = 2;
|
this.startTiles = 2;
|
||||||
|
|
||||||
this.inputManager.on("move", this.move.bind(this));
|
this.inputManager.on("move", this.move.bind(this));
|
||||||
this.inputManager.on("restart", this.restart.bind(this));
|
this.inputManager.on("restart", this.restart.bind(this));
|
||||||
@@ -15,6 +15,7 @@ function GameManager(size, InputManager, Actuator, ScoreManager) {
|
|||||||
|
|
||||||
// Restart the game
|
// Restart the game
|
||||||
GameManager.prototype.restart = function () {
|
GameManager.prototype.restart = function () {
|
||||||
|
this.storageManager.clearGameState();
|
||||||
this.actuator.continue();
|
this.actuator.continue();
|
||||||
this.setup();
|
this.setup();
|
||||||
};
|
};
|
||||||
@@ -35,15 +36,25 @@ GameManager.prototype.isGameTerminated = function () {
|
|||||||
|
|
||||||
// Set up the game
|
// Set up the game
|
||||||
GameManager.prototype.setup = function () {
|
GameManager.prototype.setup = function () {
|
||||||
this.grid = new Grid(this.size);
|
var previousState = this.storageManager.getGameState();
|
||||||
|
|
||||||
this.score = 0;
|
if (previousState) {
|
||||||
this.over = false;
|
this.grid = new Grid(previousState.grid.size,
|
||||||
this.won = false;
|
previousState.grid.cells); // Reload grid
|
||||||
this.keepPlaying = false;
|
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
|
// Add the initial tiles
|
||||||
this.addStartTiles();
|
this.addStartTiles();
|
||||||
|
}
|
||||||
|
|
||||||
// Update the actuator
|
// Update the actuator
|
||||||
this.actuate();
|
this.actuate();
|
||||||
@@ -68,20 +79,32 @@ GameManager.prototype.addRandomTile = function () {
|
|||||||
|
|
||||||
// Sends the updated grid to the actuator
|
// Sends the updated grid to the actuator
|
||||||
GameManager.prototype.actuate = function () {
|
GameManager.prototype.actuate = function () {
|
||||||
if (this.scoreManager.get() < this.score) {
|
if (this.storageManager.getBestScore() < this.score) {
|
||||||
this.scoreManager.set(this.score);
|
this.storageManager.setBestScore(this.score);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.storageManager.setGameState(this.serialize());
|
||||||
|
|
||||||
this.actuator.actuate(this.grid, {
|
this.actuator.actuate(this.grid, {
|
||||||
score: this.score,
|
score: this.score,
|
||||||
over: this.over,
|
over: this.over,
|
||||||
won: this.won,
|
won: this.won,
|
||||||
bestScore: this.scoreManager.get(),
|
bestScore: this.storageManager.getBestScore(),
|
||||||
terminated: this.isGameTerminated()
|
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
|
// Save all tile positions and remove merger info
|
||||||
GameManager.prototype.prepareTiles = function () {
|
GameManager.prototype.prepareTiles = function () {
|
||||||
this.grid.eachCell(function (x, y, tile) {
|
this.grid.eachCell(function (x, y, tile) {
|
||||||
|
|||||||
+40
-7
@@ -1,20 +1,36 @@
|
|||||||
function Grid(size) {
|
function Grid(size, previousState) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
|
this.cells = previousState ? this.fromState(previousState) : this.empty();
|
||||||
this.cells = [];
|
|
||||||
|
|
||||||
this.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a grid of the specified size
|
// 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++) {
|
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++) {
|
for (var y = 0; y < this.size; y++) {
|
||||||
row.push(null);
|
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
|
// Find the first available random position
|
||||||
@@ -82,3 +98,20 @@ Grid.prototype.withinBounds = function (position) {
|
|||||||
return position.x >= 0 && position.x < this.size &&
|
return position.x >= 0 && position.x < this.size &&
|
||||||
position.y >= 0 && position.y < 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
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
@@ -39,16 +39,17 @@ KeyboardInputManager.prototype.listen = function () {
|
|||||||
39: 1, // Right
|
39: 1, // Right
|
||||||
40: 2, // Down
|
40: 2, // Down
|
||||||
37: 3, // Left
|
37: 3, // Left
|
||||||
75: 0, // vim keybindings
|
75: 0, // Vim up
|
||||||
76: 1,
|
76: 1, // Vim right
|
||||||
74: 2,
|
74: 2, // Vim down
|
||||||
72: 3,
|
72: 3, // Vim left
|
||||||
87: 0, // W
|
87: 0, // W
|
||||||
68: 1, // D
|
68: 1, // D
|
||||||
83: 2, // S
|
83: 2, // S
|
||||||
65: 3 // A
|
65: 3 // A
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Respond to direction keys
|
||||||
document.addEventListener("keydown", function (event) {
|
document.addEventListener("keydown", function (event) {
|
||||||
var modifiers = event.altKey || event.ctrlKey || event.metaKey ||
|
var modifiers = event.altKey || event.ctrlKey || event.metaKey ||
|
||||||
event.shiftKey;
|
event.shiftKey;
|
||||||
@@ -59,32 +60,35 @@ KeyboardInputManager.prototype.listen = function () {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
self.emit("move", mapped);
|
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");
|
// Respond to button presses
|
||||||
retry.addEventListener("click", this.restart.bind(this));
|
this.bindButtonPress(".retry-button", this.restart);
|
||||||
retry.addEventListener(this.eventTouchend, this.restart.bind(this));
|
this.bindButtonPress(".restart-button", this.restart);
|
||||||
|
this.bindButtonPress(".keep-playing-button", this.keepPlaying);
|
||||||
|
|
||||||
var keepPlaying = document.querySelector(".keep-playing-button");
|
// Respond to swipe events
|
||||||
keepPlaying.addEventListener("click", this.keepPlaying.bind(this));
|
|
||||||
keepPlaying.addEventListener("touchend", this.keepPlaying.bind(this));
|
|
||||||
|
|
||||||
// Listen to swipe events
|
|
||||||
var touchStartClientX, touchStartClientY;
|
var touchStartClientX, touchStartClientY;
|
||||||
var gameContainer = document.getElementsByClassName("game-container")[0];
|
var gameContainer = document.getElementsByClassName("game-container")[0];
|
||||||
|
|
||||||
gameContainer.addEventListener(this.eventTouchstart, function (event) {
|
gameContainer.addEventListener(this.eventTouchstart, function (event) {
|
||||||
if (( !window.navigator.msPointerEnabled && event.touches.length > 1) || event.targetTouches > 1) return;
|
if ((!window.navigator.msPointerEnabled && event.touches.length > 1) ||
|
||||||
|
event.targetTouches > 1) {
|
||||||
|
return; // Ignore if touching with more than 1 finger
|
||||||
|
}
|
||||||
|
|
||||||
if(window.navigator.msPointerEnabled){
|
if (window.navigator.msPointerEnabled) {
|
||||||
touchStartClientX = event.pageX;
|
touchStartClientX = event.pageX;
|
||||||
touchStartClientY = event.pageY;
|
touchStartClientY = event.pageY;
|
||||||
} else {
|
} else {
|
||||||
touchStartClientX = event.touches[0].clientX;
|
touchStartClientX = event.touches[0].clientX;
|
||||||
touchStartClientY = event.touches[0].clientY;
|
touchStartClientY = event.touches[0].clientY;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@@ -95,15 +99,19 @@ KeyboardInputManager.prototype.listen = function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gameContainer.addEventListener(this.eventTouchend, function (event) {
|
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;
|
var touchEndClientX, touchEndClientY;
|
||||||
if(window.navigator.msPointerEnabled){
|
|
||||||
touchEndClientX = event.pageX;
|
if (window.navigator.msPointerEnabled) {
|
||||||
touchEndClientY = event.pageY;
|
touchEndClientX = event.pageX;
|
||||||
|
touchEndClientY = event.pageY;
|
||||||
} else {
|
} else {
|
||||||
touchEndClientX = event.changedTouches[0].clientX;
|
touchEndClientX = event.changedTouches[0].clientX;
|
||||||
touchEndClientY = event.changedTouches[0].clientY;
|
touchEndClientY = event.changedTouches[0].clientY;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dx = touchEndClientX - touchStartClientX;
|
var dx = touchEndClientX - touchStartClientX;
|
||||||
@@ -128,3 +136,9 @@ KeyboardInputManager.prototype.keepPlaying = function (event) {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.emit("keepPlaying");
|
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));
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
window.fakeStorage = {
|
|
||||||
_data: {},
|
|
||||||
|
|
||||||
setItem: function (id, val) {
|
|
||||||
return this._data[id] = String(val);
|
|
||||||
},
|
|
||||||
|
|
||||||
getItem: function (id) {
|
|
||||||
return this._data.hasOwnProperty(id) ? this._data[id] : undefined;
|
|
||||||
},
|
|
||||||
|
|
||||||
removeItem: function (id) {
|
|
||||||
return delete this._data[id];
|
|
||||||
},
|
|
||||||
|
|
||||||
clear: function () {
|
|
||||||
return this._data = {};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function LocalScoreManager() {
|
|
||||||
this.key = "bestScore";
|
|
||||||
|
|
||||||
var supported = this.localStorageSupported();
|
|
||||||
this.storage = supported ? window.localStorage : window.fakeStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalScoreManager.prototype.localStorageSupported = function () {
|
|
||||||
var testKey = "test";
|
|
||||||
var storage = window.localStorage;
|
|
||||||
|
|
||||||
try {
|
|
||||||
storage.setItem(testKey, "1");
|
|
||||||
storage.removeItem(testKey);
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
LocalScoreManager.prototype.get = function () {
|
|
||||||
return this.storage.getItem(this.key) || 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
LocalScoreManager.prototype.set = function (score) {
|
|
||||||
this.storage.setItem(this.key, score);
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
window.fakeStorage = {
|
||||||
|
_data: {},
|
||||||
|
|
||||||
|
setItem: function (id, val) {
|
||||||
|
return this._data[id] = String(val);
|
||||||
|
},
|
||||||
|
|
||||||
|
getItem: function (id) {
|
||||||
|
return this._data.hasOwnProperty(id) ? this._data[id] : undefined;
|
||||||
|
},
|
||||||
|
|
||||||
|
removeItem: function (id) {
|
||||||
|
return delete this._data[id];
|
||||||
|
},
|
||||||
|
|
||||||
|
clear: function () {
|
||||||
|
return this._data = {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function LocalStorageManager() {
|
||||||
|
this.bestScoreKey = "bestScore";
|
||||||
|
this.gameStateKey = "gameState";
|
||||||
|
|
||||||
|
var supported = this.localStorageSupported();
|
||||||
|
this.storage = supported ? window.localStorage : window.fakeStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalStorageManager.prototype.localStorageSupported = function () {
|
||||||
|
var testKey = "test";
|
||||||
|
var storage = window.localStorage;
|
||||||
|
|
||||||
|
try {
|
||||||
|
storage.setItem(testKey, "1");
|
||||||
|
storage.removeItem(testKey);
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Best score getters/setters
|
||||||
|
LocalStorageManager.prototype.getBestScore = function () {
|
||||||
|
return this.storage.getItem(this.bestScoreKey) || 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
LocalStorageManager.prototype.setBestScore = function (score) {
|
||||||
|
this.storage.setItem(this.bestScoreKey, score);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Game state getters/setters and clearing
|
||||||
|
LocalStorageManager.prototype.getGameState = function () {
|
||||||
|
var stateJSON = this.storage.getItem(this.gameStateKey);
|
||||||
|
return stateJSON ? JSON.parse(stateJSON) : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
LocalStorageManager.prototype.setGameState = function (gameState) {
|
||||||
|
this.storage.setItem(this.gameStateKey, JSON.stringify(gameState));
|
||||||
|
};
|
||||||
|
|
||||||
|
LocalStorageManager.prototype.clearGameState = function () {
|
||||||
|
this.storage.removeItem(this.gameStateKey);
|
||||||
|
};
|
||||||
+10
@@ -15,3 +15,13 @@ Tile.prototype.updatePosition = function (position) {
|
|||||||
this.x = position.x;
|
this.x = position.x;
|
||||||
this.y = position.y;
|
this.y = position.y;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Tile.prototype.serialize = function () {
|
||||||
|
return {
|
||||||
|
position: {
|
||||||
|
x: this.x,
|
||||||
|
y: this.y
|
||||||
|
},
|
||||||
|
value: this.value
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
@@ -77,3 +77,12 @@
|
|||||||
-moz-appearance: $args;
|
-moz-appearance: $args;
|
||||||
appearance: $args;
|
appearance: $args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clearfix
|
||||||
|
@mixin clearfix {
|
||||||
|
&:after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+33
-13
@@ -30,7 +30,6 @@ h1.title {
|
|||||||
100% {
|
100% {
|
||||||
top: -50px;
|
top: -50px;
|
||||||
opacity: 0; } }
|
opacity: 0; } }
|
||||||
|
|
||||||
@-moz-keyframes move-up {
|
@-moz-keyframes move-up {
|
||||||
0% {
|
0% {
|
||||||
top: 25px;
|
top: 25px;
|
||||||
@@ -39,7 +38,6 @@ h1.title {
|
|||||||
100% {
|
100% {
|
||||||
top: -50px;
|
top: -50px;
|
||||||
opacity: 0; } }
|
opacity: 0; } }
|
||||||
|
|
||||||
@keyframes move-up {
|
@keyframes move-up {
|
||||||
0% {
|
0% {
|
||||||
top: 25px;
|
top: 25px;
|
||||||
@@ -48,7 +46,6 @@ h1.title {
|
|||||||
100% {
|
100% {
|
||||||
top: -50px;
|
top: -50px;
|
||||||
opacity: 0; } }
|
opacity: 0; } }
|
||||||
|
|
||||||
.scores-container {
|
.scores-container {
|
||||||
float: right;
|
float: right;
|
||||||
text-align: right; }
|
text-align: right; }
|
||||||
@@ -128,21 +125,18 @@ hr {
|
|||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 1; } }
|
opacity: 1; } }
|
||||||
|
|
||||||
@-moz-keyframes fade-in {
|
@-moz-keyframes fade-in {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0; }
|
opacity: 0; }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 1; } }
|
opacity: 1; } }
|
||||||
|
|
||||||
@keyframes fade-in {
|
@keyframes fade-in {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0; }
|
opacity: 0; }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 1; } }
|
opacity: 1; } }
|
||||||
|
|
||||||
.game-container {
|
.game-container {
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -397,7 +391,6 @@ hr {
|
|||||||
-webkit-transform: scale(1);
|
-webkit-transform: scale(1);
|
||||||
-moz-transform: scale(1);
|
-moz-transform: scale(1);
|
||||||
transform: scale(1); } }
|
transform: scale(1); } }
|
||||||
|
|
||||||
@-moz-keyframes appear {
|
@-moz-keyframes appear {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@@ -410,7 +403,6 @@ hr {
|
|||||||
-webkit-transform: scale(1);
|
-webkit-transform: scale(1);
|
||||||
-moz-transform: scale(1);
|
-moz-transform: scale(1);
|
||||||
transform: scale(1); } }
|
transform: scale(1); } }
|
||||||
|
|
||||||
@keyframes appear {
|
@keyframes appear {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@@ -423,7 +415,6 @@ hr {
|
|||||||
-webkit-transform: scale(1);
|
-webkit-transform: scale(1);
|
||||||
-moz-transform: scale(1);
|
-moz-transform: scale(1);
|
||||||
transform: scale(1); } }
|
transform: scale(1); } }
|
||||||
|
|
||||||
.tile-new .tile-inner {
|
.tile-new .tile-inner {
|
||||||
-webkit-animation: appear 200ms ease 100ms;
|
-webkit-animation: appear 200ms ease 100ms;
|
||||||
-moz-animation: appear 200ms ease 100ms;
|
-moz-animation: appear 200ms ease 100ms;
|
||||||
@@ -447,7 +438,6 @@ hr {
|
|||||||
-webkit-transform: scale(1);
|
-webkit-transform: scale(1);
|
||||||
-moz-transform: scale(1);
|
-moz-transform: scale(1);
|
||||||
transform: scale(1); } }
|
transform: scale(1); } }
|
||||||
|
|
||||||
@-moz-keyframes pop {
|
@-moz-keyframes pop {
|
||||||
0% {
|
0% {
|
||||||
-webkit-transform: scale(0);
|
-webkit-transform: scale(0);
|
||||||
@@ -463,7 +453,6 @@ hr {
|
|||||||
-webkit-transform: scale(1);
|
-webkit-transform: scale(1);
|
||||||
-moz-transform: scale(1);
|
-moz-transform: scale(1);
|
||||||
transform: scale(1); } }
|
transform: scale(1); } }
|
||||||
|
|
||||||
@keyframes pop {
|
@keyframes pop {
|
||||||
0% {
|
0% {
|
||||||
-webkit-transform: scale(0);
|
-webkit-transform: scale(0);
|
||||||
@@ -479,7 +468,6 @@ hr {
|
|||||||
-webkit-transform: scale(1);
|
-webkit-transform: scale(1);
|
||||||
-moz-transform: scale(1);
|
-moz-transform: scale(1);
|
||||||
transform: scale(1); } }
|
transform: scale(1); } }
|
||||||
|
|
||||||
.tile-merged .tile-inner {
|
.tile-merged .tile-inner {
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
-webkit-animation: pop 200ms ease 100ms;
|
-webkit-animation: pop 200ms ease 100ms;
|
||||||
@@ -489,8 +477,27 @@ hr {
|
|||||||
-moz-animation-fill-mode: backwards;
|
-moz-animation-fill-mode: backwards;
|
||||||
animation-fill-mode: backwards; }
|
animation-fill-mode: backwards; }
|
||||||
|
|
||||||
|
.above-game:after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
clear: both; }
|
||||||
|
|
||||||
.game-intro {
|
.game-intro {
|
||||||
margin-bottom: 0; }
|
float: left;
|
||||||
|
line-height: 42px; }
|
||||||
|
|
||||||
|
.restart-button {
|
||||||
|
display: inline-block;
|
||||||
|
background: #8f7a66;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 0 20px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #f9f6f2;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 42px;
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
float: right; }
|
||||||
|
|
||||||
.game-explanation {
|
.game-explanation {
|
||||||
margin-top: 50px; }
|
margin-top: 50px; }
|
||||||
@@ -526,6 +533,19 @@ hr {
|
|||||||
.heading {
|
.heading {
|
||||||
margin-bottom: 10px; }
|
margin-bottom: 10px; }
|
||||||
|
|
||||||
|
.game-intro {
|
||||||
|
width: 55%;
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
line-height: 1.65; }
|
||||||
|
|
||||||
|
.restart-button {
|
||||||
|
width: 42%;
|
||||||
|
padding: 0;
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-top: 2px; }
|
||||||
|
|
||||||
.game-container {
|
.game-container {
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
+35
-5
@@ -34,10 +34,8 @@ body {
|
|||||||
margin: 80px 0;
|
margin: 80px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heading:after {
|
.heading {
|
||||||
content: "";
|
@include clearfix;
|
||||||
display: block;
|
|
||||||
clear: both;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1.title {
|
h1.title {
|
||||||
@@ -453,8 +451,24 @@ hr {
|
|||||||
@include animation-fill-mode(backwards);
|
@include animation-fill-mode(backwards);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.above-game {
|
||||||
|
@include clearfix;
|
||||||
|
// margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.game-intro {
|
.game-intro {
|
||||||
margin-bottom: 0;
|
float: left;
|
||||||
|
line-height: 42px;
|
||||||
|
// margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.restart-button {
|
||||||
|
@include button;
|
||||||
|
display: block;
|
||||||
|
// width: 100px;
|
||||||
|
// margin: 10px auto 10px auto;
|
||||||
|
text-align: center;
|
||||||
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game-explanation {
|
.game-explanation {
|
||||||
@@ -508,6 +522,22 @@ hr {
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show intro and restart button side by side
|
||||||
|
.game-intro {
|
||||||
|
width: 55%;
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
line-height: 1.65;
|
||||||
|
}
|
||||||
|
|
||||||
|
.restart-button {
|
||||||
|
width: 42%;
|
||||||
|
padding: 0;
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
// Render the game field at the right width
|
// Render the game field at the right width
|
||||||
@include game-field;
|
@include game-field;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user