collinhover / impactplusplus

Impact++ is a collection of additions to ImpactJS with full featured physics, dynamic lighting, UI, abilities, and more.
http://collinhover.github.com/impactplusplus
MIT License
276 stars 59 forks source link

How to use offset on animations in Entities? #148

Closed rhmvandelisdonk closed 10 years ago

rhmvandelisdonk commented 10 years ago

As this is my first question on this project I would like to thank you for creating the Impact++ library. My question; I have a Character entity that uses multiple animation sheets with the help of vicman's solution on http://impactjs.com/forums/code/impact-library-75-additions/page/5. For one of the animations I need to draw it using an offset , but I am unable to get this working. I am switching our project from Impact 1.23 to Impact++ R7. Below is my entity class, where I set

    this.offset = {x: 16, y: 12};

in the update() method. The offset property is set but does not seem to work on animations like it does in ImpactJS. Or am I missing something?

ig.module('game.entities.brain')
.requires('plusplus.abstractities.character')
.defines( function(){
    EntityBrain = ig.Character.extend({
        name:'brain',
        size: {x:29, y:36},
        health: 100,       
        forcefield_timer : new ig.Timer(0),
        forcefield_timeout : new ig.Timer(0),
        performance : ig.EntityExtended.PERFORMANCE.STATIC,
        collides: ig.EntityExtended.COLLIDES.FIXED,
        animSheet: new ig.AnimationSheet('media/spritesheets/brain/brain.png', 29, 36),
        animSheetForcefield: new ig.AnimationSheet('media/spritesheets/brain/brain-forcefield.png', 61, 60),
        animSheetExplosion: new ig.AnimationSheet('media/spritesheets/brain/brain-explosion.png', 61, 74),
        animSettings: {
            idle: {
                frameTime: 0.0417,
                sequence: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
            },
            forcefield: {
                animSheet: "animSheetForcefield",
                frameTime: 0.0417,
                sequence: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],
            },
            death: {
                animSheet: "animSheetExplosion",
                frameTime: 0.0417, 
                sequence: [0,1,2,3,4,5,6,7,8,9,10]
            }
        },
        animsExpected: ["idle", "forcefield", "death"],
        update: function(){           
            //Set forcefield
            if(this.forcefield_timeout.delta() > 0) {
                if(ig.input.pressed('forcefield')) { 
                    console.log('activate forcefield');
                    this.forcefield_timer = new ig.Timer(2); //2 sec shield
                    this.forcefield_timeout = new ig.Timer(4); //timeout = 2sec active + 2sec delay
                    this.animOverride('forcefield',{lock:true,loop:true});
                    this.offset = {x: 16, y: 12}; //offset for difference in sprite size
                    this.invulnerable = true;
                }
            }
            //Forcefield ended
            if(this.invulnerable === true && this.forcefield_timer.delta() > 0) {
                this.offset = {x:0, y:0};
                this.animRelease('forcefield');
                this.invulnerable = false;
            }
            this.parent();
        },
    });
});
collinhover commented 10 years ago

Hi @rhmvandelisdonk, when I built Impact++ I didn't expect entity sizes to change after initialization, only their position. In your case, it is the drawing bounding box, not the collision box, but the case is the same for both draw and collision. There are several ways you can address this, but my recommendation is to override the recordChanges and updateBounds method as follows:

First, in your override of the recordChanges method, you'll want to check for size and offset changes just like the core entity does here: https://github.com/collinhover/impactplusplus/blob/master/lib/plusplus/core/entity.js#L4921. To do so, you'll need _sizeLast and _offsetLast properties, and if there is a change just call this.parent(true), where the boolean will force the entity to update its bounds.

Next, in your override of the updateBounds method, you'll want to add two lines before or after calling parent:

this.sizeDraw.x = this.getSizeDrawX();
this.sizeDraw.y = this.getSizeDrawY();

Let me know if this works. It would probably be helpful to integrate this into the library itself, because it is not intuitive that entities ignore changes in size.

rhmvandelisdonk commented 10 years ago

Thanks for your fast response. Your method works, although I needed to change the Entity performance to MOVABLE because a STATIC Entity does not call the function updateBounds().

collinhover commented 10 years ago

Ah, yes you are correct. Static entities do not expect to change anything except their animation (I think).

collinhover commented 10 years ago

@rhmvandelisdonk the latest commit adds the auto size update to the core entity. You may want to check it out and make sure it works properly for you =)

rhmvandelisdonk commented 10 years ago

Hi Collin,

I have finally had the time to check out your changes. For me they do not fully work because not only the size of the new animation changes but also the offset. You wrote about that in your first comment on this issue but those changes are not in the changeset.