Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
黛琳ghz
2048
提交
53e08722
2048
项目概览
黛琳ghz
/
2048
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
2048
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
53e08722
编写于
3月 09, 2014
作者:
G
Gabriele Cirulli
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add tile merging
上级
efa2af59
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
157 addition
and
58 deletion
+157
-58
js/application.js
js/application.js
+5
-3
js/game_manager.js
js/game_manager.js
+34
-13
js/grid.js
js/grid.js
+14
-1
js/html_actuator.js
js/html_actuator.js
+5
-2
js/tile.js
js/tile.js
+6
-0
style/main.css
style/main.css
+70
-35
style/main.scss
style/main.scss
+23
-4
未找到文件。
js/application.js
浏览文件 @
53e08722
// Wait till the browser is ready to render the game (avoids glitches)
window
.
requestAnimationFrame
(
function
()
{
var
manager
=
new
GameManager
(
4
,
KeyboardInputManager
,
HTMLActuator
);
document
.
addEventListener
(
"
DOMContentLoaded
"
,
function
()
{
// Wait till the browser is ready to render the game (avoids glitches)
window
.
requestAnimationFrame
(
function
()
{
var
manager
=
new
GameManager
(
4
,
KeyboardInputManager
,
HTMLActuator
);
});
});
js/game_manager.js
浏览文件 @
53e08722
...
...
@@ -41,10 +41,11 @@ GameManager.prototype.actuate = function () {
this
.
actuator
.
actuate
(
this
.
grid
);
};
// Save
s all the current tile positions
GameManager
.
prototype
.
saveTilePosition
s
=
function
()
{
// Save
all tile positions and remove merger info
GameManager
.
prototype
.
prepareTile
s
=
function
()
{
this
.
grid
.
eachCell
(
function
(
x
,
y
,
tile
)
{
if
(
tile
)
{
tile
.
mergedFrom
=
null
;
tile
.
savePosition
();
}
});
...
...
@@ -54,8 +55,7 @@ GameManager.prototype.saveTilePositions = function () {
GameManager
.
prototype
.
moveTile
=
function
(
tile
,
cell
)
{
this
.
grid
.
cells
[
tile
.
x
][
tile
.
y
]
=
null
;
this
.
grid
.
cells
[
cell
.
x
][
cell
.
y
]
=
tile
;
tile
.
x
=
cell
.
x
;
tile
.
y
=
cell
.
y
;
tile
.
updatePosition
(
cell
);
};
// Move tiles on the grid in the specified direction
...
...
@@ -67,9 +67,10 @@ GameManager.prototype.move = function (direction) {
var
vector
=
this
.
getVector
(
direction
);
var
traversals
=
this
.
buildTraversals
(
vector
);
var
moved
=
false
;
// Save the current tile positions
(for actuator awareness)
this
.
saveTilePosition
s
();
// Save the current tile positions
and remove merger information
this
.
prepareTile
s
();
// Traverse the grid in the right direction and move tiles
traversals
.
x
.
forEach
(
function
(
x
)
{
...
...
@@ -78,14 +79,32 @@ GameManager.prototype.move = function (direction) {
tile
=
self
.
grid
.
cellContent
(
cell
);
if
(
tile
)
{
var
pos
=
self
.
findFarthestPosition
(
cell
,
vector
);
self
.
moveTile
(
tile
,
pos
);
var
positions
=
self
.
findFarthestPosition
(
cell
,
vector
);
var
next
=
self
.
grid
.
cellContent
(
positions
.
next
);
// Only one merger per row traversal?
if
(
next
&&
next
.
value
===
tile
.
value
&&
!
next
.
mergedFrom
)
{
var
merged
=
new
Tile
(
positions
.
next
,
tile
.
value
*
2
);
merged
.
mergedFrom
=
[
tile
,
next
];
self
.
grid
.
insertTile
(
merged
);
self
.
grid
.
removeTile
(
tile
);
// Converge the two tiles' positions
tile
.
updatePosition
(
positions
.
next
);
}
else
{
self
.
moveTile
(
tile
,
positions
.
farthest
);
}
moved
=
true
;
}
});
});
this
.
addRandomTile
();
this
.
actuate
();
if
(
moved
)
{
this
.
addRandomTile
();
this
.
actuate
();
}
};
// Get the vector representing the chosen direction
...
...
@@ -124,9 +143,11 @@ GameManager.prototype.findFarthestPosition = function (cell, vector) {
do
{
previous
=
cell
;
cell
=
{
x
:
previous
.
x
+
vector
.
x
,
y
:
previous
.
y
+
vector
.
y
};
}
while
(
cell
.
x
>=
0
&&
cell
.
x
<
this
.
size
&&
cell
.
y
>=
0
&&
cell
.
y
<
this
.
size
&&
}
while
(
this
.
grid
.
withinBounds
(
cell
)
&&
this
.
grid
.
cellAvailable
(
cell
));
return
previous
;
return
{
farthest
:
previous
,
next
:
cell
// Used to check if a merge is required
};
};
js/grid.js
浏览文件 @
53e08722
...
...
@@ -62,10 +62,23 @@ Grid.prototype.cellOccupied = function (cell) {
};
Grid
.
prototype
.
cellContent
=
function
(
cell
)
{
return
this
.
cells
[
cell
.
x
][
cell
.
y
];
if
(
this
.
withinBounds
(
cell
))
{
return
this
.
cells
[
cell
.
x
][
cell
.
y
];
}
else
{
return
null
;
}
};
// Inserts a tile at its position
Grid
.
prototype
.
insertTile
=
function
(
tile
)
{
this
.
cells
[
tile
.
x
][
tile
.
y
]
=
tile
;
};
Grid
.
prototype
.
removeTile
=
function
(
tile
)
{
this
.
cells
[
tile
.
x
][
tile
.
y
]
=
null
;
};
Grid
.
prototype
.
withinBounds
=
function
(
position
)
{
return
position
.
x
>=
0
&&
position
.
x
<
this
.
size
&&
position
.
y
>=
0
&&
position
.
y
<
this
.
size
;
};
js/html_actuator.js
浏览文件 @
53e08722
...
...
@@ -36,16 +36,19 @@ HTMLActuator.prototype.addTile = function (tile) {
this
.
tileContainer
.
appendChild
(
element
);
if
(
tile
.
previousPosition
)
{
window
.
requestAnimationFrame
(
function
()
{
element
.
classList
.
remove
(
element
.
classList
[
2
]);
element
.
classList
.
add
(
self
.
positionClass
({
x
:
tile
.
x
,
y
:
tile
.
y
}));
});
}
else
if
(
tile
.
mergedFrom
)
{
element
.
classList
.
add
(
"
tile-merged
"
);
tile
.
mergedFrom
.
forEach
(
function
(
merged
)
{
self
.
addTile
(
merged
);
});
}
else
{
element
.
classList
.
add
(
"
tile-new
"
);
}
};
HTMLActuator
.
prototype
.
normalizePosition
=
function
(
position
)
{
...
...
js/tile.js
浏览文件 @
53e08722
...
...
@@ -4,8 +4,14 @@ function Tile(position, value) {
this
.
value
=
value
||
2
;
this
.
previousPosition
=
null
;
this
.
mergedFrom
=
null
;
// Tracks tiles that merged together
}
Tile
.
prototype
.
savePosition
=
function
()
{
this
.
previousPosition
=
{
x
:
this
.
x
,
y
:
this
.
y
};
};
Tile
.
prototype
.
updatePosition
=
function
(
position
)
{
this
.
x
=
position
.
x
;
this
.
y
=
position
.
y
;
};
style/main.css
浏览文件 @
53e08722
...
...
@@ -89,6 +89,7 @@ hr {
line-height
:
116.25px
;
font-size
:
55px
;
font-weight
:
bold
;
z-index
:
10
;
-webkit-transition
:
100ms
ease-in-out
;
-moz-transition
:
100ms
ease-in-out
;
-webkit-transition-property
:
top
,
left
;
...
...
@@ -100,109 +101,109 @@ hr {
.tile.tile-position-1-2
{
position
:
absolute
;
left
:
0px
;
top
:
121
.25
px
;
}
top
:
121px
;
}
.tile.tile-position-1-3
{
position
:
absolute
;
left
:
0px
;
top
:
24
2.5
px
;
}
top
:
24
3
px
;
}
.tile.tile-position-1-4
{
position
:
absolute
;
left
:
0px
;
top
:
36
3.75
px
;
}
top
:
36
4
px
;
}
.tile.tile-position-2-1
{
position
:
absolute
;
left
:
121
.25
px
;
left
:
121px
;
top
:
0px
;
}
.tile.tile-position-2-2
{
position
:
absolute
;
left
:
121
.25
px
;
top
:
121
.25
px
;
}
left
:
121px
;
top
:
121px
;
}
.tile.tile-position-2-3
{
position
:
absolute
;
left
:
121
.25
px
;
top
:
24
2.5
px
;
}
left
:
121px
;
top
:
24
3
px
;
}
.tile.tile-position-2-4
{
position
:
absolute
;
left
:
121
.25
px
;
top
:
36
3.75
px
;
}
left
:
121px
;
top
:
36
4
px
;
}
.tile.tile-position-3-1
{
position
:
absolute
;
left
:
24
2.5
px
;
left
:
24
3
px
;
top
:
0px
;
}
.tile.tile-position-3-2
{
position
:
absolute
;
left
:
24
2.5
px
;
top
:
121
.25
px
;
}
left
:
24
3
px
;
top
:
121px
;
}
.tile.tile-position-3-3
{
position
:
absolute
;
left
:
24
2.5
px
;
top
:
24
2.5
px
;
}
left
:
24
3
px
;
top
:
24
3
px
;
}
.tile.tile-position-3-4
{
position
:
absolute
;
left
:
24
2.5
px
;
top
:
36
3.75
px
;
}
left
:
24
3
px
;
top
:
36
4
px
;
}
.tile.tile-position-4-1
{
position
:
absolute
;
left
:
36
3.75
px
;
left
:
36
4
px
;
top
:
0px
;
}
.tile.tile-position-4-2
{
position
:
absolute
;
left
:
36
3.75
px
;
top
:
121
.25
px
;
}
left
:
36
4
px
;
top
:
121px
;
}
.tile.tile-position-4-3
{
position
:
absolute
;
left
:
36
3.75
px
;
top
:
24
2.5
px
;
}
left
:
36
4
px
;
top
:
24
3
px
;
}
.tile.tile-position-4-4
{
position
:
absolute
;
left
:
36
3.75
px
;
top
:
36
3.75
px
;
}
left
:
36
4
px
;
top
:
36
4
px
;
}
.tile.tile-2
{
background
:
#eee4da
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0
)
,
inset
0
0
0
1px
rgba
(
255
,
255
,
255
,
0
)
;
}
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0
);
}
.tile.tile-4
{
background
:
#ede0c8
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0
)
,
inset
0
0
0
1px
rgba
(
255
,
255
,
255
,
0
)
;
}
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0
);
}
.tile.tile-8
{
color
:
#f9f6f2
;
background
:
#f2b179
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0
)
,
inset
0
0
0
1px
rgba
(
255
,
255
,
255
,
0
)
;
}
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0
);
}
.tile.tile-16
{
color
:
#f9f6f2
;
background
:
#f59563
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0
)
,
inset
0
0
0
1px
rgba
(
255
,
255
,
255
,
0
)
;
}
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0
);
}
.tile.tile-32
{
color
:
#f9f6f2
;
background
:
#f67c5f
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.07937
)
,
inset
0
0
0
1px
rgba
(
255
,
255
,
255
,
0.04762
)
;
}
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.07937
);
}
.tile.tile-64
{
color
:
#f9f6f2
;
background
:
#f65e3b
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.15873
)
,
inset
0
0
0
1px
rgba
(
255
,
255
,
255
,
0.09524
)
;
}
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.15873
);
}
.tile.tile-128
{
color
:
#f9f6f2
;
background
:
#edcf72
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.2381
)
,
inset
0
0
0
1px
rgba
(
255
,
255
,
255
,
0.14286
)
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.2381
);
font-size
:
45px
;
}
.tile.tile-256
{
color
:
#f9f6f2
;
background
:
#edcc61
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.31746
)
,
inset
0
0
0
1px
rgba
(
255
,
255
,
255
,
0.19048
)
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.31746
);
font-size
:
45px
;
}
.tile.tile-512
{
color
:
#f9f6f2
;
background
:
#edc850
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.39683
)
,
inset
0
0
0
1px
rgba
(
255
,
255
,
255
,
0.2381
)
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.39683
);
font-size
:
45px
;
}
.tile.tile-1024
{
color
:
#f9f6f2
;
background
:
#edc53f
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.47619
)
,
inset
0
0
0
1px
rgba
(
255
,
255
,
255
,
0.28571
)
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.47619
);
font-size
:
35px
;
}
.tile.tile-2048
{
color
:
#f9f6f2
;
background
:
#edc22e
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.55556
)
,
inset
0
0
0
1px
rgba
(
255
,
255
,
255
,
0.33333
)
;
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.55556
);
font-size
:
35px
;
}
@-webkit-keyframes
appear
{
...
...
@@ -238,6 +239,40 @@ hr {
-webkit-animation-fill-mode
:
both
;
-moz-animation-fill-mode
:
both
;
}
@-webkit-keyframes
pop
{
0
%
{
-webkit-transform
:
scale
(
0.5
);
opacity
:
0
;
}
100
%
{
-webkit-transform
:
scale
(
1
);
opacity
:
1
;
}
}
@-moz-keyframes
pop
{
0
%
{
-webkit-transform
:
scale
(
0.5
);
opacity
:
0
;
}
100
%
{
-webkit-transform
:
scale
(
1
);
opacity
:
1
;
}
}
@keyframes
pop
{
0
%
{
-webkit-transform
:
scale
(
0.5
);
opacity
:
0
;
}
100
%
{
-webkit-transform
:
scale
(
1
);
opacity
:
1
;
}
}
.tile-merged
{
z-index
:
20
;
-webkit-animation
:
pop
200ms
ease
100ms
;
-moz-animation
:
pop
200ms
ease
100ms
;
-webkit-animation-fill-mode
:
both
;
-moz-animation-fill-mode
:
both
;
}
.game-intro
{
margin-bottom
:
0
;
}
...
...
style/main.scss
浏览文件 @
53e08722
...
...
@@ -133,6 +133,7 @@ hr {
line-height
:
$tile-size
+
10px
;
font-size
:
55px
;
font-weight
:
bold
;
z-index
:
10
;
@include
transition
(
$transition-speed
ease-in-out
);
@include
transition-property
(
top
,
left
);
...
...
@@ -142,8 +143,8 @@ hr {
@for
$y
from
1
through
$grid-row-cells
{
&
.tile-position-
#{
$x
}
-
#{
$y
}
{
position
:
absolute
;
left
:
(
$tile-size
+
$grid-spacing
)
*
(
$x
-
1
);
top
:
(
$tile-size
+
$grid-spacing
)
*
(
$y
-
1
);
left
:
round
((
$tile-size
+
$grid-spacing
)
*
(
$x
-
1
)
);
top
:
round
((
$tile-size
+
$grid-spacing
)
*
(
$y
-
1
)
);
}
}
}
...
...
@@ -192,8 +193,8 @@ hr {
// Add glow
$glow-opacity
:
max
(
$exponent
-
4
,
0
)
/
(
$limit
-
4
);
box-shadow
:
0
0
30px
10px
rgba
(
$tile-gold-glow-color
,
$glow-opacity
/
1
.8
)
,
inset
0
0
0
1px
rgba
(
white
,
$glow-opacity
/
3
);
box-shadow
:
0
0
30px
10px
rgba
(
$tile-gold-glow-color
,
$glow-opacity
/
1
.8
)
;
//
,
//
inset 0 0 0 1px rgba(white, $glow-opacity / 3);
// Adjust font size for bigger numbers
@if
$power
>=
100
and
$power
<
1000
{
...
...
@@ -224,6 +225,24 @@ hr {
@include
animation-fill-mode
(
both
);
}
@include
keyframes
(
pop
)
{
0
%
{
-webkit-transform
:
scale
(
.5
);
opacity
:
0
;
}
100
%
{
-webkit-transform
:
scale
(
1
);
opacity
:
1
;
}
}
.tile-merged
{
z-index
:
20
;
@include
animation
(
pop
200ms
ease
$transition-speed
);
@include
animation-fill-mode
(
both
);
}
.game-intro
{
margin-bottom
:
0
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录