Переглянути джерело

✨ Add double buffering to better support different sizes of monitor

- Now the draw callback from all game objects receives a reference to the double buffer as a parameter,
Pedro Schneider 3 роки тому
батько
коміт
040d164a89

+ 8 - 8
pandora/game_objects/2d_objects/Object2D.js

@@ -30,17 +30,17 @@ class Object2D extends GameObject
         this.scale = Vector2.ONE();
     }
 
-    draw(delta)
+    draw(delta, db)
     {
-        push();
-        translate(this.position.x, this.position.y);
-        rotate(this.rotationDegrees);
-        scale(this.scale.x, this.scale.y);
-        this._draw(delta);
+        db.push();
+        db.translate(this.position.x, this.position.y);
+        db.rotate(this.rotationDegrees);
+        db.scale(this.scale.x, this.scale.y);
+        this._draw(delta, db);
 
         for (let i = 0; i < this.children.length; i++)
-            this.children[i].draw(delta);
+            this.children[i].draw(delta, db);
 
-        pop()
+        db.pop()
     }
 }

+ 17 - 17
pandora/game_objects/2d_objects/Shape2D.js

@@ -36,35 +36,35 @@ class Shape2D extends Object2D
         this.noStroke = false;
     }
 
-    draw(delta)
+    draw(delta, db)
     {
-        push();
-        translate(this.position.x, this.position.y);
-        rotate(this.rotationDegrees);
-        scale(this.scale.x, this.scale.y);
+        db.push();
+        db.translate(this.position.x, this.position.y);
+        db.rotate(this.rotationDegrees);
+        db.scale(this.scale.x, this.scale.y);
 
-        fill(this.fillColor);
-        strokeWeight(this.strokeWeight)
-        stroke(this.strokeColor);
+        db.fill(this.fillColor);
+        db.strokeWeight(this.strokeWeight)
+        db.stroke(this.strokeColor);
 
-        if (this.noFill) noFill();
-        if (this.noStroke) noStroke();
+        if (this.noFill) db.noFill();
+        if (this.noStroke) db.noStroke();
         switch (this.shapeType)
         {
             case SHAPES.RECT:
-                rectMode(this.shapeMode);
-                rect(0, 0, this.shape.w, this.shape.h);
+                db.rectMode(this.shapeMode);
+                db.rect(0, 0, this.shape.w, this.shape.h);
                 break;
             case SHAPES.ELLIPSE:
-                ellipseMode(this.shapeMode);
-                ellipse(0, 0, this.shape.rx, this.shape.ry);
+                db.ellipseMode(this.shapeMode);
+                db.ellipse(0, 0, this.shape.rx, this.shape.ry);
         }
 
-        this._draw(delta);
+        this._draw(delta, db);
 
         for (let i = 0; i < this.children.length; i++)
-            this.children[i].draw(delta);
+            this.children[i].draw(delta, db);
 
-        pop()
+        db.pop()
     }
 }

+ 9 - 9
pandora/game_objects/2d_objects/Sprite2D.js

@@ -28,20 +28,20 @@ class Sprite2D extends Object2D
         this.P5Image = p5Image;
     }
 
-    draw(delta)
+    draw(delta, db)
     {
-        push();
-        translate(this.position.x, this.position.y);
-        rotate(this.rotationDegrees);
-        scale(this.scale.x, this.scale.y);
+        db.push();
+        db.translate(this.position.x, this.position.y);
+        db.rotate(this.rotationDegrees);
+        db.scale(this.scale.x, this.scale.y);
 
-        image(this.P5Image, 0, 0, this.P5Image.width, this.P5Image.height);
+        db.image(this.P5Image, 0, 0, this.P5Image.width, this.P5Image.height);
 
-        this._draw(delta);
+        this._draw(delta, db);
 
         for (let i = 0; i < this.children.length; i++)
-            this.children[i].draw(delta);
+            this.children[i].draw(delta, db);
 
-        pop()
+        db.pop();
     }
 }

+ 4 - 4
pandora/game_objects/GameObject.js

@@ -127,11 +127,11 @@ class GameObject
             this.children[i].update(delta);
     }
 
-    draw(delta)
+    draw(delta, db)
     {
-        this._draw(delta);
+        this._draw(delta, db);
         for (let i = 0; i < this.children.length; i++)
-            this.children[i].draw(delta);
+            this.children[i].draw(delta, db);
     }
 
     // Callbacks
@@ -150,7 +150,7 @@ class GameObject
 
     }
 
-    _draw(delta)
+    _draw(delta, db)
     {
 
     }

+ 60 - 6
pandora/handlers/GameHandler.js

