-
Notifications
You must be signed in to change notification settings - Fork 38
/
main_online.js
150 lines (138 loc) · 7.32 KB
/
main_online.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/**
* This is the main script which executes the p2p online version game.
* General explanations for the all source code files of the game are following.
*
********************************************************************************************************************
* This p2p online version of the Pikachu Volleyball is developed based on
* the Pikachu Volleyball offline web version (https://github.com/gorisanson/pikachu-volleyball)
* which is made by reverse engineering the core part of the original Pikachu Volleyball game
* which is developed by "1997 (C) SACHI SOFT / SAWAYAKAN Programmers" & "1997 (C) Satoshi Takenouchi".
********************************************************************************************************************
*
* This p2p online version game is mainly composed of two parts below.
* 1) Offline version: All the offline web version source code files is in the directory "offline_version_js".
* 2) WebRTC data channels: It utilizes WebRTC data channels to communicate with the peer.
* The peer-to-peer online functions are contained in "data_channel.js"
*
* The game is deterministic on the user (keyboard) inputs except the RNG (random number generator) used in
* "offline_version_js/physics.js" and "offline_version_js/cloud_and_wave.js". (The RNG is contained
* in "offline_version_js/rand.js".) So if the RNG is the same on both peers, only the user inputs need
* to be communicated to maintain the same game state between the peers. In this p2p online version, the RNG
* is set to the same thing on both peers at the data channel open event (handled by the function
* "dataChannelOpened" in "data_channel.js"), then the user inputs are communicated via the data channel.
*
* And explanations for other source files are below.
* - "pikavolley_online.js": A wrapper for "offline_version_js/pikavolley.js".
* - "keyboard_online.js": A wrapper for offline version "offline_version_js/keyboard.js".
* This module gets user inputs and load them up onto the data channel to the peer.
* - "generate_pushid.js": Generate a room ID easily distinguishable by human eye.
* - "mod.js": To maintain game sync, sync counter is attached for each user input, and mod is used to
* make sync counter cycle in a range [0, 255] which fits in a byte.
* - "ui_online.js": For the user interface of the html page and inputs/outputs relevant to html elements.
* - "chat_display.js": For displaying chat messages.
* - "firebase_config.template.js": This p2p online version utilized firebase cloud firestore to establish
* webRTC data channel connection between peers. Fill this template and
* change the file name to "firebase_config.js".
* - "rtc_configuration.js": Contains RTCPeerConnection configuration.
* - "quick_match.js": It is for the quick match function. Manages communication with the quick match server.
* - "quick_match_server_url.template.js": Fill this template the url of the quick match server and change
* the file name to "quick_match_server_url.js"
*/
'use strict';
import { settings } from '@pixi/settings';
import { SCALE_MODES } from '@pixi/constants';
import { Renderer, BatchRenderer, autoDetectRenderer } from '@pixi/core';
import { Prepare } from '@pixi/prepare';
import { Container } from '@pixi/display';
import { Loader } from '@pixi/loaders';
import { SpritesheetLoader } from '@pixi/spritesheet';
import { Ticker } from '@pixi/ticker';
import { CanvasRenderer } from '@pixi/canvas-renderer';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
import { CanvasPrepare } from '@pixi/canvas-prepare';
import '@pixi/canvas-display';
import { PikachuVolleyballOnline } from './pikavolley_online.js';
import { ASSETS_PATH } from './offline_version_js/assets_path.js';
import { channel } from './data_channel/data_channel.js';
import { setUpUI, setUpUIAfterLoadingGameAssets } from './ui_online.js';
import { setUpUIForBlockingOtherUsers } from './block_other_players/ui.js';
import { setGetSpeechBubbleNeeded } from './chat_display.js';
import '../style.css';
// To show two "with friend" on the menu
const TEXTURES = ASSETS_PATH.TEXTURES;
TEXTURES.WITH_COMPUTER = TEXTURES.WITH_FRIEND;
// Reference for how to use Renderer.registerPlugin:
// https://github.com/pixijs/pixijs/blob/af3c0c6bb15aeb1049178c972e4a14bb4cabfce4/bundles/pixi.js/src/index.ts#L27-L34
Renderer.registerPlugin('prepare', Prepare);
Renderer.registerPlugin('batch', BatchRenderer);
// Reference for how to use CanvasRenderer.registerPlugin:
// https://github.com/pixijs/pixijs/blob/af3c0c6bb15aeb1049178c972e4a14bb4cabfce4/bundles/pixi.js-legacy/src/index.ts#L13-L19
CanvasRenderer.registerPlugin('prepare', CanvasPrepare);
CanvasRenderer.registerPlugin('sprite', CanvasSpriteRenderer);
Loader.registerPlugin(SpritesheetLoader);
settings.RESOLUTION = 2;
settings.SCALE_MODE = SCALE_MODES.NEAREST;
settings.ROUND_PIXELS = true;
const renderer = autoDetectRenderer({
width: 432,
height: 304,
antialias: false,
backgroundColor: 0x000000,
backgroundAlpha: 1,
// Decided to use only Canvas for compatibility reason. One player had reported that
// on their browser, where pixi chooses to use WebGL renderer, the graphics are not fine.
// And the issue had been fixed by using Canvas renderer. And also for the sake of testing,
// it is more comfortable just to stick with Canvas renderer so that it is unnecessary to switch
// between WebGL renderer and Canvas renderer.
forceCanvas: true,
});
const stage = new Container();
const ticker = new Ticker();
const loader = new Loader();
document.querySelector('#game-canvas-container').appendChild(renderer.view);
renderer.render(stage); // To make the initial canvas painting stable in the Firefox browser.
loader.add(ASSETS_PATH.SPRITE_SHEET);
for (const prop in ASSETS_PATH.SOUNDS) {
loader.add(ASSETS_PATH.SOUNDS[prop]);
}
setUpLoaderProgressBar();
channel.callbackAfterDataChannelOpened = () => {
loader.load(setup);
};
setUpUI();
setUpUIForBlockingOtherUsers();
/**
* Set up the loader progress bar.
*/
function setUpLoaderProgressBar() {
const loadingBox = document.getElementById('loading-box');
const progressBar = document.getElementById('progress-bar');
loader.onProgress.add(() => {
progressBar.style.width = `${loader.progress}%`;
});
loader.onComplete.add(() => {
loadingBox.classList.add('hidden');
});
}
function setup() {
const pikaVolley = new PikachuVolleyballOnline(stage, loader.resources);
setUpUIAfterLoadingGameAssets(pikaVolley, ticker);
setGetSpeechBubbleNeeded(pikaVolley);
start(pikaVolley);
}
function start(pikaVolley) {
ticker.maxFPS = pikaVolley.normalFPS;
ticker.add(() => {
// Rendering and gameLoop order is the opposite of
// the offline web version (refer: ./offline_version_js/main.js).
// It's for the smooth rendering for the online version
// which gameLoop can not always succeed right on this "ticker.add"ed code
// because of the transfer delay or connection status. (If gameLoop here fails,
// it is recovered by the callback gameLoop which is called after peer input received.)
// Now the rendering is delayed 40ms (when pikaVolley.normalFPS == 25)
// behind gameLoop.
renderer.render(stage);
pikaVolley.gameLoop();
});
ticker.start();
}