Compare commits
2 Commits
e1a194075f
...
cc7373f7b3
Author | SHA1 | Date |
---|---|---|
|
cc7373f7b3 | |
|
31abc99058 |
|
@ -6,3 +6,4 @@ hand.c
|
|||
index.html
|
||||
museum.c
|
||||
pengers.h
|
||||
node_modules/
|
||||
|
|
11
README.md
11
README.md
|
@ -1,10 +1,3 @@
|
|||
# WASM test
|
||||
# PENGER PARTY
|
||||
|
||||
this is a test to understand how wasm work, this repo contains exemple of :
|
||||
|
||||
- compiling wasm module from c
|
||||
- loading wasm module in js
|
||||
- importing / exporting symbol
|
||||
- PENGER
|
||||
|
||||
it's also a 'template' for copy pasting js boilerplate.
|
||||
Let's penger together
|
||||
|
|
50
app.c
50
app.c
|
@ -114,7 +114,7 @@ Collision collision_union(Collision rec1, Collision rec2)
|
|||
return overlap;
|
||||
}
|
||||
|
||||
void collision_rec(Collision fix, int i, int scale)
|
||||
Collision collision_rec(Collision fix, int i, int scale)
|
||||
{
|
||||
Collision col = collision_union(fix, (Collision) {
|
||||
.x = penger_pos.x - pengers_width[id]*scale/2,
|
||||
|
@ -122,23 +122,24 @@ void collision_rec(Collision fix, int i, int scale)
|
|||
.width = pengers_width[id]*scale,
|
||||
.height = pengers_height[id]*scale,
|
||||
});
|
||||
if (col.width == 0 && col.height == 0) return;
|
||||
if (col.width == 1 && col.height == 1) return;
|
||||
if (col.width == 0 && col.height == 0) return col;
|
||||
if (col.width == 1 && col.height == 1) return col;
|
||||
|
||||
float div = -1.8;
|
||||
if (col.width <= col.height) {
|
||||
if (fix.x + fix.width == col.x + col.width)
|
||||
penger_pos.x = fix.x + fix.width + pengers_width[id]*scale/2 + 1;
|
||||
penger_pos.x = fix.x + fix.width + pengers_width[id]*scale/2;
|
||||
else if (fix.x == col.x)
|
||||
penger_pos.x = col.x - pengers_width[id]*scale/2 + 1;
|
||||
velocity.x /= div;
|
||||
} else {
|
||||
if (fix.y + fix.height == col.y + col.height)
|
||||
penger_pos.y = fix.y + fix.height + pengers_height[id]*scale/2 + 1;
|
||||
penger_pos.y = fix.y + fix.height + pengers_height[id]*scale/2;
|
||||
else if (fix.y == col.y)
|
||||
penger_pos.y = col.y - pengers_height[id]*scale/2 + 1;
|
||||
velocity.y /= div;
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
void set_velocity(float x, float y)
|
||||
|
@ -189,31 +190,31 @@ void init()
|
|||
int col_id = 0;
|
||||
collisions[col_id++] = (Collision) {
|
||||
.x = 100,
|
||||
.y = 450,
|
||||
.y = 400,
|
||||
.width = 50,
|
||||
.height = 100,
|
||||
};
|
||||
collisions[col_id++] = (Collision) {
|
||||
.x = 150,
|
||||
.y = 500,
|
||||
.y = 450,
|
||||
.width = 500,
|
||||
.height = 50,
|
||||
};
|
||||
collisions[col_id++] = (Collision) {
|
||||
.x = 650,
|
||||
.y = 450,
|
||||
.y = 400,
|
||||
.width = 50,
|
||||
.height = 100,
|
||||
};
|
||||
collisions[col_id++] = (Collision) {
|
||||
.x = 280,
|
||||
.y = 250,
|
||||
.y = 200,
|
||||
.width = 75,
|
||||
.height = 75,
|
||||
};
|
||||
collisions[col_id++] = (Collision) {
|
||||
.x = 445,
|
||||
.y = 250,
|
||||
.y = 200,
|
||||
.width = 75,
|
||||
.height = 75,
|
||||
};
|
||||
|
@ -250,6 +251,8 @@ void draw(float dt)
|
|||
if ((!keys[ARROW_LEFT] || !keys[Q]) && (!keys[ARROW_RIGHT] || !keys[D])) {
|
||||
penger_pos.x += velocity.x;
|
||||
}
|
||||
if (id == 28) // fatger id
|
||||
velocity.y += GRAVITY * dt;
|
||||
velocity.y += GRAVITY * dt;
|
||||
penger_pos.y += velocity.y;
|
||||
if (velocity.x <= -0.1)
|
||||
|
@ -260,18 +263,25 @@ void draw(float dt)
|
|||
penger_pos.x += velocity.x;
|
||||
|
||||
// movement
|
||||
int x_collide = 0;
|
||||
float speed = 100.0f * dt;
|
||||
if (keys[SHIFT])
|
||||
speed /= 2.0f;
|
||||
|
||||
if (keys[ARROW_RIGHT] || keys[D]) {
|
||||
penger_pos.x += speed;
|
||||
if (velocity.x < 0) velocity.x *= -1;
|
||||
if (velocity.x < 0) {
|
||||
velocity.x *= -1;
|
||||
x_collide = 1;
|
||||
}
|
||||
else if (velocity.x >= -EPSILON) velocity.x = speed;
|
||||
}
|
||||
if (keys[ARROW_LEFT] || keys[Q]) {
|
||||
penger_pos.x -= speed;
|
||||
if (velocity.x > 0) velocity.x *= -1;
|
||||
if (velocity.x > 0) {
|
||||
velocity.x *= -1;
|
||||
x_collide = 1;
|
||||
}
|
||||
else if (velocity.x <= EPSILON) velocity.x = -speed;
|
||||
}
|
||||
|
||||
|
@ -282,17 +292,27 @@ void draw(float dt)
|
|||
rebondi(&penger_pos, scale);
|
||||
|
||||
for (int i = 0; i < NB_COLLISIONS; i++) {
|
||||
collision_rec(collisions[i], i, scale);
|
||||
Collision col = collision_rec(collisions[i], i, scale);
|
||||
x_collide = x_collide || (col.height > 1);
|
||||
}
|
||||
|
||||
// dessine le penger sur le canva
|
||||
for (int y = 0; y < pengers_height[id]; y++) {
|
||||
for (int i = 0; i < pengers_width[id]; i++) {
|
||||
int i_for_reverse_pixel_rendering_it_s_craazy = i;
|
||||
if (velocity.x < EPSILON)
|
||||
int i_for_reverse_pixel_rendering_it_s_craazy = 0;
|
||||
static int last_dir = 1;
|
||||
if ((velocity.x < -EPSILON && !x_collide) || last_dir == -1) {
|
||||
i_for_reverse_pixel_rendering_it_s_craazy = pengers_width[id]-i-1;
|
||||
last_dir = -1;
|
||||
}
|
||||
if ((velocity.x > EPSILON && !x_collide) || last_dir == 1) {
|
||||
i_for_reverse_pixel_rendering_it_s_craazy = i;
|
||||
last_dir = 1;
|
||||
}
|
||||
|
||||
if (pengers_img[id][y*pengers_width[id] + i_for_reverse_pixel_rendering_it_s_craazy] <= 0x00FFFFFF) // pixel transparant
|
||||
continue;
|
||||
|
||||
for (int s1 = 0; s1 < scale; s1++) {
|
||||
for (int s2 = 0; s2 < scale; s2++) {
|
||||
int idx_x = penger_origin.x + i*scale+s1;
|
||||
|
|
|
@ -3,8 +3,10 @@ version: "3"
|
|||
services:
|
||||
web:
|
||||
container_name: "web"
|
||||
image: "httpd"
|
||||
image: "node"
|
||||
ports:
|
||||
- "6969:80"
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- ".:/usr/local/apache2/htdocs/"
|
||||
- ".:/app"
|
||||
command: "node /app/server.js"
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
width: 64px;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
.players-img {
|
||||
margin-right: 10px;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 1.5em;
|
||||
|
@ -47,6 +50,14 @@
|
|||
<p>Penger is afraid of your stinky hand</p>
|
||||
</div>
|
||||
<div id="right">
|
||||
<h3>Multiplayer:</h3>
|
||||
<p>
|
||||
play with the pseudo name:
|
||||
<input id="pseudo" placeholder="Penger Lover" />
|
||||
<button id="play">Play</button>
|
||||
</p>
|
||||
<p>Players:</p>
|
||||
<ul id="players"></ul>
|
||||
<h3>Choose your penger:</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
|
61
load.js
61
load.js
|
@ -1,8 +1,46 @@
|
|||
var scale = 2;
|
||||
const connection = new WebSocket('ws://localhost:8080');
|
||||
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_memory;
|
||||
|
||||
var scale = 2;
|
||||
|
||||
window.onload = () => {
|
||||
var canvas = document.getElementById("demo-canvas");
|
||||
canvas.onmousemove = (e) => {
|
||||
var r = canvas.getBoundingClientRect();
|
||||
wasm_function('set_mouse')(e.clientX - r.x, e.clientY - r.y);
|
||||
}
|
||||
var pengers_img = document.getElementsByClassName('penger-img');
|
||||
for (var i = 0; i < pengers_img.length; i++) {
|
||||
pengers_img[i].onclick = (e) => {
|
||||
var id = e.target.getAttribute('penger-id');
|
||||
wasm_set_variable('id', id)
|
||||
connection.send('{"name": "id", "value": "'+id+'"}');
|
||||
};
|
||||
}
|
||||
var play = document.getElementById('play');
|
||||
play.onclick = () => {
|
||||
var pseudo = document.getElementById('pseudo').value;
|
||||
connection.send('{"name": "pseudo", "value": "'+pseudo+'"}');
|
||||
};
|
||||
};
|
||||
|
||||
function wasm_variable(name)
|
||||
{
|
||||
return global_memory[global_instance.exports[name].value / 4];
|
||||
|
@ -16,18 +54,6 @@ function wasm_function(name)
|
|||
return global_instance.exports[name];
|
||||
}
|
||||
|
||||
window.onload = () => {
|
||||
var canvas = document.getElementById("demo-canvas");
|
||||
var pengers_img = document.getElementsByClassName('penger-img');
|
||||
canvas.onmousemove = (e) => {
|
||||
var r = canvas.getBoundingClientRect();
|
||||
wasm_function('set_mouse')(e.clientX - r.x, e.clientY - r.y);
|
||||
}
|
||||
for (var i = 0; i < pengers_img.length; i++) {
|
||||
pengers_img[i].onclick = (e) => {wasm_set_variable('id', e.target.getAttribute('penger-id'))}
|
||||
}
|
||||
};
|
||||
|
||||
(async() => {
|
||||
|
||||
// jsp, je l'ai pris de la: https://github.com/tsoding/olive.c
|
||||
|
@ -82,7 +108,9 @@ wasm_function('init')();
|
|||
|
||||
let prev = null;
|
||||
function first(timestamp) {
|
||||
wasm_set_variable('id', Math.random() * document.getElementsByClassName('penger-img').length);
|
||||
var id = Math.floor(Math.random() * document.getElementsByClassName('penger-img').length);
|
||||
wasm_set_variable('id', id);
|
||||
connection.send('{"name": "id", "value": "'+id+'"}');
|
||||
prev = timestamp;
|
||||
wasm_function('draw')(0.16);
|
||||
window.requestAnimationFrame(loop);
|
||||
|
@ -97,7 +125,12 @@ function loop(timestamp) {
|
|||
}
|
||||
window.requestAnimationFrame(first);
|
||||
|
||||
var is_on_canva = false;
|
||||
document.getElementById("demo-canvas").addEventListener("mouseenter", () => {is_on_canva = true;});
|
||||
document.getElementById("demo-canvas").addEventListener("mouseout", () => {is_on_canva = false;});
|
||||
|
||||
addEventListener('keydown', (e) => {
|
||||
if (!is_on_canva) return;
|
||||
wasm_function('key_pressed')(e.keyCode);
|
||||
if(["Space","ArrowLeft","ArrowRight"].indexOf(e.code) > -1) {
|
||||
e.preventDefault();
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "webassembly",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "webassembly",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"ws": "^8.18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
||||
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "webassembly",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "load.js",
|
||||
"scripts": {
|
||||
"start": "node server.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/CaptainBoulbi/wasm-test.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/CaptainBoulbi/wasm-test/issues"
|
||||
},
|
||||
"homepage": "https://github.com/CaptainBoulbi/wasm-test#readme",
|
||||
"dependencies": {
|
||||
"ws": "^8.18.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
const fs = require('fs');
|
||||
const http = require("http");
|
||||
const ws = require('ws');
|
||||
|
||||
const HTTP_PORT = 80;
|
||||
const WS_PORT = 8080;
|
||||
const DIR = "/app";
|
||||
|
||||
function update_player_list()
|
||||
{
|
||||
var list = "";
|
||||
sockets.forEach((s) => { if (s.game.pseudo == undefined || s.game.pseudo == "") return; list += "<li><img class='players-img' penger-id='"+s.game.id+"' src='museum/Penger.png'>" + s.game.pseudo + "</li>"; });
|
||||
sockets.forEach((s) => { s.send('{"name": "pseudo", "value": "'+list+'"}'); });
|
||||
}
|
||||
|
||||
const requestListener = function (req, res) {
|
||||
var url = req.url;
|
||||
|
||||
if (url == "/" || url == "/index.html") {
|
||||
res.setHeader("Content-Type", "text/html");
|
||||
res.writeHead(200);
|
||||
res.end(fs.readFileSync(DIR + "/index.html"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (url == "/app.wasm") {
|
||||
res.setHeader("Content-Type", "application/wasm");
|
||||
res.writeHead(200);
|
||||
res.end(fs.readFileSync(DIR + url));
|
||||
return;
|
||||
}
|
||||
|
||||
if (url == "/load.js") {
|
||||
res.setHeader("Content-Type", "text/javascript");
|
||||
res.writeHead(200);
|
||||
res.end(fs.readFileSync(DIR + url));
|
||||
return;
|
||||
}
|
||||
|
||||
if (url.startsWith("/museum/")) {
|
||||
res.setHeader("Content-Type", "image/png");
|
||||
res.writeHead(200);
|
||||
res.end(fs.readFileSync(DIR + url));
|
||||
return;
|
||||
}
|
||||
|
||||
res.setHeader("Content-Type", "text/html");
|
||||
res.writeHead(404);
|
||||
res.end(`Page not found`);
|
||||
};
|
||||
|
||||
const http_server = http.createServer(requestListener);
|
||||
http_server.listen(HTTP_PORT, () => {
|
||||
console.log(`Server is running on port ${HTTP_PORT}`);
|
||||
});
|
||||
|
||||
const ws_server = new ws.Server({ port: WS_PORT });
|
||||
|
||||
var sockets = [];
|
||||
ws_server.on('connection', (socket) => {
|
||||
socket.game = {};
|
||||
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();
|
||||
console.log(socket.game);
|
||||
});
|
||||
|
||||
socket.on('close', () => {
|
||||
sockets = sockets.filter(s => s !== socket);
|
||||
console.log("close: ", sockets.length);
|
||||
update_player_list();
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue