Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
黛琳ghz
2048
提交
b20e26e3
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看板
提交
b20e26e3
编写于
3月 09, 2014
作者:
G
Gabriele Cirulli
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
implement tile movement
上级
b7476f1f
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
285 addition
and
35 deletion
+285
-35
index.html
index.html
+1
-0
js/application.js
js/application.js
+3
-3
js/game_manager.js
js/game_manager.js
+100
-10
js/grid.js
js/grid.js
+21
-7
js/html_actuator.js
js/html_actuator.js
+35
-12
js/keyboard_input_manager.js
js/keyboard_input_manager.js
+43
-0
js/tile.js
js/tile.js
+4
-0
style/helpers.scss
style/helpers.scss
+23
-0
style/main.css
style/main.css
+35
-2
style/main.scss
style/main.scss
+20
-1
未找到文件。
index.html
浏览文件 @
b20e26e3
...
...
@@ -6,6 +6,7 @@
<link
href=
"style/main.css"
rel=
"stylesheet"
type=
"text/css"
>
<script
src=
"js/keyboard_input_manager.js"
></script>
<script
src=
"js/html_actuator.js"
></script>
<script
src=
"js/grid.js"
></script>
<script
src=
"js/tile.js"
></script>
...
...
js/application.js
浏览文件 @
b20e26e3
document
.
addEventListener
(
"
DOMContentLoaded
"
,
function
()
{
var
actuator
=
new
HTMLActuator
;
var
manager
=
new
GameManager
(
4
,
a
ctuator
);
// Wait till the browser is ready to render the game (avoids glitches)
window
.
requestAnimationFrame
(
function
()
{
var
manager
=
new
GameManager
(
4
,
KeyboardInputManager
,
HTMLA
ctuator
);
});
js/game_manager.js
浏览文件 @
b20e26e3
function
GameManager
(
size
,
actuator
)
{
this
.
size
=
size
;
// Grid size
this
.
actuator
=
actuator
;
function
GameManager
(
size
,
InputManager
,
Actuator
)
{
this
.
size
=
size
;
// Size of the grid
this
.
inputManager
=
new
InputManager
;
this
.
actuator
=
new
Actuator
;
this
.
startTiles
=
2
;
this
.
grid
=
new
Grid
(
this
.
size
);
this
.
startTiles
=
2
;
this
.
grid
=
new
Grid
(
this
.
size
);
this
.
inputManager
.
on
(
"
move
"
,
this
.
move
.
bind
(
this
));
this
.
setup
();
}
...
...
@@ -25,10 +28,12 @@ GameManager.prototype.addStartTiles = function () {
// Adds a tile in a random position
GameManager
.
prototype
.
addRandomTile
=
function
()
{
var
value
=
Math
.
random
()
<
0.9
?
2
:
4
;
var
tile
=
new
Tile
(
this
.
grid
.
randomAvailableCell
(),
value
);
this
.
grid
.
insertTile
(
tile
);
if
(
this
.
grid
.
cellsAvailable
())
{
var
value
=
Math
.
random
()
<
0.9
?
2
:
4
;
var
tile
=
new
Tile
(
this
.
grid
.
randomAvailableCell
(),
value
);
this
.
grid
.
insertTile
(
tile
);
}
};
// Sends the updated grid to the actuator
...
...
@@ -36,9 +41,94 @@ GameManager.prototype.actuate = function () {
this
.
actuator
.
actuate
(
this
.
grid
);
};
// Move the grid in the specified direction
// Saves all the current tile positions
GameManager
.
prototype
.
saveTilePositions
=
function
()
{
this
.
grid
.
eachCell
(
function
(
x
,
y
,
tile
)
{
if
(
tile
)
{
tile
.
savePosition
();
}
});
};
// Move a tile and its representation
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
;
};
// Move tiles on the grid in the specified direction
GameManager
.
prototype
.
move
=
function
(
direction
)
{
// 0: up, 1: right, 2:down, 3: left
var
self
=
this
;
var
cell
,
tile
;
var
vector
=
this
.
getVector
(
direction
);
var
traversals
=
this
.
buildTraversals
(
vector
);
// Save the current tile positions (for actuator awareness)
this
.
saveTilePositions
();
// Traverse the grid in the right direction and move tiles
traversals
.
x
.
forEach
(
function
(
x
)
{
traversals
.
y
.
forEach
(
function
(
y
)
{
cell
=
{
x
:
x
,
y
:
y
};
tile
=
self
.
grid
.
cellContent
(
cell
);
if
(
tile
)
{
var
pos
=
self
.
findFarthestPosition
(
cell
,
vector
);
console
.
log
(
pos
);
self
.
moveTile
(
tile
,
pos
);
}
});
});
this
.
addRandomTile
();
console
.
log
(
16
-
this
.
grid
.
availableCells
().
length
);
this
.
actuate
();
};
// Get the vector representing the chosen direction
GameManager
.
prototype
.
getVector
=
function
(
direction
)
{
// Vectors representing tile movement
var
map
=
{
0
:
{
x
:
0
,
y
:
-
1
},
// up
1
:
{
x
:
1
,
y
:
0
},
// right
2
:
{
x
:
0
,
y
:
1
},
// down
3
:
{
x
:
-
1
,
y
:
0
}
// left
};
return
map
[
direction
];
};
// Build a list of positions to traverse in the right order
GameManager
.
prototype
.
buildTraversals
=
function
(
vector
)
{
var
traversals
=
{
x
:
[],
y
:
[]
};
for
(
var
pos
=
0
;
pos
<
this
.
size
;
pos
++
)
{
traversals
.
x
.
push
(
pos
);
traversals
.
y
.
push
(
pos
);
}
// Always traverse from the farthest cell in the chosen direction
if
(
vector
.
x
===
1
)
traversals
.
x
=
traversals
.
x
.
reverse
();
if
(
vector
.
y
===
1
)
traversals
.
y
=
traversals
.
y
.
reverse
();
return
traversals
;
};
GameManager
.
prototype
.
findFarthestPosition
=
function
(
cell
,
vector
)
{
var
previous
;
// Progress towards the vector direction until an obstacle is found
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
&&
this
.
grid
.
cellAvailable
(
cell
));
return
previous
;
};
js/grid.js
浏览文件 @
b20e26e3
...
...
@@ -29,17 +29,27 @@ Grid.prototype.randomAvailableCell = function () {
Grid
.
prototype
.
availableCells
=
function
()
{
var
cells
=
[];
this
.
eachCell
(
function
(
x
,
y
,
tile
)
{
if
(
!
tile
)
{
cells
.
push
({
x
:
x
,
y
:
y
});
}
});
return
cells
;
};
// Call callback for every cell
Grid
.
prototype
.
eachCell
=
function
(
callback
)
{
for
(
var
x
=
0
;
x
<
this
.
size
;
x
++
)
{
for
(
var
y
=
0
;
y
<
this
.
size
;
y
++
)
{
var
cell
=
{
x
:
x
,
y
:
y
};
if
(
this
.
cellAvailable
(
cell
))
{
cells
.
push
(
cell
);
}
callback
(
x
,
y
,
this
.
cells
[
x
][
y
]);
}
}
};
return
cells
;
// Check if there are any cells available
Grid
.
prototype
.
cellsAvailable
=
function
()
{
return
!!
this
.
availableCells
().
length
;
};
// Check if the specified cell is taken
...
...
@@ -48,7 +58,11 @@ Grid.prototype.cellAvailable = function (cell) {
};
Grid
.
prototype
.
cellOccupied
=
function
(
cell
)
{
return
!!
this
.
cells
[
cell
.
x
][
cell
.
y
];
return
!!
this
.
cellContent
(
cell
);
};
Grid
.
prototype
.
cellContent
=
function
(
cell
)
{
return
this
.
cells
[
cell
.
x
][
cell
.
y
];
};
// Inserts a tile at its position
...
...
js/html_actuator.js
浏览文件 @
b20e26e3
...
...
@@ -5,13 +5,15 @@ function HTMLActuator() {
HTMLActuator
.
prototype
.
actuate
=
function
(
grid
)
{
var
self
=
this
;
this
.
clearContainer
();
grid
.
cells
.
forEach
(
function
(
column
)
{
column
.
forEach
(
function
(
cell
)
{
if
(
cell
)
{
self
.
addTile
(
cell
);
}
window
.
requestAnimationFrame
(
function
()
{
self
.
clearContainer
();
grid
.
cells
.
forEach
(
function
(
column
)
{
column
.
forEach
(
function
(
cell
)
{
if
(
cell
)
{
self
.
addTile
(
cell
);
}
});
});
});
};
...
...
@@ -23,14 +25,35 @@ HTMLActuator.prototype.clearContainer = function () {
};
HTMLActuator
.
prototype
.
addTile
=
function
(
tile
)
{
var
element
=
document
.
createElement
(
"
div
"
)
;
var
self
=
this
;
var
x
=
tile
.
x
+
1
;
var
y
=
tile
.
y
+
1
;
var
position
=
"
tile-position-
"
+
x
+
"
-
"
+
y
;
var
element
=
document
.
createElement
(
"
div
"
)
;
var
position
=
tile
.
previousPosition
||
{
x
:
tile
.
x
,
y
:
tile
.
y
}
;
positionClass
=
this
.
positionClass
(
position
)
;
element
.
classList
.
add
(
"
tile
"
,
"
tile-
"
+
tile
.
value
,
position
);
element
.
classList
.
add
(
"
tile
"
,
"
tile-
"
+
tile
.
value
,
position
Class
);
element
.
textContent
=
tile
.
value
;
this
.
tileContainer
.
appendChild
(
element
);
if
(
tile
.
previousPosition
)
{
window
.
requestAnimationFrame
(
function
()
{
// console.log( + " === " + positionClass);
element
.
classList
.
remove
(
element
.
classList
[
2
]);
element
.
classList
.
add
(
self
.
positionClass
({
x
:
tile
.
x
,
y
:
tile
.
y
}));
});
}
else
{
element
.
classList
.
add
(
"
tile-new
"
);
}
};
HTMLActuator
.
prototype
.
normalizePosition
=
function
(
position
)
{
return
{
x
:
position
.
x
+
1
,
y
:
position
.
y
+
1
};
};
HTMLActuator
.
prototype
.
positionClass
=
function
(
position
)
{
position
=
this
.
normalizePosition
(
position
);
return
"
tile-position-
"
+
position
.
x
+
"
-
"
+
position
.
y
;
};
js/keyboard_input_manager.js
0 → 100644
浏览文件 @
b20e26e3
function
KeyboardInputManager
()
{
this
.
events
=
{};
this
.
listen
();
}
KeyboardInputManager
.
prototype
.
on
=
function
(
event
,
callback
)
{
if
(
!
this
.
events
[
event
])
{
this
.
events
[
event
]
=
[];
}
this
.
events
[
event
].
push
(
callback
);
};
KeyboardInputManager
.
prototype
.
emit
=
function
(
event
,
data
)
{
var
callbacks
=
this
.
events
[
event
];
if
(
callbacks
)
{
callbacks
.
forEach
(
function
(
callback
)
{
callback
(
data
);
});
}
};
KeyboardInputManager
.
prototype
.
listen
=
function
()
{
var
self
=
this
;
var
map
=
{
38
:
0
,
// Up
39
:
1
,
// Right
40
:
2
,
// Down
37
:
3
// Left
};
document
.
addEventListener
(
"
keydown
"
,
function
(
event
)
{
var
modifiers
=
event
.
altKey
&&
event
.
ctrlKey
&&
event
.
metaKey
&&
event
.
shiftKey
;
var
mapped
=
map
[
event
.
which
];
if
(
!
modifiers
&&
mapped
!==
undefined
)
{
event
.
preventDefault
();
self
.
emit
(
"
move
"
,
mapped
);
}
});
};
js/tile.js
浏览文件 @
b20e26e3
...
...
@@ -5,3 +5,7 @@ function Tile(position, value) {
this
.
previousPosition
=
null
;
}
Tile
.
prototype
.
savePosition
=
function
()
{
this
.
previousPosition
=
{
x
:
this
.
x
,
y
:
this
.
y
};
};
style/helpers.scss
浏览文件 @
b20e26e3
...
...
@@ -30,3 +30,26 @@
-webkit-transition-property
:
$args
;
-moz-transition-property
:
$args
;
}
// Keyframe animations
@mixin
keyframes
(
$animation-name
)
{
@-webkit-keyframes
$
animation-name
{
@content
;
}
@-moz-keyframes
$
animation-name
{
@content
;
}
@keyframes
$
animation-name
{
@content
;
}
}
@mixin
animation
(
$str
)
{
-webkit-animation
:
#{
$str
}
;
-moz-animation
:
#{
$str
}
;
}
@mixin
animation-fill-mode
(
$str
)
{
-webkit-animation-fill-mode
:
#{
$str
}
;
-moz-animation-fill-mode
:
#{
$str
}
;
}
style/main.css
浏览文件 @
b20e26e3
...
...
@@ -89,8 +89,8 @@ hr {
line-height
:
116.25px
;
font-size
:
55px
;
font-weight
:
bold
;
-webkit-transition
:
200ms
ease
;
-moz-transition
:
200ms
ease
;
-webkit-transition
:
100ms
ease-in-out
;
-moz-transition
:
100ms
ease-in-out
;
-webkit-transition-property
:
top
,
left
;
-moz-transition-property
:
top
,
left
;
}
.tile.tile-position-1-1
{
...
...
@@ -205,6 +205,39 @@ hr {
box-shadow
:
0
0
30px
10px
rgba
(
243
,
215
,
116
,
0.55556
),
inset
0
0
0
1px
rgba
(
255
,
255
,
255
,
0.33333
);
font-size
:
35px
;
}
@-webkit-keyframes
appear
{
0
%
{
-webkit-transform
:
scale
(
1.5
);
opacity
:
0
;
}
100
%
{
-webkit-transform
:
scale
(
1
);
opacity
:
1
;
}
}
@-moz-keyframes
appear
{
0
%
{
-webkit-transform
:
scale
(
1.5
);
opacity
:
0
;
}
100
%
{
-webkit-transform
:
scale
(
1
);
opacity
:
1
;
}
}
@keyframes
appear
{
0
%
{
-webkit-transform
:
scale
(
1.5
);
opacity
:
0
;
}
100
%
{
-webkit-transform
:
scale
(
1
);
opacity
:
1
;
}
}
.tile-new
{
-webkit-animation
:
appear
200ms
ease
100ms
;
-moz-animation
:
appear
200ms
ease
100ms
;
-webkit-animation-fill-mode
:
both
;
-moz-animation-fill-mode
:
both
;
}
.game-intro
{
margin-bottom
:
0
;
}
...
...
style/main.scss
浏览文件 @
b20e26e3
...
...
@@ -14,6 +14,8 @@ $tile-color: #eee4da;
$tile-gold-color
:
#edc22e
;
$tile-gold-glow-color
:
lighten
(
$tile-gold-color
,
15%
);
$transition-speed
:
100ms
;
html
,
body
{
margin
:
0
;
padding
:
0
;
...
...
@@ -132,7 +134,7 @@ hr {
font-size
:
55px
;
font-weight
:
bold
;
@include
transition
(
200ms
ease
);
@include
transition
(
$transition-speed
ease-in-out
);
@include
transition-property
(
top
,
left
);
// Build position classes
...
...
@@ -205,6 +207,23 @@ hr {
}
}
@include
keyframes
(
appear
)
{
0
%
{
-webkit-transform
:
scale
(
1
.5
);
opacity
:
0
;
}
100
%
{
-webkit-transform
:
scale
(
1
);
opacity
:
1
;
}
}
.tile-new
{
@include
animation
(
appear
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录