Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
game-stydy
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
谌继荃
game-stydy
Commits
bef3ef18
Commit
bef3ef18
authored
Mar 10, 2021
by
邱旭
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
10.FlppyBird-创建障碍
parent
76d6aefa
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
386 additions
and
12 deletions
+386
-12
10.FlppyBird-创建障碍.html
10.FlppyBird-创建障碍/10.FlppyBird-创建障碍.html
+250
-0
10.FlppyBird-创建障碍.md
10.FlppyBird-创建障碍/10.FlppyBird-创建障碍.md
+133
-0
10_1.png
images/10_1.png
+0
-0
10_2.gif
images/10_2.gif
+0
-0
flppyBirdLib.js
lib/flppyBirdLib.js
+3
-12
No files found.
10.FlppyBird-创建障碍/10.FlppyBird-创建障碍.html
0 → 100644
View file @
bef3ef18
<!DOCTYPE html>
<html
lang=
"zh"
>
<head>
<meta
charset=
"UTF-8"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
/>
<title>
10.FlppyBird-创建障碍
</title>
<style>
html
,
body
{
margin
:
0
;
padding
:
0
;
width
:
100%
;
height
:
100%
;
overflow
:
hidden
;
}
</style>
<script
src=
"../lib/flppyBirdLib.js"
></script>
</head>
<body>
</body>
<script>
/**
* 屏幕宽高
* @type {{width: number, height: number}}
*/
const
winSize
=
{
width
:
document
.
body
.
clientWidth
,
height
:
document
.
body
.
clientHeight
,
}
</script>
<script>
/**
* Bird
*/
class
Bird
extends
Sprite
{
speed
;
// bird的速度 每次移动多少距离
gravity
;
// 重力加速度
constructor
(
gravity
=
0.2
,
speed
=
0
)
{
super
(
"../images/bird/bird_01.png"
);
this
.
speed
=
speed
;
// 保存speed
this
.
gravity
=
gravity
;
// 保存gravity
}
ready
()
{
super
.
ready
();
// 放到合适的位置
const
{
width
,
height
}
=
this
.
size
;
this
.
top
=
(
winSize
.
height
-
height
)
/
2
-
100
;
this
.
left
=
(
winSize
.
width
-
width
)
/
2
;
}
update
()
{
super
.
update
();
// v = v0 + a * t²
this
.
speed
+=
this
.
gravity
;
// 速度 = 速度 + 加速度 * 时间²
this
.
top
+=
this
.
speed
;
// 更新位置
}
}
/**
* 滚动器
*/
class
ScrollMgr
extends
GameObject
{
speed
;
// 滚动速度
bg1
;
// bg1
bg2
;
// bg2
constructor
(
bg1
,
bg2
,
speed
=
5
)
{
super
();
this
.
bg1
=
bg1
;
this
.
bg2
=
bg2
;
this
.
speed
=
speed
;
this
.
addChild
(
this
.
bg1
);
this
.
addChild
(
this
.
bg2
);
}
ready
()
{
super
.
ready
();
this
.
bg1
.
top
=
winSize
.
height
-
this
.
bg1
.
size
.
height
;
// 放在底部
this
.
bg2
.
top
=
winSize
.
height
-
this
.
bg2
.
size
.
height
;
// 放在底部
}
update
()
{
super
.
update
();
// 获取一些参数
let
bg1Left
=
this
.
bg1
.
left
;
const
bg1Width
=
this
.
bg1
.
size
.
width
;
// 计算位置
bg1Left
-=
this
.
speed
;
// 计算位置
this
.
bg1
.
left
=
bg1Left
;
// 设置bg1的位置
this
.
bg2
.
left
=
bg1Left
+
this
.
bg1
.
size
.
width
;
// bg2跟在bg1后面
// 如果超出屏幕则交换bg1和bg2,为了做到循环滚动
if
(
bg1Left
<=
-
bg1Width
)
{
const
temp
=
this
.
bg1
;
this
.
bg1
=
this
.
bg2
;
this
.
bg2
=
temp
;
}
}
}
</script>
<script>
/**
* Pie
*/
class
Pie
extends
GameObject
{
up
;
// 钢管上部分
down
;
// 钢管下部分
constructor
()
{
super
();
this
.
up
=
this
.
addChild
(
new
Sprite
(
"../images/bird/pie.png"
));
this
.
down
=
this
.
addChild
(
new
Sprite
(
"../images/bird/pie.png"
));
}
/**
* 注意此函数非真正的ready函数,在被addChild的时候都会执行一次
*/
ready
()
{
super
.
ready
();
// 随机中间的距离
const
dis
=
Math
.
random
()
*
80
+
100
;
this
.
down
.
top
=
this
.
up
.
size
.
height
+
dis
;
}
}
/**
* PieMgr
*/
class
PieMgr
extends
GameObject
{
pieArr
=
[];
// 所有的Pie
speed
;
// Pie移动的速度
delay
;
// 添加Pie的延时
constructor
(
speed
,
delay
)
{
super
();
this
.
speed
=
speed
;
this
.
delay
=
delay
;
}
ready
()
{
super
.
ready
();
// 创建计时器来固定事件创建Pie
setInterval
(()
=>
this
.
createPie
(),
this
.
delay
);
}
/**
* 创建Pie
*/
createPie
()
{
const
pie
=
this
.
addChild
(
new
Pie
());
this
.
pieArr
.
push
(
pie
);
// 加入列表统一管理
pie
.
top
=
Math
.
random
()
*
-
150
;
// 高度随机
pie
.
left
=
winSize
.
width
;
// 从屏幕左边出现
}
update
()
{
super
.
update
();
// 所有的Pie同时向左移动
const
{
speed
,
pieArr
}
=
this
;
pieArr
.
forEach
((
pie
)
=>
{
pie
.
left
-=
speed
;
});
}
}
</script>
<script>
/**
* FlppyBird
*/
class
FlppyBird
extends
GameStage
{
bird
;
async
reloadRes
()
{
const
path
=
"../images/bird/"
;
const
promises
=
[
"bird_01.png"
,
"bird_02.png"
,
"bird_03.png"
,
"pie.png"
,
"land.png"
,
"background.png"
,
"start_button.png"
].
map
((
v
)
=>
{
return
loadImgAsync
(
`
${
path
}${
v
}
`
);
});
return
Promise
.
all
(
promises
);
}
async
ready
()
{
// 创建鸟
const
bird
=
this
.
bird
=
new
Bird
();
// 创建背景
const
bg1
=
new
Sprite
(
"../images/bird/background.png"
);
const
bg2
=
new
Sprite
(
"../images/bird/background.png"
);
const
bgMgr
=
new
ScrollMgr
(
bg1
,
bg2
,
2
);
// 创建地面
const
land1
=
new
Sprite
(
"../images/bird/land.png"
);
const
land2
=
new
Sprite
(
"../images/bird/land.png"
);
const
landMgr
=
new
ScrollMgr
(
land1
,
land2
,
4
);
const
pieMgr
=
new
PieMgr
(
4
,
1000
);
// 创建PieMgr
this
.
addChild
(
bgMgr
);
this
.
addChild
(
pieMgr
);
// 加在背景和地面的中间
this
.
addChild
(
landMgr
);
this
.
addChild
(
bird
);
// 将背景放在地面的上面,因为默认top是0,子节点在内部定位在底部,所以只需要把背景定位在负的land的高度就可以了
bgMgr
.
top
=
-
land1
.
size
.
height
;
// 使用mousedown监听鼠标按下,并获得鼠标点击的位置
document
.
addEventListener
(
'mousedown'
,
this
.
mouseDown
);
}
mouseDown
=
()
=>
{
this
.
bird
.
speed
=
-
8
;
}
destroy
()
{
super
.
destroy
();
document
.
removeEventListener
(
'mousedown'
,
this
.
mouseDown
);
}
}
// 创建游戏实例
new
FlppyBird
();
</script>
</html>
10.FlppyBird-创建障碍/10.FlppyBird-创建障碍.md
0 → 100644
View file @
bef3ef18
# FlppyBird - 创建障碍
引入概念:
`动态生成障碍`
本节将在上节的内容上,实现动态添加障碍
## 1.实现`Pie`类
-
实现
`Pie`
类,继承
`GameObject`
-
`Pie`
包含一个上的一个下的
-
上下两个均为
`Sprite`
,且中间距离随机
```
javascript
/**
* Pie
*/
class
Pie
extends
GameObject
{
up
;
// 钢管上部分
down
;
// 钢管下部分
constructor
()
{
super
();
this
.
up
=
this
.
addChild
(
new
Sprite
(
"../images/bird/pie_up.png"
));
this
.
down
=
this
.
addChild
(
new
Sprite
(
"../images/bird/pie_down.png"
));
}
/**
* 注意此函数非真正的ready函数,在被addChild的时候都会执行一次
*/
ready
()
{
super
.
ready
();
// 随机中间的距离
const
dis
=
Math
.
random
()
*
80
+
100
;
this
.
down
.
top
=
this
.
up
.
size
.
height
+
dis
;
}
}
```
尝试在
`FlppyBird`
的
`ready`
函数中创建,得到如下效果
![
10_1.png
](
../images/10_1.png
)
## 2.实现动态创建`Pie`且高度随机,从屏幕左边出现向左移动
-
创建
`PieMgr`
类管理
`Pie`
的创建和移动
-
实现创建
`Pie`
的方法,让
`Pie`
从屏幕左边出现且高度随机,并统一管理
-
创建定时器,固定事件创建
`Pie`
-
在
`update`
函数中让所有
`Pie`
同时向左移动
```
javascript
/**
* PieMgr
*/
class
PieMgr
extends
GameObject
{
pieArr
=
[];
// 所有的Pie
speed
;
// Pie移动的速度
delay
;
// 添加Pie的延时
constructor
(
speed
,
delay
)
{
super
();
this
.
speed
=
speed
;
this
.
delay
=
delay
;
}
ready
()
{
super
.
ready
();
// 创建计时器来固定事件创建Pie
setInterval
(()
=>
this
.
createPie
(),
this
.
delay
);
}
/**
* 创建Pie
*/
createPie
()
{
const
pie
=
this
.
addChild
(
new
Pie
());
this
.
pieArr
.
push
(
pie
);
// 加入列表统一管理
pie
.
top
=
Math
.
random
()
*
-
150
;
// 高度随机
pie
.
left
=
winSize
.
width
;
// 从屏幕左边出现
}
update
()
{
super
.
update
();
// 所有的Pie同时向左移动
const
{
speed
,
pieArr
}
=
this
;
pieArr
.
forEach
((
pie
)
=>
{
pie
.
left
-=
speed
;
});
}
}
```
## 3.创建`PieMgr`实例并添加到节点树上
-
创建
`PieMgr`
实例
-
添加到节点树上,且层级在地面和背景的中间
```
javascript
class
FlppyBird
extends
GameStage
{
/* ... */
async
ready
()
{
// 创建背景
const
bg1
=
new
Sprite
(
"../images/bird/background.png"
);
const
bg2
=
new
Sprite
(
"../images/bird/background.png"
);
const
bgMgr
=
new
ScrollMgr
(
bg1
,
bg2
,
2
);
// 创建地面
const
land1
=
new
Sprite
(
"../images/bird/land.png"
);
const
land2
=
new
Sprite
(
"../images/bird/land.png"
);
const
landMgr
=
new
ScrollMgr
(
land1
,
land2
,
4
);
const
pieMgr
=
new
PieMgr
(
4
,
1000
);
// 创建PieMgr
this
.
addChild
(
bgMgr
);
this
.
addChild
(
pieMgr
);
// 加在背景和地面的中间
this
.
addChild
(
landMgr
);
/* ... */
}
/* ... */
}
```
运行案例发现,每秒创建一个
`Pie`
,且从屏幕右边出现,不断相左移动
![
10_2.gif
](
../images/10_2.gif
)
images/10_1.png
0 → 100644
View file @
bef3ef18
86.8 KB
images/10_2.gif
0 → 100644
View file @
bef3ef18
374 KB
lib/flppyBirdLib.js
View file @
bef3ef18
...
...
@@ -41,12 +41,6 @@ class GameObject {
this
.
dom
.
style
.
position
=
"absolute"
;
}
/**
* 生命周期 start 所有构造函数完成,执行此函数
*/
async
start
()
{
}
/**
* 生命周期 start 加入显示列表执行此函数
*/
...
...
@@ -70,11 +64,8 @@ class GameObject {
child
.
parent
=
this
;
// 容错:防止子类重写的start不是async函数
// TODO dom无法在节点不在渲染树的上的时候拿到clientWidth等属性,故将start和ready放在这里
(
async
()
=>
{
await
child
.
start
();
// TODO dom无法在节点不在渲染树的上的时候拿到clientWidth等属性,故将ready放在这里
child
.
ready
();
})();
return
child
;
}
...
...
@@ -156,7 +147,7 @@ class GameStage extends GameObject {
async
_gameStart
()
{
await
this
.
reloadRes
();
this
.
start
();
this
.
ready
();
}
/**
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment