diff --git a/app.c b/app.c index 29da7f5..94df354 100644 --- a/app.c +++ b/app.c @@ -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; diff --git a/build.sh b/build.sh index 832fc2a..1b939ad 100755 --- a/build.sh +++ b/build.sh @@ -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 diff --git a/index.html.template b/index.html.template index a24967f..c1ca7ce 100644 --- a/index.html.template +++ b/index.html.template @@ -57,7 +57,7 @@

Players:

- +

Choose your penger:

diff --git a/load.js b/load.js index c5827bf..c93fbc4 100644 --- a/load.js +++ b/load.js @@ -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); diff --git a/server.js b/server.js index 9312fbe..a6a05c6 100644 --- a/server.js +++ b/server.js @@ -13,10 +13,27 @@ function update_player_list() list += "
  • " + s.game.pseudo + "
  • "; }); 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();