Optimizing my dynamic background engine for a 2d flash game in actionscript-3

前端 未结 6 1315
青春惊慌失措
青春惊慌失措 2021-02-11 05:23

Edit 2: judging on the lack of replies I start wondering if my issue is clear enough. Please tell me if I need to elaborate more.

Notice: see bottom for a co

相关标签:
6条回答
  • 2021-02-11 05:45

    Try using a single large BitmapData with it's own Bitmap, larger than the stage (although you might hit the limits of BitmapDatas if you have a really big stage and/or are using flash 9), and drawing new background images to it using the copyPixels method (a really fast way of copying pixels, faster than draw(), at least as far as I've seen).

    Pan the large Bitmap around when you want and when you reach an edge, pan the bitmap to the other side, copyPixels the whole thing back to where it was previously (so the image should stay in the same place relative to the stage, but the Bitmap should move) and copyPixels new images where they are missing.

    Since you are using alpha for the images as well, so you might want to check all the parameters of copyPixels if it doesn't copy alpha as you wanted it to (probably mergeAlpha?).

    So, to recap, use a single large Bitmap that extends well over the boundaries of the stage, have the images ready as BitmapDatas, do the wrap trick and fill in the blanks with copyPixels from images.

    I don't know if this way would perform better (the copyPixels over the whole bitmap worries me a little), but it's definitely something to try. Good luck :)

    0 讨论(0)
  • 2021-02-11 05:48

    Try stretching the window of the player, both bigger and smaller. If that has a significant effect on frame rate, your fastest and easiest way to improve performance is to shrink the size of the stage. This tends to be an unpopular answer when presented to people - especially artists - but if your bottleneck is in the size of your stage, there is not much you can do in code to fix that.

    0 讨论(0)
  • 2021-02-11 05:49
    • You should be able to simplify some of your math by using stored variables instead of stageCenterX + stageWidth * 0.75, and similar since they don't change.
    • Have you considered using HitTestPoint instead of doing the math to check positions of containers? It's a native function, so it might be faster.
    • You should use a Shape instead of a Sprite if you don't need to add children to the object. e.g., your star. This might help quite a bit.
    • What if you created a set of star backgrounds at the start of the program. Then converted them to bitmaps, and saved them for later reuse. e.g., create a star background, convert it to bitmap data, and save this in an array. Do this, say, 10 times, and then when you need a background to just randomly select one, and apply your other shapes to it. The benefit of doing this is that you don't have to render 100-250 Sprites or Shapes each time you create a new background--that takes time.

    EDIT: New idea:

    • Maybe you can play with the idea of only drawing the stars on the backgrounds rather than adding individual objects. The number of objects added to the screen are a big part of the problem. So I'm suggesting you draw the stars on the container directly, but with different sizes and alphas. Then scale the container down so that you get the effect you're looking for. You could reduce the display footprint from 500-1000 stars down to 0. That would be a huge improvement if you can get the effect you need from it.
    0 讨论(0)
  • 2021-02-11 05:52

    ok, this should show you can really get another category of numbers with other aproaches ...

    the limit here is not the number of stars, the limit is density, i.e. the number of stars visible at the same time ... with text disabled, i can get up to 700 @ 30fps, on a Core2Duo, with quite a recent version of the debug player ...

    i realized, flash player is not very good at clipping ... and that actually, using the most simple way, you spend a whole lot of time moving around objects, that are far from being visible ...

    to really be able to optimize things, i chose to use MVC here ... not in the classic bloated way ... the idea is to handle the model, and if any elements are visible, create views for them ...

    now the best aproach is to build up a spatial tree ...

    1. you have leaves, containing objects, and nodes containing leaves or nodes
    2. if you add an object to a leaf and it surpases a certain size, you turn it into a node with nxn leaves, redestributing its children between
    3. any object added to the background will be added to a grid, determined by the object's coordinates ... grids are created just-in-time, an start off as leaves

    the big advantage of this is, that you can quickly isolate the visible nodes/leaves. in each iteration, only the nodes/leaves which either turn visible, or are already visible (and may become invisible), are interesting. you need not do any updates in the rest of the tree. after finding all the visible objects, you create views for objects that turn visible, update the position of those that simply stay visible, and destroy views for objects that become invisible ...

    this saves an awful lot of everything ... memory and computation power ... if you try with a huge world size (100000), you will see, that you run out of RAM quickly, long before CPU does anything ... instantiating 500000 stars uses 700MB ram, with about 50 stars visible, running at 70 fps without any tremendous CPU usage ...

    the engine is just a proof of concept ... and code looks awful ... the only feature i am currently proud about is, that it supports object to occupate a certain area, which is why an object can be part of several leafs ... i think, this is something i will remove though, because it should give me a great speed up ... you also see, it stalls a little, while adding stars, which happens, when leafs flip to nodes ...

    i am quite sure, this is not the best way for a spatial subdivision tree, it's just that everything i found seemed kind of useless to me ... probably someone who studied (and understood) CS, can refine my approach ... :)

    other than that, i used an object pool for the views, and Haxe, since it performs better ... a thing that probably is not so clever, is to move all the views individually, instead of putting them on one layer and moving that around ...

    some people also render things into BitmapDatas manually, to gain performance, which seems to work quite well (just can't find the question right now) ... you should however consider using copyPixels instead of draw ...

    hope this helps ... ;)


    edit: i decided to turn my detailed answer into a blog post ... have fun reading ... ;)


    0 讨论(0)
  • 2021-02-11 05:57

    What if instead of destroying background squares you just put them in a pile of "ready to go" squares that you can draw on, capping it at like 4? then you don't have to create one when you need one you just move it into the right spot and maybe shuffle the stars or something.

    [would add example but i don't write AS3 code :(]

    0 讨论(0)
  • 2021-02-11 06:02

    You may want to see if you can blit all of the pieces together into a flattend Bitmaps as you go. Draw all of the layers and then use BitmapData's draw method to combine them into a single Bitmap.

    Even with cacheAsBitmap on for all of the pieces Flash is still having to combine all of those pieces every frame.

    0 讨论(0)
提交回复
热议问题