Más contenido relacionado Game architecture is different1. Game architecture is different
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
2. Is game architecture different?
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
4. Conclusion:
Entity systems are better
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
6. Code statistics
Entities (Ember) MVC (Robotlegs)
38 classes 30 classes
1047 lines of code 1092 lines of code
26710 characters of code 25915 characters of code
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
7. Robotlegs Mediators
Model Commands AsteroidsMediator
SpaceshipMediator
GameState CreateAsteroid
AsteroidMediator
GameSize CreateBullet
BulletMediator
Spaceship CreateSpaceship
SpaceshipContainer RouteInput Views
Asteroid StartGame
Asteroids
AsteroidContainer StartGame
SpaceshipView
Bullet Update
AsteroidView
BulletContainer
BulletView
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
8. Ember
Components
Nodes Systems (Processes)
Spaceship
MotionControlNode ProcessManager
Asteroid
GunControlNode GameManager
Views
Gun
BulletAgeNode MotionControlSystem SpaceshipView
Bullet
MovementNode GunControlSystem AsteroidView
GameState
SpaceshipCollisionNode BulletAgeSystem BulletView
Position
AsteroidCollisionNode MovementSystem
Motion
BulletCollisionNode CollisionSystem
Display
RenderNode RendersSystem
MotionControls
GunControls
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
9. Evolution of entity systems
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
10. The game loop
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
11. function update( time:Number ):void
{
game.update( time );
spaceship.updateInputs( time );
for each( var flyingSaucer:FlyingSaucer in flyingSaucers )
flyingSaucer.updateAI( time );
spaceship.update( time );
for each( var flyingSaucer:FlyingSaucer in flyingSaucers )
flyingSaucer.update( time );
for each( var asteroid:Asteroid in asteroids )
asteroid.update( time );
for each( var bullet:Bullet in bullets )
bullet.update( time );
collisionManager.update( time );
spaceship.render();
for each( var flyingSaucer:FlyingSaucer in flyingSaucers )
flyingSaucer.render();
for each( var asteroid:Asteroid in asteroids )
asteroid.render();
for each( var bullet:Bullet in bullets )
bullet.render();
try { harder } conference 2011 } ©Richard Lord 2011 - www.richardlord.net
12. Processes & Process Manager
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
13. interface IProcess
{
function start():Boolean;
function update( time:Number ):void;
function end():void;
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
14. class ProcessManager
{
private var processes:PrioritisedList;
public function addProcess( process:IProcess, priority:int ):Boolean {
if( process.start() ) {
processes.add( process, priority );
return true;
}
return false;
}
public function update( time:Number ):void {
for each( var process:IProcess in processes )
process.update( time );
}
public function removeProcess( process:IProcess ):void {
process.end();
processes.remove( process );
}
try { harder } conference 2011
} ©Richard Lord 2011 - www.richardlord.net
15. class RenderProcess implements iProcess
{
public function update( time:Number ):void {
spaceship.render();
for each( var flyingSaucer:FlyingSaucer in flyingSaucers )
flyingSaucer.render();
for each( var asteroid:Asteroid in asteroids )
asteroid.render();
for each( var bullet:Bullet in bullets )
bullet.render();
}
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
16. interface IRenderable
{
function render();
}
class RenderProcess implements IProcess
{
private var targets:Vector.<IRenderable>;
public function update( time:Number ):void {
for each( var target:IRenderable in targets )
target.render();
}
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
17. class Spaceship implements IRenderable
{
public var view:DisplayObject;
public var position:Point;
public var rotation:Number;
public function render():void {
view.x = position.x;
view.y = position.y;
view.rotation = rotation;
}
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
18. class Renderable implements IRenderable
{
public var view:DisplayObject;
public var position:Point;
public var rotation:Number;
public function render():void {
view.x = position.x;
view.y = position.y;
view.rotation = rotation;
}
}
class Spaceship extends Renderable
{
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
19. Renderable
Spaceship FlyingSaucer Asteroid Bullet
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
20. interface IMoveable
{
function move();
}
class MoveProcess implements IProcess
{
private var targets:Vector.<IMoveable>;
public function update( time:Number ):void {
for each( var target:IMoveable in targets )
target.move( time );
}
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
21. class Moveable implements IMoveable
{
public var position:Point;
public var rotation:Number;
public var velocity:Point;
public var angularVelocity:Number;
public function move( time:Number ):void {
position.x += velocity.x * time;
position.y += velocity.y * time;
rotation += angularVelocity * time;
}
}
class Spaceship extends Moveable
{
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
22. class Moveable extends Renderable implements IMoveable
{
// public var position:Point;
// public var rotation:Number;
public var velocity:Point;
public var angularVelocity:Number;
public function move( time:Number ):void {
position.x += velocity.x * time;
position.y += velocity.y * time;
rotation += angularVelocity * time;
}
}
class Spaceship extends Moveable
{
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
23. Renderable
Moveable
Spaceship FlyingSaucer Asteroid Bullet
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
24. Moveable Renderable
Spaceship FlyingSaucer Asteroid Bullet
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
25. class Renderable implements IRenderable class Moveable implements IMoveable
{ {
public var view:DisplayObject; public var position:Point;
public var position:Point; public var rotation:Number;
public var rotation:Number; public var velocity:Point;
public var angularVelocity:Number;
public function render():void {
view.x = position.x; public function move( time:Number ):void {
view.y = position.y; position.x += velocity.x * time;
view.rotation = rotation; position.y += velocity.y * time;
} rotation += angularVelocity * time;
} }
}
class Spaceship
{
public var renderData:IRenderable;
public var moveData:IMoveable;
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
26. interface IRenderable interface IMoveable
{ {
function render(); function move();
} }
class RenderProcess implements IProcess class MoveProcess implements IProcess
{ {
private var targets:Vector.<IRenderable>; private var targets:Vector.<IMoveable>;
public function update(time:Number):void{ public function update(time:Number):void {
for each(var target:IRenderable in targets) for each(var target:IMoveable in targets)
target.render(); target.move( time );
} }
} }
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
27. public function createSpaceship( time:Number ):Spaceship {
var spaceship:Spaceship = new Spaceship();
...
renderProcess.addItem( spaceship.renderData );
moveProcess.addItem( spaceship.moveData );
...
return spaceship;
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
28. class Renderable implements IRenderable class Moveable implements IMoveable
{ {
public var view:DisplayObject; public var position:Point;
public var position:Point; public var rotation:Number;
public var rotation:Number; public var velocity:Point;
public var angularVelocity:Number;
public function render():void {
view.x = position.x; public function move( time:Number ):void {
view.y = position.y; position.x += velocity.x * time;
view.rotation = rotation; position.y += velocity.y * time;
} rotation += angularVelocity * time;
} }
}
class Spaceship
{
public var renderData:IRenderable;
public var moveData:IMoveable;
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
29. class Renderable implements IRenderable class Moveable implements IMoveable
{ {
public var display:DisplayComponent; public var position:PositionComponent;
public var position:PositionComponent; public var velocity:VelocityComponent;
public function render():void { public function move( time:Number ):void {
display.view.x = position.x; position.x += velocity.velocityX * time;
display.view.y = position.y; position.y += velocity.velocityY * time;
display.view.rotation position.rotation
= position.rotation; += velocity.angularVelocity * time;
} }
} }
class DisplayComponent { class VelocityComponent {
public var view:DisplayObject; public var velocityX:Number;
} public var velocityY:Number;
public var angularVelocity:Number;
class PositionComponent {
}
public var x:Number;
public var y:Number;
public var rotation:Number;
try { harder } conference 2011
} ©Richard Lord 2011 - www.richardlord.net
30. class Spaceship
{
public function Spaceship() {
moveData = new MoveData( new PositionComponent(), new VelocityComponent() );
renderData = new RenderData( new DisplayComponent(), moveData.position );
}
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
31. class Renderable implements IRenderable
{
public var display:DisplayComponent;
public var position:PositionComponent;
public function render():void {
display.view.x = position.x;
display.view.y = position.y;
display.view.rotation = position.rotation;
}
}
class RenderProcess implements IProcess
{
private var targets:Vector.<IRenderable>;
public function update( time:Number ):void {
for each( var target:IRenderable in targets )
target.render();
}
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
32. class RenderData
{
public var display:DisplayComponent;
public var position:PositionComponent;
}
class RenderProcess implements IProcess
{
private var targets:Vector.<RenderData>;
public function update( time:Number ):void {
for each( var target:RenderData in targets ) {
target.display.view.x = target.position.x;
target.display.view.y = target.position.y;
target.display.view.rotation = target.position.rotation;
}
}
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
33. class Moveable implements IMoveable
{
public var position:PositionComponent;
public var velocity:VelocityComponent;
public function move( time:Number ):void {
position.x += velocity.velocityX * time;
position.y += velocity.velocityY * time;
position.rotation += velocity.angularVelocity * time;
}
}
class MoveProcess implements IProcess
{
private var targets:Vector.<IMoveable>;
public function move( time:Number ):void {
for each( var target:Moveable in targets )
target.move( time );
}
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
34. class MoveData
{
public var position:PositionComponent;
public var velocity:VelocityComponent;
}
class MoveProcess implements IProcess
{
private var targets:Vector.<MoveData>;
public function move( time:Number ):void {
for each( var target:MoveData in targets ) {
target.position.x += target.velocity.velocityX * time;
target.position.y += target.velocity.velocityY * time;
target.position.rotation += target.velocity.angularVelocity * time;
}
}
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
35. class Spaceship {
public var renderData:RenderData;
public var moveData:MoveData;
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
36. class Spaceship {
public var renderData:RenderData; class RenderData {
public var moveData:MoveData; public var display:DisplayComponent;
} public var position:PositionComponent;
}
class MoveData {
public var position:PositionComponent;
public var velocity:VelocityComponent;
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
37. class Spaceship {
public var renderData:RenderData; class RenderData {
public var moveData:MoveData; public var display:DisplayComponent;
} public var position:PositionComponent;
}
class MoveData {
public var position:PositionComponent; class DisplayComponent {
public var velocity:VelocityComponent; public var view:DisplayObject;
} }
class VelocityComponent { class PositionComponent {
public var velocityX:Number; public var x:Number;
public var velocityY:Number; public var y:Number;
public var angularVelocity:Number; public var rotation:Number;
} }
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
38. class Spaceship {
public var renderData:RenderData; class RenderData {
public var moveData:MoveData; public var display:DisplayComponent;
} public var position:PositionComponent;
}
class MoveData {
public var position:PositionComponent; class DisplayComponent {
public var velocity:VelocityComponent; public var view:DisplayObject;
} }
class VelocityComponent { class PositionComponent {
public var velocityX:Number; public var x:Number;
public var velocityY:Number; public var y:Number;
public var angularVelocity:Number; public var rotation:Number;
} }
class RenderProcess implements IProcess {
class MoveProcess implements IProcess { private var targets:Vector.<RenderData>;
private var targets:Vector.<MoveData>; }
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
39. class Spaceship {
public var display:DisplayComponent; class DisplayComponent {
public var position:PositionComponent; public var view:DisplayObject;
public var velocity:VelocityComponent; }
}
class VelocityComponent { class PositionComponent {
public var velocityX:Number; public var x:Number;
public var velocityY:Number; public var y:Number;
public var angularVelocity:Number; public var rotation:Number;
} }
class RenderData {
public var display:DisplayComponent;
class MoveData {
public var position:PositionComponent;
public var position:PositionComponent;
}
public var velocity:VelocityComponent;
}
class RenderProcess implements IProcess {
class MoveProcess implements IProcess { private var targets:Vector.<RenderData>;
private var targets:Vector.<MoveData>; }
}
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
40. class Entity { class DisplayComponent {
public var data:Array; public var view:DisplayObject;
} }
class PositionComponent {
public var x:Number;
class VelocityComponent { public var y:Number;
public var velocityX:Number; public var rotation:Number;
public var velocityY:Number; }
public var angularVelocity:Number;
} class RenderData {
public var display:DisplayComponent;
public var position:PositionComponent;
class MoveData { }
public var position:PositionComponent;
public var velocity:VelocityComponent;
}
class MoveProcess implements IProcess { class RenderProcess implements IProcess {
private var targets:Vector.<MoveData>; private var targets:Vector.<RenderData>;
} }
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
41. Entity systems are better
(for games driven by a game loop)
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
42. Ember
Components
Nodes Systems (Processes)
Spaceship
MotionControlNode ProcessManager
Asteroid
GunControlNode GameManager
Views
Gun
BulletAgeNode MotionControlSystem SpaceshipView
Bullet
MovementNode GunControlSystem AsteroidView
GameState
SpaceshipCollisionNode BulletAgeSystem BulletView
Position
AsteroidCollisionNode MovementSystem
Motion
BulletCollisionNode CollisionSystem
Display
RenderNode RendersSystem
MotionControls
GunControls
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
43. Robotlegs Mediators
Model Commands AsteroidsMediator
SpaceshipMediator
GameState CreateAsteroid
AsteroidMediator
GameSize CreateBullet
BulletMediator
Spaceship CreateSpaceship
SpaceshipContainer RouteInput Views
Asteroid StartGame
Asteroids
AsteroidContainer StartGame
SpaceshipView
Bullet Update
AsteroidView
BulletContainer
BulletView
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
44. And now I've run out of stuff to say
try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net