multiplayer
This commit is contained in:
parent
05e1db36e4
commit
3a8f7f785f
79
app.c
79
app.c
|
@ -14,6 +14,7 @@ const unsigned int width = 800;
|
||||||
const unsigned int height = 600;
|
const unsigned int height = 600;
|
||||||
unsigned int BUFFER[width * height];
|
unsigned int BUFFER[width * height];
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
int dir = 0;
|
||||||
|
|
||||||
// importer depuis js
|
// importer depuis js
|
||||||
int get_scale(void);
|
int get_scale(void);
|
||||||
|
@ -29,6 +30,53 @@ v2 penger_pos = {width/2, height/2};
|
||||||
v2 velocity = {0, 0};
|
v2 velocity = {0, 0};
|
||||||
v2 mouse = {0, 0};
|
v2 mouse = {0, 0};
|
||||||
|
|
||||||
|
float get_pos_x(void)
|
||||||
|
{
|
||||||
|
return penger_pos.x - pengers_width[id];
|
||||||
|
}
|
||||||
|
float get_pos_y(void)
|
||||||
|
{
|
||||||
|
return penger_pos.y - pengers_height[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct Player {
|
||||||
|
int rid, id, x, y, dir;
|
||||||
|
} Player;
|
||||||
|
|
||||||
|
#define MAX_PLAYERS 20
|
||||||
|
Player players[MAX_PLAYERS] = {0};
|
||||||
|
int nb_players = 0;
|
||||||
|
|
||||||
|
void deco_player(int rid)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < nb_players; i++) {
|
||||||
|
if (players[i].rid == rid) {
|
||||||
|
players[i].rid = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_player(int rid, int id, int x, int y, int dir)
|
||||||
|
{
|
||||||
|
if (nb_players >= MAX_PLAYERS) return;
|
||||||
|
for (int i = 0; i < nb_players; i++) {
|
||||||
|
if (players[i].rid == rid) {
|
||||||
|
players[i].id = id;
|
||||||
|
players[i].x = x;
|
||||||
|
players[i].y = y;
|
||||||
|
players[i].dir = dir;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
players[nb_players].rid = rid;
|
||||||
|
players[nb_players].id = id;
|
||||||
|
players[nb_players].x = x;
|
||||||
|
players[nb_players].y = y;
|
||||||
|
players[nb_players].dir = dir;
|
||||||
|
nb_players++;
|
||||||
|
}
|
||||||
|
|
||||||
v2 v2_diff(v2 vec1, v2 vec2)
|
v2 v2_diff(v2 vec1, v2 vec2)
|
||||||
{
|
{
|
||||||
return (v2) {
|
return (v2) {
|
||||||
|
@ -252,8 +300,9 @@ void draw(float dt)
|
||||||
penger_pos.x += velocity.x;
|
penger_pos.x += velocity.x;
|
||||||
}
|
}
|
||||||
if (id == 28) // fatger id
|
if (id == 28) // fatger id
|
||||||
|
velocity.y += GRAVITY * dt * 7;
|
||||||
|
else
|
||||||
velocity.y += GRAVITY * dt;
|
velocity.y += GRAVITY * dt;
|
||||||
velocity.y += GRAVITY * dt;
|
|
||||||
penger_pos.y += velocity.y;
|
penger_pos.y += velocity.y;
|
||||||
if (velocity.x <= -0.1)
|
if (velocity.x <= -0.1)
|
||||||
velocity.x += AIR_RESISTANCE * dt;
|
velocity.x += AIR_RESISTANCE * dt;
|
||||||
|
@ -296,6 +345,33 @@ void draw(float dt)
|
||||||
x_collide = x_collide || (col.height > 1);
|
x_collide = x_collide || (col.height > 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dessine le penger des autres joueur
|
||||||
|
for (int p = 0; p < nb_players; p ++) {
|
||||||
|
Player player = players[p];
|
||||||
|
if (player.rid == -1) continue;
|
||||||
|
int scale = 2;
|
||||||
|
for (int y = 0; y < pengers_height[player.id]; y++) {
|
||||||
|
for (int i = 0; i < pengers_width[player.id]; i++) {
|
||||||
|
int real_i = i;
|
||||||
|
if (player.dir == -1)
|
||||||
|
real_i = pengers_width[player.id]-i-1;
|
||||||
|
|
||||||
|
if (pengers_img[player.id][y*pengers_width[player.id] + real_i] <= 0x00FFFFFF) // pixel transparant
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int s1 = 0; s1 < scale; s1++) {
|
||||||
|
for (int s2 = 0; s2 < scale; s2++) {
|
||||||
|
int idx_x = player.x + i*scale+s1;
|
||||||
|
int idx_y = player.y + y*scale+s2;
|
||||||
|
if (idx_x < 0 || idx_x >= width || idx_y < 0 || idx_y >= height)
|
||||||
|
continue;
|
||||||
|
BUFFER[idx_y*width + idx_x] = pengers_img[player.id][y*pengers_width[player.id] + real_i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// dessine le penger sur le canva
|
// dessine le penger sur le canva
|
||||||
for (int y = 0; y < pengers_height[id]; y++) {
|
for (int y = 0; y < pengers_height[id]; y++) {
|
||||||
for (int i = 0; i < pengers_width[id]; i++) {
|
for (int i = 0; i < pengers_width[id]; i++) {
|
||||||
|
@ -309,6 +385,7 @@ void draw(float dt)
|
||||||
i_for_reverse_pixel_rendering_it_s_craazy = i;
|
i_for_reverse_pixel_rendering_it_s_craazy = i;
|
||||||
last_dir = 1;
|
last_dir = 1;
|
||||||
}
|
}
|
||||||
|
dir = last_dir;
|
||||||
|
|
||||||
if (pengers_img[id][y*pengers_width[id] + i_for_reverse_pixel_rendering_it_s_craazy] <= 0x00FFFFFF) // pixel transparant
|
if (pengers_img[id][y*pengers_width[id] + i_for_reverse_pixel_rendering_it_s_craazy] <= 0x00FFFFFF) // pixel transparant
|
||||||
continue;
|
continue;
|
||||||
|
|
4
build.sh
4
build.sh
|
@ -5,7 +5,7 @@ if [[ "$1" == "clear" ]]; then
|
||||||
exit
|
exit
|
||||||
fi;
|
fi;
|
||||||
|
|
||||||
export_sym="init draw key_pressed key_released set_velocity set_mouse BUFFER width height id"
|
export_sym="init draw key_pressed key_released set_velocity set_mouse get_pos_x get_pos_y draw_player deco_player BUFFER width height id nb_players dir"
|
||||||
export_cmd=""
|
export_cmd=""
|
||||||
for e in $export_sym; do
|
for e in $export_sym; do
|
||||||
export_cmd="$export_cmd -Wl,--export=$e";
|
export_cmd="$export_cmd -Wl,--export=$e";
|
||||||
|
@ -53,6 +53,6 @@ rm pengers_image.html.temp
|
||||||
|
|
||||||
./png2c "hand.png" > hand.c
|
./png2c "hand.png" > hand.c
|
||||||
|
|
||||||
clang -O2 --target=wasm32 -fno-builtin -nostdlib --no-standard-libraries -Wl,--no-entry $export_cmd -Wl,--allow-undefined -o $f.wasm $a
|
clang -O3 --target=wasm32 -fno-builtin -nostdlib --no-standard-libraries -Wl,--no-entry $export_cmd -Wl,--allow-undefined -o $f.wasm $a
|
||||||
|
|
||||||
wasm2wat $f.wasm > $f.wat
|
wasm2wat $f.wasm > $f.wat
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
<button id="play">Play</button>
|
<button id="play">Play</button>
|
||||||
</p>
|
</p>
|
||||||
<p>Players:</p>
|
<p>Players:</p>
|
||||||
<ul id="players"></ul>
|
<ul id="players">Not connected</ul>
|
||||||
<h3>Choose your penger:</h3>
|
<h3>Choose your penger:</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
82
load.js
82
load.js
|
@ -1,19 +1,4 @@
|
||||||
const connection = new WebSocket('ws://localhost:4242');
|
var is_connected = false;
|
||||||
connection.onmessage = (e) => {
|
|
||||||
var req = JSON.parse(e.data);
|
|
||||||
if (req.name == 'pseudo') {
|
|
||||||
document.getElementById('players').innerHTML = req.value;
|
|
||||||
var pengers_img = document.getElementsByClassName('penger-img');
|
|
||||||
var list = [];
|
|
||||||
for (var i = 0; i < pengers_img.length; i++) {
|
|
||||||
list[list.length] = pengers_img[i].src;
|
|
||||||
}
|
|
||||||
var players_img = document.getElementsByClassName('players-img');
|
|
||||||
for (var i = 0; i < players_img.length; i++) {
|
|
||||||
players_img[i].src = list[players_img[i].getAttribute('penger-id')];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var global_instance;
|
var global_instance;
|
||||||
var global_memory;
|
var global_memory;
|
||||||
|
@ -31,13 +16,18 @@ window.onload = () => {
|
||||||
pengers_img[i].onclick = (e) => {
|
pengers_img[i].onclick = (e) => {
|
||||||
var id = e.target.getAttribute('penger-id');
|
var id = e.target.getAttribute('penger-id');
|
||||||
wasm_set_variable('id', id)
|
wasm_set_variable('id', id)
|
||||||
connection.send('{"name": "id", "value": "'+id+'"}');
|
connection.send('{"name": "id", "value": '+id+'}');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var play = document.getElementById('play');
|
var play = document.getElementById('play');
|
||||||
var pseudo = document.getElementById('pseudo');
|
var pseudo = document.getElementById('pseudo');
|
||||||
pseudo.onchange = play.onclick = () => {
|
pseudo.onchange = play.onclick = () => {
|
||||||
var pseudo = document.getElementById('pseudo').value;
|
var pseudo = document.getElementById('pseudo').value;
|
||||||
|
if (pseudo == "") {
|
||||||
|
is_connected = false;
|
||||||
|
wasm_set_variable('nb_players', 0);
|
||||||
|
document.getElementById('players').innerHTML = "Not connected";
|
||||||
|
}
|
||||||
connection.send('{"name": "pseudo", "value": "'+pseudo+'"}');
|
connection.send('{"name": "pseudo", "value": "'+pseudo+'"}');
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -55,6 +45,62 @@ function wasm_function(name)
|
||||||
return global_instance.exports[name];
|
return global_instance.exports[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const connection = new WebSocket(document.URL.replace('http', 'ws').replace('6969', '4242'));
|
||||||
|
// const connection = new WebSocket('ws://localhost:4242');
|
||||||
|
connection.onopen = (e) => { console.log("connection to server opened"); };
|
||||||
|
connection.onmessage = (e) => {
|
||||||
|
var req = JSON.parse(e.data);
|
||||||
|
console.log(req);
|
||||||
|
if (req.name == 'pseudo') {
|
||||||
|
if (req.value != "") is_connected = true;
|
||||||
|
document.getElementById('players').innerHTML = req.value;
|
||||||
|
var pengers_img = document.getElementsByClassName('penger-img');
|
||||||
|
var list = [];
|
||||||
|
for (var i = 0; i < pengers_img.length; i++) {
|
||||||
|
list[list.length] = pengers_img[i].src;
|
||||||
|
}
|
||||||
|
var players_img = document.getElementsByClassName('players-img');
|
||||||
|
for (var i = 0; i < players_img.length; i++) {
|
||||||
|
players_img[i].src = list[players_img[i].getAttribute('penger-id')];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (req.name == "rid") {
|
||||||
|
my_rid = req.value;
|
||||||
|
}
|
||||||
|
else if (req.name == "pos") {
|
||||||
|
var players = req.value;
|
||||||
|
for (var i = 0; i < players.length; i++) {
|
||||||
|
var player = players[i];
|
||||||
|
if (player.rid == my_rid) continue;
|
||||||
|
wasm_function('draw_player')(player.rid, player.id, player.x, player.y, player.dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (req.name == "disconnect") {
|
||||||
|
wasm_function('deco_player')(req.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
connection.onclose = (e) => {
|
||||||
|
console.log("connection to server closed");
|
||||||
|
is_connected = false;
|
||||||
|
wasm_set_variable('nb_players', 0);
|
||||||
|
document.getElementById('players').innerHTML = "Not connected";
|
||||||
|
};
|
||||||
|
|
||||||
|
var update_time_ms = 100;
|
||||||
|
function send_pos()
|
||||||
|
{
|
||||||
|
if (is_connected) {
|
||||||
|
var rep = {};
|
||||||
|
rep.name = "pos";
|
||||||
|
rep.x = wasm_function("get_pos_x")();
|
||||||
|
rep.y = wasm_function("get_pos_y")();
|
||||||
|
rep.dir = wasm_variable("dir");
|
||||||
|
connection.send(JSON.stringify(rep));
|
||||||
|
}
|
||||||
|
setTimeout(send_pos, update_time_ms);
|
||||||
|
}
|
||||||
|
setTimeout(send_pos, update_time_ms);
|
||||||
|
|
||||||
(async() => {
|
(async() => {
|
||||||
|
|
||||||
// jsp, je l'ai pris de la: https://github.com/tsoding/olive.c
|
// jsp, je l'ai pris de la: https://github.com/tsoding/olive.c
|
||||||
|
@ -111,7 +157,7 @@ let prev = null;
|
||||||
function first(timestamp) {
|
function first(timestamp) {
|
||||||
var id = Math.floor(Math.random() * document.getElementsByClassName('penger-img').length);
|
var id = Math.floor(Math.random() * document.getElementsByClassName('penger-img').length);
|
||||||
wasm_set_variable('id', id);
|
wasm_set_variable('id', id);
|
||||||
connection.send('{"name": "id", "value": "'+id+'"}');
|
connection.send('{"name": "id", "value": '+id+'}');
|
||||||
prev = timestamp;
|
prev = timestamp;
|
||||||
wasm_function('draw')(0.16);
|
wasm_function('draw')(0.16);
|
||||||
window.requestAnimationFrame(loop);
|
window.requestAnimationFrame(loop);
|
||||||
|
|
38
server.js
38
server.js
|
@ -13,10 +13,27 @@ function update_player_list()
|
||||||
list += "<li><img class='players-img' penger-id='"+s.game.id+"' src='museum/Penger.png'>" + s.game.pseudo + "</li>";
|
list += "<li><img class='players-img' penger-id='"+s.game.id+"' src='museum/Penger.png'>" + s.game.pseudo + "</li>";
|
||||||
});
|
});
|
||||||
sockets.forEach((s) => {
|
sockets.forEach((s) => {
|
||||||
|
if (s.game.pseudo == undefined || s.game.pseudo == "") return;
|
||||||
s.send('{"name": "pseudo", "value": "'+list+'"}');
|
s.send('{"name": "pseudo", "value": "'+list+'"}');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var update_time_ms = 100;
|
||||||
|
function update_player_pos()
|
||||||
|
{
|
||||||
|
var list = [];
|
||||||
|
sockets.forEach((s) => {
|
||||||
|
if (s.game.pseudo == undefined || s.game.pseudo == "") return;
|
||||||
|
list[list.length] = {rid: s.game.rid, id: s.game.id, x: s.game.x, y: s.game.y, dir: s.game.dir};
|
||||||
|
});
|
||||||
|
sockets.forEach((s) => {
|
||||||
|
if (s.game.pseudo == undefined || s.game.pseudo == "") return;
|
||||||
|
s.send('{"name": "pos", "value": '+JSON.stringify(list)+'}');
|
||||||
|
});
|
||||||
|
setTimeout(update_player_pos, update_time_ms);
|
||||||
|
}
|
||||||
|
setTimeout(update_player_pos, update_time_ms);
|
||||||
|
|
||||||
const requestListener = function (req, res) {
|
const requestListener = function (req, res) {
|
||||||
var url = req.url;
|
var url = req.url;
|
||||||
|
|
||||||
|
@ -60,20 +77,37 @@ http_server.listen(HTTP_PORT, () => {
|
||||||
|
|
||||||
const ws_server = new ws.Server({ port: WS_PORT });
|
const ws_server = new ws.Server({ port: WS_PORT });
|
||||||
|
|
||||||
|
var global_id = 0;
|
||||||
|
|
||||||
var sockets = [];
|
var sockets = [];
|
||||||
ws_server.on('connection', (socket) => {
|
ws_server.on('connection', (socket) => {
|
||||||
socket.game = {};
|
socket.game = {};
|
||||||
|
socket.game.rid = global_id++;
|
||||||
|
socket.send('{"name": "rid", "value": '+socket.game.rid+'}');
|
||||||
sockets.push(socket);
|
sockets.push(socket);
|
||||||
console.log("connect: ", sockets.length);
|
console.log("connect: ", sockets.length);
|
||||||
|
|
||||||
socket.on('message', (msg) => {
|
socket.on('message', (msg) => {
|
||||||
var msg_str = Buffer.from(msg).toString('latin1');
|
var msg_str = Buffer.from(msg).toString('latin1');
|
||||||
var req = JSON.parse(msg_str);
|
var req = JSON.parse(msg_str);
|
||||||
socket.game[req.name] = req.value;
|
if (req.name == "pseudo") {
|
||||||
update_player_list();
|
socket.game.pseudo = req.value;
|
||||||
|
if (req.value == "") sockets.forEach((s) => { s.send('{"name": "disconnect", "value": '+socket.game.rid+'}') });
|
||||||
|
update_player_list();
|
||||||
|
}
|
||||||
|
else if (req.name == "id") {
|
||||||
|
socket.game.id = req.value;
|
||||||
|
update_player_list();
|
||||||
|
}
|
||||||
|
else if (req.name == "pos") {
|
||||||
|
socket.game.x = req.x;
|
||||||
|
socket.game.y = req.y;
|
||||||
|
socket.game.dir = req.dir;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('close', () => {
|
socket.on('close', () => {
|
||||||
|
sockets.forEach((s) => { s.send('{"name": "disconnect", "value": '+socket.game.rid+'}') });
|
||||||
sockets = sockets.filter(s => s !== socket);
|
sockets = sockets.filter(s => s !== socket);
|
||||||
console.log("close: ", sockets.length);
|
console.log("close: ", sockets.length);
|
||||||
update_player_list();
|
update_player_list();
|
||||||
|
|
Loading…
Reference in New Issue