. .
CREATE OR DIE Special Downloads Shop webinale

Schauplatz

Artikel
  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Juli 2008

Zähflüssige Physik

Fluide Tendenzen mit ActionScript

(Link zum Artikel: http://www.createordie.de/cod/artikel/1850)

Flüssige Aggregatzustände mit ActionScript nachzubilden, ist nicht immer einfach, gerade wenn es sich dabei um biomorphe Formen handelt. Will man dazu noch auf physikalisch korrekte Verhaltensweisen wie beispielsweise Kollisionen nicht verzichten, kann man an diesem Thema mit Blick auf ein performantes Ergebnis schon mal länger knabbern. Das sollte uns jetzt aber nicht davon abhalten, Blob-Architekt zu spielen und etwas ordentlich Schleimiges zu entwickeln.

Text: Frank Reitberger

Die physikalische Basis

Die Grundlage unserer Blobs bildet eine Physics-Engine, der wir vertrauensvoll die wesentlichen Aufgaben der Kollisionsabfrage, Fließgeschwindigkeit und -richtung sowie die Objektverwaltung überlassen.
An dieser Stelle muss man den Kreis auch nicht mehr selber quadratieren, sondern kann auf zahlreiche Physic-Engines für die Verwendung mit AS2- und AS3 zurückgreifen. Zu den bekanntesten gehören wohl APE, Box2Dflash und Flashfisix. In diesem Beispiel gebrauchen wir allerdings keinen der eben genannten Kandidaten, sondern übertragen diese Anforderungen einer Engine namens "Motor2". Bei der Entwicklung von Motor2 legte der Autor Michael Baczynski besonderen Wert auf Performance. Sehr sympathisch in unserem Fall, denn wir brauchen ja nicht nur den physikalischen Unterbau, sondern müssen unsere Freiformen schließlich auch noch rendern. Ein nicht zu unterschätzender Teil, der ordentlich Ressourcen beansprucht.

Listing 1

  1. import display.BoxRenderer;
  2. import display.PolyRenderer;
  3. import display.ShapeRenderer;
  4. import display.Style;
  5. import de.polygonal.motor2.dynamics.contact.*;
  6. import de.polygonal.motor2.dynamics.*;
  7. import de.polygonal.motor2.collision.shapes.*;
  8. import de.polygonal.motor2.World;
  9. var world :World;
  10. var displayList :Array;
  11. var worldShapes :ShapeRenderer;
  12. var i :int;
  13. // setup: object(s).list
  14. this.displayList = [];
  15. // setup: world
  16. this.world = new World(null, true);
  17. this.world.setGravity(0, 400);
  18. createWorld();
  19. // create: moving.polygon(s)
  20. for( this.i = 0; this.i < 40; this.i++ ) {
  21. createPoly(50,-10,10,10,10,10,true);
  22. }
  23. function createWorld() :void {
  24. // create: left.border
  25. createBox( 0, 180, 2, 378, 0, 0, 0, 0 );
  26. // create: right.border
  27. createBox( 506, 180, 2, 378, 0, 0, 0, 0 );
  28. // create: top.floor
  29. createBox( 130, 100, 300, 10, 0, 0, 0, .05 );
  30. // create: middle.floor
  31. createBox( 400, 190, 220, 10, 0, 0, 0, -.05 )
  32. }
  33. function onFrameUpdate() :void {
  34. // refresh(s) world
  35. world.step(.018, 400);
  36. // render world
  37. for (this.i=0;this.i<this.displayList.length;
  38. this.i++ ) {
  39. // update: each object in list
  40. this.displayList[i].update();
  41. // render: each object in list
  42. this.displayList[i].render(1);
  43. }
  44. }
  45. function createBox(
  46. x:Number,y:Number,w:Number,h:Number,
  47. density:Number,mx:Number=0,my:Number=0,
  48. mr:Number = 0, addTo:Boolean = false):RigidBody
  49. {
  50. var sd:BoxData = new BoxData(density, w, h);
  51. sd.mx = mx;
  52. sd.my = my;
  53. sd.mr = mr;
  54. sd.friction = .2;
  55. var bd:RigidBodyData = new RigidBodyData();
  56. bd.addShapeData(sd);
  57. bd.x = x;
  58. bd.y = y;
  59. var rb:RigidBody = world.createBody(bd);
  60. var sr:ShapeRenderer = new
  61. BoxRenderer(rb.shapeList);
  62. sr.draw();
  63. this.displayList.push(sr);
  64. return rb;
  65. }
  66. function createPoly(
  67. x:Number,y:Number,sides:int,xradius:Number,
  68. yradius:Number, density:Number,addTo:Boolean =
  69. false):RigidBody
  70. {
  71. var vertices:Array = ShapeLib.ngon(
  72. sides, xradius, yradius);
  73. var sd:PolyData = new PolyData(
  74. density, vertices);
  75. sd.mx = 0;
  76. sd.my = 0;
  77. sd.friction = .25;
  78. var bd:RigidBodyData = new RigidBodyData();
  79. bd.addShapeData(sd);
  80. bd.x = x;
  81. bd.y = y;
  82. var b:RigidBody = world.createBody(bd);
  83. var sr:ShapeRenderer = new
  84. PolyRenderer(b.shapeList);
  85. sr.draw();
  86. if ( isBlob ) {
  87. this.radius = 20 + Math.random()*8 +
  88. Math.sin(.3) * 12;
  89. this.blobList.push( new soapBlob( sr, this.col,
  90. this.radius ) );
  91. }
  92. if ( addTo ) {
  93. this.displayList.push(sr);
  94. }
  95. return b;
  96. }

 

Kommentare
Bisher keine Kommentare
Neuer Kommentar
  • Gute Kommentare werden belohnt.
  •   (optional)
  •   (Kommentar abonnieren/Gravatar - wird nicht veröffentlicht)
  •    Benachrichtige mich bei nachfolgenden Kommentaren per E-Mail
  • -+
Tags
Werbung
actionscript