multiplayer

This commit is contained in:
nemo 2024-11-19 14:48:38 +01:00
parent 05e1db36e4
commit 3a8f7f785f
5 changed files with 181 additions and 24 deletions

79
app.c
View File

@ -14,6 +14,7 @@ const unsigned int width = 800;
const unsigned int height = 600;
unsigned int BUFFER[width * height];
int id = 0;
int dir = 0;
// importer depuis js
int get_scale(void);
@ -29,6 +30,53 @@ v2 penger_pos = {width/2, height/2};
v2 velocity = {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)
{
return (v2) {
@ -252,8 +300,9 @@ void draw(float dt)
penger_pos.x += velocity.x;
}
if (id == 28) // fatger id
velocity.y += GRAVITY * dt * 7;
else
velocity.y += GRAVITY * dt;
velocity.y += GRAVITY * dt;
penger_pos.y += velocity.y;
if (velocity.x <= -0.1)
velocity.x += AIR_RESISTANCE * dt;
@ -296,6 +345,33 @@ void draw(float dt)
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
for (int y = 0; y < pengers_height[id]; y++) {
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;
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
continue;

View File

@ -5,7 +5,7 @@ if [[ "$1" == "clear" ]]; then
exit
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=""
for e in $export_sym; do
export_cmd="$export_cmd -Wl,--export=$e";
@ -53,6 +53,6 @@ rm pengers_image.html.temp
./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

View File

@ -57,7 +57,7 @@
<button id="play">Play</button>
</p>
<p>Players:</p>
<ul id="players"></ul>
<ul id="players">Not connected</ul>
<h3>Choose your penger:</h3>
</div>
</div>

82
load.js
View File

@ -1,19 +1,4 @@
const connection = new WebSocket('ws://localhost:4242');
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 is_connected = false;
var global_instance;
var global_memory;
@ -31,13 +16,18 @@ window.onload = () => {
pengers_img[i].onclick = (e) => {
var id = e.target.getAttribute('penger-id');
wasm_set_variable('id', id)
connection.send('{"name": "id", "value": "'+id+'"}');
connection.send('{"name": "id", "value": '+id+'}');
};
}
var play = document.getElementById('play');
var pseudo = document.getElementById('pseudo');
pseudo.onchange = play.onclick = () => {
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+'"}');
};
};
@ -55,6 +45,62 @@ function wasm_function(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() => {
// jsp, je l'ai pris de la: https://github.com/tsoding/olive.c
@ -111,7 +157,7 @@ let prev = null;
function first(timestamp) {
var id = Math.floor(Math.random() * document.getElementsByClassName('penger-img').length);
wasm_set_variable('id', id);
connection.send('{"name": "id", "value": "'+id+'"}');
connection.send('{"name": "id", "value": '+id+'}');
prev = timestamp;
wasm_function('draw')(0.16);
window.requestAnimationFrame(loop);

View File

@ -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>";
});
sockets.forEach((s) => {
if (s.game.pseudo == undefined || s.game.pseudo == "") return;
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) {
var url = req.url;
@ -60,20 +77,37 @@ http_server.listen(HTTP_PORT, () => {
const ws_server = new ws.Server({ port: WS_PORT });
var global_id = 0;
var sockets = [];
ws_server.on('connection', (socket) => {
socket.game = {};
socket.game.rid = global_id++;
socket.send('{"name": "rid", "value": '+socket.game.rid+'}');
sockets.push(socket);
console.log("connect: ", sockets.length);
socket.on('message', (msg) => {
var msg_str = Buffer.from(msg).toString('latin1');
var req = JSON.parse(msg_str);
socket.game[req.name] = req.value;
update_player_list();
if (req.name == "pseudo") {
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', () => {
sockets.forEach((s) => { s.send('{"name": "disconnect", "value": '+socket.game.rid+'}') });
sockets = sockets.filter(s => s !== socket);
console.log("close: ", sockets.length);
update_player_list();