forked from OmarShehata/tutsplus-glitch-multiplayer
-
Notifications
You must be signed in to change notification settings - Fork 15
/
index.html
276 lines (231 loc) · 12.5 KB
/
index.html
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
<html>
<head>
<meta charset="UTF-8" />
<title>Multiplayer Experiment</title>
<!-- Load the Phaser game library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/2.4.2/phaser.min.js"></script>
<!-- Load the Socket.io networking library -->
<script src="/socket.io/socket.io.js"></script>
<!-- Some simple styles and fonts -->
<style type="text/css">
body,html { /* Remove margins */
margin: 0px;
position: relative;
background-color:#9FC7E1;
}
canvas { /* Center the canvas */
margin:auto;
/*border: 1px solid black;*/
}
</style>
</head>
<body>
<script type="text/javascript">
var ASSET_URL = "assets/"
//We first initialize the phaser game object
var WINDOW_WIDTH = 750;
var WINDOW_HEIGHT = 500;
var game = new Phaser.Game(WINDOW_WIDTH, WINDOW_HEIGHT, Phaser.AUTO, '', {preload:preload, create:create, update:GameLoop} );
var WORLD_SIZE = {w:750,h:500};
var water_tiles = [];
var bullet_array = [];
var socket; //Declare it in this scope, initialize in the `create` function
var other_players = {};
var player = {
sprite:null,//Will hold the sprite when it's created
speed_x:0,// This is the speed it's currently moving at
speed_y:0,
speed:0.5, // This is the parameter for how fast it should move
friction:0.95,
shot:false,
update: function(){
// Lerp rotation towards mouse
var dx = (game.input.mousePointer.x + game.camera.x) - this.sprite.x;
var dy = (game.input.mousePointer.y + game.camera.y) - this.sprite.y;
var angle = Math.atan2(dy,dx) - Math.PI/2;
var dir = (angle - this.sprite.rotation) / (Math.PI * 2);
dir -= Math.round(dir);
dir = dir * Math.PI * 2;
this.sprite.rotation += dir * 0.1;
// Move forward
if(game.input.keyboard.isDown(Phaser.Keyboard.W) || game.input.keyboard.isDown(Phaser.Keyboard.UP)){
this.speed_x += Math.cos(this.sprite.rotation + Math.PI/2) * this.speed;
this.speed_y += Math.sin(this.sprite.rotation + Math.PI/2) * this.speed;
}
this.sprite.x += this.speed_x;
this.sprite.y += this.speed_y;
this.speed_x *= this.friction;
this.speed_y *= this.friction;
// Shoot bullet
if(game.input.activePointer.leftButton.isDown && !this.shot){
var speed_x = Math.cos(this.sprite.rotation + Math.PI/2) * 20;
var speed_y = Math.sin(this.sprite.rotation + Math.PI/2) * 20;
/* The server is now simulating the bullets, clients are just rendering bullet locations, so no need to do this anymore
var bullet = {};
bullet.speed_x = speed_x;
bullet.speed_y = speed_y;
bullet.sprite = game.add.sprite(this.sprite.x + bullet.speed_x,this.sprite.y + bullet.speed_y,'bullet');
bullet_array.push(bullet);
*/
this.shot = true;
// Tell the server we shot a bullet
socket.emit('shoot-bullet',{x:this.sprite.x,y:this.sprite.y,angle:this.sprite.rotation,speed_x:speed_x,speed_y:speed_y})
}
if(!game.input.activePointer.leftButton.isDown) this.shot = false;
// To make player flash when they are hit, set player.spite.alpha = 0
if(this.sprite.alpha < 1){
this.sprite.alpha += (1 - this.sprite.alpha) * 0.16;
} else {
this.sprite.alpha = 1;
}
// Tell the server we've moved
socket.emit('move-player',{x:this.sprite.x,y:this.sprite.y,angle:this.sprite.rotation})
}
};
function CreateShip(type,x,y,angle){
// type is an int that can be between 1 and 6 inclusive
// returns the sprite just created
var sprite = game.add.sprite(x,y,'ship' + String(type) + '_1');
sprite.rotation = angle;
sprite.anchor.setTo(0.5,0.5);
return sprite;
}
function preload(){
game.load.crossOrigin = "Anonymous";
game.stage.backgroundColor = "#3399DA";
// Load all the ships
for(var i=1;i<=6;i++){
game.load.image('ship'+String(i) +'_1', ASSET_URL + 'ship'+String(i)+'_1.png');
game.load.image('ship'+String(i) +'_2', ASSET_URL + 'ship'+String(i)+'_2.png');
game.load.image('ship'+String(i) +'_3', ASSET_URL + 'ship'+String(i)+'_3.png');
game.load.image('ship'+String(i) +'_4', ASSET_URL + 'ship'+String(i)+'_4.png');
}
game.load.image('bullet', ASSET_URL + 'cannon_ball.png');
game.load.image('water', ASSET_URL + 'water_tile.png');
}
function create(){
// Create water tiles
for(var i=0;i<=WORLD_SIZE.w/64+1;i++){
for(var j=0;j<=WORLD_SIZE.h/64+1;j++){
var tile_sprite = game.add.sprite(i * 64, j * 64, 'water');
tile_sprite.anchor.setTo(0.5,0.5);
tile_sprite.alpha = 0.5;
water_tiles.push(tile_sprite);
}
}
game.stage.disableVisibilityChange = true;
// Create player
var player_ship_type = String(1);
player.sprite = game.add.sprite(Math.random() * WORLD_SIZE.w/2 + WORLD_SIZE.w/2,Math.random() * WORLD_SIZE.h/2 + WORLD_SIZE.h/2,'ship'+player_ship_type+'_1');
player.sprite.anchor.setTo(0.5,0.5);
game.world.setBounds(0, 0, WORLD_SIZE.w, WORLD_SIZE.h);
game.camera.x = player.sprite.x - WINDOW_WIDTH/2;
game.camera.y = player.sprite.y - WINDOW_HEIGHT/2;
socket = io(); // This triggers the 'connection' event on the server
socket.emit('new-player',{x:player.sprite.x,y:player.sprite.y,angle:player.sprite.rotation,type:1})
// Listen for other players connecting
socket.on('update-players',function(players_data){
var players_found = {};
// Loop over all the player data received
for(var id in players_data){
// If the player hasn't been created yet
if(other_players[id] == undefined && id != socket.id){ // Make sure you don't create yourself
var data = players_data[id];
var p = CreateShip(data.type,data.x,data.y,data.angle);
other_players[id] = p;
console.log("Created new player at (" + data.x + ", " + data.y + ")");
}
players_found[id] = true;
// Update positions of other players
if(id != socket.id){
other_players[id].target_x = players_data[id].x; // Update target, not actual position, so we can interpolate
other_players[id].target_y = players_data[id].y;
other_players[id].target_rotation = players_data[id].angle;
}
}
// Check if a player is missing and delete them
for(var id in other_players){
if(!players_found[id]){
other_players[id].destroy();
delete other_players[id];
}
}
})
// Listen for bullet update events
socket.on('bullets-update',function(server_bullet_array){
// If there's not enough bullets on the client, create them
for(var i=0;i<server_bullet_array.length;i++){
if(bullet_array[i] == undefined){
bullet_array[i] = game.add.sprite(server_bullet_array[i].x,server_bullet_array[i].y,'bullet');
} else {
//Otherwise, just update it!
bullet_array[i].x = server_bullet_array[i].x;
bullet_array[i].y = server_bullet_array[i].y;
}
}
// Otherwise if there's too many, delete the extra
for(var i=server_bullet_array.length;i<bullet_array.length;i++){
bullet_array[i].destroy();
bullet_array.splice(i,1);
i--;
}
})
// Listen for any player hit events and make that player flash
socket.on('player-hit',function(id){
if(id == socket.id){
//If this is you
player.sprite.alpha = 0;
} else {
// Find the right player
other_players[id].alpha = 0;
}
})
}
function GameLoop(){
player.update();
// Move camera with player
var camera_x = player.sprite.x - WINDOW_WIDTH/2;
var camera_y = player.sprite.y - WINDOW_HEIGHT/2;
game.camera.x += (camera_x - game.camera.x) * 0.08;
game.camera.y += (camera_y - game.camera.y) * 0.08;
// Each player is responsible for bringing their alpha back up on their own client
// Make sure other players flash back to alpha = 1 when they're hit
for(var id in other_players){
if(other_players[id].alpha < 1){
other_players[id].alpha += (1 - other_players[id].alpha) * 0.16;
} else {
other_players[id].alpha = 1;
}
}
// Interpolate all players to where they should be
for(var id in other_players){
var p = other_players[id];
if(p.target_x != undefined){
p.x += (p.target_x - p.x) * 0.16;
p.y += (p.target_y - p.y) * 0.16;
// Intepolate angle while avoiding the positive/negative issue
var angle = p.target_rotation;
var dir = (angle - p.rotation) / (Math.PI * 2);
dir -= Math.round(dir);
dir = dir * Math.PI * 2;
p.rotation += dir * 0.16;
}
}
/* We're updating the bullets on the server, so we don't need to do this on the client anymore
// Update bullets
for(var i=0;i<bullet_array.length;i++){
var bullet = bullet_array[i];
bullet.sprite.x += bullet.speed_x;
bullet.sprite.y += bullet.speed_y;
// Remove if it goes too far off screen
if(bullet.sprite.x < -10 || bullet.sprite.x > WORLD_SIZE.w || bullet.sprite.y < -10 || bullet.sprite.y > WORLD_SIZE.h){
bullet.sprite.destroy();
bullet_array.splice(i,1);
i--;
}
}
*/
}
</script>
</body>
</html>