Browse Source

Merge branch 'animated-sprite-2d' into 'master'

Add Animated sprite 2d

See merge request pedrotrschneider/project-edu!5
Pedro Tonini Rosenberg Schneider 3 years ago
parent
commit
609247e32e

+ 2 - 0
index.html

@@ -30,6 +30,7 @@
       <script type="text/javascript" src="pandora/game_objects/2d_objects/Object2D.js"></script>
       <script type="text/javascript" src="pandora/game_objects/2d_objects/Shape2D.js"></script>
       <script type="text/javascript" src="pandora/game_objects/2d_objects/Sprite2D.js"></script>
+      <script type="text/javascript" src="pandora/game_objects/2d_objects/AnimatedSprite2D.js"></script>
     
       <!-- UI Game Objects -->
       <script type="text/javascript" src="pandora/game_objects/ui_objects/UIObject.js"></script>
@@ -50,6 +51,7 @@
     <script type="text/javascript" src="pandora/resources/AudioRes.js"></script>
     <script type="text/javascript" src="pandora/resources/FontRes.js"></script>
     <script type="text/javascript" src="pandora/resources/TextureRes.js"></script>
+    <script type="text/javascript" src="pandora/resources/SpriteFrames.js"></script>
     
     <!-- Singletons -->
     <script type="text/javascript" src="pandora/Enums.js"></script>

+ 99 - 0
pandora/game_objects/2d_objects/AnimatedSprite2D.js

@@ -0,0 +1,99 @@
+class AnimatedSprite2D extends Sprite2D
+{
+    constructor(name, p5Image, spriteFrames)
+    {
+        super(name, p5Image);
+
+        this.spriteFrames = spriteFrames;
+        this.playing = false;
+        this.frame = 0;
+        this.currentAnimation = 0;
+        this.timeSinceLastFrame = 0;
+    }
+
+    // Setters
+    setCurrentAnimationByIndex(idx)
+    {
+        if (idx < this.spriteFrames.numAnimations)
+            this.currentAnimation = idx;
+        else this.currentAnimation = null;
+        this.frame = 0;
+        this.timeSinceLastFrame = 0;
+    }
+
+    setCurrentAnimationByName(name)
+    {
+        this.currentAnimation = this.spriteFrames.getAnimationIndexByName(name);
+        this.frame = 0;
+        this.timeSinceLastFrame = 0;
+    }
+
+    setCurrentFrameTime(time)
+    {
+        this.getCurrentAnimation().setFrameTime(time);
+    }
+
+    setCurrentFPS(fps)
+    {
+        this.getCurrentAnimation().setFPS(fps);
+    }
+
+    // Getters
+    getAnimationByIndex(idx)
+    {
+        return this.spriteFrames.getAnimationByIndex(idx);
+    }
+
+    getCurrentAnimation()
+    {
+        return this.spriteFrames.getAnimationByIndex(this.currentAnimation);
+    }
+
+    getCurrentFrame()
+    {
+        return this.getCurrentAnimation().getFrame(this.frame);
+    }
+
+    getCurrentFrameTime()
+    {
+        return this.getCurrentAnimation().getFrameTime();
+    }
+
+    getCurrentNumFrames()
+    {
+        return this.getCurrentAnimation().getNumFrames();
+    }
+
+    // Methods
+    play()
+    {
+        this.playing = true;
+    }
+
+    stop()
+    {
+        this.playing = false;
+    }
+
+    isPlaying()
+    {
+        return this.playing;
+    }
+
+    update(delta)
+    {
+        if (this.playing)
+        {
+            this.timeSinceLastFrame += delta;
+            if (this.timeSinceLastFrame >= this.getCurrentFrameTime())
+            {
+                this.frame = (this.frame + 1) % this.getCurrentNumFrames();
+                this.timeSinceLastFrame = 0;
+            }
+        }
+        this.P5Image = this.getCurrentFrame();
+        this._update(delta);
+        for (let i = 0; i < this.children.length; i++)
+            this.children[i].update(delta);
+    }
+}

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

