Skip to content

Commit 9687286

Browse files
committed
full edition = =
1 parent d7c9d6c commit 9687286

14 files changed

+1640
-0
lines changed

2048/full/favicon.ico

4.19 KB
Binary file not shown.

2048/full/index.html

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+

2+
<!DOCTYPE html>
3+
<html>
4+
<head>
5+
<meta charset="utf-8">
6+
<title>2048</title>
7+
8+
<link href="style/main.css" rel="stylesheet" type="text/css">
9+
<link rel="shortcut icon" href="favicon.ico">
10+
<link rel="apple-touch-icon" href="meta/apple-touch-icon.png">
11+
<meta name="apple-mobile-web-app-capable" content="yes">
12+
13+
<meta name="HandheldFriendly" content="True">
14+
<meta name="MobileOptimized" content="320">
15+
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0, maximum-scale=1, user-scalable=no, minimal-ui">
16+
17+
<meta property="og:title" content="2048 game"/>
18+
<meta property="og:site_name" content="2048 game"/>
19+
</head>
20+
<body>
21+
<div class="container">
22+
<div class="heading">
23+
<h1 class="title">PRC</h1>
24+
<div class="scores-container">
25+
<div class="score-container">0</div>
26+
<div class="best-container">0</div>
27+
</div>
28+
</div>
29+
<p class="game-intro">Join the characters and get to the <strong>PRC epoch!</strong></p>
30+
31+
<div class="game-container">
32+
<div class="game-message">
33+
<p></p>
34+
<div class="lower">
35+
<a class="retry-button">Try again</a>
36+
<div class="score-sharing"></div>
37+
</div>
38+
</div>
39+
40+
<div class="grid-container">
41+
<div class="grid-row">
42+
<div class="grid-cell"></div>
43+
<div class="grid-cell"></div>
44+
<div class="grid-cell"></div>
45+
<div class="grid-cell"></div>
46+
</div>
47+
<div class="grid-row">
48+
<div class="grid-cell"></div>
49+
<div class="grid-cell"></div>
50+
<div class="grid-cell"></div>
51+
<div class="grid-cell"></div>
52+
</div>
53+
<div class="grid-row">
54+
<div class="grid-cell"></div>
55+
<div class="grid-cell"></div>
56+
<div class="grid-cell"></div>
57+
<div class="grid-cell"></div>
58+
</div>
59+
<div class="grid-row">
60+
<div class="grid-cell"></div>
61+
<div class="grid-cell"></div>
62+
<div class="grid-cell"></div>
63+
<div class="grid-cell"></div>
64+
</div>
65+
</div>
66+
67+
<div class="tile-container">
68+
69+
</div>
70+
</div>
71+
<p>
72+
<strong class="important">How to play:</strong> Use your <strong>arrow keys</strong> to move the tiles. When two tiles with the same character touch, they <strong>merge into a latter one!</strong>
73+
</p>
74+
<hr>
75+
<p>
76+
<strong class="important">Note:</strong> This is a fork from <a href="http://gabrielecirulli.github.io/2048">http://gabrielecirulli.github.io/2048</a>, which created by <a href="http://gabrielecirulli.com" target="_blank">Gabriele Cirulli.</a> </p>
77+
<hr>
78+
<p>
79+
<strong>呵呵</strong></p>
80+
<hr>
81+
<p>
82+
不知道后面的样式会不会特别丑,反正我没试着玩下去..以及这个也不全哦十六国啥的还没加上呢</p>
83+
</div>
84+
85+
<script src="js/animframe_polyfill.js"></script>
86+
<script src="js/keyboard_input_manager.js"></script>
87+
<script src="js/html_actuator.js"></script>
88+
<script src="js/grid.js"></script>
89+
<script src="js/tile.js"></script>
90+
<script src="js/local_score_manager.js"></script>
91+
<script src="js/game_manager.js"></script>
92+
<script src="js/application.js"></script>
93+
94+
<script type="text/javascript">
95+
var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
96+
document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3Fe23aadd301a50ea32e3a17b096eaa594' type='text/javascript'%3E%3C/script%3E"));
97+
</script>
98+
<img border="0" src="style/65536.jpg" width="0" height="0"><img border="0" src="style/131072.jpg" width="0" height="0">
99+
</body>
100+
</html>

