2015-เตฝ เดชเตเดฑเดคเตเดคเดฟเดฑเดเตเดเดฟ
เด เดเตเดฏเดฟเดฎเตเดเดณเตเดเตเดเตเดฑเดฟเดเตเดเต เดจเดฟเดเตเดเตพ เดฎเตเดฎเตเดชเต เดเตเดเตเดเดฟเดเตเดเดฟเดฒเตเดฒเตเดเตเดเดฟเตฝ, เด
เดต เดธเตเดเดจเตเดฏ เดฎเตพเดเตเดเดฟเดชเตเดฒเตเดฏเตผ เดตเตเดฌเต เดเตเดฏเดฟเดฎเตเดเดณเดพเดฃเต, เด
เดคเต เดเดณเดฟเดเตเดเดพเตป เดเดณเตเดชเตเดชเดฎเดพเดฃเต (เด
เดเตเดเตเดฃเตเดเต เดเดตเดถเตเดฏเดฎเดฟเดฒเตเดฒ). เด
เดตเตผ เดธเดพเดงเดพเดฐเดฃเดฏเดพเดฏเดฟ เดจเดฟเดฐเดตเดงเดฟ เดเดคเดฟเตผ เดเดณเดฟเดเตเดเดพเดฐเต เดเดฐเต เดตเตเดฆเดฟเดฏเดฟเตฝ เดฎเดคเตเดธเดฐเดฟเดชเตเดชเดฟเดเตเดเตเดจเตเดจเต. เดฎเดฑเตเดฑเต เดชเตเดฐเดถเดธเตเดคเดฎเดพเดฏ .io เดเตเดฏเดฟเดฎเตเดเตพ:
เดเดเตเดเดจเตเดฏเตเดจเตเดจเต เด เดชเตเดธเตเดฑเตเดฑเดฟเตฝ เดจเดฎเตเดฎเตพ เดเดฃเตเดเตเดคเตเดคเตเด เดเดฆเตเดฏเด เดฎเตเดคเตฝ เดเดฐเต .io เดเตเดฏเดฟเด เดธเตเดทเตเดเดฟเดเตเดเตเด. เดเดคเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเต, เดเดพเดตเดพเดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเดฟเดจเตเดเตเดเตเดฑเดฟเดเตเดเตเดณเตเดณ เด
เดฑเดฟเดตเต เดฎเดพเดคเตเดฐเด เดฎเดคเดฟเดฏเดพเดเตเด: เดตเดพเดเตเดฏเดเดเดจ เดชเตเดฒเตเดณเตเดณ เดเดพเดฐเตเดฏเดเตเดเตพ เดจเดฟเดเตเดเตพ เดฎเดจเดธเตเดธเดฟเดฒเดพเดเตเดเตเดฃเตเดเดคเตเดฃเตเดเต this
ะธ
เดเดฐเต .io เดเตเดฏเดฟเดฎเดฟเดจเตเดฑเต เดเดฆเดพเดนเดฐเดฃเด
เดชเดฐเดฟเดถเตเดฒเดจ เดธเดนเดพเดฏเดคเตเดคเดฟเดจเดพเดฏเดฟ เดเดเตเดเตพ เดฑเดซเตผ เดเตเดฏเตเดฏเตเด
เดเตเดฏเดฟเด เดตเดณเดฐเต เดฒเดณเดฟเดคเดฎเดพเดฃเต: เดฎเดฑเตเดฑเต เดเดณเดฟเดเตเดเดพเตผเดเตเดเตเดชเตเดชเด เดเดฐเต เด
เดฑเตเดจเดฏเดฟเตฝ เดจเดฟเดเตเดเตพ เดเดฐเต เดเดชเตเดชเตฝ เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเดจเตเดจเต. เดจเดฟเดเตเดเดณเตเดเต เดเดชเตเดชเตฝ เดธเตเดตเดชเตเดฐเตเดฐเดฟเดคเดฎเดพเดฏเดฟ เดชเตเดฐเตเดเดเตโเดเตเดฒเตเดเตพ เดตเตเดเดฟเดตเดฏเตเดเตเดเตเดเดฏเตเด เดฎเดฑเตเดฑเต เดเดณเดฟเดเตเดเดพเดฐเต เด
เดตเดฐเตเดเต เดชเตเดฐเตเดเดเตโเดเตเดฒเตเดเตพ เดเดดเดฟเดตเดพเดเตเดเดฟเดเตเดเตเดฃเตเดเต เดจเดฟเดเตเดเตพ เด
เดเดฟเดเตเดเดพเตป เดถเตเดฐเดฎเดฟเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจเต.
1. เดธเดเดเตเดทเดฟเดชเตเดค เด เดตเดฒเตเดเดจเด/เดชเดฆเตเดงเดคเดฟ เดเดเดจ
เดเดพเตป เดถเตเดชเดพเตผเดถเดเตเดฏเตเดฏเตเดจเตเดจเต
เดธเตเดดเตเดธเต เดเตเดกเต เดกเตเตบเดฒเตเดกเต เดเตเดฏเตเดฏเตเด เดเดฆเดพเดนเดฐเดฃ เดเตเดฏเดฟเด เด เดคเดฟเดจเดพเตฝ เดจเดฟเดเตเดเตพเดเตเดเต เดเดจเตเดจเต เดชเดฟเดจเตเดคเตเดเดฐเดพเดจเดพเดเตเด.
เดเดฆเดพเดนเดฐเดฃเด เดเดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจเดต เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต:
เดชเตเดฐเดเดเดฟเดชเตเดชเดฟเดเตเดเตเด เดเตเดฏเดฟเดฎเดฟเดจเตเดฑเต เดตเตเดฌเต เดธเตเตผเดตเตผ เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเดจเตเดจ Node.js-เดจเตเดณเตเดณ เดเดฑเตเดฑเดตเตเด เดเดจเดชเตเดฐเดฟเดฏ เดตเตเดฌเต เดเดเตเดเดเตเดเตเดเดพเดฃเต.socket.io โ เดฌเตเดฐเตเดธเดฑเดฟเดจเตเด เดธเตเตผเดตเดฑเดฟเดจเตเดฎเดฟเดเดฏเดฟเตฝ เดกเดพเดฑเตเดฑ เดเตเดฎเดพเดฑเตเดฑเด เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดตเตเดฌเตโเดธเตเดเตเดเดฑเตเดฑเต เดฒเตเดฌเตเดฐเดฑเดฟ.เดตเตเดฌเตโเดชเดพเดฏเตเดเตเดเต - เดฎเตเดกเตเดฏเตเตพ เดฎเดพเดจเตเดเตผ. เดเดจเตเดคเตเดเตเดฃเตเดเต เดตเตเดฌเตโเดชเดพเดเตเดเต เดเดชเดฏเตเดเดฟเดเตเดเดฃเด เดเดจเตเดจเดคเดฟเดจเตเดเตเดเตเดฑเดฟเดเตเดเต เดจเดฟเดเตเดเตพเดเตเดเต เดตเดพเดฏเดฟเดเตเดเดพเดเดเดตเดฟเดเต .
เดชเตเดฐเตเดเดเตเดฑเตเดฑเต เดกเดฏเดฑเดเตเดเดฑเดฟ เดเดเดจ เดเดเตเดเดจเตเดฏเดพเดฃเต:
public/
assets/
...
src/
client/
css/
...
html/
index.html
index.js
...
server/
server.js
...
shared/
constants.js
เดชเตเดคเต/
เดเดฒเตเดฒเดพเด เดซเตเตพเดกเดฑเดฟเตฝ เดเดฃเตเดเต public/
เดธเตเตผเดตเตผ เดธเตเดฅเดฟเดฐเดฎเดพเดฏเดฟ เดเตเดฎเดพเดฑเตเด. IN public/assets/
เดเดเตเดเดณเตเดเต เดชเตเดฐเตเดเดเตเดฑเตเดฑเต เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจ เดเดฟเดคเตเดฐเดเตเดเตพ เด
เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต.
src /
เดเดฒเตเดฒเดพ เดธเตเดดเตโเดธเต เดเตเดกเตเด เดซเตเตพเดกเดฑเดฟเดฒเดพเดฃเต src/
. เดถเตเตผเดทเดเดเตเดเตพ client/
ะธ server/
เดธเตเดตเดฏเด เดธเดเดธเดพเดฐเดฟเดเตเดเตเดเดฏเตเด shared/
เดเตเดฒเดฏเดจเตเดฑเตเด เดธเตเตผเดตเดฑเตเด เดเดฑเดเตเดเตเดฎเดคเดฟ เดเตเดฏเตเดค เดเดฐเต เดเตเตบเดธเตเดฑเตเดฑเดจเตเดฑเตเดธเต เดซเดฏเตฝ เด
เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต.
2. เด เดธเดเดฌเตเดฒเดฟเดเตพ/เดชเดฆเตเดงเดคเดฟ เดชเดพเดฐเดพเดฎเตเดฑเตเดฑเดฑเตเดเตพ
เดฎเตเดเดณเดฟเตฝ เดชเดฑเดเตเดเดคเตเดชเตเดฒเต, เดชเตเดฐเตเดเดเตเดฑเตเดฑเต เดจเดฟเตผเดฎเตเดฎเดฟเดเตเดเดพเตป เดเดเตเดเตพ เดเดฐเต เดฎเตเดกเตเดฏเตเตพ เดฎเดพเดจเตเดเตผ เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต
webpack.common.js:
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: {
game: './src/client/index.js',
},
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ['@babel/preset-env'],
},
},
},
{
test: /.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
'css-loader',
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/client/html/index.html',
}),
],
};
เดเดตเดฟเดเต เดเดฑเตเดฑเดตเตเด เดชเตเดฐเดงเดพเดจเดชเตเดชเตเดเตเด เดตเดฐเดฟเดเตพ เดเดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจเดตเดฏเดพเดฃเต:
src/client/index.js
Javascript (JS) เดเตเดฒเดฏเดจเตเดฑเดฟเตปเดฑเต เดเตปเดเตเดฐเดฟ เดชเตเดฏเดฟเดจเตเดฑเต เดเดฃเต. Webpack เดเดตเดฟเดเต เดจเดฟเดจเตเดจเต เดเดฐเดเดญเดฟเดเตเดเตเดเดฏเตเด เดฎเดฑเตเดฑเต เดเดฑเดเตเดเตเดฎเดคเดฟ เดเตเดฏเตเดค เดซเดฏเดฒเตเดเตพเดเตเดเดพเดฏเดฟ เดเดตเตผเดคเตเดคเดฟเดเตเดเต เดจเตเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเด.- เดเดเตเดเดณเตเดเต เดตเตเดฌเตโเดชเดพเดเตเดเต เดฌเดฟเตฝเดกเดฟเดจเตเดฑเต เดเดเตเดเตโเดชเตเดเตเดเต JS เดกเดฏเดฑเดเตเดเดฑเดฟเดฏเดฟเตฝ เดธเตเดฅเดฟเดคเดฟเดเตเดฏเตเดฏเตเด
dist/
. เดเดพเตป เด เดซเดฏเดฒเดฟเดจเต เดเดเตเดเดณเตเดเต เดเดจเตเดจเต เดตเดฟเดณเดฟเดเตเดเตเด JS เดชเดพเดเตเดเตเดเต. - เดเดเตเดเตพ เดเดชเดฏเตเดพเดเดฟเดเตเดเตเดจเตเดจเต
เดฌเดพเดฌเตเตฝ , เดชเตเดฐเดคเตเดฏเตเดเดฟเดเตเดเต เดเตเตบเดซเดฟเดเดฑเตเดทเตป@babel/preset-env เดชเดดเดฏ เดฌเตเดฐเตเดธเดฑเตเดเตพเดเตเดเดพเดฏเดฟ เดเดเตเดเดณเตเดเต JS เดเตเดกเต เดเตเดฐเดพเตปเดธเตเดชเตเตฝ เดเตเดฏเตเดฏเดพเตป. - JS เดซเดฏเดฒเตเดเตพ เดฑเดซเดฑเตปเดธเต เดเตเดฏเตเดค เดเดฒเตเดฒเดพ CSS-เดเด เดเดเตโเดธเตโเดเตเดฐเดพเดเตโเดฑเตเดฑเตเดเตเดฏเตเดฏเดพเดจเตเด เด เดตเดฏเต เดเดฐเดฟเดเดคเตเดคเต เดธเดเดฏเตเดเดฟเดชเตเดชเดฟเดเตเดเดพเดจเตเด เดเดเตเดเตพ เดเดฐเต เดชเตเดฒเดเดฟเตป เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต. เดเดพเตป เด เดคเดฟเดจเต เดจเดฎเตเดฎเตเดเตเดคเต เดเดจเตเดจเต เดตเดฟเดณเดฟเดเตเดเตเด CSS เดชเดพเดเตเดเตเดเต.
เดตเดฟเดเดฟเดคเตเดฐเดฎเดพเดฏ เดชเดพเดเตเดเตเดเต เดซเดฏเตฝ เดจเดพเดฎเดเตเดเตพ เดจเดฟเดเตเดเตพ เดถเตเดฐเดฆเตเดงเดฟเดเตเดเดฟเดฐเดฟเดเตเดเดพเด '[name].[contenthash].ext'
. เด
เดต เด
เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต [name]
เดเตปเดชเตเดเตเดเต เดชเตเดฏเดฟเดจเตเดฑเดฟเดจเตเดฑเต เดชเตเดฐเต เดเดชเดฏเตเดเดฟเดเตเดเต เดฎเดพเดฑเตเดฑเดฟเดธเตเดฅเดพเดชเดฟเดเตเดเตเด (เดเดเตเดเดณเตเดเต เดเดพเดฐเตเดฏเดคเตเดคเดฟเตฝ เด
เดคเต game
), เดเดชเตเดชเด [contenthash]
เดซเดฏเตฝ เดเดณเตเดณเดเดเตเดเดเตเดเดณเตเดเต เดเดฐเต เดนเดพเดทเต เดเดชเดฏเตเดเดฟเดเตเดเต เดฎเดพเดฑเตเดฑเดฟเดธเตเดฅเดพเดชเดฟเดเตเดเตเด. เดเดเตเดเตพ เดเดคเต เดเตเดฏเตเดฏเตเดจเตเดจเต contenthash
). เดชเตเตผเดคเตเดคเดฟเดฏเดพเดฏ เดซเดฒเด เดเดพเดดเตเดเดฏเตเดเต เดซเดฏเตฝ เดจเดพเดฎเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเตเด game.dbeee76e91a97d0c7207.js
.
เดซเดฏเดฒเต webpack.common.js
- เดกเตเดตเดฒเดชเตโเดฎเตเดจเตเดฑเต, เดชเตเตผเดคเตเดคเดฟเดฏเดพเดฏ เดชเตเดฐเตเดเดเตเดฑเตเดฑเต เดเตเตบเดซเดฟเดเดฑเตเดทเดจเตเดเดณเดฟเดฒเตเดเตเดเต เดเดเตเดเตพ เดเดฑเดเตเดเตเดฎเดคเดฟ เดเตเดฏเตเดฏเตเดจเตเดจ เด
เดเดฟเดธเตเดฅเดพเดจ เดเตเตบเดซเดฟเดเดฑเตเดทเตป เดซเดฏเดฒเดพเดฃเดฟเดคเต. เดเดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เดตเดฟเดเดธเดจ เดเตเตบเดซเดฟเดเดฑเตเดทเตป เดเดคเดพ:
webpack.dev.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'development',
});
เดเดพเดฐเตเดฏเดเตเดทเดฎเดคเดฏเตเดเตเดเดพเดฏเดฟ, เดเดเตเดเตพ เดตเดฟเดเดธเดจ เดชเตเดฐเดเตเดฐเดฟเดฏเดฏเดฟเตฝ เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต webpack.dev.js
, เดเดจเตเดจเดฟเดตเดฏเดฟเดฒเตเดเตเดเต เดฎเดพเดฑเตเดจเตเดจเต webpack.prod.js
, เดเตฝเดชเตเดชเดพเดฆเดจเดคเตเดคเดฟเดฒเตเดเตเดเต เดตเดฟเดจเตเดฏเดธเดฟเดเตเดเตเดฎเตเดชเตเตพ เดชเดพเดเตเดเตเดเต เดตเดฒเตเดชเตเดชเดเตเดเตพ เดเดชเตเดฑเตเดฑเดฟเดฎเตเดธเต เดเตเดฏเตเดฏเดพเตป.
เดชเตเดฐเดพเดฆเตเดถเดฟเด เดธเดเตเดเตเดเดฐเดฃเด
เดจเดฟเดเตเดเดณเตเดเต เดฒเตเดเตเดเตฝ เดฎเตเดทเตเดจเดฟเตฝ เดชเตเดฐเตเดเดเตเดฑเตเดฑเต เดเตปเดธเตเดฑเตเดฑเดพเตพ เดเตเดฏเตเดฏเดพเตป เดเดพเตป เดถเตเดชเดพเตผเดถ เดเตเดฏเตเดฏเตเดจเตเดจเต, เด
เดคเตเดตเดดเดฟ เดจเดฟเดเตเดเตพเดเตเดเต เด เดชเตเดธเตเดฑเตเดฑเดฟเตฝ เดฒเดฟเดธเตเดฑเตเดฑเตเดเตเดฏเตเดคเดฟเดฐเดฟเดเตเดเตเดจเตเดจ เดเดเตเดเดเตเดเตพ เดชเดฟเดจเตเดคเตเดเดฐเดพเดจเดพเดเตเด. เดธเดเตเดเตเดเดฐเดฃเด เดฒเดณเดฟเดคเดฎเดพเดฃเต: เดเดฆเตเดฏเด, เดธเดฟเดธเตเดฑเตเดฑเด เดเดฃเตเดเดพเดฏเดฟเดฐเดฟเดเตเดเดฃเด
$ git clone https://github.com/vzhou842/example-.io-game.git
$ cd example-.io-game
$ npm install
เดจเดฟเดเตเดเตพ เดชเตเดเดพเตป เดคเดฏเตเดฏเดพเดฑเดพเดฃเต! เดตเดฟเดเดธเดจ เดธเตเตผเดตเตผ เดเดฐเดเดญเดฟเดเตเดเดพเตป, เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเดเตเดเตเด
$ npm run develop
เดจเดฟเดเตเดเดณเตเดเต เดตเตเดฌเต เดฌเตเดฐเตเดธเดฑเดฟเดฒเตเดเตเดเต เดชเตเดเตเด
3. เดเตเดฒเดฏเดจเตเดฑเต เดเตปเดเตเดฐเดฟ เดชเตเดฏเดฟเดจเตเดฑเตเดเตพ
เดเตเดฏเดฟเด เดเตเดกเดฟเดฒเตเดเตเดเต เดคเดจเตเดจเต เดเดฑเดเตเดเดพเด. เดเดฆเตเดฏเด เดจเดฎเตเดเตเดเต เดเดฐเต เดชเตเดเต เดตเตเดฃเด index.html
, เดจเดฟเดเตเดเตพ เดธเตเดฑเตเดฑเต เดธเดจเตเดฆเตผเดถเดฟเดเตเดเตเดฎเตเดชเตเตพ, เดฌเตเดฐเตเดธเตผ เดเดฆเตเดฏเด เด
เดคเต เดฒเตเดกเต เดเตเดฏเตเดฏเตเด. เดเดเตเดเดณเตเดเต เดชเตเดเต เดตเดณเดฐเต เดฒเดณเดฟเดคเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเตเด:
Index.html
เดเดฐเต เดเดฆเดพเดนเดฐเดฃเด .io เดเตเดฏเดฟเด เดเดณเดฟเดเตเดเตเด
เด เดเตเดกเต เดเดฆเดพเดนเดฐเดฃเด เดตเตเดฏเดเตเดคเดคเดฏเตเดเตเดเดพเดฏเดฟ เดเตเดฑเตเดคเดพเดฏเดฟ เดฒเดณเดฟเดคเดฎเดพเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต, เดเตเดเดพเดคเต เดชเตเดธเตเดฑเตเดฑเดฟเดฒเต เดฎเดฑเตเดฑเต เดชเดฒ เดเดฆเดพเดนเดฐเดฃเดเตเดเดณเดฟเดฒเตเด เดเดพเตป เดเดคเต เดเตเดฏเตเดฏเตเด. เดจเดฟเดเตเดเตพเดเตเดเต เดเดฒเตเดฒเดพเดฏเตเดชเตเดชเตเดดเตเด เดฎเตเดดเตเดตเตป เดเตเดกเตเด เดจเตเดเตเดเดพเด
เดจเดฎเตเดเตเดเต เดเดฃเตเดเต:
HTML5 เดเตเดฏเดพเตปเดตเดพเดธเต เดเดเดเด (<canvas>
), เดเตเดฏเดฟเด เดฑเตเตปเดกเตผ เดเตเดฏเตเดฏเดพเตป เดเดเตเดเตพ เดเดชเดฏเตเดเดฟเดเตเดเตเด.<link>
เดเดเตเดเดณเตเดเต CSS เดชเดพเดเตเดเตเดเต เดเตเตผเดเตเดเดพเตป.<script>
เดเดเตเดเดณเตเดเต Javascript เดชเดพเดเตเดเตเดเต เดเตเตผเดเตเดเดพเตป.- เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเดฎเตเดณเตเดณ เดชเตเดฐเดงเดพเดจ เดฎเตเดจเต
<input>
เดเดชเตเดชเด "เดชเตเดฒเต" เดฌเดเตเดเดฃเตเด (<button>
).
เดนเตเด เดชเตเดเต เดฒเตเดกเต เดเตเดฏเตโเดคเตเดเดดเดฟเดเตเดเดพเตฝ, เดเตปเดเตเดฐเดฟ เดชเตเดฏเดฟเดจเตเดฑเต JS เดซเดฏเดฒเดฟเตฝ เดคเตเดเดเตเดเดฟ เดฌเตเดฐเตเดธเตผ Javascript เดเตเดกเต เดเดเตโเดธเดฟเดเตเดฏเตเดเตเดเต เดเตเดฏเตเดฏเดพเตป เดคเตเดเดเตเดเตเด: src/client/index.js
.
index.js
import { connect, play } from './networking';
import { startRendering, stopRendering } from './render';
import { startCapturingInput, stopCapturingInput } from './input';
import { downloadAssets } from './assets';
import { initState } from './state';
import { setLeaderboardHidden } from './leaderboard';
import './css/main.css';
const playMenu = document.getElementById('play-menu');
const playButton = document.getElementById('play-button');
const usernameInput = document.getElementById('username-input');
Promise.all([
connect(),
downloadAssets(),
]).then(() => {
playMenu.classList.remove('hidden');
usernameInput.focus();
playButton.onclick = () => {
// Play!
play(usernameInput.value);
playMenu.classList.add('hidden');
initState();
startCapturingInput();
startRendering();
setLeaderboardHidden(false);
};
});
เดเดคเต เดธเดเตเดเตเตผเดฃเตเดฃเดฎเดพเดฃเตเดจเตเดจเต เดคเตเดจเตเดจเตเดฎเตเดเตเดเดฟเดฒเตเด เดฏเดฅเดพเตผเดคเตเดฅเดคเตเดคเดฟเตฝ เดเดตเดฟเดเต เดเดพเดฐเตเดฏเดฎเดพเดฏเตเดจเตเดจเตเด เดจเดเดเตเดเตเดจเตเดจเดฟเดฒเตเดฒ:
- เดฎเดฑเตเดฑเต เดจเดฟเดฐเดตเดงเดฟ JS เดซเดฏเดฒเตเดเตพ เดเดฑเดเตเดเตเดฎเดคเดฟ เดเตเดฏเตเดฏเตเด.
- CSS เดเดฑเดเตเดเตเดฎเดคเดฟ เดเตเดฏเตเดฏเตเด (เด เดคเดฟเดจเดพเตฝ เดตเตเดฌเตโเดชเดพเดเตเดเดฟเดจเต เด เดต เดเดเตเดเดณเตเดเต CSS เดชเดพเดเตเดเตเดเดฟเตฝ เดเตพเดชเตเดชเตเดเตเดคเตเดคเดพเตป เด เดฑเดฟเดฏเดพเด).
- เดธเดฎเดพเดฐเดเดญเดฟเดเตเดเตเด
connect()
เดธเตเตผเดตเดฑเดฟเดฒเตเดเตเดเต เดเดฐเต เดเดฃเดเตเดทเตป เดธเตเดฅเดพเดชเดฟเดเตเดเดพเดจเตเด เดเดฐเดเดญเดฟเดเตเดเดพเดจเตเดdownloadAssets()
เดเตเดฏเดฟเด เดฑเตเตปเดกเตผ เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเต เดเดตเดถเตเดฏเดฎเดพเดฏ เดเดฟเดคเตเดฐเดเตเดเตพ เดกเตเตบเดฒเตเดกเต เดเตเดฏเตเดฏเดพเตป. - เดเดเตเดเด 3 เดชเตเตผเดคเตเดคเดฟเดฏเดพเดเตเดเดฟเดฏ เดถเตเดทเด เดชเตเดฐเดงเดพเดจ เดฎเตเดจเต เดชเตเดฐเดฆเตผเดถเดฟเดชเตเดชเดฟเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต (
playMenu
). - "เดชเตเดฒเต" เดฌเดเตเดเตบ เดเตเดฒเดฟเดเตเดเต เดนเดพเตปเดกเตเดฒเตผ เดธเดเตเดเตเดเดฐเดฟเดเตเดเตเดจเตเดจเต. เดฌเดเตเดเตบ เด เดฎเตผเดคเตเดคเตเดฎเตเดชเตเตพ, เดเตเดกเต เดเตเดฏเดฟเด เดเดฐเดเดญเดฟเดเตเดเตเดเดฏเตเด เดเดเตเดเตพ เดเดณเดฟเดเตเดเดพเตป เดคเดฏเตเดฏเดพเดฑเดพเดฃเตเดจเตเดจเต เดธเตเตผเดตเดฑเดฟเดจเตเดเต เดชเดฑเดฏเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจเต.
เดเดเตเดเดณเตเดเต เดเตเดฒเดฏเดจเตเดฑเต-เดธเตเตผเดตเตผ เดฒเตเดเดฟเดเตเดเดฟเดจเตเดฑเต เดชเตเดฐเดงเดพเดจ "เดฎเดพเดเดธเด" เดซเดฏเตฝ เดเดฑเดเตเดเตเดฎเดคเดฟ เดเตเดฏเตเดค เดซเดฏเดฒเตเดเดณเดฟเดฒเดพเดฃเต. index.js
. เดเดชเตเดชเตเตพ เดเดเตเดเตพ เด
เดตเดฏเตเดฒเตเดฒเดพเด เดเตเดฐเดฎเดคเตเดคเดฟเตฝ เดจเตเดเตเดเตเด.
4. เดเตเดฒเดฏเดจเตเดฑเต เดกเดพเดฑเตเดฑเดฏเตเดเต เดเตเดฎเดพเดฑเตเดฑเด
เด เดเตเดฏเดฟเดฎเดฟเตฝ เดธเตเตผเดตเดฑเตเดฎเดพเดฏเดฟ เดเดถเดฏเดตเดฟเดจเดฟเดฎเดฏเด เดจเดเดคเตเดคเดพเตป เดเดเตเดเตพ เด
เดฑเดฟเดฏเดชเตเดชเตเดเตเดจเตเดจ เดเดฐเต เดฒเตเดฌเตเดฐเดฑเดฟ เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต
เดเดเตเดเตพเดเตเดเต เดเดฐเต เดซเดฏเตฝ เดเดฃเตเดเดพเดเตเด src/client/networking.js
เดเดฐเต เดชเดฐเดฟเดชเดพเดฒเดฟเดเตเดเตเด เดเดฒเตเดฒเดพเดตเดฐเตเด เดธเตเตผเดตเดฑเตเดฎเดพเดฏเตเดณเตเดณ เดเดถเดฏเดตเดฟเดจเดฟเดฎเดฏเดเตเดเตพ:
networking.js
import io from 'socket.io-client';
import { processGameUpdate } from './state';
const Constants = require('../shared/constants');
const socket = io(`ws://${window.location.host}`);
const connectedPromise = new Promise(resolve => {
socket.on('connect', () => {
console.log('Connected to server!');
resolve();
});
});
export const connect = onGameOver => (
connectedPromise.then(() => {
// Register callbacks
socket.on(Constants.MSG_TYPES.GAME_UPDATE, processGameUpdate);
socket.on(Constants.MSG_TYPES.GAME_OVER, onGameOver);
})
);
export const play = username => {
socket.emit(Constants.MSG_TYPES.JOIN_GAME, username);
};
export const updateDirection = dir => {
socket.emit(Constants.MSG_TYPES.INPUT, dir);
};
เดตเตเดฏเดเตเดคเดคเดฏเตเดเตเดเดพเดฏเดฟ เด เดเตเดกเตเด เดเตเดฑเตเดคเดพเดฏเดฟ เดเตเดฐเตเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต.
เด เดซเดฏเดฒเดฟเตฝ เดชเตเดฐเดงเดพเดจเดฎเดพเดฏเตเด เดฎเตเดจเตเดจเต เดเดพเดฐเตเดฏเดเตเดเดณเดพเดฃเต เดจเดเดเตเดเตเดจเตเดจเดคเต:
- เดเดเตเดเตพ เดธเตเตผเดตเดฑเดฟเดฒเตเดเตเดเต เดเดฃเดเตเดฑเตเดฑเตเดเตเดฏเตเดฏเดพเตป เดถเตเดฐเดฎเดฟเดเตเดเตเดจเตเดจเต.
connectedPromise
เดเดเตเดเตพ เดเดฐเต เดเดฃเดเตเดทเตป เดธเตเดฅเดพเดชเดฟเดเตเดเตเดฎเตเดชเตเตพ เดฎเดพเดคเตเดฐเดฎเต เด เดจเตเดตเดฆเดฟเดเตเดเต. - เดเดฃเดเตเดทเตป เดตเดฟเดเดฏเดเดฐเดฎเดพเดฃเตเดเตเดเดฟเตฝ, เดเดเตเดเตพ เดเตเตพเดฌเดพเดเตเดเต เดชเตเดฐเดตเตผเดคเตเดคเดจเดเตเดเตพ เดฐเดเดฟเดธเตเดฑเตเดฑเตผ เดเตเดฏเตเดฏเตเดจเตเดจเต (
processGameUpdate()
ะธonGameOver()
) เดธเตเตผเดตเดฑเดฟเตฝ เดจเดฟเดจเตเดจเต เดเดเตเดเตพเดเตเดเต เดฒเดญเดฟเดเตเดเตเดเตเดเดพเดตเตเดจเตเดจ เดธเดจเตเดฆเตเดถเดเตเดเตพเดเตเดเต. - เดเดเตเดเตพ เดเดฏเดฑเตเดฑเตเดฎเดคเดฟ เดเตเดฏเตเดฏเตเดจเตเดจเต
play()
ะธupdateDirection()
เด เดคเดฟเดจเดพเตฝ เดฎเดฑเตเดฑเต เดซเดฏเดฒเตเดเตพเดเตเดเต เด เดต เดเดชเดฏเตเดเดฟเดเตเดเดพเดจเดพเดเตเด.
5. เดเตเดฒเดฏเดจเตเดฑเต เดฑเตเตปเดกเดฑเดฟเดเดเต
เดเดฟเดคเตเดฐเด เดธเตเดเตเดฐเตเดจเดฟเตฝ เดชเตเดฐเดฆเตผเดถเดฟเดชเตเดชเดฟเดเตเดเดพเดจเตเดณเตเดณ เดธเดฎเดฏเดฎเดพเดฃเดฟเดคเต!
...เดเดจเตเดจเดพเตฝ เดเดคเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเต เดฎเตเดฎเตเดชเต, เดเดคเดฟเดจเต เดเดตเดถเตเดฏเดฎเดพเดฏ เดเดฒเตเดฒเดพ เดเดฟเดคเตเดฐเดเตเดเดณเตเด (เดตเดฟเดญเดตเดเตเดเตพ) เดกเตเตบเดฒเตเดกเต เดเตเดฏเตเดฏเตเดฃเตเดเดคเตเดฃเตเดเต. เดจเดฎเตเดเตเดเต เดเดฐเต เดฑเดฟเดธเตเดดเตเดธเต เดฎเดพเดจเตเดเตผ เดเดดเตเดคเดพเด:
Assets.js
const ASSET_NAMES = ['ship.svg', 'bullet.svg'];
const assets = {};
const downloadPromise = Promise.all(ASSET_NAMES.map(downloadAsset));
function downloadAsset(assetName) {
return new Promise(resolve => {
const asset = new Image();
asset.onload = () => {
console.log(`Downloaded ${assetName}`);
assets[assetName] = asset;
resolve();
};
asset.src = `/assets/${assetName}`;
});
}
export const downloadAssets = () => downloadPromise;
export const getAsset = assetName => assets[assetName];
เดฑเดฟเดธเตเดดเตเดธเต เดฎเดพเดจเตเดเตเดฎเตเดจเตเดฑเต เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเดพเตป เด
เดคเตเดฐ เดฌเตเดฆเตเดงเดฟเดฎเตเดเตเดเตเดณเตเดณ เดเดพเดฐเตเดฏเดฎเดฒเตเดฒ! เดเดฐเต เดตเดธเตเดคเตเดตเดฟเดจเต เดธเดเดญเดฐเดฟเดเตเดเตเด เดเดจเตเดจเดคเดพเดฃเต เดชเตเดฐเดงเดพเดจ เดเดพเดฐเตเดฏเด assets
, เดเดคเต เดซเดฏเตฝเดจเดพเดฎ เดเตเดฏเต เดเดฌเตเดเดเตเดฑเตเดฑเต เดฎเตเดฒเตเดฏเดตเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเดเตเด Image
. เดเดฑเดตเดฟเดเด เดฒเตเดกเต เดเตเดฏเตเดฏเตเดฎเตเดชเตเตพ, เดเดเตเดเตพ เด
เดคเต เดเดฐเต เดเดฌเตเดเดเตเดฑเตเดฑเดฟเดฒเตเดเตเดเต เดธเดเดฐเดเตเดทเดฟเดเตเดเตเดจเตเดจเต assets
เดญเดพเดตเดฟเดฏเดฟเตฝ เดชเตเดเตเดเตเดจเตเดจเตเดณเตเดณ เดฐเดธเตเดคเดฟเดจเดพเดฏเดฟ. เดเดฐเต เดตเตเดฏเดเตเดคเดฟเดเดค เดเดฑเดตเดฟเดเดคเตเดคเดฟเดจเตเดฑเตเดฏเตเด เดกเตเตบเดฒเตเดกเต เดเดชเตเดชเตเตพ เด
เดจเตเดตเดฆเดฟเดเตเดเตเด (เด
เดคเดพเดฏเดคเต, เดกเตเตบเดฒเตเดกเต เดเตเดฏเตเดฏเตเด เดเดฒเตเดฒเดพเด เดตเดฟเดญเดตเดเตเดเตพ), เดเดเตเดเตพ เด
เดจเตเดตเดฆเดฟเดเตเดเตเดจเตเดจเต downloadPromise
.
เดเดฑเดตเดฟเดเดเตเดเตพ เดกเตเตบเดฒเตเดกเต เดเตเดฏเตเดค เดถเตเดทเด, เดจเดฟเดเตเดเตพเดเตเดเต เดฑเตเตปเดกเดฑเดฟเดเดเต เดเดฐเดเดญเดฟเดเตเดเดพเด. เดจเตเดฐเดคเตเดคเต เดชเดฑเดเตเดเดคเตเดชเตเดฒเต, เดเดเตเดเตพ เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจ เดเดฐเต เดตเตเดฌเต เดชเตเดเดฟเตฝ เดตเดฐเดฏเตเดเตเดเดพเตป <canvas>
). เดเดเตเดเดณเตเดเต เดเตเดฏเดฟเด เดตเดณเดฐเต เดฒเดณเดฟเดคเดฎเดพเดฃเต, เด
เดคเดฟเดจเดพเตฝ เดเดเตเดเตพ เดเดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจเดต เดฎเดพเดคเตเดฐเด เดฑเตเตปเดกเตผ เดเตเดฏเตเดฏเตเดฃเตเดเดคเตเดฃเตเดเต:
- เดชเดถเตเดเดพเดคเตเดคเดฒเด
- เดเดณเดฟเดเตเดเดพเดฐเตป เดเดชเตเดชเตฝ
- เดเดณเดฟเดฏเดฟเดฒเต เดฎเดฑเตเดฑเต เดเดณเดฟเดเตเดเดพเตผ
- เดทเตเดฒเตเดฒเตเดเตพ
เดชเตเดฐเดงเดพเดจเดชเตเดชเตเดเตเด เดธเตโเดจเดฟเดชเตเดชเตเดฑเตเดฑเตเดเตพ เดเดคเดพ src/client/render.js
, เดฎเตเดเดณเดฟเตฝ เดฒเดฟเดธเตเดฑเตเดฑเตเดเตเดฏเตเดคเดฟเดฐเดฟเดเตเดเตเดจเตเดจ เดจเดพเดฒเต เดชเตเดฏเดฟเดจเตเดฑเตเดเตพ เดเตเดคเตเดฏเดฎเดพเดฏเดฟ เดตเดฐเดฏเตเดเตเดเตเดจเตเดจเต:
render.js
import { getAsset } from './assets';
import { getCurrentState } from './state';
const Constants = require('../shared/constants');
const { PLAYER_RADIUS, PLAYER_MAX_HP, BULLET_RADIUS, MAP_SIZE } = Constants;
// Get the canvas graphics context
const canvas = document.getElementById('game-canvas');
const context = canvas.getContext('2d');
// Make the canvas fullscreen
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
function render() {
const { me, others, bullets } = getCurrentState();
if (!me) {
return;
}
// Draw background
renderBackground(me.x, me.y);
// Draw all bullets
bullets.forEach(renderBullet.bind(null, me));
// Draw all players
renderPlayer(me, me);
others.forEach(renderPlayer.bind(null, me));
}
// ... Helper functions here excluded
let renderInterval = null;
export function startRendering() {
renderInterval = setInterval(render, 1000 / 60);
}
export function stopRendering() {
clearInterval(renderInterval);
}
เดตเตเดฏเดเตเดคเดคเดฏเตเดเตเดเดพเดฏเดฟ เด เดเตเดกเตเด เดเตเดฐเตเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต.
render()
เดเดจเตเดจเดคเดพเดฃเต เด เดซเดฏเดฒเดฟเดจเตเดฑเต เดชเตเดฐเดงเดพเดจ เดชเตเดฐเดตเตผเดคเตเดคเดจเด. startRendering()
ะธ stopRendering()
60 FPS-เตฝ เดฑเตเตปเดกเดฑเดฟเดเดเต เดธเตเดเตเดเดฟเดณเดฟเดจเตเดฑเต เดธเดเตเดตเดฎเดพเดเตเดเตฝ เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเด.
เดตเตเดฏเดเตเดคเดฟเดเดค เดฑเตเตปเดกเดฑเดฟเดเดเต เดธเดนเดพเดฏ เดชเตเดฐเดตเตผเดคเตเดคเดจเดเตเดเดณเตเดเต เดชเตเดฐเดคเตเดฏเตเด เดจเดฟเตผเดตเตเดตเดนเดฃเดเตเดเตพ (เดเดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต renderBullet()
) เด
เดคเตเดฐ เดชเตเดฐเดงเดพเดจเดฎเดฒเตเดฒ, เดเดจเตเดจเดพเตฝ เดเดฐเต เดฒเดณเดฟเดคเดฎเดพเดฏ เดเดฆเดพเดนเดฐเดฃเด เดเดคเดพ:
render.js
function renderBullet(me, bullet) {
const { x, y } = bullet;
context.drawImage(
getAsset('bullet.svg'),
canvas.width / 2 + x - me.x - BULLET_RADIUS,
canvas.height / 2 + y - me.y - BULLET_RADIUS,
BULLET_RADIUS * 2,
BULLET_RADIUS * 2,
);
}
เดเดเตเดเตพ เดฐเตเดคเดฟเดฏเดพเดฃเต เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเดคเต เดเดจเตเดจเดคเต เดถเตเดฐเดฆเตเดงเดฟเดเตเดเตเด getAsset()
, เดเดคเดฟเตฝ เดฎเตเดฎเตเดชเต เดเดฃเตเดเดฟเดฐเตเดจเตเดจเต asset.js
!
เดฎเดฑเตเดฑเต เดฑเตเตปเดกเดฑเดฟเดเดเต เดธเดนเดพเดฏ เดชเตเดฐเดตเตผเดคเตเดคเดจเดเตเดเตพ เดชเดฐเตเดฏเดตเตเดเตเดทเดฃเด เดเตเดฏเตเดฏเดพเตป เดจเดฟเดเตเดเตพเดเตเดเต เดคเดพเตฝเดชเตเดชเดฐเตเดฏเดฎเตเดฃเตเดเตเดเตเดเดฟเตฝ, เดฌเดพเดเตเดเดฟเดฏเตเดณเตเดณเดต เดตเดพเดฏเดฟเดเตเดเตเด
src/client/render.js .
6. เดเตเดฒเดฏเดจเตเดฑเต เดเตปเดชเตเดเตเดเต
เดเดฐเต เดเตเดฏเดฟเด เดเดฃเตเดเดพเดเตเดเดพเตป เดธเดฎเดฏเดฎเดพเดฏเดฟ เดเดณเดฟเดเตเดเดพเดตเตเดจเตเดจ! เดจเดฟเดฏเดจเตเดคเตเดฐเดฃ เดธเตเดเตเด เดตเดณเดฐเต เดฒเดณเดฟเดคเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเตเด: เดเดฒเดจเดคเตเดคเดฟเดจเตเดฑเต เดฆเดฟเดถ เดฎเดพเดฑเตเดฑเดพเตป, เดจเดฟเดเตเดเตพเดเตเดเต เดฎเตเดธเต (เดเดฐเต เดเดฎเตเดชเตเดฏเตเดเตเดเดฑเดฟเตฝ) เดเดชเดฏเตเดเดฟเดเตเดเดพเด เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดธเตเดเตเดฐเตเดจเดฟเตฝ เดธเตเดชเตผเดถเดฟเดเตเดเดพเด (เดเดฐเต เดฎเตเดฌเตเตฝ เดเดชเดเดฐเดฃเดคเตเดคเดฟเตฝ). เดเดคเต เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเดพเตป เดเดเตเดเตพ เดฐเดเดฟเดธเตเดฑเตเดฑเตผ เดเตเดฏเตเดฏเตเด
เดเดคเตเดเตเดเต เดถเตเดฐเดฆเตเดงเดฟเดเตเดเตเด src/client/input.js
:
input.js
import { updateDirection } from './networking';
function onMouseInput(e) {
handleInput(e.clientX, e.clientY);
}
function onTouchInput(e) {
const touch = e.touches[0];
handleInput(touch.clientX, touch.clientY);
}
function handleInput(x, y) {
const dir = Math.atan2(x - window.innerWidth / 2, window.innerHeight / 2 - y);
updateDirection(dir);
}
export function startCapturingInput() {
window.addEventListener('mousemove', onMouseInput);
window.addEventListener('touchmove', onTouchInput);
}
export function stopCapturingInput() {
window.removeEventListener('mousemove', onMouseInput);
window.removeEventListener('touchmove', onTouchInput);
}
onMouseInput()
ะธ onTouchInput()
เดตเดฟเดณเดฟเดเตเดเตเดจเตเดจ เดเดตเดจเตเดฑเต เดถเตเดฐเตเดคเดพเดเตเดเดณเดพเดฃเต updateDirection()
(เดจเดฟเดจเตเดจเต networking.js
) เดเดฐเต เดเตปเดชเตเดเตเดเต เดเดตเดจเตเดฑเต เดธเดเดญเดตเดฟเดเตเดเตเดฎเตเดชเตเตพ (เดเดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เดฎเตเดธเต เดจเตเดเตเดเตเดฎเตเดชเตเตพ). updateDirection()
เดเตปเดชเตเดเตเดเต เดเดตเดจเตเดฑเต เดชเตเดฐเตเดธเดธเตเดธเต เดเตเดฏเตเดฏเตเดเดฏเตเด เด
เดคเดฟเดจเดจเตเดธเดฐเดฟเดเตเดเต เดเตเดฏเดฟเด เด
เดตเดธเตเดฅ เด
เดชเตโเดกเตเดฑเตเดฑเต เดเตเดฏเตเดฏเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจ เดธเตเตผเดตเดฑเตเดฎเดพเดฏเตเดณเตเดณ เดธเดจเตเดฆเตเดถเดเตเดเดณเตเดเต เดเตเดฎเดพเดฑเตเดฑเด เดเตเดเดพเดฐเตเดฏเด เดเตเดฏเตเดฏเตเดจเตเดจเต.
7. เดเตเดฒเดฏเดจเตเดฑเต เดจเดฟเดฒ
เด เดตเดฟเดญเดพเดเดฎเดพเดฃเต เดชเตเดธเตเดฑเตเดฑเดฟเดจเตเดฑเต เดเดฆเตเดฏ เดญเดพเดเดคเตเดคเดฟเตฝ เดเดฑเตเดฑเดตเตเด เดฌเตเดฆเตเดงเดฟเดฎเตเดเตเดเตเดณเตเดณเดคเต. เดเดฆเตเดฏเดฎเดพเดฏเดฟ เดตเดพเดฏเดฟเดเตเดเตเดฎเตเดชเตเตพ เดคเดจเตเดจเต เดฎเดจเดธเดฟเดฒเดพเดฏเดฟเดฒเตเดฒเตเดเตเดเดฟเตฝ เดจเดฟเดฐเดพเดถเดชเตเดชเตเดเดฐเตเดคเต! เดจเดฟเดเตเดเตพเดเตเดเต เด เดคเต เดเดดเดฟเดตเดพเดเตเดเดพเดจเตเด เดชเดฟเดจเตเดจเตเดเต เดเดคเดฟเดฒเตเดเตเดเต เดฎเดเดเตเดเดพเดจเตเด เดเดดเดฟเดฏเตเด.
เดเตเดฒเดฏเดจเตเดฑเต-เดธเตเตผเดตเตผ เดเตเดกเต เดชเตเตผเดคเตเดคเดฟเดฏเดพเดเตเดเดพเตป เดเดตเดถเตเดฏเดฎเดพเดฏ เดชเดธเดฟเดฒเดฟเดจเตเดฑเต เด เดตเดธเดพเดจ เดญเดพเดเดฎเดพเดฃเต เดธเดเดธเตเดฅเดพเดจเด. เดเตเดฒเดฏเดจเตเดฑเต เดฑเตเตปเดกเดฑเดฟเดเดเต เดตเดฟเดญเดพเดเดคเตเดคเดฟเตฝ เดจเดฟเดจเตเดจเตเดณเตเดณ เดเตเดกเต เดธเตเดจเดฟเดชเตเดชเดฑเตเดฑเต เดเตผเดเตเดเตเดจเตเดจเตเดฃเตเดเต?
render.js
import { getCurrentState } from './state';
function render() {
const { me, others, bullets } = getCurrentState();
// Do the rendering
// ...
}
getCurrentState()
เดเตเดฒเดฏเดจเตเดฑเดฟเดฒเตเดณเตเดณ เดจเดฟเดฒเดตเดฟเดฒเต เดเตเดฏเดฟเด เดจเดฟเดฒ เดเดเตเดเตพเดเตเดเต เดจเตฝเดเดพเตป เดเดดเดฟเดฏเดฃเด เดเดคเต เดธเดฎเดฏเดคเตเดคเตเด เดธเตเตผเดตเดฑเดฟเตฝ เดจเดฟเดจเตเดจเต เดฒเดญเดฟเดเตเด เด
เดชเตโเดกเตเดฑเตเดฑเตเดเดณเต เด
เดเดฟเดธเตเดฅเดพเดจเดฎเดพเดเตเดเดฟ. เดธเตเตผเดตเตผ เด
เดฏเดเตเดเตเดเตเดเดพเดตเตเดจเตเดจ เดเตเดฏเดฟเด เด
เดชเตโเดกเตเดฑเตเดฑเดฟเดจเตเดฑเต เดเดฐเต เดเดฆเดพเดนเดฐเดฃเด เดเดคเดพ:
{
"t": 1555960373725,
"me": {
"x": 2213.8050880413657,
"y": 1469.370893425012,
"direction": 1.3082443894581433,
"id": "AhzgAtklgo2FJvwWAADO",
"hp": 100
},
"others": [],
"bullets": [
{
"id": "RUJfJ8Y18n",
"x": 2354.029197099604,
"y": 1431.6848318262666
},
{
"id": "ctg5rht5s",
"x": 2260.546457727445,
"y": 1456.8088728920968
}
],
"leaderboard": [
{
"username": "Player",
"score": 3
}
]
}
เดเดฐเต เดเตเดฏเดฟเด เด เดชเตโเดกเตเดฑเตเดฑเดฟเดฒเตเด เดธเดฎเดพเดจเดฎเดพเดฏ เด เดเตเดเต เดซเตเตฝเดกเตเดเตพ เด เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต:
- t: เด เด เดชเตโเดกเตเดฑเตเดฑเต เดเดชเตเดชเตเดดเดพเดฃเต เดธเตเดทเตโเดเดฟเดเตเดเดคเตเดจเตเดจเต เดธเตเดเดฟเดชเตเดชเดฟเดเตเดเตเดจเตเดจ เดธเตเตผเดตเตผ เดเตเดเดธเตเดฑเตเดฑเดพเดฎเตเดชเต.
- me: เด เด เดชเตโเดกเตเดฑเตเดฑเต เดฒเดญเดฟเดเตเดเตเดจเตเดจ เดเดณเดฟเดเตเดเดพเดฐเดจเตเดเตเดเตเดฑเดฟเดเตเดเตเดณเตเดณ เดตเดฟเดตเดฐเดเตเดเตพ.
- เดฎเดฑเตเดฑเตเดณเตเดณเดตเดฐเต: เดเดฐเต เดเตเดฏเดฟเดฎเดฟเตฝ เดชเดเตเดเตเดเตเดเตเดเตเดจเตเดจ เดฎเดฑเตเดฑเต เดเดณเดฟเดเตเดเดพเดฐเตเดเตเดเตเดฑเดฟเดเตเดเตเดณเตเดณ เดตเดฟเดตเดฐเดเตเดเดณเตเดเต เดเดฐเต เดจเดฟเดฐ.
- เดฌเตเดณเตเดณเดฑเตเดฑเตเดเตพ: เดเตเดฏเดฟเดฎเดฟเดฒเต เดชเตเดฐเตเดเดเตโเดเตเดฒเตเดเดณเตเดเตเดเตเดฑเดฟเดเตเดเตเดณเตเดณ เดตเดฟเดตเดฐเดเตเดเดณเตเดเต เดเดฐเต เดจเดฟเดฐ.
- เดฒเตเดกเตผเดฌเตเตผเดกเต: เดจเดฟเดฒเดตเดฟเดฒเต เดฒเตเดกเตผเดฌเตเตผเดกเต เดกเดพเดฑเตเดฑ. เด เดชเตเดธเตเดฑเตเดฑเดฟเตฝ เดเดเตเดเตพ เด เดต เดเดฃเดเตเดเดฟเดฒเตเดเตเดเตเดเดฟเดฒเตเดฒ.
7.1 เดเดชเดญเตเดเตเดคเดพเดตเดฟเดจเตเดฑเต เดจเดฟเดทเตเดเดณเดเตเดเดฎเดพเดฏ เด เดตเดธเตเดฅ
เดจเดฟเดทเตเดเดณเดเตเดเดฎเดพเดฏ เดจเดเดชเตเดชเดพเดเตเดเตฝ getCurrentState()
เด
เดเตเดคเตเดคเดฟเดเต เดฒเดญเดฟเดเตเด เดเตเดฏเดฟเด เด
เดชเตโเดกเตเดฑเตเดฑเดฟเตฝ เดจเดฟเดจเตเดจเตเดณเตเดณ เดกเดพเดฑเตเดฑ เดฎเดพเดคเตเดฐเดฎเต เดจเตเดฐเดฟเดเตเดเต เดจเตฝเดเดพเดจเดพเดตเต.
naive-state.js
let lastGameUpdate = null;
// Handle a newly received game update.
export function processGameUpdate(update) {
lastGameUpdate = update;
}
export function getCurrentState() {
return lastGameUpdate;
}
เดฎเดจเตเดนเดฐเดตเตเด เดตเตเดฏเดเตเดคเดตเตเด! เดเดจเตเดจเดพเตฝ เด เดคเต เดตเดณเดฐเต เดฒเดณเดฟเดคเดฎเดพเดฏเดฟเดฐเตเดจเตเดจเตเดเตเดเดฟเตฝ. เด เดจเดเดชเตเดชเดพเดเตเดเตฝ เดชเตเดฐเดถเตเดจเดฎเดพเดเดพเดจเตเดณเตเดณ เดเดฐเต เดเดพเดฐเดฃเด: เดเดคเต เดฑเตเตปเดกเดฑเดฟเดเดเต เดซเตเดฐเตเดฏเดฟเด เดฑเตเดฑเตเดฑเต เดธเตเตผเดตเตผ เดเตเดฒเตเดเตเดเต เดธเตเดชเตเดกเดฟเดฒเตเดเตเดเต เดชเดฐเดฟเดฎเดฟเดคเดชเตเดชเตเดเตเดคเตเดคเตเดจเตเดจเต.
เดซเตเดฐเตเดฏเดฟเด เดฑเตเดฑเตเดฑเต: เดซเตเดฐเตเดฏเดฟเดฎเตเดเดณเตเดเต เดเดฃเตเดฃเด (เด เดคเดพเดฏเดคเต เดเตเดณเตเดเตพ
render()
) เดธเตเดเตเดเตปเดกเดฟเตฝ, เด เดฒเตเดฒเตเดเตเดเดฟเตฝ FPS. เดเตเดฏเดฟเดฎเตเดเตพ เดธเดพเดงเดพเดฐเดฃเดฏเดพเดฏเดฟ เดเตเดฑเดเตเดเดคเต 60 FPS เดเดเตเดเดฟเดฒเตเด เดจเตเดเดพเตป เดถเตเดฐเดฎเดฟเดเตเดเตเดจเตเดจเต.
เดเดฟเดเตเดเต เดจเดฟเดฐเดเตเดเต: เดธเตเตผเดตเตผ เดเตเดฒเดฏเดจเตเดฑเตเดเตพเดเตเดเต เดเตเดฏเดฟเด เด เดชเตโเดกเตเดฑเตเดฑเตเดเตพ เด เดฏเดฏเตโเดเตเดเตเดจเตเดจ เดเดตเตเดคเตเดคเดฟ. เดเดคเต เดชเดฒเดชเตเดชเตเดดเตเด เดซเตเดฐเตเดฏเดฟเด เดฑเตเดฑเตเดฑเดฟเดจเตเดเตเดเดพเตพ เดเตเดฑเดตเดพเดฃเต. เดเดเตเดเดณเตเดเต เดเตเดฏเดฟเดฎเดฟเตฝ, เดธเตเตผเดตเตผ เดธเตเดเตเดเตปเดกเดฟเตฝ 30 เดเดฟเดเตเดเตเดเดณเดฟเตฝ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดจเตเดจเต.
เดเดเตเดเตพ เดเดฑเตเดฑเดตเตเด เดชเตเดคเดฟเดฏ เดเตเดฏเดฟเด เด
เดชเตโเดกเตเดฑเตเดฑเต เดฑเตเตปเดกเตผ เดเตเดฏเตเดฏเตเดเดฏเดพเดฃเตเดเตเดเดฟเตฝ, FPS-เดจเต เดเดฐเดฟเดเตเดเดฒเตเด 30 เดเดตเดฟเดฏเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ เดธเตเตผเดตเดฑเดฟเตฝ เดจเดฟเดจเตเดจเต เดธเตเดเตเดเตปเดกเดฟเตฝ 30-เตฝ เดเตเดเตเดคเตฝ เด
เดชเตโเดกเตเดฑเตเดฑเตเดเตพ เดเดเตเดเตพเดเตเดเต เดเดฐเดฟเดเตเดเดฒเตเด เดฒเดญเดฟเดเตเดเดฟเดฒเตเดฒ. เดจเดฎเตเดฎเตพ เดตเดฟเดณเดฟเดเตเดเดพเดฒเตเด render()
เดธเตเดเตเดเตปเดกเดฟเตฝ 60 เดคเดตเดฃ, เด เดเตเดณเตเดเดณเดฟเตฝ เดชเดเตเดคเดฟเดฏเตเด เด
เดคเต เดเดพเดฐเตเดฏเด เดตเตเดฃเตเดเตเด เดตเดฐเดฏเตเดเตเดเตเด, เด
เดเดฟเดธเตเดฅเดพเดจเดชเดฐเดฎเดพเดฏเดฟ เดเดจเตเดจเตเด เดเตเดฏเตเดฏเดฟเดฒเตเดฒ. เดจเดฟเดทเตเดเดณเดเตเดเดฎเดพเดฏ เดจเดเดชเตเดชเดพเดเตเดเดฒเดฟเดจเตเดฑเต เดฎเดฑเตเดฑเตเดฐเต เดชเตเดฐเดถเตโเดจเดฎเดพเดฃเต เด
เดคเต เดเดพเดฒเดคเดพเดฎเดธเดคเตเดคเดฟเดจเต เดตเดฟเดงเตเดฏเดฎเดพเดฃเต. เด
เดจเตเดฏเตเดเตเดฏเดฎเดพเดฏ เดเดจเตเดฑเตผเดจเตเดฑเตเดฑเต เดตเตเดเดคเดฏเดฟเตฝ, เดเตเดฒเดฏเดจเตเดฑเดฟเดจเต เดเดฐเต 33 เดเดเดเดธเดฟเดฒเตเด (เดธเตเดเตเดเตปเดกเดฟเตฝ 30) เดเดฐเต เดเตเดฏเดฟเด เด
เดชเตโเดกเตเดฑเตเดฑเต เดฒเดญเดฟเดเตเดเตเด:
เดจเดฟเตผเดญเดพเดเตเดฏเดตเดถเดพเตฝ, เดเดจเตเดจเตเด เดคเดฟเดเดเตเดเดคเดฒเตเดฒ. เดเตเดเตเดคเตฝ เดฑเดฟเดฏเดฒเดฟเดธเตเดฑเตเดฑเดฟเดเต เดเดฟเดคเตเดฐเด เดเดคเดพเดฏเดฟเดฐเดฟเดเตเดเตเด:
เดเดพเดฒเดคเดพเดฎเดธเด เดตเดฐเตเดฎเตเดชเตเตพ เดจเดฟเดทเตเดเดณเดเตเดเดฎเดพเดฏ เดจเดเดชเตเดชเดพเดเตเดเตฝ เดเดฑเตเดฑเดตเตเด เดฎเตเดถเด เด
เดตเดธเตเดฅเดฏเดพเดฃเต. 50ms เดเดพเดฒเดคเดพเดฎเดธเดคเตเดคเตเดเต เดเดฐเต เดเตเดฏเดฟเด เด
เดชเตโเดกเตเดฑเตเดฑเต เดฒเดญเดฟเดเตเดเตเดเดฏเดพเดฃเตเดเตเดเดฟเตฝ, เดคเตเดเตผเดจเตเดจเต เดเตเดฒเดฏเดจเตเดฑเต เดฎเดจเตเดฆเดเดคเดฟเดฏเดฟเดฒเดพเดฏเดฟ เดฎเตเดฎเตเดชเดคเตเดคเต เด
เดชเตโเดกเตเดฑเตเดฑเดฟเตฝ เดจเดฟเดจเตเดจเต เดเตเดฏเดฟเด เดจเดฟเดฒ เดเดชเตเดชเตเดดเตเด เดฑเตเตปเดกเตผ เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเดพเตฝ เด
เดงเดฟเด 50ms. เดเดณเดฟเดเตเดเดพเดฐเดจเต เดเดคเต เดเดคเตเดฐเดคเตเดคเตเดณเด เด
เดธเตเดเดฐเตเดฏเดฎเดพเดฃเตเดจเตเดจเต เดจเดฟเดเตเดเตพเดเตเดเต เดเดนเดฟเดเตเดเดพเดตเตเดจเตเดจเดคเดพเดฃเต: เดเดเดชเดเตเดทเตเดฏเดฎเดพเดฏ เดฎเดพเดจเตเดฆเตเดฏเด เดเดพเดฐเดฃเด, เดเตเดฏเดฟเด เดเตเดเตเดเดฟเดเตเดเตเดจเตเดจเดคเตเด เด
เดธเตเดฅเดฟเดฐเดตเตเดฎเดพเดฃเตเดจเตเดจเต เดคเตเดจเตเดจเตเด.
7.2 เดฎเตเดเตเดเดชเตเดชเตเดเตเด เดเตเดฒเดฏเดจเตเดฑเต เดจเดฟเดฒ
เดจเดฟเดทเตเดเดณเดเตเดเดฎเดพเดฏ เดจเดเดชเตเดชเดพเดเตเดเดฒเดฟเตฝ เดเดเตเดเตพ เดเดฟเดฒ เดฎเตเดเตเดเดชเตเดชเตเดเตเดคเตเดคเดฒเตเดเตพ เดจเดเดคเตเดคเตเด. เดเดจเตเดจเดพเดฎเดคเดพเดฏเดฟ, เดเดเตเดเตพ เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต เดฑเตเตปเดกเดฑเดฟเดเดเต เดเดพเดฒเดคเดพเดฎเดธเด 100 เดเด.เดเดธเต. เดเดคเดฟเดจเตผเดคเตเดฅเด เดเตเดฒเดฏเดจเตเดฑเดฟเตปเดฑเต "เดจเดฟเดฒเดตเดฟเดฒเต" เดจเดฟเดฒ เดเดชเตเดชเตเดดเตเด เดธเตเตผเดตเดฑเดฟเดฒเต เดเตเดฏเดฟเด เดจเดฟเดฒเดฏเตเดเตเดเดพเตพ 100เดฎเดฟ.เดเดธเต เดชเดฟเดจเตเดจเดฟเดฒเดพเดฏเดฟเดฐเดฟเดเตเดเตเด. เดเดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เดธเตเตผเดตเตผ เดธเดฎเดฏเด เดเดฃเตเดเตเดเดฟเตฝ 150, เด เดชเตเดชเตเตพ เดเตเดฒเดฏเดจเตเดฑเต เด เดธเดฎเดฏเดคเตเดคเต เดธเตเตผเดตเตผ เดเดฃเตเดเดพเดฏเดฟเดฐเตเดจเตเดจ เด เดตเดธเตเดฅเดฏเต เดฑเตเตปเดกเตผ เดเตเดฏเตเดฏเตเด 50:
เดเตเดฏเดฟเด เด
เดชเตโเดกเตเดฑเตเดฑเตเดเดณเตเดเต เดชเตเดฐเดตเดเดจเดพเดคเตเดคเดฎเดพเดฏ เดธเดฎเดฏเดคเตเดคเต เด
เดคเดฟเดเตเดตเดฟเดเตเดเดพเตป เดเดคเต เดเดเตเดเตพเดเตเดเต 100ms เดฌเดซเตผ เดจเตฝเดเตเดจเตเดจเต:
เดเดคเดฟเดจเตเดณเตเดณ เดตเดฟเดฒ เดธเตเดฅเดฟเดฐเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเตเด
เดเดจเตเดจเต เดตเดฟเดณเดฟเดเตเดเดชเตเดชเตเดเตเดจเตเดจ เดฎเดฑเตเดฑเตเดฐเต เดธเดพเดเตเดเตเดคเดฟเดเดค เดจเดฎเตเดเตเดเต เดเดชเดฏเตเดเดฟเดเตเดเดพเด
"เดเตเดฒเดฏเดจเตเดฑเต-เดธเตเดกเต เดชเตเดฐเดตเดเดจเด" , เดฎเดจเดธเตเดธเดฟเดฒเดพเดเตเดเดฟเดฏ เดเดพเดฒเดคเดพเดฎเดธเด เดเตเดฑเดฏเตเดเตเดเตเดจเตเดจเดคเดฟเดจเต เดเดคเต เดเดฐเต เดจเดฒเตเดฒ เดเตเดฒเดฟ เดเตเดฏเตเดฏเตเดจเตเดจเต, เดเดจเตเดจเดพเตฝ เด เดชเตเดธเตเดฑเตเดฑเดฟเตฝ เดเตผเดเตเด เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฒเตเดฒ.
เดเดเตเดเตพ เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจ เดฎเดฑเตเดฑเตเดฐเต เดฎเตเดเตเดเดชเตเดชเตเดเตเดคเตเดคเตฝ เดฒเตเดจเดฟเดฏเตผ เดเดจเตเดฑเตผเดชเตเดณเตเดทเตป. เดฑเตเตปเดกเดฑเดฟเดเดเต เดเดพเดฒเดคเดพเดฎเดธเด เดเดพเดฐเดฃเด, เดเดเตเดเตพ เดธเดพเดงเดพเดฐเดฃเดฏเดพเดฏเดฟ เดเตเดฒเดฏเดจเตเดฑเดฟเดฒเตเดณเตเดณ เดจเดฟเดฒเดตเดฟเดฒเต เดธเดฎเดฏเดคเตเดคเตเดเตเดเดพเตพ เดเดฐเต เด
เดชเตโเดกเตเดฑเตเดฑเตเดเตเดเดฟเดฒเตเด เดฎเตเดจเตเดจเดฟเดฒเดพเดฃเต. เดตเดฟเดณเดฟเดเตเดเดชเตเดชเตเตพ getCurrentState()
, เดจเดฎเตเดเตเดเต เดจเดฟเดฑเดตเตเดฑเตเดฑเดพเด
เดเดคเต เดซเตเดฐเตเดฏเดฟเด เดฑเตเดฑเตเดฑเต เดชเตเดฐเดถเตเดจเด เดชเดฐเดฟเดนเดฐเดฟเดเตเดเตเดจเตเดจเต: เดเดชเตเดชเตเตพ เดจเดฎเตเดเตเดเต เดเดตเดถเตเดฏเดฎเตเดณเตเดณ เดเดคเต เดซเตเดฐเตเดฏเดฟเด เดฑเตเดฑเตเดฑเดฟเดฒเตเด เดคเดจเดคเดพเดฏ เดซเตเดฐเตเดฏเดฟเดฎเตเดเตพ เดฑเตเตปเดกเตผ เดเตเดฏเตเดฏเดพเด!
7.3 เดฎเตเดเตเดเดชเตเดชเตเดเตเด เดเดฐเต เดเตเดฒเดฏเดจเตเดฑเต เด เดตเดธเตเดฅ เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเตเดจเตเดจเต
เดเดฆเดพเดนเดฐเดฃเด เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเตฝ src/client/state.js
เดฑเตเตปเดกเดฑเดฟเดเดเต เดเดพเดฒเดคเดพเดฎเดธเดตเตเด เดฒเตเดจเดฟเดฏเตผ เดเดจเตเดฑเตผเดชเตเดณเตเดทเดจเตเด เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต, เดชเดเตเดทเต เดเดคเต เด
เดงเดฟเดเดเดพเดฒเด เดจเดฟเดฒเดจเดฟเตฝเดเตเดเดฟเดฒเตเดฒ. เดจเดฎเตเดเตเดเต เดเตเดกเต เดฐเดฃเตเดเต เดญเดพเดเดเตเดเดณเดพเดฏเดฟ เดตเดฟเดญเดเดฟเดเตเดเดพเด. เดเดฆเตเดฏเดคเตเดคเตเดคเต เดเดคเดพ:
state.js, เดญเดพเดเด 1
const RENDER_DELAY = 100;
const gameUpdates = [];
let gameStart = 0;
let firstServerTimestamp = 0;
export function initState() {
gameStart = 0;
firstServerTimestamp = 0;
}
export function processGameUpdate(update) {
if (!firstServerTimestamp) {
firstServerTimestamp = update.t;
gameStart = Date.now();
}
gameUpdates.push(update);
// Keep only one game update before the current server time
const base = getBaseUpdate();
if (base > 0) {
gameUpdates.splice(0, base);
}
}
function currentServerTime() {
return firstServerTimestamp + (Date.now() - gameStart) - RENDER_DELAY;
}
// Returns the index of the base update, the first game update before
// current server time, or -1 if N/A.
function getBaseUpdate() {
const serverTime = currentServerTime();
for (let i = gameUpdates.length - 1; i >= 0; i--) {
if (gameUpdates[i].t <= serverTime) {
return i;
}
}
return -1;
}
เดจเดฟเดเตเดเตพ เดเดฆเตเดฏเด เดเตเดฏเตเดฏเตเดฃเตเดเดคเต เด
เดคเต เดเดจเตเดคเดพเดฃเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเตเดจเตเดจเต เดเดฃเตเดเตเดคเตเดคเตเด เดเดจเตเดจเดคเดพเดฃเต currentServerTime()
. เดเดเตเดเตพ เดจเตเดฐเดคเตเดคเต เดเดฃเตเดเดคเตเดชเตเดฒเต, เดเดฐเต เดเตเดฏเดฟเด เด
เดชเตโเดกเตเดฑเตเดฑเดฟเดฒเตเด เดเดฐเต เดธเตเตผเดตเตผ เดเตเดเดธเตเดฑเตเดฑเดพเดฎเตเดชเต เดเตพเดชเตเดชเตเดเตเดจเตเดจเต. เดธเตเตผเดตเดฑเดฟเดจเต เดชเดฟเดจเตเดจเดฟเตฝ 100เดฎเดฟ.เดธเดฟ เด
เดเดฒเต เดเดฟเดคเตเดฐเด เดฑเตเตปเดกเตผ เดเตเดฏเตเดฏเดพเตป เดฑเตเตปเดกเตผ เดฒเตเดฑเตเดฑเตปเดธเดฟ เดเดชเดฏเตเดเดฟเดเตเดเดพเตป เดเดเตเดเตพ เดเดเตเดฐเดนเดฟเดเตเดเตเดจเตเดจเต, เดชเดเตเดทเต เดธเตเตผเดตเดฑเดฟเดฒเต เดจเดฟเดฒเดตเดฟเดฒเต เดธเดฎเดฏเด เดเดเตเดเตพ เดเดฐเดฟเดเตเดเดฒเตเด เด
เดฑเดฟเดฏเตเดเดฏเดฟเดฒเตเดฒ, เดเดพเดฐเดฃเด เดเดคเตเดเตเดเดฟเดฒเตเด เด
เดชเตโเดกเตเดฑเตเดฑเตเดเตพ เดเดเตเดเดณเดฟเดฒเตเดเตเดเต เดเดคเตเดคเดพเตป เดเดคเตเดฐ เดธเดฎเดฏเดฎเตเดเตเดคเตเดคเตเดตเตเดจเตเดจเต เดเดเตเดเตพเดเตเดเต เด
เดฑเดฟเดฏเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ. เดเดจเตเดฑเตผเดจเตเดฑเตเดฑเต เดชเตเดฐเดตเดเดจเดพเดคเตเดคเดฎเดพเดฃเต, เด
เดคเดฟเดจเตเดฑเต เดตเตเดเดค เดตเดณเดฐเตเดฏเดงเดฟเดเด เดตเตเดฏเดคเตเดฏเดพเดธเดชเตเดชเตเดเดพเด!
เด เดชเตเดฐเดถเตเดจเด เดชเดฐเดฟเดนเดฐเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเต, เดจเดฎเตเดเตเดเต เดจเตเดฏเดพเดฏเดฎเดพเดฏ เดเดฐเต เดเดเดฆเตเดถเด เดเดชเดฏเตเดเดฟเดเตเดเดพเด: เดเดเตเดเตพ เดเดฆเตเดฏเดคเตเดคเต เด
เดชเตโเดกเตเดฑเตเดฑเต เดคเตฝเดเตเดทเดฃเด เดตเดจเตเดจเดคเดพเดฏเดฟ เดจเดเดฟเดเตเดเดพเด. เดเดคเต เดถเดฐเดฟเดฏเดพเดฃเตเดเตเดเดฟเตฝ, เด เดชเตเดฐเดคเตเดฏเตเด เดจเดฟเดฎเดฟเดทเดคเตเดคเดฟเตฝ เดจเดฎเตเดเตเดเต เดธเตเตผเดตเตผ เดธเดฎเดฏเด เด
เดฑเดฟเดฏเดพเดฎเดพเดฏเดฟเดฐเตเดจเตเดจเต! เดเดเตเดเตพ เดธเตเตผเดตเตผ เดเตเดเดธเตเดฑเตเดฑเดพเดฎเตเดชเต เดธเดเดญเดฐเดฟเดเตเดเตเดจเตเดจเต firstServerTimestamp
เดจเดฎเตเดฎเตเดเต เดฐเดเตเดทเดฟเดเตเดเตเด เดชเตเดฐเดพเดฆเตเดถเดฟเดเดฎเดพเดฏ (เดเตเดฒเดฏเดจเตเดฑเต) เดเตเดเดธเตเดฑเตเดฑเดพเดฎเตเดชเต เด
เดคเต เดจเดฟเดฎเดฟเดทเดคเตเดคเดฟเตฝ gameStart
.
เด, เดเดฐเต เดจเดฟเดฎเดฟเดทเด. เดธเตเตผเดตเดฑเดฟเตฝ เดธเดฎเดฏเด เดเดฃเตเดเดพเดเตเดฃเตเดเดคเดฒเตเดฒเต = เดเตเดฒเดฏเดจเตเดฑเดฟเดฒเตเดณเตเดณ เดธเดฎเดฏเด? เดเดจเตเดคเตเดเตเดฃเตเดเดพเดฃเต เดเดเตเดเตพ "เดธเตเตผเดตเตผ เดเตเดเดธเตเดฑเตเดฑเดพเดฎเตเดชเต", "เดเตเดฒเดฏเดจเตเดฑเต เดเตเดเดธเตเดฑเตเดฑเดพเดฎเตเดชเต" เดเดจเตเดจเดฟเดต เดคเดฎเตเดฎเดฟเตฝ เดตเตเตผเดคเดฟเดฐเดฟเดเตเดเตเดจเตเดจเดคเต? เดเดคเตเดฐเต เดตเดฒเดฟเดฏ เดเตเดฆเตเดฏเดฎเดพเดฃเต! เดเดต เดเดฐเต เดเดพเดฐเตเดฏเดฎเดฒเตเดฒเตเดจเตเดจเต เดเดคเต เดฎเดพเดฑเตเดจเตเดจเต. Date.now()
เดเตเดฒเดฏเดจเตเดฑเดฟเดฒเตเด เดธเตเตผเดตเดฑเดฟเดฒเตเด เดตเตเดฏเดคเตเดฏเดธเตโเดค เดเตเดเดธเตเดฑเตเดฑเดพเดฎเตเดชเตเดเตพ เดคเดฟเดฐเดฟเดเต เดจเตฝเดเตเด, เดเดคเต เด เดฎเตเดทเตเดจเตเดเดณเตเดเต เดชเตเดฐเดพเดฆเตเดถเดฟเด เดเดเดเดเตเดเดณเต เดเดถเตเดฐเดฏเดฟเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต. เดเดฒเตเดฒเดพ เดฎเตเดทเตเดจเตเดเดณเดฟเดฒเตเด เดเตเดเดธเตเดฑเตเดฑเดพเดฎเตเดชเตเดเตพ เดเดฐเตเดชเตเดฒเตเดฏเดพเดฏเดฟเดฐเดฟเดเตเดเตเดฎเตเดจเตเดจเต เดเดฐเดฟเดเตเดเดฒเตเด เดเดฐเตเดคเดฐเตเดคเต.
เด
เดคเต เดเดจเตเดคเดพเดฃเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเตเดจเตเดจเต เดเดชเตเดชเตเตพ เดเดเตเดเตพ เดฎเดจเดธเตเดธเดฟเดฒเดพเดเตเดเตเดจเตเดจเต currentServerTime()
: เด
เดคเต เดคเดฟเดฐเดฟเดเต เดตเดฐเตเดจเตเดจเต เดจเดฟเดฒเดตเดฟเดฒเต เดฑเตเตปเดกเดฑเดฟเดเดเต เดธเดฎเดฏเดคเตเดคเดฟเดจเตเดฑเต เดธเตเตผเดตเตผ เดเตเดเดธเตเดฑเตเดฑเดพเดฎเตเดชเต. เดฎเดฑเตเดฑเตเดฐเต เดตเดฟเดงเดคเตเดคเดฟเตฝ เดชเดฑเดเตเดเดพเตฝ, เดเดคเดพเดฃเต เดจเดฟเดฒเดตเดฟเดฒเต เดธเตเตผเดตเตผ เดธเดฎเดฏเด (firstServerTimestamp <+ (Date.now() - gameStart)
เดฑเตเตปเดกเดฑเดฟเดเดเต เดเดพเดฒเดคเดพเดฎเดธเด เดฎเตเดจเดธเต (RENDER_DELAY
).
เดเตเดฏเดฟเด เด
เดชเตโเดกเตเดฑเตเดฑเตเดเตพ เดเดเตเดเดจเต เดเตเดเดพเดฐเตเดฏเด เดเตเดฏเตเดฏเตเดจเตเดจเต เดเดจเตเดจเต เดจเตเดเตเดเดพเด. เดธเตเตผเดตเดฑเดฟเตฝ เดจเดฟเดจเตเดจเต เดเดฐเต เด
เดชเตโเดกเตเดฑเตเดฑเต เดฒเดญเดฟเดเตเดเตเดฎเตเดชเตเตพ, เด
เดคเดฟเดจเต เดตเดฟเดณเดฟเดเตเดเตเดจเตเดจเต processGameUpdate()
, เดเดเตเดเตพ เดชเตเดคเดฟเดฏ เด
เดชเตโเดกเตเดฑเตเดฑเต เดเดฐเต เด
เดฑเตเดฏเดฟเดฒเตเดเตเดเต เดธเดเดฐเดเตเดทเดฟเดเตเดเตเดจเตเดจเต gameUpdates
. เดคเตเดเตผเดจเตเดจเต, เดฎเตเดฎเตเดฎเดฑเดฟ เดเดชเดฏเตเดเด เดชเดฐเดฟเดถเตเดงเดฟเดเตเดเดพเตป, เดเดเตเดเตพ เดชเดดเดฏ เด
เดชเตเดกเตเดฑเตเดฑเตเดเดณเตเดฒเตเดฒเดพเด เดจเตเดเตเดเด เดเตเดฏเตเดฏเตเดจเตเดจเต เด
เดเดฟเดธเตเดฅเดพเดจ เด
เดชเตเดกเตเดฑเตเดฑเตเดเดพเดฐเดฃเด เดจเดฎเตเดเตเดเต เด
เดตเดฐเต เดเดจเดฟ เดเดตเดถเตเดฏเดฎเดฟเดฒเตเดฒ.
เดเดจเตเดคเดพเดฃเต "เดเตเตผ เด เดชเตเดกเตเดฑเตเดฑเต"? เด เดจเดฟเดฒเดตเดฟเดฒเต เดธเตเตผเดตเตผ เดธเดฎเดฏเดคเตเดคเดฟเตฝ เดจเดฟเดจเตเดจเต เดชเดฟเดจเตเดจเดฟเดฒเตเดเตเดเต เดจเตเดเตเดเดฟเดเตเดเตเดฃเตเดเต เดเดเตเดเตพ เดเดฃเตเดเตเดคเตเดคเตเดจเตเดจ เดเดฆเตเดฏเดคเตเดคเต เด เดชเตโเดกเตเดฑเตเดฑเต. เด เดกเดฏเดเตเดฐเด เดเตผเดเตเดเตเดจเตเดจเตเดฃเตเดเต?
"เดเตเดฒเดฏเดจเตเดฑเต เดฑเตเตปเดกเตผ เดเตเด" เดเดจเตเดจเดคเดฟเดจเตเดฑเต เดเดเดคเตเดตเดถเดคเตเดคเตเดณเตเดณ เดเตเดฏเดฟเด เด
เดชเตโเดกเตเดฑเตเดฑเต เด
เดเดฟเดธเตเดฅเดพเดจ เด
เดชเตโเดกเตเดฑเตเดฑเดพเดฃเต.
เด
เดเดฟเดธเตเดฅเดพเดจ เด
เดชเตโเดกเตเดฑเตเดฑเต เดเดจเตเดคเดฟเดจเตเดตเตเดฃเตเดเดฟเดฏเดพเดฃเต เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเดคเต? เดเดจเตเดคเตเดเตเดฃเตเดเดพเดฃเต เดเดเตเดเตพเดเตเดเต เด
เดชเตโเดกเตเดฑเตเดฑเตเดเตพ เด
เดเดฟเดธเตเดฅเดพเดจเดคเตเดคเดฟเดฒเตเดเตเดเต เดกเตเดฐเตเดชเตเดชเต เดเตเดฏเตเดฏเดพเตป เดเดดเดฟเดฏเตเด? เดเดคเต เดฎเดจเดธเดฟเดฒเดพเดเตเดเดพเตป, เดจเดฎเตเดเตเดเต เดเดเตเดตเดฟเตฝ เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเตเดจเตเดจเดคเต เดจเตเดเตเดเดพเด getCurrentState()
:
state.js, เดญเดพเดเด 2
export function getCurrentState() {
if (!firstServerTimestamp) {
return {};
}
const base = getBaseUpdate();
const serverTime = currentServerTime();
// If base is the most recent update we have, use its state.
// Else, interpolate between its state and the state of (base + 1).
if (base < 0) {
return gameUpdates[gameUpdates.length - 1];
} else if (base === gameUpdates.length - 1) {
return gameUpdates[base];
} else {
const baseUpdate = gameUpdates[base];
const next = gameUpdates[base + 1];
const r = (serverTime - baseUpdate.t) / (next.t - baseUpdate.t);
return {
me: interpolateObject(baseUpdate.me, next.me, r),
others: interpolateObjectArray(baseUpdate.others, next.others, r),
bullets: interpolateObjectArray(baseUpdate.bullets, next.bullets, r),
};
}
}
เดเดเตเดเตพ เดฎเตเดจเตเดจเต เดเตเดธเตเดเตพ เดเตเดเดพเดฐเตเดฏเด เดเตเดฏเตเดฏเตเดจเตเดจเต:
base < 0
เดจเดฟเดฒเดตเดฟเดฒเต เดฑเตเตปเดกเดฑเดฟเดเดเต เดธเดฎเดฏเด เดตเดฐเต เด เดชเตโเดกเตเดฑเตเดฑเตเดเดณเตเดจเตเดจเตเด เดเดฒเตเดฒ เดเดจเตเดจเดพเดฃเต เด เตผเดคเตเดฅเดฎเดพเดเตเดเตเดจเตเดจเดคเต (เดฎเตเดเดณเดฟเตฝ เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเตเดจเตเดจเดคเต เดเดพเดฃเตเดgetBaseUpdate()
). เดฑเตเตปเดกเดฑเดฟเดเดเต เดฒเดพเดเต เดเดพเดฐเดฃเด เดเตเดฏเดฟเดฎเดฟเดจเตเดฑเต เดคเตเดเดเตเดเดคเตเดคเดฟเตฝ เดคเดจเตเดจเต เดเดคเต เดธเดเดญเดตเดฟเดเตเดเดพเด. เด เดธเดพเดนเดเดฐเตเดฏเดคเตเดคเดฟเตฝ, เดฒเดญเดฟเดเตเด เดเดฑเตเดฑเดตเตเด เดชเตเดคเดฟเดฏ เด เดชเตเดกเตเดฑเตเดฑเต เดเดเตเดเตพ เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต.base
เดเดเตเดเตพเดเตเดเต เดฒเดญเดฟเดเตเด เดเดฑเตเดฑเดตเตเด เดชเตเดคเดฟเดฏ เด เดชเตโเดกเตเดฑเตเดฑเดพเดฃเต. เดจเตเดฑเตเดฑเตโเดตเตผเดเตเดเต เดเดพเดฒเดคเดพเดฎเดธเด เด เดฒเตเดฒเตเดเตเดเดฟเตฝ เดฎเตเดถเด เดเดจเตเดฑเตผเดจเตเดฑเตเดฑเต เดเดฃเดเตเดทเตป เดเดพเดฐเดฃเด เดเดคเต เดธเดเดญเดตเดฟเดเตเดเดพเด. เด เดธเดพเดนเดเดฐเตเดฏเดคเตเดคเดฟเดฒเตเด เดเดเตเดเตพ เดเดฑเตเดฑเดตเตเด เดชเตเดคเดฟเดฏ เด เดชเตเดกเตเดฑเตเดฑเต เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต.- เดจเดฟเดฒเดตเดฟเดฒเต เดฑเตเตปเดกเตผ เดธเดฎเดฏเดคเตเดคเดฟเดจเต เดฎเตเดฎเตเดชเตเด เดถเตเดทเดตเตเด เดเดเตเดเตพเดเตเดเต เดเดฐเต เด เดชเตโเดกเตเดฑเตเดฑเต เดเดฃเตเดเต, เด เดคเดฟเดจเดพเตฝ เดเดเตเดเตพเดเตเดเต เดเดดเดฟเดฏเตเด เดเดจเตเดฑเตผเดชเตเดณเตเดฑเตเดฑเต!
เดเดณเตเดณเดฟเตฝ เด
เดตเดถเตเดทเดฟเดเตเดเตเดจเตเดจเดคเตเดฒเตเดฒเดพเด state.js
เดฒเดณเดฟเดคเดฎเดพเดฏ (เดเดจเตเดจเดพเตฝ เดตเดฟเดฐเดธเดฎเดพเดฏ) เดเดฃเดฟเดคเดคเตเดคเดฟเดจเตเดฑเต เดฒเตเดจเดฟเดฏเตผ เดเดจเตเดฑเตผเดชเตเดณเตเดทเดจเตเดฑเต เดเดฐเต เดจเดฟเตผเดตเตเดตเดนเดฃเดฎเดพเดฃเต. เดจเดฟเดเตเดเตพเดเตเดเดคเต เดธเตเดตเดฏเด เดชเดฐเตเดฏเดตเตเดเตเดทเดฃเด เดเตเดฏเตเดฏเดฃเดฎเตเดเตเดเดฟเตฝ, เดคเตเดฑเดเตเดเตเด state.js
เดเตบ
เดญเดพเดเด 2. เดฌเดพเดเตเดเตเตปเดกเต เดธเตเตผเดตเตผ
เด เดญเดพเดเดคเตเดคเต เดจเดฎเตเดฎเดณเต เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเดจเตเดจ Node.js เดฌเดพเดเตเดเตเตปเดกเต เดจเตเดเตเดเดพเด
1. เดธเตเตผเดตเตผ เดเตปเดเตเดฐเดฟ เดชเตเดฏเดฟเดจเตเดฑเต
เดตเตเดฌเต เดธเตเตผเดตเตผ เดฎเดพเดจเตเดเตเดเตเดฏเตเดฏเดพเตป Node.js เดเดจเตเดจ เดชเตเดฐเดฟเตฝ เดเดเตเดเตพ เดเดฐเต เดเดจเดชเตเดฐเดฟเดฏ เดตเตเดฌเต เดซเตเดฐเตเดฏเดฟเดเดตเตผเดเตเดเต เดเดชเดฏเตเดเดฟเดเตเดเตเด src/server/server.js
:
server.js, เดญเดพเดเด 1
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackConfig = require('../../webpack.dev.js');
// Setup an Express server
const app = express();
app.use(express.static('public'));
if (process.env.NODE_ENV === 'development') {
// Setup Webpack for development
const compiler = webpack(webpackConfig);
app.use(webpackDevMiddleware(compiler));
} else {
// Static serve the dist/ folder in production
app.use(express.static('dist'));
}
// Listen on port
const port = process.env.PORT || 3000;
const server = app.listen(port);
console.log(`Server listening on port ${port}`);
เดเดฆเตเดฏ เดญเดพเดเดคเตเดคเดฟเตฝ เดจเดฎเตเดฎเตพ Webpack เดเตผเดเตเด เดเตเดฏเตเดคเดคเต เดเตผเดเตเดเตเดจเตเดจเตเดฃเตเดเต? เดเดตเดฟเดเตเดฏเดพเดฃเต เดเดเตเดเตพ เดเดเตเดเดณเตเดเต เดตเตเดฌเตโเดชเดพเดเตเดเต เดเตเตบเดซเดฟเดเดฑเตเดทเดจเตเดเตพ เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเดคเต. เดเดเตเดเตพ เด เดต เดฐเดฃเตเดเต เดคเดฐเดคเตเดคเดฟเตฝ เดชเตเดฐเดฏเตเดเดฟเดเตเดเตเด:
- เดเดชเดฏเตเดเดฟเดเตเดเตเด
webpack-dev-middleware เดเดเตเดเดณเตเดเต เดตเดฟเดเดธเดจ เดชเดพเดเตเดเตเดเตเดเตพ เดธเตเดตเดฏเดฎเตเดต เดชเตเดจเตผเดจเดฟเตผเดฎเตเดฎเดฟเดเตเดเดพเตป, เด เดฒเตเดฒเตเดเตเดเดฟเตฝ - เดเดฐเต เดซเตเตพเดกเตผ เดธเตเดฅเดฟเดฐเดฎเดพเดฏเดฟ เดเตเดฎเดพเดฑเตเด
dist/
, เดชเตเดฐเตเดกเดเตเดทเตป เดฌเดฟเตฝเดกเดฟเดจเต เดถเตเดทเด เดตเตเดฌเตโเดชเดพเดเตเดเต เดเดเตเดเดณเตเดเต เดซเดฏเดฒเตเดเตพ เดเดดเตเดคเตเด.
เดฎเดฑเตเดฑเตเดฐเต เดชเตเดฐเดงเดพเดจ เดฆเตเดคเตเดฏเด server.js
เดธเตเตผเดตเตผ เดธเดเตเดเตเดเดฐเดฟเดเตเดเตเดจเตเดจเดคเต เดเตพเดเตเดเตเดณเตเดณเตเดจเตเดจเต
server.js, เดญเดพเดเด 2
const socketio = require('socket.io');
const Constants = require('../shared/constants');
// Setup Express
// ...
const server = app.listen(port);
console.log(`Server listening on port ${port}`);
// Setup socket.io
const io = socketio(server);
// Listen for socket.io connections
io.on('connection', socket => {
console.log('Player connected!', socket.id);
socket.on(Constants.MSG_TYPES.JOIN_GAME, joinGame);
socket.on(Constants.MSG_TYPES.INPUT, handleInput);
socket.on('disconnect', onDisconnect);
});
เดธเตเตผเดตเดฑเตเดฎเดพเดฏเดฟ เดเดฐเต socket.io เดเดฃเดเตเดทเตป เดตเดฟเดเดฏเดเดฐเดฎเดพเดฏเดฟ เดธเตเดฅเดพเดชเดฟเดเตเด เดถเตเดทเด, เดชเตเดคเดฟเดฏ เดธเตเดเตเดเดฑเตเดฑเดฟเดจเดพเดฏเดฟ เดเดเตเดเตพ เดเดตเดจเตเดฑเต เดนเดพเตปเดกเตโเดฒเดฑเตเดเตพ เดเตเตบเดซเดฟเดเตผ เดเตเดฏเตเดฏเตเดจเตเดจเต. เดเดตเดจเตเดฑเต เดนเดพเตปเดกเตโเดฒเตผเดฎเดพเตผ เดเดฐเต เดธเดฟเดเดเดฟเตพเดเตบ เดเดฌเตโเดเดเตโเดฑเตเดฑเดฟเดฒเตเดเตเดเต เดกเตเดฒเดฟเดเตเดฑเตเดฑเต เดเตเดฏเตโเดคเต เดเตเดฒเดฏเดจเตเดฑเตเดเดณเดฟเตฝ เดจเดฟเดจเตเดจเต เดฒเดญเดฟเดเตเดเตเดจเตเดจ เดธเดจเตเดฆเตเดถเดเตเดเตพ เดชเตเดฐเตเดธเดธเตเดธเต เดเตเดฏเตเดฏเตเดจเตเดจเต game
:
server.js, เดญเดพเดเด 3
const Game = require('./game');
// ...
// Setup the Game
const game = new Game();
function joinGame(username) {
game.addPlayer(this, username);
}
function handleInput(dir) {
game.handleInput(this, dir);
}
function onDisconnect() {
game.removePlayer(this);
}
เดเดเตเดเตพ เดเดฐเต .io เดเตเดฏเดฟเด เดธเตเดทเตเดเดฟเดเตเดเตเดเดฏเดพเดฃเต, เด
เดคเดฟเดจเดพเตฝ เดเดเตเดเตพเดเตเดเต เดเดฐเต เดชเดเตผเดชเตเดชเต เดฎเดพเดคเตเดฐเดฎเต เดเดตเดถเตเดฏเดฎเตเดณเตเดณเต Game
("เดเตเดฏเดฟเด") - เดเดฒเตเดฒเดพ เดเดณเดฟเดเตเดเดพเดฐเตเด เดเดฐเต เดตเตเดฆเดฟเดฏเดฟเตฝ เดเดณเดฟเดเตเดเตเดจเตเดจเต! เด เดเตเดฒเดพเดธเต เดเดเตเดเดจเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดจเตเดจเตเดตเตเดจเตเดจเต เด
เดเตเดคเตเดค เดตเดฟเดญเดพเดเดคเตเดคเดฟเตฝ เดจเดฎเตเดเตเดเต เดจเตเดเตเดเดพเด Game
.
2. เดเตเดฏเดฟเด เดธเตเตผเดตเดฑเตเดเตพ
เดเตเดฒเดพเดธเต Game
เดเดฑเตเดฑเดตเตเด เดชเตเดฐเดงเดพเดจเดชเตเดชเตเดเตเด เดธเตเตผเดตเตผ เดธเตเดกเต เดฒเตเดเดฟเดเต เด
เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต. เดเดคเดฟเดจเต เดฐเดฃเตเดเต เดชเตเดฐเดงเดพเดจ เดเตเดฒเดฟเดเดณเตเดฃเตเดเต: เดชเตเดฒเตเดฏเตผ เดฎเดพเดจเตเดเตเดฎเตเดจเตเดฑเต ะธ เดเตเดฏเดฟเด เดธเดฟเดฎเตเดฒเตเดทเตป.
เดเดฆเตเดฏ เดเดพเดธเตเดเตเดเดฟเตฝ เดจเดฟเดจเตเดจเต เดเดฐเดเดญเดฟเดเตเดเดพเด - เดเดณเดฟเดเตเดเดพเดฐเต เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเด.
game.js, เดญเดพเดเด 1
const Constants = require('../shared/constants');
const Player = require('./player');
class Game {
constructor() {
this.sockets = {};
this.players = {};
this.bullets = [];
this.lastUpdateTime = Date.now();
this.shouldSendUpdate = false;
setInterval(this.update.bind(this), 1000 / 60);
}
addPlayer(socket, username) {
this.sockets[socket.id] = socket;
// Generate a position to start this player at.
const x = Constants.MAP_SIZE * (0.25 + Math.random() * 0.5);
const y = Constants.MAP_SIZE * (0.25 + Math.random() * 0.5);
this.players[socket.id] = new Player(socket.id, username, x, y);
}
removePlayer(socket) {
delete this.sockets[socket.id];
delete this.players[socket.id];
}
handleInput(socket, dir) {
if (this.players[socket.id]) {
this.players[socket.id].setDirection(dir);
}
}
// ...
}
เด เดเตเดฏเดฟเดฎเดฟเตฝ เดเดเตเดเตพ เดเดณเดฟเดเตเดเดพเดฐเต เดซเตเตฝเดกเต เด
เดจเตเดธเดฐเดฟเดเตเดเต เดคเดฟเดฐเดฟเดเตเดเดฑเดฟเดฏเตเด id
เด
เดตเดฐเตเดเต เดธเตเดเตเดเดฑเตเดฑเต socket.io (เดจเดฟเดเตเดเตพ เดเดถเดฏเดเตเดเตเดดเดชเตเดชเดคเตเดคเดฟเดฒเดพเดฃเตเดเตเดเดฟเตฝ, เดคเดฟเดฐเดฟเดเต เดชเตเดเตเด server.js
). Socket.io เดคเดจเตเดจเต เดเดฐเต เดธเตเดเตเดเดฑเตเดฑเดฟเดจเตเด เดเดฐเต เดคเดจเดคเต เดจเตฝเดเตเดจเตเดจเต id
, เด
เดคเดฟเดจเดพเตฝ เดจเดฎเตเดฎเตพ เด
เดคเดฟเดจเตเดเตเดเตเดฑเดฟเดเตเดเต เดตเดฟเดทเดฎเดฟเดเตเดเตเดฃเตเดเดคเดฟเดฒเตเดฒ. เดเดพเตป เด
เดตเดจเต เดตเดฟเดณเดฟเดเตเดเดพเด เดชเตเดฒเตเดฏเตผ เดเดกเดฟ.
เด
เดคเต เดฎเดจเดธเตเดธเดฟเตฝ เดตเตเดเตเดเตเดเตเดฃเตเดเต, เดเตเดฒเดพเดธเตเดธเดฟเดฒเต เดเตปเดธเตเดฑเตเดฑเตปเดธเต เดตเตเดฐเดฟเดฏเดฌเดฟเดณเตเดเตพ เดชเดฐเดฟเดถเตเดงเดฟเดเตเดเดพเด Game
:
sockets
เดชเตเดฒเตเดฏเดฑเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดชเตเดชเตเดเตเด เดธเตเดเตเดเดฑเตเดฑเดฟเดฒเตเดเตเดเต เดชเตเดฒเตเดฏเตผ เดเดกเดฟเดฏเต เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเดเตเดจเตเดจ เดเดฐเต เดตเดธเตเดคเตเดตเดพเดฃเต. เดเดพเดฒเดเตเดฐเดฎเตเดฃ เด เดตเดฐเตเดเต เดชเตเดฒเตเดฏเตผ เดเดกเดฟเดเตพ เดเดชเดฏเตเดเดฟเดเตเดเต เดธเตเดเตเดเดฑเตเดฑเตเดเตพ เดเดเตโเดธเดธเต เดเตเดฏเตเดฏเดพเตป เดเดคเต เดเดเตเดเดณเต เด เดจเตเดตเดฆเดฟเดเตเดเตเดจเตเดจเต.players
เดชเตเดฒเตเดฏเตผ เดเดกเดฟเดฏเต เดเตเดกเต> เดชเตเดฒเตเดฏเตผ เดเดฌเตโเดเดเตโเดฑเตเดฑเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเดเตเดจเตเดจ เดเดฐเต เดเดฌเตโเดเดเตเดฑเตเดฑเต เดเดฃเต
bullets
เดตเดธเตเดคเตเดเตเดเดณเตเดเต เดเดฐเต เดจเดฟเดฐเดฏเดพเดฃเต Bullet
, เดเดฐเต เดชเตเดฐเดคเตเดฏเตเด เดเตเดฐเดฎเด เดเดฒเตเดฒ.
lastUpdateTime
- เดเดคเดพเดฃเต เด
เดตเดธเดพเดจ เดเตเดฏเดฟเด เด
เดชเตโเดกเตเดฑเตเดฑเดฟเดจเตเดฑเต เดเตเดเดธเตเดฑเตเดฑเดพเดฎเตเดชเต. เดเดคเต เดเดเตเดเดจเต เดเดชเดฏเตเดเดฟเดเตเดเตเดฎเตเดจเตเดจเต เดจเดฎเตเดเตเดเต เดเดเตป เดเดพเดฃเดพเด.
shouldSendUpdate
เดเดฐเต เดเดเตเดธเดฟเดฒเดฑเดฟ เดตเตเดฐเดฟเดฏเดฌเดฟเตพ เดเดฃเต. เด
เดคเดฟเดจเตเดฑเต เดเดชเดฏเตเดเดตเตเด เดเดเตป เดเดพเดฃเดพเด.
เดฐเตเดคเดฟเดเตพ addPlayer()
, removePlayer()
ะธ handleInput()
เดตเดฟเดถเดฆเตเดเดฐเดฟเดเตเดเตเดฃเตเด เดเดตเดถเตเดฏเดฎเดฟเดฒเตเดฒ, เด
เดต เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต server.js
. เดจเดฟเดเตเดเตพเดเตเดเต เดเดฐเต เดฑเดฟเดซเตเดฐเดทเตผ เดเดตเดถเตเดฏเดฎเตเดฃเตเดเตเดเตเดเดฟเตฝ, เดเตเดฑเดเตเดเต เดเดฏเดฐเดคเตเดคเดฟเดฒเตเดเตเดเต เดฎเดเดเตเดเตเด.
เด
เดตเดธเดพเดจ เดตเดฐเดฟ constructor()
เดเดฐเดเดญเดฟเดเตเดเตเดจเตเดจเต เด
เดชเตเดกเตเดฑเตเดฑเต เดธเตเดเตเดเดฟเตพ เดเตเดฏเดฟเดฎเตเดเตพ (60 เด
เดชเตเดกเตเดฑเตเดฑเตเดเตพ/เดธเตเดเตเดเดจเตเดฑเตเดเดณเตเดเต เดเดตเตเดคเตเดคเดฟเดฏเดฟเตฝ):
game.js, เดญเดพเดเด 2
const Constants = require('../shared/constants');
const applyCollisions = require('./collisions');
class Game {
// ...
update() {
// Calculate time elapsed
const now = Date.now();
const dt = (now - this.lastUpdateTime) / 1000;
this.lastUpdateTime = now;
// Update each bullet
const bulletsToRemove = [];
this.bullets.forEach(bullet => {
if (bullet.update(dt)) {
// Destroy this bullet
bulletsToRemove.push(bullet);
}
});
this.bullets = this.bullets.filter(
bullet => !bulletsToRemove.includes(bullet),
);
// Update each player
Object.keys(this.sockets).forEach(playerID => {
const player = this.players[playerID];
const newBullet = player.update(dt);
if (newBullet) {
this.bullets.push(newBullet);
}
});
// Apply collisions, give players score for hitting bullets
const destroyedBullets = applyCollisions(
Object.values(this.players),
this.bullets,
);
destroyedBullets.forEach(b => {
if (this.players[b.parentID]) {
this.players[b.parentID].onDealtDamage();
}
});
this.bullets = this.bullets.filter(
bullet => !destroyedBullets.includes(bullet),
);
// Check if any players are dead
Object.keys(this.sockets).forEach(playerID => {
const socket = this.sockets[playerID];
const player = this.players[playerID];
if (player.hp <= 0) {
socket.emit(Constants.MSG_TYPES.GAME_OVER);
this.removePlayer(socket);
}
});
// Send a game update to each player every other time
if (this.shouldSendUpdate) {
const leaderboard = this.getLeaderboard();
Object.keys(this.sockets).forEach(playerID => {
const socket = this.sockets[playerID];
const player = this.players[playerID];
socket.emit(
Constants.MSG_TYPES.GAME_UPDATE,
this.createUpdate(player, leaderboard),
);
});
this.shouldSendUpdate = false;
} else {
this.shouldSendUpdate = true;
}
}
// ...
}
เดฐเตเดคเดฟ update()
เดธเตเตผเดตเตผ เดธเตเดกเต เดฒเตเดเดฟเดเตเดเดฟเดจเตเดฑเต เดเดฑเตเดฑเดตเตเด เดชเตเดฐเดงเดพเดจเดชเตเดชเตเดเตเด เดญเดพเดเด เด
เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต. เด
เดคเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเตเดฒเตเดฒเดพเด เดเตเดฐเดฎเดคเตเดคเดฟเตฝ เดชเดเตเดเดฟเดเดชเตเดชเตเดเตเดคเตเดคเดพเด:
- เดธเดฎเดฏเด เดเดคเตเดฐเดฏเดพเดฃเตเดจเตเดจเต เดเดฃเดเตเดเดพเดเตเดเตเดจเตเดจเต
dt
เด เดคเต เดเดดเดฟเดเตเด เดเดพเดฒเด เดฎเตเดคเตฝ เดเดฃเตเดเตupdate()
. - เดเดฐเต เดชเตเดฐเตเดเดเตเดฑเตเดฑเดฟเดฒเตเด เดชเตเดคเตเดเตเดเตเดเดฏเตเด เดเดตเดถเตเดฏเดฎเตเดเตเดเดฟเตฝ เด
เดตเดฏเต เดจเดถเดฟเดชเตเดชเดฟเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจเต. เด เดชเตเดฐเดตเตผเดคเตเดคเดจเด เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเตเดจเตเดจเดคเต เดจเดฎเตเดเตเดเต เดชเดฟเดจเตเดจเตเดเต เดเดพเดฃเดพเด. เดคเตฝเดเตเดเดพเดฒเด เดจเดฎเตเดเตเดเต เด
เดคเดฑเดฟเดเตเดเดพเตฝ เดฎเดคเดฟ
bullet.update()
เดฎเดเดเตเดเตเดจเตเดจเตtrue
, เดชเตเดฐเตเดเดเตเดฑเตเดฑเตเตฝ เดจเดถเดฟเดชเตเดชเดฟเดเตเดเดชเตเดชเตเดเตเดฃเตเดเดคเตเดฃเตเดเตเดเตเดเดฟเตฝ (เด เดตเตป เด เดฐเดเตเดเดฟเดจเต เดชเตเดฑเดคเตเดคเตเดเตเดเต เดชเตเดฏเดฟ). - เดเดฐเต เดเดณเดฟเดเตเดเดพเดฐเดจเตเด เด
เดชเตเดกเตเดฑเตเดฑเต เดเตเดฏเตเดฏเตเดเดฏเตเด เดเดตเดถเตเดฏเดฎเตเดเตเดเดฟเตฝ เดเดฐเต เดชเตเดฐเตเดเดเตเดฑเตเดฑเตเตฝ เดธเตเดทเตเดเดฟเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจเต. เด เดจเดเดชเตเดชเดพเดเตเดเดฒเตเด เดจเดฎเตเดเตเดเต เดชเดฟเดจเตเดจเตเดเต เดเดพเดฃเดพเด -
player.update()
เดเดฐเต เดตเดธเตเดคเต เดคเดฟเดฐเดฟเดเต เดจเตฝเดเดพเดBullet
. - เดชเตเดฐเตเดเดเตโเดเตเดฒเตเดเดณเตเด เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจ เดเดณเดฟเดเตเดเดพเดฐเตเด เดคเดฎเตเดฎเดฟเดฒเตเดณเตเดณ เดเตเดเตเดเดฟเดฏเดฟเดเดฟ เดชเดฐเดฟเดถเตเดงเดฟเดเตเดเตเดจเตเดจเต
applyCollisions()
, เดเดคเต เดเดณเดฟเดเตเดเดพเดฐเต เด เดเดฟเดเตเดเตเดจเตเดจ เดชเตเดฐเตเดเดเตโเดเตเดฒเตเดเดณเตเดเต เดเดฐเต เดจเดฟเดฐ เดจเตฝเดเตเดจเตเดจเต. เดฎเดเดเตเดเดฟเดฏ เดเดฐเต เดชเตเดฐเตเดเดเตโเดเตเดฒเดฟเดจเตเด, เด เดคเต เดเดฑเดฟเดเตเด เดเดณเดฟเดเตเดเดพเดฐเดจเตเดฑเต เดธเตโเดเตเตผ เดเดเตเดเตพ เดตเตผเดฆเตเดงเดฟเดชเตเดชเดฟเดเตเดเตเดจเตเดจเต (เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเดคเตplayer.onDealtDamage()
), เดคเตเดเตผเดจเตเดจเต เด เดฑเตเดฏเดฟเตฝ เดจเดฟเดจเตเดจเต เดชเตเดฐเตเดเดเตเดฑเตเดฑเตเตฝ เดจเตเดเตเดเด เดเตเดฏเตเดฏเตเดbullets
. - เดเตเดฒเตเดฒเดชเตเดชเตเดเตเด เดเดฒเตเดฒเดพ เดเดณเดฟเดเตเดเดพเดฐเตเดฏเตเด เด เดฑเดฟเดฏเดฟเดเตเดเตเดเดฏเตเด เดจเดถเดฟเดชเตเดชเดฟเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจเต.
- เดเดฒเตเดฒเดพ เดเดณเดฟเดเตเดเดพเตผเดเตเดเตเด เดเดฐเต เดเตเดฏเดฟเด เด
เดชเตโเดกเตเดฑเตเดฑเต เด
เดฏเดฏเตโเดเตเดเตเดจเตเดจเต เดเดฐเตเดพ เดจเดฟเดฎเดฟเดทเดตเตเด เดตเดฟเดณเดฟเดเตเดเดชเตเดชเตเตพ
update()
. เดเดคเต เดเตเดฐเดพเดเตเดเต เดเตเดฏเตเดฏเดพเตป เดฎเตเดเดณเดฟเตฝ เดธเตเดเดฟเดชเตเดชเดฟเดเตเด เดเดเตเดธเดฟเดฒเดฑเดฟ เดตเตเดฐเดฟเดฏเดฌเดฟเตพ เดเดเตเดเดณเต เดธเดนเดพเดฏเดฟเดเตเดเตเดจเตเดจเตshouldSendUpdate
. เดเดพเดฐเดฃเดupdate()
60 เดคเดตเดฃ/เดธเตเดเตเดเตปเดกเต เดตเดฟเดณเดฟเดเตเดเตเดจเตเดจเต, เดเดเตเดเตพ เดเตเดฏเดฟเด เด เดชเตโเดกเตเดฑเตเดฑเตเดเตพ 30 เดคเดตเดฃ/เดธเตเดเตเดเตปเดกเต เด เดฏเดฏเตโเดเตเดเตเดจเตเดจเต. เด เดเตเดเดจเต, เดเตเดฒเตเดเตเดเต เดเดตเตเดคเตเดคเดฟ เดธเตเตผเดตเตผ 30 เดเตเดฒเตเดเตเดเต เดธเตเดเตเดเดฟเดณเตเดเตพ/เดธเต เดเดฃเต (เดเดเตเดเตพ เดเดฆเตเดฏ เดญเดพเดเดคเตเดคเดฟเตฝ เดเตเดฒเตเดเตเดเต เดซเตเดฐเตเดเตเดตเตปเดธเดฟเดฏเตเดเตเดเตเดฑเดฟเดเตเดเต เดธเดเดธเดพเดฐเดฟเดเตเดเต).
เดเดจเตเดคเตเดเตเดฃเตเดเดพเดฃเต เดเตเดฏเดฟเด เด เดชเตโเดกเตเดฑเตเดฑเตเดเตพ เดฎเดพเดคเตเดฐเด เด เดฏเดฏเตโเดเตเดเตเดจเตเดจเดคเต เดเดพเดฒเดคเตเดคเดฟเดฒเตเดเต ? เดเดพเดจเตฝ เดธเดเดฐเดเตเดทเดฟเดเตเดเดพเตป. เดธเตเดเตเดเตปเดกเดฟเตฝ 30 เดเตเดฏเดฟเด เด เดชเตโเดกเตเดฑเตเดฑเตเดเตพ เดงเดพเดฐเดพเดณเด!
เดชเดฟเดจเตเดจเต เดตเตเดฑเตเดคเต เดตเดฟเดณเดฟเดเตเดเดพเดฒเต?
update()
เดธเตเดเตเดเตปเดกเดฟเตฝ 30 เดคเดตเดฃ? เดเตเดฏเดฟเด เดธเดฟเดฎเตเดฒเตเดทเตป เดฎเตเดเตเดเดชเตเดชเตเดเตเดคเตเดคเดพเตป. เดเตเดเตเดคเตฝ เดคเดตเดฃ เด เดคเต เดตเดฟเดณเดฟเดเตเดเดชเตเดชเตเดเตเดจเตเดจเตupdate()
, เดเตเดฏเดฟเด เดธเดฟเดฎเตเดฒเตเดทเตป เดเตเดเตเดคเตฝ เดเตเดคเตเดฏเดคเดฏเตเดณเตเดณเดคเดพเดฏเดฟเดฐเดฟเดเตเดเตเด. เดเดจเตเดจเดพเตฝ เดตเตเดฒเตเดฒเตเดตเดฟเดณเดฟเดเดณเตเดเต เดเดฃเตเดฃเดคเตเดคเดฟเตฝ เดตเดฒเตเดฒเดพเดคเต เดญเตเดฐเดฎเดฟเดเตเดเดฐเตเดคเตupdate()
, เดเดพเดฐเดฃเด เดเดคเต เดเดฃเดฟเดคเดชเดฐเดฎเดพเดฏเดฟ เดเตเดฒเดตเตเดฑเดฟเดฏ เดเตเดฒเดฟเดฏเดพเดฃเต - เดธเตเดเตเดเตปเดกเดฟเตฝ 60 เดฎเดคเดฟ.
เดเตเดฒเดพเดธเตเดธเดฟเดฒเต เดฌเดพเดเตเดเดฟเดฏเตเดณเตเดณเดตเตผ Game
เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจ เดธเดนเดพเดฏ เดฐเตเดคเดฟเดเตพ เดเตพเดเตเดเตเดณเตเดณเตเดจเตเดจเต update()
:
game.js, เดญเดพเดเด 3
class Game {
// ...
getLeaderboard() {
return Object.values(this.players)
.sort((p1, p2) => p2.score - p1.score)
.slice(0, 5)
.map(p => ({ username: p.username, score: Math.round(p.score) }));
}
createUpdate(player, leaderboard) {
const nearbyPlayers = Object.values(this.players).filter(
p => p !== player && p.distanceTo(player) <= Constants.MAP_SIZE / 2,
);
const nearbyBullets = this.bullets.filter(
b => b.distanceTo(player) <= Constants.MAP_SIZE / 2,
);
return {
t: Date.now(),
me: player.serializeForUpdate(),
others: nearbyPlayers.map(p => p.serializeForUpdate()),
bullets: nearbyBullets.map(b => b.serializeForUpdate()),
leaderboard,
};
}
}
getLeaderboard()
เดเดคเต เดตเดณเดฐเต เดฒเดณเดฟเดคเดฎเดพเดฃเต - เดเดคเต เดเดณเดฟเดเตเดเดพเดฐเต เดธเตโเดเตเตผ เด
เดจเตเดธเดฐเดฟเดเตเดเต เดคเดฐเดเดคเดฟเดฐเดฟเดเตเดเตเดเดฏเตเด เดฎเดฟเดเดเตเด เด
เดเตเดเต เดชเตเดฐเต เดเดเตเดเตเดเตเดเดฏเตเด เดเดฐเตเดจเตเดจเดฟเดจเตเด เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเดตเตเด เดธเตโเดเตเดฑเตเด เดจเตฝเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจเต.
createUpdate()
เตฝ เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต update()
เดเดณเดฟเดเตเดเดพเตผเดเตเดเต เดตเดฟเดคเดฐเดฃเด เดเตเดฏเตเดฏเตเดจเตเดจ เดเตเดฏเดฟเด เด
เดชเตโเดกเตเดฑเตเดฑเตเดเตพ เดธเตเดทเตโเดเดฟเดเตเดเดพเตป. เด
เดคเดฟเดจเตเดฑเต เดชเตเดฐเดงเดพเดจ เดฆเตเดคเตเดฏเด เดฐเตเดคเดฟเดเตพ เดตเดฟเดณเดฟเดเตเดเตเด เดเดจเตเดจเดคเดพเดฃเต serializeForUpdate()
, เดเตเดฒเดพเดธเตเดเตพเดเตเดเดพเดฏเดฟ เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเดฟ Player
ะธ Bullet
. เดเดคเต เดเดฐเต เดเดณเดฟเดเตเดเดพเดฐเดจเตเด เดกเดพเดฑเตเดฑ เดเตเดฎเดพเดฑเตเดจเตเดจเต เดเดจเตเดจเดคเต เดถเตเดฐเดฆเตเดงเดฟเดเตเดเตเด เดเดฑเตเดฑเดตเตเด เด
เดเตเดคเตเดคเตเดณเตเดณ เดเดณเดฟเดเตเดเดพเดฐเตเด เดชเตเดฐเตเดเดเตโเดเตเดฒเตเดเดณเตเด - เดชเตเดฒเตเดฏเดฑเดฟเตฝ เดจเดฟเดจเตเดจเต เด
เดเดฒเตเดฏเตเดณเตเดณ เดเตเดฏเดฟเด เดเดฌเตโเดเดเตเดฑเตเดฑเตเดเดณเตเดเตเดเตเดฑเดฟเดเตเดเตเดณเตเดณ เดตเดฟเดตเดฐเดเตเดเตพ เดเตเดฎเดพเดฑเตเดฃเตเด เดเดตเดถเตเดฏเดฎเดฟเดฒเตเดฒ!
3. เดธเตเตผเดตเดฑเดฟเดฒเต เดเตเดฏเดฟเด เดตเดธเตเดคเตเดเตเดเตพ
เดเดเตเดเดณเตเดเต เดเตเดฏเดฟเดฎเดฟเตฝ, เดชเตเดฐเตเดเดเตโเดเตเดฒเตเดเดณเตเด เดเดณเดฟเดเตเดเดพเดฐเตเด เดฏเดฅเดพเตผเดคเตเดฅเดคเตเดคเดฟเตฝ เดตเดณเดฐเต เดธเดฎเดพเดจเดฎเดพเดฃเต: เด
เดต เด
เดฎเตเตผเดคเตเดคเดฎเดพเดฏ เดตเตเดคเตเดคเดพเดเตเดคเดฟเดฏเดฟเดฒเตเดณเตเดณ เดเดฒเดฟเดเตเดเตเดจเตเดจ เดเตเดฏเดฟเด เดเดฌเตโเดเดเตเดฑเตเดฑเตเดเดณเดพเดฃเต. เดเดณเดฟเดเตเดเดพเดฐเตเด เดชเตเดฐเตเดเดเตโเดเตเดฒเตเดเดณเตเด เดคเดฎเตเดฎเดฟเดฒเตเดณเตเดณ เด เดธเดพเดฎเตเดฏเด เดชเตเดฐเดฏเตเดเดจเดชเตเดชเตเดเตเดคเตเดคเตเดจเตเดจเดคเดฟเดจเต, เดเดฐเต เด
เดเดฟเดธเตเดฅเดพเดจ เดเตเดฒเดพเดธเต เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเดฟเดเตเดเตเดฃเตเดเต เดจเดฎเตเดเตเดเต เดเดฐเดเดญเดฟเดเตเดเดพเด Object
:
object.js
class Object {
constructor(id, x, y, dir, speed) {
this.id = id;
this.x = x;
this.y = y;
this.direction = dir;
this.speed = speed;
}
update(dt) {
this.x += dt * this.speed * Math.sin(this.direction);
this.y -= dt * this.speed * Math.cos(this.direction);
}
distanceTo(object) {
const dx = this.x - object.x;
const dy = this.y - object.y;
return Math.sqrt(dx * dx + dy * dy);
}
setDirection(dir) {
this.direction = dir;
}
serializeForUpdate() {
return {
id: this.id,
x: this.x,
y: this.y,
};
}
}
เดเดตเดฟเดเต เดธเดเตเดเตเตผเดฃเตเดฃเดฎเดพเดฏ เดเดจเตเดจเตเด เดจเดเดเตเดเตเดจเตเดจเดฟเดฒเตเดฒ. เด เดเตเดฒเดพเดธเต เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดคเตเดคเดฟเดจเต เดจเดฒเตเดฒเตเดฐเต เดคเตเดเดเตเดเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเตเด. เดเตเดฒเดพเดธเต เดเดเตเดเดจเตเดฏเตเดจเตเดจเต เดจเตเดเตเดเดพเด Bullet
เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต Object
:
bullet.js
const shortid = require('shortid');
const ObjectClass = require('./object');
const Constants = require('../shared/constants');
class Bullet extends ObjectClass {
constructor(parentID, x, y, dir) {
super(shortid(), x, y, dir, Constants.BULLET_SPEED);
this.parentID = parentID;
}
// Returns true if the bullet should be destroyed
update(dt) {
super.update(dt);
return this.x < 0 || this.x > Constants.MAP_SIZE || this.y < 0 || this.y > Constants.MAP_SIZE;
}
}
เดจเดเดชเตเดชเดพเดเตเดเตฝ Bullet
เดตเดณเดฐเต เดเตเดฑเตเดคเต! เดเดเตเดเตพ เดเตเตผเดคเตเดคเต Object
เดเดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดเตเดเตพ เดฎเดพเดคเตเดฐเด:
- เดชเดพเดเตเดเตเดเต เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต
เดนเตเดฐเดธเตเดตเดฎเดพเดฏ เดเตเดฐเดฎเดฐเดนเดฟเดคเดฎเดพเดฏ เดคเดฒเดฎเตเดฑเดฏเตเดเตเดเดพเดฏเดฟid
เดชเตเดฐเตเดเดเตเดฑเตเดฑเตเตฝ. - เดเดฐเต เดซเตเตฝเดกเต เดเตเตผเดเตเดเตเดจเตเดจเต
parentID
, เด เดคเตเดตเดดเดฟ เด เดชเตเดฐเตเดเดเตโเดเตเตฝ เดธเตเดทเตโเดเดฟเดเตเด เดเดณเดฟเดเตเดเดพเดฐเดจเต เดจเดฟเดเตเดเตพเดเตเดเต เดเตเดฐเดพเดเตเดเตเดเตเดฏเตเดฏเดพเดจเดพเดเตเด. - เดเดคเดฟเดฒเตเดเตเดเต เดฑเดฟเดเตเดเตเตบ เดฎเตเดฒเตเดฏเด เดเตเตผเดเตเดเตเดจเตเดจเต
update()
, เดเดคเต เดคเตเดฒเตเดฏเดฎเดพเดฃเตtrue
, เดชเตเดฐเตเดเดเตโเดเตเตฝ เด เดฐเตเดจเดฏเตเดเตเดเต เดชเตเดฑเดคเตเดคเดพเดฃเตเดเตเดเดฟเตฝ (เด เดตเดธเดพเดจ เดตเดฟเดญเดพเดเดคเตเดคเดฟเตฝ เดเดเตเดเตพ เดเดคเดฟเดจเตเดเตเดเตเดฑเดฟเดเตเดเต เดธเดเดธเดพเดฐเดฟเดเตเดเดคเดพเดฏเดฟ เดเตผเดเตเดเตเดจเตเดจเตเดฃเตเดเต?).
เดจเดฎเตเดเตเดเต เดฎเตเดจเตเดจเตเดเตเดเต เดชเตเดเดพเด Player
:
player.js
const ObjectClass = require('./object');
const Bullet = require('./bullet');
const Constants = require('../shared/constants');
class Player extends ObjectClass {
constructor(id, username, x, y) {
super(id, x, y, Math.random() * 2 * Math.PI, Constants.PLAYER_SPEED);
this.username = username;
this.hp = Constants.PLAYER_MAX_HP;
this.fireCooldown = 0;
this.score = 0;
}
// Returns a newly created bullet, or null.
update(dt) {
super.update(dt);
// Update score
this.score += dt * Constants.SCORE_PER_SECOND;
// Make sure the player stays in bounds
this.x = Math.max(0, Math.min(Constants.MAP_SIZE, this.x));
this.y = Math.max(0, Math.min(Constants.MAP_SIZE, this.y));
// Fire a bullet, if needed
this.fireCooldown -= dt;
if (this.fireCooldown <= 0) {
this.fireCooldown += Constants.PLAYER_FIRE_COOLDOWN;
return new Bullet(this.id, this.x, this.y, this.direction);
}
return null;
}
takeBulletDamage() {
this.hp -= Constants.BULLET_DAMAGE;
}
onDealtDamage() {
this.score += Constants.SCORE_BULLET_HIT;
}
serializeForUpdate() {
return {
...(super.serializeForUpdate()),
direction: this.direction,
hp: this.hp,
};
}
}
เดเดณเดฟเดเตเดเดพเตผ เดชเตเดฐเตเดเดเตโเดเตเดฒเตเดเดณเตเดเตเดเดพเตพ เดธเดเตเดเตเตผเดฃเตเดฃเดฎเดพเดฃเต, เด
เดคเดฟเดจเดพเตฝ เด เดเตเดฒเดพเดธเต เดเตเดฑเดเตเดเต เดซเตเตฝเดกเตเดเตพ เดเตเดเดฟ เดธเตเดเตเดทเดฟเดเตเดเดฃเด. เด
เดตเดจเตเดฑเต เดฐเตเดคเดฟ update()
เดเตเดเตเดคเตฝ เดเตเดฒเดฟ เดเตเดฏเตเดฏเตเดจเตเดจเต, เดชเตเดฐเดคเตเดฏเตเดเดฟเดเตเดเตเด เดชเตเดคเตเดคเดพเดฏเดฟ เดธเตเดทเตเดเดฟเดเตเด เดชเตเดฐเตเดเดเตเดฑเตเดฑเตเตฝ เด
เดตเดถเตเดทเดฟเดเตเดเตเดจเตเดจเดฟเดฒเตเดฒเตเดเตเดเดฟเตฝ เดคเดฟเดฐเดฟเดเต เดจเตฝเดเตเดจเตเดจเต fireCooldown
(เดฎเตเดฎเตเดชเดคเตเดคเต เดตเดฟเดญเดพเดเดคเตเดคเดฟเตฝ เดเดเตเดเตพ เดเดคเดฟเดจเตเดเตเดเตเดฑเดฟเดเตเดเต เดธเดเดธเดพเดฐเดฟเดเตเดเดคเดพเดฏเดฟ เดเตผเดเตเดเตเดจเตเดจเตเดฃเตเดเต?). เดเดคเต เดฐเตเดคเดฟ เดตเดฟเดชเตเดฒเตเดเดฐเดฟเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจเต serializeForUpdate()
, เดเดพเดฐเดฃเด เดเดเตเดเตพ เดเตเดฏเดฟเด เด
เดชเตโเดกเตเดฑเตเดฑเดฟเตฝ เดเดณเดฟเดเตเดเดพเดฐเดจเตเดณเตเดณ เด
เดงเดฟเด เดซเตเตฝเดกเตเดเตพ เดเตพเดชเตเดชเตเดเตเดคเตเดคเตเดฃเตเดเดคเตเดฃเตเดเต.
เด
เดเดฟเดธเตเดฅเดพเดจ เดเตเดฒเดพเดธเดฟเดจเตเดฑเต เดฒเดญเตเดฏเดค Object
- เดเตเดกเต เดเดตเตผเดคเตเดคเดจเด เดเดดเดฟเดตเดพเดเตเดเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดเดฐเต เดชเตเดฐเดงเดพเดจ เดเดเตเดเด. เดเดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เดเตเดฒเดพเดธเต เดเดฒเตเดฒเดพเดคเต Object
เดเดฒเตเดฒเดพ เดเตเดฏเดฟเด เดเดฌเตเดเดเตเดฑเตเดฑเดฟเดจเตเด เดเดฐเต เดจเดฟเตผเดตเตเดตเดนเดฃเด เดเดฃเตเดเดพเดฏเดฟเดฐเดฟเดเตเดเดฃเด distanceTo()
, เดเตเดเดพเดคเต เดเดจเตเดจเดฟเดฒเดงเดฟเดเด เดซเดฏเดฒเตเดเดณเดฟเดฒเตเดเดจเตเดณเด เด เดจเดเดชเตเดชเดพเดเตเดเดฒเตเดเดณเตเดฒเตเดฒเดพเด เดเตเดชเตเดชเดฟ-เดชเตเดธเตเดฑเตเดฑเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเต เดเดฐเต เดชเตเดเดฟเดธเตเดตเดชเตเดจเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเตเด. เดตเดฒเดฟเดฏ เดชเดฆเตเดงเดคเดฟเดเตพเดเตเดเต เดเดคเต เดตเดณเดฐเต เดชเตเดฐเดงเดพเดจเดฎเดพเดฃเต, เดตเดฟเดเดธเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเตเดฑเต เดเดฃเตเดฃเด เดตเดฐเตเดฎเตเดชเตเตพ Object
เดเตเดฒเดพเดธเตเดเตพ เดตเดณเดฐเตเดจเตเดจเต.
4. เดเตเดเตเดเดฟเดฏเดฟเดเดฟ เดเดฃเตเดเตเดคเตเดคเตฝ
เดชเตเดฐเตเดเดเตโเดเตเดฒเตเดเตพ เดเดณเดฟเดเตเดเดพเดฐเต เดคเดเตเดเดฟเดฏเดคเต เดคเดฟเดฐเดฟเดเตเดเดฑเดฟเดฏเตเด เดฎเดพเดคเตเดฐเดฎเดพเดฃเต เดเดเตเดเตพเดเตเดเต เดเตเดฏเตเดฏเดพเตป เด
เดตเดถเตเดทเดฟเดเตเดเตเดจเตเดจเดคเต! เดฐเตเดคเดฟเดฏเดฟเตฝ เดจเดฟเดจเตเดจเตเดณเตเดณ เด เดเตเดกเต เดธเตเดจเดฟเดชเตเดชเดฑเตเดฑเต เดเตผเดเตเดเตเด update()
เดเตเดฒเดพเดธเดฟเตฝ Game
:
game.js
const applyCollisions = require('./collisions');
class Game {
// ...
update() {
// ...
// Apply collisions, give players score for hitting bullets
const destroyedBullets = applyCollisions(
Object.values(this.players),
this.bullets,
);
destroyedBullets.forEach(b => {
if (this.players[b.parentID]) {
this.players[b.parentID].onDealtDamage();
}
});
this.bullets = this.bullets.filter(
bullet => !destroyedBullets.includes(bullet),
);
// ...
}
}
เดเดเตเดเตพ เดฐเตเดคเดฟ เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเตเดฃเตเดเดคเตเดฃเตเดเต applyCollisions()
, เดเดคเต เดเดณเดฟเดเตเดเดพเดฐเต เด
เดเดฟเดเตเดเตเดจเตเดจ เดเดฒเตเดฒเดพ เดชเตเดฐเตเดเดเตเดฑเตเดฑเดฟเดฒเตเดเดณเตเด เดคเดฟเดฐเดฟเดเต เดจเตฝเดเตเดจเตเดจเต. เดญเดพเดเตเดฏเดตเดถเดพเตฝ, เดเดคเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเต เด
เดคเตเดฐ เดฌเตเดฆเตเดงเดฟเดฎเตเดเตเดเตเดณเตเดณ เดเดพเดฐเตเดฏเดฎเดฒเตเดฒ, เดเดพเดฐเดฃเด
- เดเตเดเตเดเดฟเดฏเดฟเดเดฟเดเตเดเตเดจเตเดจ เดเดฒเตเดฒเดพ เดตเดธเตเดคเตเดเตเดเดณเตเด เดธเตผเดเตเดเดฟเดณเตเดเดณเดพเดฃเต, เดเตเดเตเดเดฟเดฏเดฟเดเดฟ เดเดฃเตเดเตเดคเตเดคเตฝ เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดเดฑเตเดฑเดตเตเด เดฒเดณเดฟเดคเดฎเดพเดฏ เดฐเตเดชเดฎเดพเดฃเดฟเดคเต.
- เดเดเตเดเตพเดเตเดเต เดเดคเดฟเดจเดเด เดเดฐเต เดฐเตเดคเดฟเดฏเตเดฃเตเดเต
distanceTo()
, เดฎเตเดฎเตเดชเดคเตเดคเต เดตเดฟเดญเดพเดเดคเตเดคเดฟเดฒเต เดเตเดฒเดพเดธเตเดธเดฟเตฝ เดเดเตเดเตพ เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเดฟเดฏเดคเตObject
.
เดเดเตเดเดณเตเดเต เดเตเดเตเดเดฟเดฏเดฟเดเดฟ เดเดฃเตเดเตเดคเตเดคเตฝ เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเตเดจเตเดจเดคเต เดเดเตเดเดจเตเดฏเดพเดฃเต:
collisions.js
const Constants = require('../shared/constants');
// Returns an array of bullets to be destroyed.
function applyCollisions(players, bullets) {
const destroyedBullets = [];
for (let i = 0; i < bullets.length; i++) {
// Look for a player (who didn't create the bullet) to collide each bullet with.
// As soon as we find one, break out of the loop to prevent double counting a bullet.
for (let j = 0; j < players.length; j++) {
const bullet = bullets[i];
const player = players[j];
if (
bullet.parentID !== player.id &&
player.distanceTo(bullet) <= Constants.PLAYER_RADIUS + Constants.BULLET_RADIUS
) {
destroyedBullets.push(bullet);
player.takeBulletDamage();
break;
}
}
}
return destroyedBullets;
}
เด เดฒเดณเดฟเดคเดฎเดพเดฏ เดเตเดเตเดเดฟเดฏเดฟเดเดฟ เดเดฃเตเดเตเดคเตเดคเตฝ เดตเดธเตเดคเตเดคเดฏเต เด เดเดฟเดธเตเดฅเดพเดจเดฎเดพเดเตเดเดฟเดฏเตเดณเตเดณเดคเดพเดฃเต เดฐเดฃเตเดเต เดธเตผเดเตเดเดฟเดณเตเดเตพ เด เดตเดฏเตเดเต เดเตเดจเตเดฆเตเดฐเดเตเดเตพ เดคเดฎเตเดฎเดฟเดฒเตเดณเตเดณ เดฆเตเดฐเด เด เดตเดฏเตเดเต เดเดฐเดเตเดเดณเตเดเต เดเดเตเดคเตเดคเตเดเดฏเตเดเตเดเดพเตพ เดเตเดฑเดตเดพเดฃเตเดเตเดเดฟเตฝ เดเตเดเตเดเดฟเดฏเดฟเดเดฟเดเตเดเตเดจเตเดจเต. เดฐเดฃเตเดเต เดธเตผเดเตเดเดฟเดณเตเดเดณเตเดเต เดเตเดจเตเดฆเตเดฐเดเตเดเตพ เดคเดฎเตเดฎเดฟเดฒเตเดณเตเดณ เดฆเตเดฐเด เด เดตเดฏเตเดเต เดเดฐเดเตเดเดณเตเดเต เดเดเตเดคเตเดคเตเดเดฏเตเดเตเดเต เดคเตเดฒเตเดฏเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจ เดเดฐเต เดเตเดธเต เดเดคเดพ:
เดเดตเดฟเดเต เดจเดฟเดเตเดเตพ เดเตเดฑเดเตเดเต เดตเดถเดเตเดเตพ เดเตเดเดฟ เดธเตเดเตเดทเตเดฎเดฎเดพเดฏเดฟ เดถเตเดฐเดฆเตเดงเดฟเดเตเดเตเดฃเตเดเดคเตเดฃเตเดเต:
- เดชเตเดฐเตเดเดเตโเดเตเตฝ เด
เดคเต เดธเตเดทเตโเดเดฟเดเตเด เดเดณเดฟเดเตเดเดพเดฐเดจเต เดฌเดพเดงเดฟเดเตเดเดฐเตเดคเต. เดคเดพเดฐเดคเดฎเตเดฏเด เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดฒเตเดเต เดเดคเต เดจเตเดเดพเดจเดพเดเตเด
bullet.parentID
ัplayer.id
. - เดเดฐเต เดธเดฎเดฏเด เดเดจเตเดจเดฟเดฒเดงเดฟเดเด เดเดณเดฟเดเตเดเดพเดฐเต เด
เดเดฟเดเตเดเตเดจเตเดจ เด
เดเตเดเตเดฏเดฑเตเดฑเดคเตเดคเต เดธเดพเดนเดเดฐเตเดฏเดคเตเดคเดฟเตฝ เดชเตเดฐเตเดเดเตโเดเตเตฝ เดเดฐเต เดคเดตเดฃ เดฎเดพเดคเตเดฐเดฎเต เด
เดเดฟเดเตเดเดพเดตเต. เดเดชเตเดชเดฑเตเดฑเตเดฑเตผ เดเดชเดฏเตเดเดฟเดเตเดเต เดเดเตเดเตพ เด เดชเตเดฐเดถเตเดจเด เดชเดฐเดฟเดนเดฐเดฟเดเตเดเตเด
break
: เดเดฐเต เดชเตเดฐเตเดเดเตโเดเตเดฒเตเดฎเดพเดฏเดฟ เดเตเดเตเดเดฟเดฏเดฟเดเดฟเดเตเดเตเดจเตเดจ เดเดฐเต เดเดณเดฟเดเตเดเดพเดฐเดจเต เดเดฃเตเดเตเดคเตเดคเดฟเดเตเดเดดเดฟเดเตเดเดพเตฝ, เดเดเตเดเตพ เดคเดฟเดฐเดฏเตฝ เดจเดฟเตผเดคเตเดคเดฟ เด เดเตเดคเตเดค เดชเตเดฐเตเดเดเตโเดเตเดฒเดฟเดฒเตเดเตเดเต เดชเตเดเตเด.
เด เดตเดธเดพเดจเด
เด เดคเตเดฐเดฏเตเดฏเตเดณเตเดณเต! เดเดฐเต .io เดตเตเดฌเต เดเตเดฏเดฟเด เดธเตเดทเตโเดเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเต เดจเดฟเดเตเดเตพ เด เดฑเดฟเดฏเตเดฃเตเดเดคเตเดฒเตเดฒเดพเด เดเดเตเดเตพ เดเตพเดชเตเดชเตเดเตเดคเตเดคเดฟเดฏเดฟเดเตเดเตเดฃเตเดเต. เด เดเตเดคเตเดคเดคเต เดเดจเตเดคเดพเดฃเต? เดจเดฟเดเตเดเดณเตเดเต เดธเตเดตเดจเตเดคเด .io เดเตเดฏเดฟเด เดจเดฟเตผเดฎเตเดฎเดฟเดเตเดเตเด!
เดเดฒเตเดฒเดพ เดเดฆเดพเดนเดฐเดฃ เดเตเดกเตเดเดณเตเด เดเดชเตเดชเตบ เดธเตเดดเตโเดธเต เดเดฃเต เดเตเดเดพเดคเต เดชเตเดธเตเดฑเตเดฑเตเดเตเดฏเตเดคเดคเตเดฎเดพเดฃเต
เด
เดตเดฒเดเดฌเด: www.habr.com