@@ -32,11 +32,11 @@ class Shape2D extends Object2D
         {
             case SHAPES.RECT:
                 rectMode(this.shapeMode);
-                rect(this.position.x, this.position.y, this.shape.w, this.shape.h);
+                rect(0, 0, this.shape.w, this.shape.h);
                 break;
             case SHAPES.ELLIPSE:
                 ellipseMode(this.shapeMode);
-                ellipse(this.position.x, this.position.y, this.shape.rx, this.shape.ry);
+                ellipse(0, 0, this.shape.rx, this.shape.ry);
         }
 
         this._draw(delta);

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

@@ -14,7 +14,7 @@ class Sprite2D extends Object2D
         rotate(this.rotationDegrees);
         scale(this.scale.x, this.scale.y);
 
-        image(this.P5Image, this.position.x, this.position.y, this.P5Image.width, this.P5Image.height);
+        image(this.P5Image, 0, 0, this.P5Image.width, this.P5Image.height);
 
         this._draw(delta);
 

+ 102 - 0
pandora/resources/SpriteFrames.js

@@ -0,0 +1,102 @@
+class SpriteAnimation
+{
+    constructor(name = "default", p5Image, rows, cols, indices, fps)
+    {
+        this.name = name;
+        this.fullP5Image = p5Image;
+        this.rows = rows;
+        this.columns = cols;
+        this.indices = indices;
+        this.numFrames = this.indices.length;
+        this.frameTime = 1 / fps;
+
+        this.frames = [];
+        for (let i = 0; i < this.numFrames; i++)
+        {
+            this.frames.push(this.makeFrame(i));
+        }
+    }
+
+    setFrameTime(time)
+    {
+        this.frameTime = time;
+    }
+
+    setFPS(fps)
+    {
+        this.frameTime = 1 / fps;
+    }
+
+    getFrame(idx)
+    {
+        if (idx < this.numFrames)
+            return this.frames[idx];
+        return null;
+    }
+
+    getFrameTime()
+    {
+        return this.frameTime;
+    }
+
+    getNumFrames()
+    {
+        return this.numFrames;
+    }
+
+    makeFrame(idx)
+    {
+        let r = int(this.indices[idx] / this.columns);
+        let c = this.indices[idx] % this.columns;
+        let w = this.fullP5Image.width / this.columns;
+        let h = this.fullP5Image.height / this.rows;
+        let x = c * w;
+        let y = r * h;
+        return this.fullP5Image.get(x, y, w, h);
+    }
+}
+
+class SpriteFrames
+{
+    constructor()
+    {
+        this.animations = [];
+        this.numAnimations = 0;
+    }
+
+    getAnimationByIndex(idx)
+    {
+        if (idx < this.numAnimations) return this.animations[idx];
+        return null;
+    }
+
+    getAnimationByName(name)
+    {
+        for (let i = 0; this.numAnimations; i++)
+        {
+            if (this.animations[i].name == name)
+            {
+                return this.animations[i];
+            }
+        }
+        return null;
+    }
+
+    getAnimationIndexByName(name)
+    {
+        for (let i = 0; this.numAnimations; i++)
+        {
+            if (this.animations[i].name == name)
+            {
+                return i;
+            }
+        }
+        return null;
+    }
+
+    addAnimation(name, p5Image, rows, cols, indices, fps = 24)
+    {
+        this.animations.push(new SpriteAnimation(name, p5Image, rows, cols, indices, fps));
+        this.numAnimations++;
+    }
+}

+ 7 - 1
src/sketch.js

@@ -1,4 +1,5 @@
 let test, test2;
+let monke;
 
 function preload()
 {
@@ -14,7 +15,12 @@ function setup()
     GameHandler.init();
     textFont(AssetHandler.getP5FontByName("Lato"));
 
-    test2 = new Input("myInput", "", "text");
+    monke = AssetHandler.getP5ImageByName("monke");
+    let sf = new SpriteFrames();
+    sf.addAnimation("monke", monke, 4, 4, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], 1);
+    test2 = new AnimatedSprite2D("myAnimSprite", null, sf);
+    test2.play();
+    test2.setCurrentFPS(1);
     GameHandler.addRootObject(test2);
 }