2048/full/js/animframe_polyfill.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
(function() {
2+
var lastTime = 0;
3+
var vendors = ['webkit', 'moz'];
4+
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
5+
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
6+
window.cancelAnimationFrame =
7+
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
8+
}
9+
10+
if (!window.requestAnimationFrame) {
11+
window.requestAnimationFrame = function(callback, element) {
12+
var currTime = new Date().getTime();
13+
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
14+
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
15+
timeToCall);
16+
lastTime = currTime + timeToCall;
17+
return id;
18+
};
19+
}
20+
21+
if (!window.cancelAnimationFrame) {
22+
window.cancelAnimationFrame = function(id) {
23+
clearTimeout(id);
24+
};
25+
}
26+
}());

2048/full/js/application.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Wait till the browser is ready to render the game (avoids glitches)
2+
window.requestAnimationFrame(function () {
3+
new GameManager(4, KeyboardInputManager, HTMLActuator, LocalScoreManager);
4+
});

2048/full/js/game_manager.js

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
var maxscore = 2;
2+
3+
function GameManager(size, InputManager, Actuator, ScoreManager) {
4+
this.size = size; // Size of the grid
5+
this.inputManager = new InputManager;
6+
this.scoreManager = new ScoreManager;
7+
this.actuator = new Actuator;
8+
9+
this.startTiles = 2;
10+
11+
this.inputManager.on("move", this.move.bind(this));
12+
this.inputManager.on("restart", this.restart.bind(this));
13+
this.inputManager.on("keepPlaying", this.keepPlaying.bind(this));
14+
15+
this.setup();
16+
}
17+
18+
// Restart the game
19+
GameManager.prototype.restart = function () {
20+
maxscore = 2;
21+
this.actuator.continue();
22+
this.setup();
23+
};
24+
25+
// Keep playing after winning
26+
GameManager.prototype.keepPlaying = function () {
27+
this.keepPlaying = true;
28+
this.actuator.continue();
29+
};
30+
31+
GameManager.prototype.isGameTerminated = function () {
32+
if (this.over || (this.won && !this.keepPlaying)) {
33+
return true;
34+
} else {
35+
return false;
36+
}
37+
};
38+
39+
// Set up the game
40+
GameManager.prototype.setup = function () {
41+
this.grid = new Grid(this.size);
42+
43+
this.score = 0;
44+
this.over = false;
45+
this.won = false;
46+
this.keepPlaying = false;
47+
48+
// Add the initial tiles
49+
this.addStartTiles();
50+
51+
// Update the actuator
52+
this.actuate();
53+
};
54+
55+
// Set up the initial tiles to start the game with
56+
GameManager.prototype.addStartTiles = function () {
57+
for (var i = 0; i < this.startTiles; i++) {
58+
this.addRandomTile();
59+
}
60+
};
61+
62+
// Adds a tile in a random position
63+
GameManager.prototype.addRandomTile = function () {
64+
if (this.grid.cellsAvailable()) {
65+
var value = Math.random() < 0.9 ? 2 : 4;
66+
var tile = new Tile(this.grid.randomAvailableCell(), value);
67+
68+
this.grid.insertTile(tile);
69+
}
70+
};
71+
72+
// Sends the updated grid to the actuator
73+
GameManager.prototype.actuate = function () {
74+
if (this.scoreManager.get() < this.score) {
75+
this.scoreManager.set(this.score);
76+
}
77+
78+
this.actuator.actuate(this.grid, {
79+
score: this.score,
80+
over: this.over,
81+
won: this.won,
82+
bestScore: this.scoreManager.get(),
83+
terminated: this.isGameTerminated()
84+
});
85+
86+
};
87+
88+
// Save all tile positions and remove merger info
89+
GameManager.prototype.prepareTiles = function () {
90+
this.grid.eachCell(function (x, y, tile) {
91+
if (tile) {
92+
tile.mergedFrom = null;
93+
tile.savePosition();
94+
}
95+
});
96+
};
97+
98+
// Move a tile and its representation
99+
GameManager.prototype.moveTile = function (tile, cell) {
100+
this.grid.cells[tile.x][tile.y] = null;
101+
this.grid.cells[cell.x][cell.y] = tile;
102+
tile.updatePosition(cell);
103+
};
104+
105+
// Move tiles on the grid in the specified direction
106+
GameManager.prototype.move = function (direction) {
107+
// 0: up, 1: right, 2:down, 3: left
108+
var self = this;
109+
110+
if (this.isGameTerminated()) return; // Don't do anything if the game's over
111+
112+
var cell, tile;
113+
114+
var vector = this.getVector(direction);
115+
var traversals = this.buildTraversals(vector);
116+
var moved = false;
117+
118+
// Save the current tile positions and remove merger information
119+
this.prepareTiles();
120+
121+
// Traverse the grid in the right direction and move tiles
122+
traversals.x.forEach(function (x) {
123+
traversals.y.forEach(function (y) {
124+
cell = { x: x, y: y };
125+
tile = self.grid.cellContent(cell);
126+
127+
if (tile) {
128+
var positions = self.findFarthestPosition(cell, vector);
129+
var next = self.grid.cellContent(positions.next);
130+
131+
// Only one merger per row traversal?
132+
if (next && next.value === tile.value && !next.mergedFrom) {
133+
var merged = new Tile(positions.next, tile.value * 2);
134+
merged.mergedFrom = [tile, next];
135+
136+
self.grid.insertTile(merged);
137+
self.grid.removeTile(tile);
138+
139+
// Converge the two tiles' positions
140+
tile.updatePosition(positions.next);
141+
142+
// Update the score
143+
self.score += merged.value;
144+
145+
if (merged.value > maxscore)
146+
maxscore = merged.value;
147+
148+
// The mighty 2048 tile
149+
if (merged.value === 2048) self.won = true;
150+
} else {
151+
self.moveTile(tile, positions.farthest);
152+
}
153+
154+
if (!self.positionsEqual(cell, tile)) {
155+
moved = true; // The tile moved from its original cell!
156+
}
157+
}
158+
});
159+
});
160+
161+
if (moved) {
162+
this.addRandomTile();
163+
164+
if (!this.movesAvailable()) {
165+
this.over = true; // Game over!
166+
}
167+
168+
this.actuate();
169+
}
170+
};
171+
172+
// Get the vector representing the chosen direction
173+
GameManager.prototype.getVector = function (direction) {
174+
// Vectors representing tile movement
175+
var map = {
176+
0: { x: 0, y: -1 }, // up
177+
1: { x: 1, y: 0 }, // right
178+
2: { x: 0, y: 1 }, // down
179+
3: { x: -1, y: 0 } // left
180+
};
181+
182+
return map[direction];
183+
};
184+
185+
// Build a list of positions to traverse in the right order
186+
GameManager.prototype.buildTraversals = function (vector) {
187+
var traversals = { x: [], y: [] };
188+
189+
for (var pos = 0; pos < this.size; pos++) {
190+
traversals.x.push(pos);
191+
traversals.y.push(pos);
192+
}
193+
194+
// Always traverse from the farthest cell in the chosen direction
195+
if (vector.x === 1) traversals.x = traversals.x.reverse();
196+
if (vector.y === 1) traversals.y = traversals.y.reverse();
197+
198+
return traversals;
199+
};
200+
201+
GameManager.prototype.findFarthestPosition = function (cell, vector) {
202+
var previous;
203+
204+
// Progress towards the vector direction until an obstacle is found
205+
do {
206+
previous = cell;
207+
cell = { x: previous.x + vector.x, y: previous.y + vector.y };
208+
} while (this.grid.withinBounds(cell) &&
209+
this.grid.cellAvailable(cell));
210+
211+
return {
212+
farthest: previous,
213+
next: cell // Used to check if a merge is required
214+
};
215+
};
216+
217+
GameManager.prototype.movesAvailable = function () {
218+
return this.grid.cellsAvailable() || this.tileMatchesAvailable();
219+
};
220+
221+
// Check for available matches between tiles (more expensive check)
222+
GameManager.prototype.tileMatchesAvailable = function () {
223+
var self = this;
224+
225+
var tile;
226+
227+
for (var x = 0; x < this.size; x++) {
228+
for (var y = 0; y < this.size; y++) {
229+
tile = this.grid.cellContent({ x: x, y: y });
230+
231+
if (tile) {
232+
for (var direction = 0; direction < 4; direction++) {
233+
var vector = self.getVector(direction);
234+
var cell = { x: x + vector.x, y: y + vector.y };
235+
236+
var other = self.grid.cellContent(cell);
237+
238+
if (other && other.value === tile.value) {
239+
return true; // These two tiles can be merged
240+
}
241+
}
242+
}
243+
}
244+
}
245+
246+
return false;
247+
};
248+
249+
GameManager.prototype.positionsEqual = function (first, second) {
250+
return first.x === second.x && first.y === second.y;
251+
};

0 commit comments

Comments
 (0)