-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alpha changing incorrectly #13
Comments
Comment by: mouseas Did a little more poking. My guess is that when the bug does occur, the graphic has alpha applied, and the alpha-applied version is assigned to the graphic's place. Thus each frame the alpha is adjusted, the graphic becomes that much more transparent. |
I couldn't reproduce this by following the users steps. Has anyone else tried yet? |
Yes, I tried and I could reproduce the problem. You have to reproduce the exactly same scenario described by the author. I've spent some hours trying to narrow down the problem but had no success. It seems to be some really obscure behavior... |
@Dovyski If you still have it, could you throw up the sample code for this issue in the FlixelSandbox? |
Sure! I've just pushed the testing code to FlixelSandbox (it is called |
Still trying to find the cause of this bug, but I removed some unnecessary code from the test (and also updated the code so we don't have to modify
|
Found it. :) In case anyone is curious, it all came from this little function in protected function calcFrame():void
{
_flashRect.x = _curIndex*frameWidth; // <---(1)
_flashRect.y = 0;
//Handle sprite sheets
if(_flashRect.x >= _pixels.width) // <---(2)
{
_flashRect.x = uint(_flashRect.x/widthHelper)*frameHeight;
_flashRect.y %= widthHelper;
}
//Update display bitmap
framePixels.copyPixels(_pixels,_flashRect,_flashPointZero); // <---(3)
_flashRect.x = _flashRect.y = 0;
if(_colorTransform != null)
framePixels.colorTransform(_flashRect,_colorTransform); // <---(4)
} In our example, the sprite was sized 50x50, with the "expected" sprite being on frame 0, and the "bugged" sprite on frame 1. Let's also assume that the alpha is always set to
By the point you reach (1), the location for the "expected" sprite's frame is set to By section (2), Flixel realizes the "bugged" sprite's rectangle is too far right to be on the image, so it moves it down to what it thinks is "the next line" of the sprite sheet. New values (only for the "bugged" sprite) Once it gets to section (3), two different things happen: For the "expected" sprite: the old BitmapData gets copied over with entirely new data, retrieved from For the "bugged" sprite: Notice now that |
As for a solution, all this can be avoided by preventing the user from ever setting the current frame number above the maximum number of frames, either directly (through the I'm taking a break on this issue for a while, so if anyone wants to take the information I have gathered and propose a solution, feel free to do so. I'm going to loaf about on the couch for a few hours. |
Nice catch! I can take a look at this issue and implement your solution, @IQAndreas. If you agree, just assign the issue to me and I will work on it as soon as I have some free time. |
Sorry, I didn't realize it had gone an entire week and I still hadn't updated this issue. Actually, there is no reason to read up on the details on why the bug occurs. As you correctly deduced in the FlixelSandbox, it happens because the current frame number is set above the maximum number of frames; that is all that needs to be fixed. One "gotcha" to keep in mind, Where should the "frame number" check be done? There are two places an invalid frame number can be set:
Should this error (or better yet, a warning) be thrown:
The latter will produce an error message every frame (not ideal). However, the former will produce other problems if they add the animation before loading the graphics, or if they change the graphics any time after the animations have been added, and the new sprite sheet doesn't contain enough frames. Is this a valid concern? How many frames are there actually? Finally, there is a slight inconsistency in how to calculate the amount of available frames. In
But in
Should there be an additional check to make sure the frame index isn't outside of the y axis? Should it then loop around to frame 0, or should it just stop and whine? So once again, I guess I'm waiting for my "moment of inspiration" to magically clarify my mind and help me know what to do. But I seem to be "groggy minded" still, so feel free to tackle it yourself. If you only want to tackle the questions, I will gladly tackle the code as long as I know what to do. |
I've been thinking about this issue and I guess there is a simple solution. The whole problems is related to the frame index, so we should fix/sanitize the value before assigning it. Why would Flixel show a warning when a wrong frame value is used? To make the developer aware of the problem, so he can fix it. Why doesn't Flixel fix the problem already? If there are 4 frames, then the index should range from How about that? |
I forgot to finish this issue, thanks for resurfacing it.
That works. But, which of the two methods do we use to calculate how many frames there are? (see under the heading "How many frames are there actually?" in my previous comment) If we use the first method (requiring all the frames to be on the same row) we know exactly when the frame index is out of bounds. If we use the second method (i.e. assuming frames can wrap around to the next line), we have no way of telling if frames
That's a good point, displaying the same warning several times in a row in the output isn't really that big of deal then. And you are right, these questions only become relevant if the developer is making a mistake in the first place; all we really are doing is writing the warning system to assist in debugging. Sorry for over-thinking things, let me know if I get out of hand. |
The over-thinking is good :) First about the output message, I guess I was not clear enough when I made my point. I think Flixel should not output any error message when an incorrect frame is used. Flixel should analyze the value and sanitize/fix it silently.
Yeah, I noticed that now. Checking the code I think the only property we should care about is public function set frame(Frame:uint):void
{
_curAnim = null;
_curIndex = Frame;
dirty = true;
} That's the only "entrance" point where someone can mess up with the animations. |
Keeping in mind, since Flixel only alerts you of warnings if the console is enabled and open, we don't run the risk of bothering "users/players" with the error message. Imagine you are creating a game and for no reason one of your sprites suddenly resets to the first frame (frame 0). Assuming you even notice it, first you have to spend several minutes debugging if it's your code to find out where the problem is: is it in the tile sheet, the animation code, or a bug in Flixel? Wouldn't you rather have an error message tell you "Warning: Trying to set the |
Yeah I agree with you. A warning will not harm anybody, but I keep on thinking if we should fix the mistake on the fly too. Using your example, if you try to set a frame above the upper range, Flixel should set the frame as the last one available. It will not cause the sprite to reset its animation. The same happens if a negative value is used in a frame ( |
Perfect! So, the only issue that remains is, how many frames are there in a tilemap? |
Yes, that's the only thing we must figure out. It will fix the |
How about this, we add a public getter/setter named
Does that sound like a good solution? Any other thoughts? |
I like the idea of adding
Since |
But that would still make functions like
How about instead making that read-only property named |
Perfect! |
I was working on this when I noticed another potential bug (albeit, a rare case one). If the width of your sprite sheet doesn't evenly divide by the width of each tile (say, the sprite sheet is 25 pixels wide, and each tile is 10 pixels wide), Flixel will currently assume that frame 2 (zero based) will be located at x:20, and will only render "half of" a sprite. I'm going to change the way Flixel handles such cases and require that a frame be entirely inside of the sprite sheet. I don't see any reason to throw an error or warning, the "overhanging pixels" will just be silently ignored. If anyone has a good argument against this, I will revert back to Flixel's old way. |
I guess Flixel calculates tiles that way to maintain the uniformity between the game code and tile editors such as DAME (or any image editor with grids enabled). If you change that behavior developers might face inconsistencies beteween what the tile editor is showing and what Flixel is actually showing. We should test that change with DAME and other editor to check if everything is ok. |
Issue has been fixed in df5dfc6. |
Fixes FlixelCommunity#13 Prevents an "out of range" frame number from being set either by an animation, or by manually setting the `frame` property. Adds new getter/setter `numFrames` where user can manually specify how many frames an animation has (in case some frame are empty). To go hand in hand with this is the read-only property `maxFrames` which calculates how many frames can fit on that sprite sheet. NOTE: it rounds up, so sprites may "hang off the edge" if the sheet is the wrong dimensions. This may be fixed in the future depending on how other applications handle "overhanging frames".
Issue #219 by: mouseas
I have the following code in a FlxSprite:
Instead of taking 15 seconds to fade out, the sprite fades out in less than a second. I took a quick poke into the alpha-related code in FlxSprite, and it looks like alpha is adjusted in discrete increments. Problem is, if the amount the alpha is supposed to change is too small, it still drops it one increment. The end result? The FlxSprite is invisible when its alpha value is actually at around 0.95 - 95% opaque, i.e. ever-so-slightly see-through.
Edit: I was able to isolate the problem quite a bit. It was trying to fade on a non-existant frame (thanks to a +1 error on my part), ie the frame it was currently on was a copy of the last frame. I tried using makeGraphic() and the same bug happened. Basically, this bug occurs when the graphic is unique and there's no sprite/spritesheet to reference back to. If the frame is a valid image on a spritesheet, this bug does not occur.
Expected behavior: Sprite fades slowly, based on alpha value.
Actual behavior: If sprite graphic is unique, it fades quickly. The change in actual transparency is not in line with the alpha value.
To reproduce:
The text was updated successfully, but these errors were encountered: