improve rendering

This commit is contained in:
Asraelite 2016-03-29 21:21:01 +01:00
parent c47ad92f21
commit 8a059b92d5
30 changed files with 286 additions and 260 deletions

Binary file not shown.

Binary file not shown.

View file

@ -1,59 +0,0 @@
@font-face {
font-family: 'FreePixel';
src: url("/css/FreePixel.ttf");
}
* {
margin: 0;
padding: 0;
font-family: FreePixel;
}
body {
overflow: hidden;
}
#gui {
color: #fff;
}
.container {
position: fixed;
}
#chat {
bottom: 0;
left: 0;
width: 400px;
max-height: 300px;
overflow: hidden;
background-color: rgba(0,0,0,0.55);
}
#chat #chat-messages > span {
display: block;
margin-top: 5px;
}
#chat #chat-messages > span > span {
color: #afa;
}
#chat #chat-messages > span > span.teama {
color: #f76;
}
#chat #chat-messages > span > span.teamb {
color: #8af;
}
#chat #chat-messages > span.server {
color: #68c;
}
#chat input {
font-family: inherit;
font-size: 16px;
border: 0;
display: block;
width: 100%;
padding: 2px 0 2px 0;
background-color: rgba(20,20,20,0.5);
}
#chat input:focus {
background-color: #eee;
}
#weapons {
bottom: 0;
left: 50%;
transform: translate(-50%, 0);
}

BIN
public/static/css/test.ttf Normal file

Binary file not shown.

BIN
public/static/img/space.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

View file

@ -13,8 +13,11 @@ Game.prototype.loadAssets = _ => {
},
turrets: {
'01': {
small: 'img/turrets/01/small.png'
small: 'img/turrets/01/normal.png'
}
},
backgrounds: {
'01': 'img/space.jpg'
}
}
}

View file

@ -0,0 +1,17 @@
GUI.prototype.Weapons = class {
constructor(gui) {
this.gui = gui;
this.element = this.gui.query('#weapons');
this.weaponElements = [];
this.currentWeapon = 0;
}
update() {
}
switchWeapon(slot) {
this.currentWeapon = 0;
}
}

View file

@ -17,6 +17,7 @@ class Net {
});
this.socket.on('update', data => {
window.q = data;
game.world.update(data);
});

View file

@ -1,29 +0,0 @@
Renderer.prototype.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, pos.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.clip();
context.fillStyle = body.debug ? `rgb(${body.debug}, 9, 9)` : '#090909';
context.fill();
context.lineWidth = 7;
context.strokeStyle = '#000';
context.stroke();
context.lineWidth = 3;
context.strokeStyle = '#fff';
context.stroke();
pallet.restore();
};

View file

