# webgame
**Repository Path**: shadaileng/webgame
## Basic Information
- **Project Name**: webgame
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: WTFPL
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-04-26
- **Last Updated**: 2022-02-20
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
> https://developer.mozilla.org/zh-CN/docs/Games 的学习案例
#
游戏开发
[toc]
## 一. 序言
得益于`JavaScript`实时编译技术性能的大幅提升,以及新开放的`API`,开发基于`HTML5`的游戏更加容易.
### 1 功能与对应的技术
浏览器`web`平台实现的功能与对应的技术:
功能|技术
---|---
音频|`Web Audio API`
图形|`WebGL (OpenGL ES 2.0)`
输入|`Touch events`, `Gamepad API`, `设备传感器`, `WebRTC`,` Full Screen API`, `Pointer Lock API`
语言|`JavaScript` (或是`C/C++`使用`Emscripten`来编译成`JavaScript`)
网络|`WebRTC`和/或`WebSockets`
存储|`IndexedDB`或是 "云(存储)"
`Web`|`HTML`, `CSS`, `SVG`,`Social API`(还有其他很多很多东西!)
### 2 游戏结构与工作流程
#### 2.1 呈现\接受\解析\计算\重复
每个视频游戏的目标是向用户`呈现`一个场景,`接受`用户的输入,将输入`解析`成动作信息,并`计算`这些动作在场景中的变化,游戏场景是不断`重复`的,直到有终止游戏的信号出现.
有一些游戏是通过用户输入来驱动游戏循环的,通过输入来判断下一个要呈现的游戏场景,如: 找不同游戏
有一些游戏是控制每个时间点,每一帧都遍历游戏逻辑,实现呈现场景状态.
#### 2.2 构建一个游戏循环
游戏场景是循环渲染的结果,在循环过程中响应事件回调函数,处理用户输入事件.`window.requestAnimationFrame()`回调调用函数本身可以形成循环.
```
window.main = function(){
window.requestAnimationFrame(main);
//无论你的主循环需要做什么
};
main(); //开始循环
```
上面的程序中出现了两个问题:
- `main()`函数污染了`window`对象
- 没有提供停止循环的方法
第一个问题可以使用立即调用的函数表达式(`IIFE`)创建创建游戏循环.第二个问题可以创建一个`Game`主体对象,保存`requestAnimationFrame`返回值`stopKey`,需要停止循环时,调用`window.cancelAnimationFrame()`方法,并传入`stopKey`.
```
;(function(){
function main(){
Game.stopKey = window.requestAnimationFrame(main);
//你的主循环内容
}
main(); //开始循环
})();
```
`requestAnimationFrame`方法会给回调函数传入一个精确到千分之一毫秒的事件对象`DOMHighResTimeStamp`,用来记录循环时间.
```
;(function(){
Game = {}
function main(tFrame) {
Game.stopKey = requestAnimationFrame(main)
console.log(tFrame)
}
main()
})();
```
每帧的工作时间
```
;(function(){
function init() {
Game = {
tickLength: 16, // 20Hz
lastTick: performance.now(), // 最后更新时间
stopKey: 0
}
}
function updateBatch(tickNum) {
for(let i = 0; i < tickNum; i++) {
Game.lastTick = Game.lastTick + Game.tickLength
update(Game.lastTick)
}
}
function update(lastTick) {
console.log('update: ' + lastTick)
}
function render(tFrame) {
}
function main(tFrame) {
Game.stopKey = requestAnimationFrame(main)
let nextTick = Game.lastTick + Game.tickLength
let tickNum = 0
/*
console.log('tFrame: ' + tFrame)
console.log('Game.lastTick: ' + Game.lastTick)
console.log('nextTick: ' + nextTick)
*/
if (tFrame > nextTick) {
let sinceTick = tFrame - Game.lastTick
tickNum = Math.floor((tFrame - Game.lastTick) / Game.tickLength)
}
// console.log('tFrame: ' + tFrame)
// console.log('now: ' + performance.now())
updateBatch(tickNum)
render(tFrame)
Game.lastTick = tFrame
}
init()
main()
})();
```
# 二. 游戏开发技术
## 1 Canvas
`