How do I set an animation frame from a behavior, for collisions. (Solved) you can do it... (;

0 favourites
  • 2 posts
From the Asset Store
Selection frame like in RTS games, works both on mobile and desktop devices.
  • ---Solution---

    You can't via officially sanctioned methods - but I did anyway... As an aside, an api should exist for this, but doesn't, so what choice do I have! ITS NOT MY FAULT!!!! THEY FORCED ME!!!! </derangement>

    *ehem* When declaring variables for the behavior, inside the constructor, I added this:

    this._sprite = null;

    If I cared, I would add error checks to handle the plugin not being of type sprite, but I don't care. Because I only need this behavior on sprites- that are not even drawn to screen. Later on, when I need to change frames, I do this:

    	if(this._sprite === null) this._sprite = this._inst.GetSdkInstance();
    	this._sprite._SetAnimFrame(2);
    

    As far as I can tell, nothing is happening here that should be of concern, and the path to frame change is exactly as it would be if you called it via events or the scripting api (not included for the plugin sdk).

    However, I have special needs. I don't want to be referencing a frame by tag, and I don't want c3 to do a bunch of error checks I don't need. and I definitely don't care about updating the image texture or other nonsense related to sprite. I just want the cold hard collision poly handed over to the collision system. Done:

    const change = 2;
     const changeFrame = this._sprite._currentAnimation.GetFrameAt( change );
    	 const wi = this.GetWorldInfo();
    			//wi.SetOriginX(changeFrame.GetOriginX());
    	 //wi.SetOriginY(changeFrame.GetOriginY());
    	 wi.SetSourceCollisionPoly(changeFrame.GetCollisionPoly());
    	 wi.SetBboxChanged(); 

    This gets to the meat, and it bypasses the following:

    • Error checking for the index number passed in, no use of tags
    • Errors resulting from frame being out of bounds
    • It runs regardless if you are changing to the same frame
    • It doesn't update the texture or change the renderer
    • The sprite plugin doesn't accurately know which frame you are on
    • It doesn't trigger On Frame Changed
    • It bypasses the c3 event system
    • It doesn't change any variables in the sprite anim system

    TLDR: As far as the sprite is concerned, you didn't change frames. Only world info knows a change happened. It black magic, and breaks the intended behavior of the sprite - which is exactly what I want >.>

    What does this mean? You can bloody change collision polys whenever you want without alot of useless overhead. Savings can range from 20%-45% depending on the "real world" application. For me, that falls on the higher side and has a huge impact on overall performance.

    ---Original Post---

    Hi, I tried to revive someone else's old post on this, but the website told me to make a new post... So here it is.

    Ashley followed up with info about how animation frames are tied to a sprite, and behaviors can be applied to more than just sprites - all makes sense. Then Ashley asked what was the use case was but the original poster never answered.

    Given chribbe never described the use case, maybe I can describe why I am looking to do the same.

    I am creating a retro platformer behavior that resolves collisions the same way nes era games would (not by means, just results). To do so, you need collision points for sides, head, toe, and a few others, because each collision point will resolve differently.

    In an event sheet, I would manage these different collision zones by means of animation frames. (for example, 0 = full collider, 1 = right side, 2 = down, so on. You simply set the frame, test for an overlap, do the resolve, then move on. The advantage is that you can easily set the collision poly for each frame in a visual way in the editor, and afiak, this is how many c3 users do things like this. The only alternative is to have multiple objects (with all the picking problems and foreach loop requirements (which hurts performance), or hierarchies with even worse performance still. Don't get me wrong, hierarchies are great, but not in my case. (enter feature suggestion: allow user to define multiple collision poly's without the need for it to be attached to animations).... The leanest, most performant solution within the editor (for my use case) is the frame based one.

    Anyway, I have shoveled most of this logic into a behavior, but I have to still externally set the animation frames and then tell the behavior to then test and resolve the collision - This is boilerplate required in every project that shoudl clearly be handled by the behavior. Not only that, every event I have to interact with the behavior is performance I can't spare. The ehavior can't do its job correctly without a user knowing how to work with it. Great for an api, but behaviors are nice when they are plug and play. I would much prefer for it to handle changing the collision poly to the different positions and testing for collisions and resolving them without help. Outside of doing that, I could have the behavior have a bunch of variables representing the collisions points and have it reposition and resize the object to match them, one by one, but entering the data is tedious, easy to mess up, hard to visualize and kinda silly when we already have collision poly editor..

    The way I envision my behavior, is that there would be an action/property that sets/holds an index of a animation frame for each collision point. I feed it that via a property or action, and let 'er rip - at that point without ever having to interact with it except to disable it.

    Why put it in a behavior? Performance most of all, and ease of use across projects as a close second, etc...

    If there was a better way (which there could be) for handling multiple collision boxes that still allow the user to set them visually via the editor.... Ideally, collision stuff wouldn't be paired so tightly (or at all) with the sprite object, as they really aren't the same responsibility. Everybody be making projects with two sprites for each object, because one is the collider the other the visual model is basically proving that point... but that aside, is there an obvious solution I missed?

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • One final caveat, if you are setting frames only to get collision polygons for a behavior to use, this works really well, however - I have a strict editor side hands off policy on the changing animations or frames for objects using this behavior.

    This results in a behavior that can only be used so long as the user adheres to "rules" of use. This is true of any code, but its not a grand replacement for a proper collision system with a dedicated api for all the obvious reasons.

    Such a dedicated api would allow for the creation of custom platformers and 8way controllers. The built in ones are nice, but they have issues you can't resolve via events. Mario and sonic behaviors clones with exacting detail could totally be created and shared. But not currently, not without hacks like this, meaning its likely to break in the future when Scirra changes things.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)