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
2faf2811
Commit
2faf2811
authored
Mar 10, 2021
by
邱旭
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
04.高性能鸟
parent
452ed2f1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
206 additions
and
0 deletions
+206
-0
04.高性能鸟.html
04.高性能鸟/04.高性能鸟.html
+110
-0
04.高性能鸟.md
04.高性能鸟/04.高性能鸟.md
+96
-0
No files found.
04.高性能鸟/04.高性能鸟.html
0 → 100644
View file @
2faf2811
<!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>
04.高性能鸟
</title>
<style>
html
,
body
{
margin
:
0
;
padding
:
0
;
width
:
100%
;
height
:
100%
;
overflow
:
hidden
;
}
#bird
{
/* 大小 */
width
:
50px
;
height
:
50px
;
/* 颜色 */
background-color
:
#f00
;
/* 位置 */
position
:
absolute
;
/* 旋转、缩放等属性 */
transform
:
scale
(
1
,
1
)
rotate
(
45deg
);
/* 锚点 */
transform-origin
:
center
;
}
</style>
</head>
<body>
<div
id=
"bird"
></div>
</body>
<script>
const
bird
=
document
.
getElementById
(
"bird"
);
const
speed
=
15
;
// bird的速度 每次移动多少距离
const
pos
=
{
// bird的位置 bird当前的位置
top
:
150
,
left
:
150
,
}
const
clickPos
=
{
// 鼠标点击的位置 bird将要的到达的位置
top
:
150
,
left
:
150
,
}
// 使用mousedown监听鼠标按下,并获得鼠标点击的位置
const
mouseDown
=
(
e
)
=>
{
// 记录bird将要到达的位置,使用动画慢慢到达
clickPos
.
top
=
e
.
clientY
;
clickPos
.
left
=
e
.
clientX
;
}
document
.
addEventListener
(
'mousedown'
,
mouseDown
);
/**
* 计算Bird的位置(数据更新)
*/
function
update
()
{
// 计算新的top
if
(
pos
.
top
!==
clickPos
.
top
)
{
const
dis
=
clickPos
.
top
-
pos
.
top
;
// 计算差值
const
dir
=
dis
>
0
?
1
:
-
1
;
// 计算在top上移动的方向 1 正向移动 或 -1 反向移动;
// 如果速度过快,本次移动直接过头了(即差值
<
速度
)
,就直接移动到指定
top
if
(
Math
.
abs
(
dis
)
<
speed
)
{
pos
.
top
=
clickPos
.
top
;
}
else
{
pos
.
top
=
pos
.
top
+
dir
*
speed
;
// 计算新的top,新的位置 = 之前的位置 + 方向 * 速度
}
}
// 用相同的方式计算left
if
(
pos
.
left
!==
clickPos
.
left
)
{
const
dis
=
clickPos
.
left
-
pos
.
left
;
const
dir
=
dis
>
0
?
1
:
-
1
;
if
(
Math
.
abs
(
dis
)
<
speed
)
{
pos
.
left
=
clickPos
.
left
;
}
else
{
pos
.
left
=
pos
.
left
+
dir
*
speed
;
}
}
}
/**
* 更新显示对象位置(渲染)
*/
function
render
()
{
bird
.
style
.
top
=
pos
.
top
+
"px"
;
bird
.
style
.
left
=
pos
.
left
+
"px"
;
}
function
loop
()
{
requestAnimationFrame
(
loop
);
// 循环调用requestAnimationFrame
update
();
// 先数据更新
render
();
// 后渲染更新
}
loop
();
</script>
</html>
04.高性能鸟/04.高性能鸟.md
0 → 100644
View file @
2faf2811
# 高性能Bird
引入概念:
`requestAnimationFrame`
`帧`
`更新和渲染的抽离`
经过上一节的操作,我们已经得到了一只演员鸟
众所周知,现在的游戏玩家都鬼的很,游戏每个高帧率他都不玩。
一般人游戏30帧就感觉比较流畅,可是这群游戏玩家,非要60帧才看着舒服
## 一、概念解释,什么是帧
帧率表示视频、游戏每秒钟刷新画面的次数
60帧即每秒钟刷新60次画面
一般电影的帧率是23.97frame/s,而游戏,低于45帧,会感到明显卡顿
为什么电影只需要24帧就比较流畅呢?
是因为摄影机记录的是1/24秒的所有光线信息,可以理解电影是无数张快门时间是1/24秒的照片同步播放组成的
而游戏计算出来的只有那一瞬间的画面,没有一个时间段内的光线信息,所以需要更高的帧率
因此我们就知道了我们的游戏需要高帧率的重要性了
## 二、requestAnimationFrame
理解了什么是帧就得出来,一个游戏60帧,每帧的时间是,1/60,约等于16.667ms;
我们大可以把
`setInterval`
的延时改成16.667
但是,众所周知,浏览器提供的延时函数都不靠谱,我们无法通过它得到稳定了60帧画面
隆重的介绍
[
requestAnimationFrame
](
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame
)
[
requestAnimationFrame详解
](
https://segmentfault.com/a/1190000020639465?utm_source=tag-newest
)
[
被誉为神器的requestAnimationFrame
](
https://www.cnblogs.com/xiaohuochai/p/5777186.html
)
这个是一个浏览器给我们提供的API
借助这个API我们可以在浏览器这个平台很好的控制每秒60帧的帧率
接下来我们将数据更新和渲染更新拆分为两个函数
```
javascript
/**
* 计算Bird的位置(数据更新)
*/
function
update
()
{
// 计算新的top
if
(
pos
.
top
!==
clickPos
.
top
)
{
const
dis
=
clickPos
.
top
-
pos
.
top
;
// 计算差值
const
dir
=
dis
>
0
?
1
:
-
1
;
// 计算在top上移动的方向 1 正向移动 或 -1 反向移动;
// 如果速度过快,本次移动直接过头了(即差值<速度),就直接移动到指定top
if
(
Math
.
abs
(
dis
)
<
speed
)
{
pos
.
top
=
clickPos
.
top
;
}
else
{
pos
.
top
=
pos
.
top
+
dir
*
speed
;
// 计算新的top,新的位置 = 之前的位置 + 方向 * 速度
}
}
// 用相同的方式计算left
if
(
pos
.
left
!==
clickPos
.
left
)
{
const
dis
=
clickPos
.
left
-
pos
.
left
;
const
dir
=
dis
>
0
?
1
:
-
1
;
if
(
Math
.
abs
(
dis
)
<
speed
)
{
pos
.
left
=
clickPos
.
left
;
}
else
{
pos
.
left
=
pos
.
left
+
dir
*
speed
;
}
}
}
/**
* 更新显示对象位置(渲染)
*/
function
render
()
{
bird
.
style
.
top
=
pos
.
top
+
"px"
;
bird
.
style
.
left
=
pos
.
left
+
"px"
;
}
```
然后用
`requestAnimationFrame`
来创建一个主循环,在主循环中依次调用这两个函数
```
javascript
function
loop
()
{
requestAnimationFrame
(
loop
);
// 循环调用requestAnimationFrame
update
();
// 先数据更新
render
();
// 后渲染更新
}
loop
();
```
再次运行案例,我们得到了更流畅,性能更高的Bird了
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