Pixel-by-pixel destructible terrain?[Yup, why not]

  • Hey guys!

    Just curious if someone's tried to do it without using 3rd party pug-ins..

    Here's what I've tried to do:

    Example capx

    Bresenham's algorithm inside a while loop & decreasing radius. Yikes <img src="smileys/smiley11.gif" border="0" align="middle">

    Well, it works, but waay too buggy and dirty, as expected:)

    Try setting global Radius to 32 and radius decrement(at the end of first "while" loop)

    to something like 0.05 and you'll see that it's way too CPU-abusive..

    Yeah, I know it's far from optimal:(

    I would really appreciate if someone point me in a right direction on how to optimise this algorithm <img src="smileys/smiley9.gif" border="0" align="middle">

    Or, even better, show me a better filled-circle drawing method :P

    Not that I need it badly for my projects, just curious <img src="smileys/smiley36.gif" border="0" align="middle">

    //upd I guess I have an idea how to modify Bres's algorithm, but I'm too weak at programming so it may take a while <img src="smileys/smiley9.gif" border="0" align="middle">

    Thanks in advance!

    George.

  • Yay, think I'm getting closer :D Example 2

    Now it's clean, but still seems a bit slow :( Any ideas how to make it run smoother?:P

    //Upd. Not sure if it is any faster, but Example 3

    Allright, I'm running out of ideas <img src="smileys/smiley36.gif" border="0" align="middle">

    //Upd. Looks simple, but still slow : Example 4 and Example 5

  • I'm impressed that the tilemap renders so fast with 1x1 tiles. This has potential, and I do enjoy optimizing.

    I took your forth capx and added a text object to store the average time it takes the function to clear a circle.

    https://www.dropbox.com/s/mwjxctu4vhx7w ... .capx?dl=0

    So now I have something to compare against. For an initial test I went for circle clearing with as few events as possible. The algorithm I used is just the graph of a circle. Bresenham's algorithm probably will be faster but I haven't fiddled with your events with the same stuff I did with mine.

    https://www.dropbox.com/s/t8mizv3e6hugt ... .capx?dl=0

    Compared to the two "simple.capx" is about 3 times faster. Here are some things I did and my reasoning. Note that I wasn't profiling as I went along so I'm unsure of the boost each gave, if any.

    * I changed the function so x,y and radius are passed as parameters. This to eliminate the need to re-pick the bullet in the function. Actually this probably was a negligible change. It was more of a style preference.

    * I used "erase tile range" instead of "erase tile". This likely was the biggest boost since it eliminated a loop level since we can just erase spans of tiles at a time.

    * I didn't use the "Tilemap.PositionToTile" functions since with 1x1 tiles pixel position is the same as tile position. A little flexibility is lost doing this since the tilemap object has to be at position 0,0.

    That's about it. Next I'll have tinker with your events to see avoiding a sqrt() with some more events perform better.

  • Now that's what I call an optimisation! <img src="smileys/smiley32.gif" border="0" align="middle" />

    Thank you so much R0J0hound ! I understand the changes you've made, and I totally agree. I've learned alot from them, thanks again <img src="smileys/smiley9.gif" border="0" align="middle" />

    Hehe, I guess that's a nice way to generate new ideas: first, a curious newbie (Me) shows a potential of something to an experienced person(Master R0J0).

    Than this skilled person finds the best way to make it work and releases a nice new solution, usable for all other community people:P

    R0J0hound, I admire your skills:) Would be nice to see if avoiding sqrt() can make it run even faster! (Tho I think it's already usable as it is :P )

    P.S. Would be nice if someone could test it on mobile platforms, btw ;)

  • JJList : I don't have time to see the work you've done, but I really like the idea of pixel by pixel destructible terrain, I think it opens really a lot of possibilities, Worms armageddon for instance uses this kind of logic I think (except that you could import a picture in Worms armageddon to define the level also, but I don't think it'll be possible to do without serious work in C2, it was also limited in size and color), maybe some algorythms to generate from a mathematical graphic equation? I am thinking too much sometimes.

    Anyway, good concept you got there

  • R0J0hound dat math! Simple yet elegant. This is actually working extremely fast and solid! Sometime I notice bullets going missing when I fire in salvo's but I couldn't test this further. This is so awesome!

    EDIT: I think it's possible to add "diffX and diffY" variables if you don't want to place tilemap at "0,0". Just set them manually at startup and include in your math, but I'm just unsure how to.

  • Wow!

    I didn't think per pixel stuff was doable, but that may be even faster than Construct Classic could have done.

    Great job, or should I say tanks guys?

  • Ditto wow, the old artillery games didn't erase that fast.

    Firing rapidly I got my processor usage to spike at 23%, (averaged 9%) but could never get the framerate to drop from 60.

  • JJList

    Tested on Ipad 3, and there is a slowdown on fps for the function, more like a choke really.

    It goes from 45, down to 40, accumulative for multiple shots, so that's not advisable.

  • newt wow, 40-45 fps? And that's while rendering a ton of 1x1 pix tiles.. Ain't that impressive? :D

    Sure it still has those little "chokes" when erasing tiles, even on desktop:(

    Note sure if we can avoid it.. but I think it's not that bad and it fits worms-like games pretty good:)

    Another problem I see is to "draw" the tiles. Kinda hard to fill our layout with 1pix tiles manually:(

    Any thoughts on how to solve this one?

    One way, i guess is to use tilemap as a collision mask, leave it empty,

    build our level scenery with regular sprites/tiledBGR and than generate our tilemap on those sprites.

    Here's an example. Mask generation

    Works fine for rectangles.. Not sure how to do it for other shapes:(

    Ideas?:)

  • Pixel by pixel isn't so bad if you split a tile-able image into 1 pixel tiles, and use the rectangle tool to place multiple tiles. Like the bitwise/ Salt method.

    Then again Im quite sure the mask method would work using an fx.

    Edit:

    Scratch that first suggestion, it seems a bunch of different tiles really brings the fps down!

    It might work if it wasn't all 1 pixel. 2, 4, or 8 might be ok, but you might run into symmetry issues finding a single point in an even number.

  • Looks like the Overlay fx will work nicely.

    Also its painfully hard to edit anything at that size without a zoom in the tiles menu. I noticed Tiled does not have that feature either. Any possibilities there Ashley?

    If not perhaps some other type, or new object would be better suited for this. I say that since it seems one pixel is the way to go.

  • Tiled has a drop-down to increase the size of the tileset.

  • newt I still think that filling entire tilemap by hand inside layout editor.. with 1px tiles.. is a real pain in the butt, pardon my french.

    At least until we get an adjustable "tile brush" or something like that.

    I guess, generating tilemap (as a collision mask, just one tile) and using sprites as a reference is a way to go. Probably I'm wrong:(

    And i really have no idea how to implement generation of non-rectangular shapes, due to the limitaions of C2 and tilemap system.

    @Everyone and especially R0J0hound :P

    =

    ( Caution! Abusive logic detected. Author is not responsible for any brain damage caused by reading the following text )

    =

    But! Imagine that we have a method to detect alphachannel value of a particular pixel in a raster image?

    Something like pixelalpha(x,y)=[0..255]. Where (x,y) is the position of the pixel inside an image.

    (I believe it's not too hard to implement it as plugin or something..

    No idea how it works, tho :P)

    Then we could set up our layout with sprite scenery( lets call it MaskSprites ), like I did in the example..

    NOTE that MaskSprites should have origin at top-left.

    On start of layout we just need to populate a huge array.

    Here it gets tricky and will definitely take a while to do..

    So, for each MaskSprite we run a loop like

    |   for i from 0 to MaskSprite.width

    |     {

    |        for j from 0 to MaskSprite.height

    |          {

    |             if pixelalpha(i,j)=255 set Tilemap At(MaskSprite.X + i, MaskSprite.Y + j)

    |          }

    |     }

    So we'll get our collisionmask tilemap generated, following the shape of all MaskSprites we have.. And we have our layout scenery underneath. Then give our tilemap something like Addictive blendmode or Overlay fx and TADAM! We have our level :D

    Does that make any sense, guys?:P

    UPD: I do understand that generating entire level each time we start our layout ingame is insane xD

    But we can use it in level editor or something, then save our tilemap as JSON( or however we save tilemaps ) and just load it from that file?

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I think your best bet is to do a separate editor, and load a map at runtime, perhaps using Rojo's Canvas plug. It can do per pixel comparisons.

    The reason for that is that kind of generation would take a long time.

    As to the corners:

    saltgames.com/2010/a-bitwise-method-for-applying-tilemaps

    Seems to me you could check the offset for more than one tile.

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