add asteroids
This commit is contained in:
parent
0ceea5f4af
commit
0aa259b874
17 changed files with 246 additions and 37 deletions
|
@ -16,11 +16,16 @@ function Net() {
|
|||
|
||||
this.socket.on('update', function(data) {
|
||||
game.world.update(data);
|
||||
window.q = data;
|
||||
});
|
||||
|
||||
this.socket.on('world', function(data) {
|
||||
game.world.clear();
|
||||
game.world.playerShipId = data;
|
||||
console.log(data);
|
||||
game.world.playerShipId = data.playerShipId;
|
||||
for (var i in data.bodies) {
|
||||
game.world.add(data.bodies[i]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -31,4 +36,8 @@ function Net() {
|
|||
right: move[2]
|
||||
});
|
||||
}
|
||||
|
||||
this.send = function(msg, data) {
|
||||
this.socket.emit(msg, data);
|
||||
}
|
||||
}
|
||||
|
|
22
public/js/starbugs/render/asteroids.js
Normal file
22
public/js/starbugs/render/asteroids.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
function renderAsteroid(pallet, body) {
|
||||
var pos = body.getPos();
|
||||
var x = pos.x * SCALE;
|
||||
var y = pos.y * SCALE;
|
||||
var vx = -game.world.getCenter().x;
|
||||
var vy = -game.world.getCenter().y;
|
||||
|
||||
pallet.view(x + vx, y + vy, false, body.r);
|
||||
|
||||
var context = pallet.context;
|
||||
var points = body.frame[0];
|
||||
context.beginPath();
|
||||
context.moveTo(points[0][0], points[0][1]);
|
||||
for (var i = 1; i < points.length; i++) {
|
||||
context.lineTo(points[i][0], points[i][1]);
|
||||
}
|
||||
context.closePath();
|
||||
context.strokeStyle = '#fff';
|
||||
context.stroke();
|
||||
|
||||
pallet.restore();
|
||||
}
|
|
@ -51,6 +51,8 @@ function Renderer() {
|
|||
|
||||
if (body.bodyType == 'ship') {
|
||||
renderShip(pallet, body);
|
||||
} else if (body.bodyType == 'asteroid') {
|
||||
renderAsteroid(pallet, body);
|
||||
} else {
|
||||
pallet.rect('#338', body.x, body.y, 10, 10);
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ function renderShip(pallet, ship) {
|
|||
var thr8 = game.assets.images.ships[ship.hull].thrust8;
|
||||
//pallet.view(ship.x, ship.y, false, ship.r);
|
||||
var pos = ship.getPos();
|
||||
var x = pos.x + 16;
|
||||
var y = pos.y + 16;
|
||||
var x = pos.x;
|
||||
var y = pos.y;
|
||||
var vx = -game.world.getCenter().x;
|
||||
var vy = -game.world.getCenter().y;
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
function Body() {
|
||||
|
||||
}
|
21
public/js/starbugs/world/asteroid.js
Normal file
21
public/js/starbugs/world/asteroid.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
function Asteroid(data) {
|
||||
this.id = data.id;
|
||||
this.x = data.delta[0];
|
||||
this.y = data.delta[1];
|
||||
this.r = data.delta[2];
|
||||
this.bodyType = 'asteroid';
|
||||
this.frame = data.frame;
|
||||
|
||||
this.getPos = function() {
|
||||
return {
|
||||
x: this.x,
|
||||
y: this.y
|
||||
};
|
||||
}
|
||||
|
||||
this.update = function(data) {
|
||||
this.x = data[0];
|
||||
this.y = data[1];
|
||||
this.r = data[4];
|
||||
}
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
function Ship(id) {
|
||||
this.id = id;
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.r = 0;
|
||||
function Ship(data) {
|
||||
this.id = data.id;
|
||||
this.x = data.delta[0];
|
||||
this.y = data.delta[1];
|
||||
this.r = data.delta[4];
|
||||
this.xvel = data.delta[2];
|
||||
this.yvel = data.delta[3];
|
||||
this.rvel = data.delta[5];
|
||||
this.hull = '01';
|
||||
this.move = [];
|
||||
this.lastMove = [];
|
||||
|
@ -21,6 +24,14 @@ function Ship(id) {
|
|||
}
|
||||
}
|
||||
|
||||
this.update = function (data) {
|
||||
this.x = data[0];
|
||||
this.y = data[1];
|
||||
this.xvel = data[2];
|
||||
this.yvel = data[3];
|
||||
this.r = data[4];
|
||||
}
|
||||
|
||||
this.updateMove = function() {
|
||||
if (JSON.stringify(this.move) != JSON.stringify(this.lastMove) || true) {
|
||||
game.net.update(this.move);
|
||||
|
|
|
@ -22,6 +22,19 @@ function World() {
|
|||
return { x: x, y: y };
|
||||
}
|
||||
|
||||
this.add = function(data) {
|
||||
var body;
|
||||
if (data.type == 'asteroid') body = new Asteroid(data);
|
||||
if (data.type == 'ship') body = new Ship(data);
|
||||
if (data.type == 'structure') body = new Structure(data);
|
||||
|
||||
this.bodies[body.id] = body;
|
||||
}
|
||||
|
||||
this.remove = function(id) {
|
||||
delete this.bodies[id];
|
||||
}
|
||||
|
||||
this.clear = function() {
|
||||
this.bodies = {};
|
||||
this.playerShip = false;
|
||||
|
@ -32,15 +45,14 @@ function World() {
|
|||
|
||||
for (var id in data) {
|
||||
if (!this.bodies[id]) {
|
||||
this.bodies[id] = new Ship(id);
|
||||
game.net.send('requestBodyData', id);
|
||||
continue;
|
||||
}
|
||||
|
||||
var body = this.bodies[id];
|
||||
body.x = data[id][0];
|
||||
body.y = data[id][1];
|
||||
body.r = data[id][2];
|
||||
|
||||
body.update(data[id]);
|
||||
|
||||
if (data[id].destroy) delete this.bodies[id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ class Player {
|
|||
});
|
||||
}
|
||||
|
||||
sendWorld() {
|
||||
this.connection.send('world', this.ship.id);
|
||||
sendWorld(data) {
|
||||
this.connection.send('world', data);
|
||||
}
|
||||
|
||||
sendUpdate() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
|
@ -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.');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -2,7 +2,12 @@
|
|||
"spawnShip": {
|
||||
"build": {
|
||||
"hull": "01",
|
||||
"turrets": [0]
|
||||
"turrets": [0],
|
||||
"power": {
|
||||
"forward": 0.0015,
|
||||
"back": 0,
|
||||
"rotation": 0.0001
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue