Skip to content

Commit

Permalink
add tanks_emit example
Browse files Browse the repository at this point in the history
  • Loading branch information
jbakse committed Jan 12, 2022
1 parent 2abab15 commit bbb8916
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 0 deletions.
6 changes: 6 additions & 0 deletions public/examples/tanks_emit/README.md
@@ -0,0 +1,6 @@
# tanks

- **asdw** move tank
- **space** to fire

> Open this example in two browser windows at once!
29 changes: 29 additions & 0 deletions public/examples/tanks_emit/index.html
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="../sketch.css" />
<style>
body {
display: flex;
}
#create {
padding: 10px;
}
#shared {
background: #eee;
white-space: pre;
}
</style>
</head>
<body>
<div id="canvas-wrap"></div>
<div id="shared"></div>
<script src="https://unpkg.com/uuid@latest/dist/umd/uuidv4.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>

<script src="/dist/p5.party.js"></script>

<script src="index.js"></script>
</body>
</html>
133 changes: 133 additions & 0 deletions public/examples/tanks_emit/index.js
@@ -0,0 +1,133 @@
/* global uuidv4 */
/* global partyEmit partySubscribe*/

class Rect {
constructor(l = 0, t = 0, w = 0, h = 0) {
this.l = l;
this.t = t;
this.w = w;
this.h = h;
}
}

class Point {
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
}
}

function pointInRect(p, r) {
return p.x > r.l && p.x < r.l + r.w && p.y > r.t && p.y < r.t + r.h;
}

const bounds = new Rect(0, 0, 400, 400);

let shared, me, participants;

function preload() {
partyConnect("wss://deepstream-server-1.herokuapp.com", "tanks", "main");
shared = partyLoadShared("shared");
me = partyLoadMyShared();
participants = partyLoadParticipantShareds();
}

function setup() {
createCanvas(400, 400).parent("canvas-wrap");

noStroke();

if (partyIsHost()) {
shared.bullets = [];
}
me.tank = { x: 100, y: 100, a: 0 };

// hosting can change mid-game so every client subscribes, and then checks if it is host on every event

partySubscribe("createBullet", createBullet);
}

function draw() {
checkKeys();
showData();
if (partyIsHost()) stepGame();
drawScene();
}

function stepGame() {
// step bullets
shared.bullets.forEach(stepBullet);
}

function showData() {
document.getElementById("shared").innerText = JSON.stringify(
shared,
null,
"\t"
);
}
function drawScene() {
background("#cc6666");
shared.bullets.forEach(drawBullet);
for (const p of participants) {
if (p.tank) drawTank(p.tank);
}
}

function drawTank(tank) {
push();
rectMode(CENTER);
translate(tank.x, tank.y);
rotate(tank.a);
rect(0, 0, 30, 30);
rect(0, -20, 5, 5);
pop();
}

function createBullet(b) {
if (partyIsHost()) shared.bullets.push(b);
}

function stepBullet(b) {
b.x += b.dX;
b.y += b.dY;
if (!pointInRect(b, bounds)) {
const i = shared.bullets.indexOf(b);
shared.bullets.splice(i, 1);
}
}

function drawBullet(b) {
push();
ellipse(b.x, b.y, 10, 10);
pop();
}

function keyPressed() {
if (key === " ") {
partyEmit("createBullet", {
x: me.tank.x,
y: me.tank.y,
dX: sin(me.tank.a) * 6,
dY: -cos(me.tank.a) * 6,
});
}

return false;
}
function checkKeys() {
// forward
if (keyIsDown(87) /*w*/) {
me.tank.x += sin(me.tank.a) * 3;
me.tank.y -= cos(me.tank.a) * 3;
}

// backward
if (keyIsDown(83) /*s*/) {
me.tank.x += sin(me.tank.a) * -1;
me.tank.y -= cos(me.tank.a) * -1;
}

if (keyIsDown(65) /*a*/) me.tank.a -= radians(2);
if (keyIsDown(68) /*d*/) me.tank.a += radians(2);
}
26 changes: 26 additions & 0 deletions public/examples/tanks_emit/notes.md
@@ -0,0 +1,26 @@
when two players try to alter the same share object at the same time, one or the other share object "wins"

even if the changes are to different properties of the shared object, one change is lost

this commonly happens when the host is trying to animate some data in a shared object (like moving a bullet) and another player tires to change _anything_ in the same shared object

i just tried working around this by having players add bullets in their own shared object and the host moves them over into the main shared.

this way the players don't write to shared at all

it partly worked but...

now the player writes new bullets to its own participant share + the host removes bullets from that share so they are both writing to the same share. If the player is writing to it a lot (like the player is turning when the shot is fired) we end up with the same kind of problem.

possible solution:
create a second global shared
all particpants write new bullets there
host consumes them
now we have multiple players + hosts writing to the same record, but not rapidly.

This is starting to look a lot like a message sending or event scheme. And deepstream does have Event stuff built in, and maybe that should be exposed by p5.party?

https://deepstream.io/tutorials/core/pubsub/

con - more complixty to the API
pro - maybe less complexity/workarounds in sketch code

0 comments on commit bbb8916

Please sign in to comment.