@ -1,27 +1,113 @@
Renderer.prototype.renderBody = (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, pos.r);
var context = pallet.context;
var polys = body.frame;
for (var points of polys) {
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.lineWidth = 0.5;
context.strokeStyle = '#fff';
context.fillStyle = '#200';
context.fill();
context.stroke();
class BodyRenderer {
constructor(renderer) {
this.pallet = renderer.pallet;
this.canvas = this.pallet.canvas;
this.context = this.pallet.context;
}
pallet.restore();
render(body) {
let pos = body.getPos();
let x = pos.x * SCALE;
let y = pos.y * SCALE;
let vx = -game.world.center.x;
let vy = -game.world.center.y;
let pallet = this.pallet;
let context = pallet.context;
pallet.view(vx, vy, false, 0);
pallet.view(x, y, false, pos.r);
for (let f of body.fixtures) {
if (!f.type) continue;
let img = game.assets.images.turrets[f.type].small;
this.pallet.image(img, f.x - 32, f.y - 32, 0);
}
if (body.bodyType == 'ship') {
this.renderShip(body);
} else if (body.bodyType == 'asteroid') {
this.renderAsteroid(body);
} else {
this.renderBody(body);
}
pallet.restore();
}
renderAsteroid(body) {
// Mostly duplicated from renderBody however later on asteroids should
// be rendered differently so this is fine.
let polys = body.frame;
let context = this.context;
for (var points of polys) {
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.clip();
context.fillStyle = body.debug ? `rgb(${body.debug}, 9, 9)` : '#090909';
context.fill();
context.lineWidth = 7;
context.strokeStyle = '#000';
context.stroke();
context.lineWidth = 3;
context.strokeStyle = '#fff';
context.stroke();
}
this.pallet.restore();
}
renderBody(body) {
let polys = body.frame;
let context = this.context;
for (var points of polys) {
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.lineWidth = 0.5;
context.strokeStyle = '#fff';
context.fillStyle = '#200';
context.fill();
context.stroke();
}
this.pallet.restore();
}
renderShip(ship) {
let img = game.assets.images.ships[ship.hull].hull;
let teama = game.assets.images.ships[ship.hull].teama;
let teamb = game.assets.images.ships[ship.hull].teamb;
let thr0 = game.assets.images.ships[ship.hull].thrust0;
let thr8 = game.assets.images.ships[ship.hull].thrust8;
let pos = ship.pos;
this.pallet.image(ship.team == 'a' ? teama : teamb, 0, 0, 0);
this.pallet.image(img, 0, 0, 0);
this.pallet.image(ship.thrust.forward ? thr8 : thr0, 0, 0, 0);
if (ship.debug) {
this.pallet.square('#f00', ship.debug.x * SCALE, ship.debug.y * SCALE, 2);
}
this.pallet.restore();
}
renderShipNameplate(ship) {
let x = -game.world.center.x + ship.center.x * 32;
let y = -game.world.center.y + ship.center.y * 32 - 15;
this.pallet.opacity(0.3);
this.pallet.text(ship.name, x, y, '#fff', 'FreePixel', 16, 'center', 'bottom');
}
};

View file

@ -15,6 +15,8 @@ class Effect {
x: 0,
y: 0
};
} else if (this.type == 'engineTrail') {
this.createEngineTrail();
} else {
}
@ -22,24 +24,29 @@ class Effect {
generateParticles(_x, _y, radius, number, colors, sizes, bhv, lf, vel) {
for (var i = 0; i < number; i++) {
let x = _x + (Math.random() - 0.5) * radius * 2;
let y = _y + (Math.random() - 0.5) * radius * 2;
let color = colors[Math.random() * colors.length | 0];
let size = sizes[Math.random() * sizes.length | 0];
let angle = Math.random() * Math.PI * 2;
let v = Math.random() * vel + 0.1;
let xvel = Math.cos(angle) * v + (Math.random() - 0.5);
let yvel = Math.sin(angle) * v + (Math.random() - 0.5);
let p = new Particle(this, x, y, xvel, yvel, color, size, bhv, lf);
this.particles.add(p);
let speed = Math.random() * vel + 0.1;
let properties = {
x: _x + (Math.random() - 0.5) * radius * 2,
y: _y + (Math.random() - 0.5) * radius * 2,
color: colors[Math.random() * colors.length | 0],
size: sizes[Math.random() * sizes.length | 0],
xvel: Math.cos(angle) * speed + (Math.random() - 0.5),
yvel: Math.sin(angle) * speed + (Math.random() - 0.5),
behaviour: bhv,
lifetime: lf
};
let particle = new EffectParticle(this, properties);
this.particles.add(particle);
}
}
render() {
let x = this.pos.x * SCALE;
let y = this.pos.y * SCALE;
let vx = -game.world.getCenter().x;
let vy = -game.world.getCenter().y;
let vx = -game.world.center.x;
let vy = -game.world.center.y;
this.pallet.view(x + vx, y + vy, false, 0);
this.particles.forEach(p => {
@ -65,6 +72,10 @@ class Effect {
context.beginPath();
context.moveTo(posA.x * SCALE, posA.y * SCALE);
context.lineTo(posB.x * SCALE, posB.y * SCALE);
context.lineWidth = 4;
context.strokeStyle = '#000';
context.stroke();
context.lineWidth = 1;
context.strokeStyle = '#555';
context.stroke();
@ -74,12 +85,15 @@ class Effect {
}
// Effect generation.
createEngineTrail() {
this.generateParticles(0, 0, 2, 3, ['#ff8'], [3], '', 20, 1);
}
createExplosion() {
let num = this.size * this.size;
let colors = ['#f52', '#ff7', '#fff'];
let b = 'sizzle';
this.generateParticles(0, 0, 1, num, colors, [1, 2], b, 50, 3);
this.generateParticles(0, 0, 10, num, colors, [1, 2], b, 50, 2);
}
createRope() {

View file

@ -1,14 +1,17 @@
class Particle {
constructor(effect, x, y, xvel, yvel, color, size, behaviour, lifetime) {
class EffectParticle {
constructor(effect, properties) {
this.effect = effect;
this.x = x;
this.y = y;
this.xvel = xvel || 0;
this.yvel = yvel || 0;
this.color = color || '#f00';
this.size = size || 1;
this.behaviour = behaviour;
this.lifetime = lifetime * (1 + (Math.random() - 0.5) * 0.5) || 100;
this.x = properties.x || 0;
this.y = properties.y || 0;
this.xvel = properties.xvel || 0;
this.yvel = properties.yvel || 0;
this.color = properties.color || '#f00';
this.size = properties.size || 1;
this.behaviour = properties.behaviour;
this.lifetime = properties.lifetime || 50;
// Randomly adjust lifetime so not all particles die at once.
this.lifetime *= (1 + (Math.random() - 0.5) * 0.5) || 100;
}
tick() {

View file

@ -14,77 +14,80 @@ class Renderer {
pallet.fillScreen();
window.addEventListener('resize', _ => pallet.fillScreen(1000, 600));
this.bodyRenderer = new BodyRenderer(this);
}
render(state) {
let canvas = this.canvas;
let context = this.context;
let pallet = this.pallet;
let ship = game.world.playerShip;
let cpos = game.world.getCenter();
let cx = -cpos.x;
let cy = -cpos.y;
let cw = canvas.width;
let ch = canvas.height;
let cw = this.canvas.width;
let ch = this.canvas.height;
let center = game.world.center;
if (state == 'connecting' || state == 'disconnected') {
pallet.clear();
pallet.fill('#111');
this.pallet.clear();
this.pallet.fill('#111');
var str = state == 'connecting' ? 'Connecting' : 'Disconnected';
pallet.text(str, canvas.width / 2, canvas.height / 2, '#fff',
this.pallet.text(str, cw / 2, ch / 2, '#fff',
'FreePixel', 16, 'center', 'middle');
return;
}
pallet.clear();
pallet.fill('#020202');
this.pallet.clear();
this.pallet.fill('#020202');
context.save();
this.context.save();
pallet.view(cw / 2, ch / 2, 1, 0);
//context.translate(-cx / s, -cy / s);
this.pallet.view(cw / 2, ch / 2, 1, 0);
// Grid
var gridx = cx % 50;
var gridy = cy % 50;
pallet.opacity(0.05);
for (var x = gridx - cw / 2 - 50; x < cw + 50; x += 50) {
for (var y = gridy - ch / 2 - 50; y < ch + 50; y += 50) {
var wx = (-cx + x) / SCALE;
var wy = (-cy + y) / SCALE;
var b = game.world.bounds;
if (wx > b.right || wx < b.left || wy > b.bottom || wy < b.top) {
pallet.opacity(0.2);
pallet.outline('#8af', x, y, 51, 51, 1);
pallet.opacity(0.05);
} else pallet.outline('#fff', x, y, 51, 51, 1);
}
}
pallet.opacity(1);
this.pallet.opacity(0.3);
let img = game.assets.images.backgrounds['01'];
let bgx = -img.width / 2 - center.x / 20;
let bgy = -img.height / 2 - center.y / 20;
this.pallet.image(img, bgx, bgy);
this.pallet.opacity(1);
this.renderGrid();
for (var id in game.world.bodies) {
var body = game.world.bodies[id];
if (body.bodyType == 'ship') {
this.renderShip(pallet, body);
} else if (body.bodyType == 'asteroid') {
this.renderAsteroid(pallet, body);
} else {
this.renderBody(pallet, body);
// Render structures, projectiles etc..
}
this.bodyRenderer.render(game.world.bodies[id]);
}
this.effects.forEach(effect => {
effect.render();
});
pallet.restore();
for (var id in game.world.bodies) {
if (game.world.bodies[id].bodyType == 'ship')
this.bodyRenderer.renderShipNameplate(game.world.bodies[id]);
}
this.pallet.restore();
}
renderGrid() {
let cpos = game.world.center;
let cx = -cpos.x;
let cy = -cpos.y;
let cw = this.canvas.width;
let ch = this.canvas.height;
var gridx = cx % 50;
var gridy = cy % 50;
this.pallet.opacity(0.05);
for (var x = gridx - cw / 2 - 50; x < cw + 50; x += 50) {
for (var y = gridy - ch / 2 - 50; y < ch + 50; y += 50) {
var wx = (-cx + x) / SCALE;
var wy = (-cy + y) / SCALE;
var b = game.world.bounds;
if (wx > b.right || wx < b.left || wy > b.bottom || wy < b.top) {
this.pallet.opacity(0.2);
this.pallet.outline('#8af', x, y, 51, 51, 1);
this.pallet.opacity(0.05);
} else this.pallet.outline('#fff', x, y, 51, 51, 1);
}
}
this.pallet.opacity(1);
}
addEffect(data) {

View file

@ -1,35 +0,0 @@
Renderer.prototype.renderShip = (pallet, ship) => {
let img = game.assets.images.ships[ship.hull].hull;
let teama = game.assets.images.ships[ship.hull].teama;
let teamb = game.assets.images.ships[ship.hull].teamb;
let thr0 = game.assets.images.ships[ship.hull].thrust0;
let thr5 = game.assets.images.ships[ship.hull].thrust5;
let thr8 = game.assets.images.ships[ship.hull].thrust8;
let turr = game.assets.images.turrets['01'].small;
//pallet.view(ship.x, ship.y, false, ship.r);
let pos = ship.getPos();
let x = pos.x * SCALE;
let y = pos.y * SCALE;
let vx = -game.world.getCenter().x;
let vy = -game.world.getCenter().y;
pallet.view(x + vx, y + vy, false, pos.r);
let ts = ship.size / 2;
for (let i = 0; i < ship.fixtures.length; i++) {
if (ship.fixtures[i]) {
pallet.image(turr, ship.fixtures[i][0] - ts, ship.fixtures[i][1] - ts, 0);
}
}
pallet.image(ship.team == 'a' ? teama : teamb, 0, 0, 0);
pallet.image(img, 0, 0, 0);
pallet.image(ship.thrust.forward ? thr8 : thr0, 0, 0, 0);
if (ship.debug) {
pallet.square('#f00', ship.debug.x * SCALE, ship.debug.y * SCALE, 2);
}
pallet.restore();
//pallet.text(ship.name, x + vx | 0, y + vy | 0, '#fff', 'FreePixel', 16, 'center', 'bottom');
}

View file

@ -2,7 +2,6 @@
class Body {
constructor(data) {
console.log(data);
this.interface = data.interface;
let s = this.interface.order.length + this.interface.fixtures;
this.interface.size = s;
@ -21,13 +20,7 @@ class Body {
}
getPos() {
var pos = this.b2body.GetPosition();
var angle = this.b2body.GetAngle();
return {
x: pos.x,
y: pos.y,
r: angle
};
return this.pos;
}
applyForce(x, y) {
@ -62,4 +55,22 @@ class Body {
tick() {
}
get center() {
let pos = this.b2body.GetWorldCenter();
return {
x: pos.x,
y: pos.y
};
}
get pos() {
let pos = this.b2body.GetPosition();
let angle = this.b2body.GetAngle();
return {
x: pos.x,
y: pos.y,
r: angle
};
}
}

View file

@ -14,11 +14,6 @@ class World {
}
}
// Deprecated
getCenter() {
return this.center;
};
add(data) {
var body;
if (data.type == 'asteroid') body = new Asteroid(data);

View file

@ -1,17 +1,23 @@
@font-face {
font-family: 'FreePixel';
src: url('/css/FreePixel.ttf');
}
@font-face
font-family 'FreePixel'
src url('/css/FreePixel.ttf')
* {
margin: 0;
padding: 0;
font-family: FreePixel;
}
@font-face
font-family 'PixelArial'
src url('/css/PixelArial11.ttf')
body {
overflow: hidden;
}
*
margin 0
padding 0
body
overflow hidden
font-family FreePixel
font-size 16px
.small
font-family PixelArial
font-size 8px
#gui
color #fff
@ -38,13 +44,15 @@ body {
color #68c
input
font-family inherit
font-size 16px
font-size inherit
border 0
display block
width 100%
padding 2px 0 2px 0
background-color rgba(20, 20, 20, 0.5)
height 0
&:focus
height inherit
background-color #eee
#weapons
bottom 0

View file

@ -21,6 +21,7 @@
"Dragonfruit",
"Durian",
"Elderberry",
"Etrog",
"Feijoa",
"Fig",
"Goji Berry",
@ -100,7 +101,9 @@
],
"c": [
"Crazy",
"Cool"
"Cool",
"Cute",
"Careful"
],
"d": [
"Dizzy",
@ -108,7 +111,8 @@
],
"e": [
"Energetic",
"Easy"
"Easy",
"Evil"
],
"f": [
"Funny",

View file

@ -22,11 +22,12 @@ class Body {
this.rvel = data.rvel || 0;
this.mounts = data.mounts || [];
this.fixtures = data.fixtures || [];
this.health = data.health || 1;
this.mounts = this.mounts.map(m => new Mount(this, m));
let fixtures = data.fixtures || [];
this.fixtures = this.mounts.map((m, i) => fixtures[i] || 0);
this.mounts = this.mounts.map((m, i) => {
let fixture = this.fixtures[i];
return new Mount(this, m, fixture);
});
this.interface = {
order: [
@ -38,7 +39,7 @@ class Body {
'rvel'
],
type: 'body',
fixtures: this.fixtures.length
fixtures: this.mounts.length
};
}

View file

@ -36,10 +36,10 @@ class Grapple extends Projectile {
}
connect() {
let p1 = { x: 0, y: 0.5 };
let p1 = { x: 0.1, y: 0.5 };
let p2 = { x: 0.0625, y: 0 };
this.rope = new Rope(this.player.ship, this, p1, p2);
this.rope.initLength = 6;
this.rope.initLength = 8;
this.world.addCopula(this.rope);
}

View file

@ -9,7 +9,8 @@ class Ship extends Body {
constructor(world, pos, player, build) {
build = build || defaults.spawnShip;
let traits = shipTraits[build.ship];
super(world, traits, build);
traits.fixtures = build.fixtures;
super(world, traits);
// Body data.
this.x = pos.x || 0;

View file

@ -6,8 +6,6 @@ const Laser = require('./shot/laser.js');
class Blaster extends Fixture {
constructor(hardpoint, data) {
super(hardpoint, data);
console.log(data);
}
fire() {

View file

@ -23,7 +23,6 @@ class Fixture {
packFull() {
return {
traversal: this.traversal
}
}

View file

@ -7,7 +7,7 @@ class Mount {
this.ship = ship;
this.type = data.type || 'turret';
this.fixture = false;
this.fixture = fixture || false;
this.size = data.size || 0;
this.position = {
x: data.pos[0],
@ -24,7 +24,7 @@ class Mount {
destruct() {
if (!this.fixture) return;
this.fixture.destruct();
//this.fixture.destruct();
}
packDelta() {
@ -32,14 +32,14 @@ class Mount {
}
updateDeltaInterface() {
this.deltaInterface = this.fixture ? ['traversal'] : [];
this.deltaInterface = ['traversal'];
}
packFull() {
return {
x: this.position.x,
y: this.position.y,
turret: this.turret ? this.turret.type : 0
type: this.fixture ? this.fixture : 0
};
}
}

View file

@ -171,7 +171,8 @@ class World {
this.tps = this.tpsCount / 5 | 0;
this.tpsCount = 0;
this.tpsStart = Date.now();
//console.log('TPS: ' + this.tps);
if(this.tps < 50)
wingbase.warning(`${this.room.name} TPS: ${this.tps}`);
}
this.tpsCount++;

View file

@ -35,7 +35,11 @@ class ServerInterface {
}
error(msg) {
this.log(msg, 'red');
this.log(msg, 'red', 'bold');
}
warning(msg) {
this.log(msg, 'yellow');
}
capLogfile() {