@@ -31,11 +31,21 @@ const GameHandler = {
     prevMillis: 0,
     delta: 0,
 
+    db: null,
+    dbWidth: 1920,
+    dbHeight: 1080,
+
     setRenderMode: function(mode)
     {
         this.renderMode = mode;
     },
 
+    setDoubleBufferSize: function(w, h)
+    {
+        this.dbWidth = w;
+        this.dbHeight = h;
+    },
+
     drawDebugFPS(val)
     {
         this.bDrawDebugFPS = val;
@@ -48,17 +58,29 @@ const GameHandler = {
         {
             case RENDER_MODES.P2D:
                 createCanvas(windowWidth, windowHeight);
+                this.db = createGraphics(this.dbWidth, this.dbHeight);
                 break;
             case RENDER_MODES.WEBGL:
                 createCanvas(windowWidth, windowHeight, WEBGL);
+                this.db = createGraphics(this.dbWidth, this.dbHeight, WEBGL);
+                this.db.smooth();
                 break;
 
         }
         frameRate(fps);
         smooth();
 
+        if (this.renderMode == RENDER_MODES.WEBGL)
+        {
+            translate(-windowWidth / 2, -windowHeight / 2);
+            db.translate(-this.dbWidth / 2, -this.dbHeight / 2);
+        }
+
         if (this.bDrawDebugFPS)
-            this.debugFpsLabel = new Label(`FPS: ${frameRate()}`)
+        {
+            this.debugFpsLabel = new Label("debugFps", `FPS: ${frameRate()}`);
+            this.addRootObject(this.debugFpsLabel);
+        }
     },
 
     instanceGameObject: function(obj)
@@ -73,9 +95,22 @@ const GameHandler = {
         obj.setup();
     },
 
+    upframecount: 0,
+    upframenum: 20,
     update: function()
     {
-        if (this.bDrawDebugFPS) this.debugFpsLabel.setText(`FPS: ${frameRate()}`)
+        if (this.bDrawDebugFPS)
+        {
+            if (frameCount % this.upframenum == 0)
+            {
+                this.debugFpsLabel.setText(`FPS: ${
+                    Math.round(this.upframecount * 1000) / 1000
+                }`);
+                this.upframecount = 0;
+            }
+            else
+                this.upframecount = max(this.upframecount, frameRate());
+        }
         this.delta = (millis() - this.prevMillis) / 1000;
         for (let i = 0; i < this.rootObjects.length; i++)
             this.rootObjects[i].update(this.delta);
@@ -83,11 +118,30 @@ const GameHandler = {
 
     draw: function()
     {
-        if (this.renderMode == RENDER_MODES.WEBGL)
-            translate(-windowWidth / 2, -windowHeight / 2);
-
+        this.db.clear();
         for (let i = 0; i < this.rootObjects.length; i++)
-            this.rootObjects[i].draw(this.delta);
+            this.rootObjects[i].draw(this.delta, this.db);
+
+        this.db.push();
+        this.db.strokeWeight(5);
+        this.db.noFill();
+        this.db.rect(0, 0, this.dbWidth, this.dbHeight);
+        this.db.pop();
+
+        imageMode(CENTER);
+        if (windowWidth / windowHeight < this.dbWidth / this.dbHeight)
+        {
+            this.db.screenWidth = windowWidth;
+            this.db.screenHeight = windowWidth * (this.dbHeight / this.dbWidth);
+        }
+        else
+        {
+            this.db.screenHeight = windowHeight;
+            this.db.screenWidth = windowHeight * (this.dbWidth / this.dbHeight);
+        }
+
+        image(this.db, windowWidth / 2, windowHeight / 2, this.db.screenWidth, this.db.screenHeight);
+
         this.prevMillis = millis();
     }
 }

+ 9 - 9
src/sketch.js

@@ -23,9 +23,9 @@ class TestObject extends Object2D
 
     }
 
-    _draw(delta)
+    _draw(delta, db)
     {
-        if (this.visible) ellipse(0, 0, 20);
+        if (this.visible) db.ellipse(0, 0, 50);
     }
 }
 
@@ -52,9 +52,9 @@ class TestObject2 extends Object2D
 
     }
 
-    _draw(delta)
+    _draw(delta, db)
     {
-        if (this.visible) ellipse(0, 0, 20);
+        if (this.visible) db.ellipse(0, 0, 50);
     }
 }
 
@@ -67,8 +67,8 @@ class TestButton extends Button
 
     _setup()
     {
-        this.setPosition(200, 200);
-        this.setSize(100, 50)
+        this.setPosition(100, 200);
+        this.setSize(150, 50);
     }
 
     _onMousePressed()
@@ -87,8 +87,8 @@ function preload()
 
 function setup()
 {
-    // GameHandler.drawDebugFPS(true);
-    GameHandler.setRenderMode(RENDER_MODES.WEBGL);
+    GameHandler.drawDebugFPS(true);
+    // GameHandler.setRenderMode(RENDER_MODES.WEBGL);
     GameHandler.init();
     textFont(AssetHandler.getP5FontByName("Lato"));
 
@@ -96,7 +96,7 @@ function setup()
     but = new TestButton("b1", "Emit signal");
     test.addChild(but);
     GameHandler.addRootObject(test);
-    GameHandler.addRootObject(new TestObject2("myTest2"))
+    GameHandler.addRootObject(new TestObject2("myTest2"));
 }
 
 function draw()