add asteroids

This commit is contained in:
Asraelite 2016-03-22 18:34:11 +00:00
parent 0ceea5f4af
commit 0aa259b874
17 changed files with 246 additions and 37 deletions

View file

@ -25,8 +25,8 @@ class Player {
});
}
sendWorld() {
this.connection.send('world', this.ship.id);
sendWorld(data) {
this.connection.send('world', data);
}
sendUpdate() {

View file

@ -20,7 +20,7 @@ class Room {
this.players.add(player);
this.setTeam(player, this.teamA.size > this.teamB.size ? 'b' : 'a');
this.world.addPlayer(player);
player.sendWorld();
this.sendWorld(player);
}
remove(player) {
@ -42,7 +42,17 @@ class Room {
self.players.forEach(player => player.sendUpdate());
}
sendWorld(player) {
let data = {
playerShipId: player.ship.id,
bodies: Array.from(this.world.bodies).map(b => b.packFull())
};
player.sendWorld(data);
}
start() {
this.world.populate();
this.world.start();
this.interval = setInterval(_ => this.update(this), 1 / 60);
}

View file

@ -0,0 +1,39 @@
'use strict';
const Body = require('./body.js');
class Asteroid extends Body {
constructor(world, pos, size) {
super(world);
this.x = pos.x;
this.y = pos.y;
this.type = 'asteroid';
this.size = size;
this.frame = this.randomFrame();
}
randomFrame() {
let s = this.size;
let l = (Math.random() * 4 + 4) | 0;
let build = Array(l).fill().map(_ => Math.random() * Math.PI * 2);
build = build.sort().map(a => [Math.cos(a) * s, Math.sin(a) * s]);
return [build];
}
packTypeDelta() {
return [];
}
packFull() {
return {
type: 'asteroid',
id: this.id,
frame: this.frame,
delta: this.packDelta()
}
}
}
module.exports = Asteroid;

View file

@ -10,14 +10,14 @@ class Body {
this.y = 0;
this.r = 0;
this.b2body = false;
this.type = 'dynamic';
this.type = 'asteroid';
this.health = 1;
this.world = world;
this.id = uuid.v4().slice(0, 8);
}
applyDelta() {
this.world.applyDelta(this.id, this.pack());
this.world.applyDelta(this.id, this.packDelta());
}
applyForce(x, y, center) {
@ -29,11 +29,22 @@ class Body {
this.b2body.ApplyTorque(f);
}
pack() {
packDelta() {
let pos = this.b2body.GetPosition();
let vel = this.b2body.GetLinearVelocity();
let rot = this.b2body.GetAngleRadians();
let rvel = this.b2body.GetAngularVelocity();
return [pos.x, pos.y, rot];
// Simple array to save bandwidth.
return [pos.x, pos.y, vel.x, vel.y, rot, rvel].concat(this.packTypeDelta());
}
packTypeDelta() {
throw new Error('Attempt to pack raw body.');
}
packFull() {
throw new Error('Attempt to pack raw body.');
}
}

View file

@ -1,5 +1,6 @@
'use strict';
const Asteroid = require('./asteroid.js');
const Physics = require('./physics.js');
const Ship = require('./ship.js');
@ -15,17 +16,42 @@ class World {
addPlayer(player) {
this.players.add(player);
let ship = new Ship(this, player);
let pos = {
x: player.team == 'b' ? 200 : 0,
y: 0
};
let ship = new Ship(this, pos, player);
player.ship = ship;
this.ships.set(player, ship);
this.addShip(ship);
}
addShip(ship) {
this.ships.set(ship.player, ship);
this.bodies.add(ship);
this.physics.createBody(ship);
}
addAsteroid(asteroid) {
this.asteroids.add(asteroid);
this.bodies.add(asteroid);
this.physics.createBody(asteroid);
}
applyDelta(body, data) {
this.players.forEach(player => player.delta[body] = data);
}
populate() {
for (var i = 0; i < 20; i++) {
let pos = {
x: Math.random() * 2000 - 200,
y: Math.random() * 500 - 250
};
let asteroid = new Asteroid(this, pos, Math.random() * 50 + 10);
this.addAsteroid(asteroid);
}
}
removePlayer(player) {
this.removeBody(player.ship);
this.ships.delete(player);

View file

@ -10,13 +10,31 @@ const Box2D = require('box2d-html5');
const b2Vec2 = Box2D.b2Vec2;
Box2D.b2Settings.b2_linearSleepTolerance = 0.0002;
class Physics {
constructor() {
this.world = new Box2D.b2World(new b2Vec2(0, 0), false);
this.toRemove = [];
let onContact = contact => {
let bodya = contact.GetFixtureA().GetBody().GetUserData();
let bodyb = contact.GetFixtureB().GetBody().GetUserData();
bodya.applyDelta();
bodyb.applyDelta();
}
let listener = new Box2D.b2ContactListener();
listener.BeginContact = onContact;
listener.EndContact = onContact;
this.world.SetContactListener(listener);
}
createBody(body) {
//console.log(Object.keys(Box2D.b2Settings).sort());
//console.log(Box2D.b2Settings.b2_linearSleepTolerance = 0.002);
let s = SCALE;
let bodyDef = new Box2D.b2BodyDef();
bodyDef.userData = body;
@ -25,19 +43,19 @@ class Physics {
bodyDef.active = true;
bodyDef.linearVelocity = new b2Vec2(body.xvel / s || 0, body.yvel / s || 0);
bodyDef.angularVelocity = body.rvel || 0;
bodyDef.linearDamping = 0.001;
bodyDef.angularDamping = 0.001;
bodyDef.type = body.type == 'static' ?
bodyDef.linearDamping = body.type == 'ship' ? 0.001 : 0.0003;
bodyDef.angularDamping = body.type == 'ship' ? 0.001 : 0.0003;
bodyDef.type = body.type == 'structure' ?
Box2D.b2BodyType.b2_staticBody : Box2D.b2BodyType.b2_dynamicBody;
if (body.player) bodyDef.allowSleep = false;
if (body.player || true) bodyDef.allowSleep = false;
let b2body = this.world.CreateBody(bodyDef);
let fixtureDef = new Box2D.b2FixtureDef();
fixtureDef.density = 10;
fixtureDef.friction = 1;
fixtureDef.restitution = 0;
fixtureDef.restitution = 1;
for (var poly of body.structure) {
for (var poly of body.frame) {
poly = poly.map(vertex => new b2Vec2(vertex[0] / s, vertex[1] / s));
fixtureDef.shape = new Box2D.b2PolygonShape();
fixtureDef.shape.SetAsArray(poly, poly.length);
@ -45,6 +63,7 @@ class Physics {
}
body.b2body = b2body;
//console.log(Object.keys(b2body).sort());
}
step() {

View file

@ -6,12 +6,21 @@ const hulls = require('./traits/hulls.json');
const Body = require('./body.js');
class Ship extends Body {
constructor(world, player, build) {
constructor(world, pos, player, build) {
super(world);
this.build = build || defaults.spawnShip.build;
this.player = player;
this.structure = hulls[this.build.hull];
this.frame = hulls[this.build.hull];
this.type = 'ship';
this.thrust = {
forward: 0,
left: 0,
right: 0
}
this.power = this.build.power;
}
move(data) {
@ -25,20 +34,36 @@ class Ship extends Body {
}
if (data.forward) {
let power = 0.002;
let power = this.power.forward;
let x = Math.cos(this.b2body.GetAngleRadians()) * power;
let y = Math.sin(this.b2body.GetAngleRadians()) * power;
this.applyForce(x, y);
}
if (data.left) {
this.applyTorque(-0.0001);
this.applyTorque(-this.power.rotation);
}
if (data.right) {
this.applyTorque(0.0001);
this.applyTorque(this.power.rotation);
}
}
packTypeDelta() {
let t = this.thrust;
return [t.forward, t.left, t.right];
}
packFull() {
return {
type: 'ship',
id: this.id,
team: this.player.team,
build: this.build,
delta: this.packDelta()
};
}
}
module.exports = Ship;

View file

@ -2,7 +2,12 @@
"spawnShip": {
"build": {
"hull": "01",
"turrets": [0]
"turrets": [0],
"power": {
"forward": 0.0015,
"back": 0,
"rotation": 0.0001
}
}
}
}