Jump to content


Photo

Destructible Terrain


  • This topic is locked This topic is locked
79 replies to this topic

#61 Tweak2

Tweak2

    GMC Member

  • New Member
  • 122 posts

Posted 30 August 2009 - 02:31 AM

Here's my idea. I've looked at DTE's, and have experimented with kaietnap's enough to know how it works. I propose to do the following (I am making a DTE with falling "sand"); use multiple ds_grids at a size of 50x50 or smaller (still experimenting, maybe larger) to store parts of the environment. Creating rooms of even 200x200 cause lag so far, so here's what I think could reduce it. After every ds_grid is initialized, the draw_pixel is only called once, and then a sprite is created from surface. Then when a destruction takes place, a change is registered in the appropriate grid, and it acts accordingly (I've already figured out a script to make it fall). Then after all changes are made, it makes another sprite from surface and resets the image. I am still working on this, so I don't know if it works yet.
  • 0

#62 ditdingiscool

ditdingiscool

    GMC Member

  • New Member
  • 335 posts

Posted 09 September 2009 - 07:38 PM

Here's my idea. I've looked at DTE's, and have experimented with kaietnap's enough to know how it works. I propose to do the following (I am making a DTE with falling "sand"); use multiple ds_grids at a size of 50x50 or smaller (still experimenting, maybe larger) to store parts of the environment. Creating rooms of even 200x200 cause lag so far, so here's what I think could reduce it. After every ds_grid is initialized, the draw_pixel is only called once, and then a sprite is created from surface. Then when a destruction takes place, a change is registered in the appropriate grid, and it acts accordingly (I've already figured out a script to make it fall). Then after all changes are made, it makes another sprite from surface and resets the image. I am still working on this, so I don't know if it works yet.

that's a bit rube-goldberg, you should have one big ds-list and one big surface, then when damaging the terain just update the list and the surface, for 'normal' room sizes that's lag free,
  • 0

#63 blue_chu_jelly

blue_chu_jelly

    Shut your FMaj7

  • GMC Member
  • 228 posts

Posted 10 September 2009 - 04:45 AM

Here's my idea. I've looked at DTE's, and have experimented with kaietnap's enough to know how it works. I propose to do the following (I am making a DTE with falling "sand"); use multiple ds_grids at a size of 50x50 or smaller (still experimenting, maybe larger) to store parts of the environment. Creating rooms of even 200x200 cause lag so far, so here's what I think could reduce it. After every ds_grid is initialized, the draw_pixel is only called once, and then a sprite is created from surface. Then when a destruction takes place, a change is registered in the appropriate grid, and it acts accordingly (I've already figured out a script to make it fall). Then after all changes are made, it makes another sprite from surface and resets the image. I am still working on this, so I don't know if it works yet.

that's a bit rube-goldberg, you should have one big ds-list and one big surface, then when damaging the terain just update the list and the surface, for 'normal' room sizes that's lag free,


define what a "normal" room size is for me.
  • 0

#64 ditdingiscool

ditdingiscool

    GMC Member

  • New Member
  • 335 posts

Posted 12 September 2009 - 02:35 PM

Here's my idea. I've looked at DTE's, and have experimented with kaietnap's enough to know how it works. I propose to do the following (I am making a DTE with falling "sand"); use multiple ds_grids at a size of 50x50 or smaller (still experimenting, maybe larger) to store parts of the environment. Creating rooms of even 200x200 cause lag so far, so here's what I think could reduce it. After every ds_grid is initialized, the draw_pixel is only called once, and then a sprite is created from surface. Then when a destruction takes place, a change is registered in the appropriate grid, and it acts accordingly (I've already figured out a script to make it fall). Then after all changes are made, it makes another sprite from surface and resets the image. I am still working on this, so I don't know if it works yet.

that's a bit rube-goldberg, you should have one big ds-list and one big surface, then when damaging the terain just update the list and the surface, for 'normal' room sizes that's lag free,


define what a "normal" room size is for me.

1280x1024 is probably the max, but it's only limited by ram/video memory, so it should be possible to work around that...
  • 0

#65 theg721

theg721

    G Dawg

  • GMC Member
  • 1959 posts
  • Version:GM8

Posted 10 October 2009 - 12:12 PM

Err.. Sinaz, you didn't add my example to your list.
  • 0

#66 vadim647

vadim647

    Quite Epic

  • New Member
  • 840 posts

Posted 10 October 2009 - 12:33 PM

Err.. Sinaz, you didn't add my example to your list.

If you have seen what you have made and saying that, you're about to be trolled.
  • 0

#67 theg721

theg721

    G Dawg

  • GMC Member
  • 1959 posts
  • Version:GM8

Posted 10 October 2009 - 02:57 PM

Err.. Sinaz, you didn't add my example to your list.

If you have seen what you have made and saying that, you're about to be trolled.

Err.. what's trolled mean?
  • 0

#68 tomster1996

tomster1996

    GMC Member

  • New Member
  • 312 posts

Posted 05 December 2009 - 08:32 PM

Check out my very simple DT engine. It uses grid cells that divide into smaller cells but only in concentrated areas.
It does lag a bit, but rarely and not very much. Here's my forum post.
  • 0

#69 superjoebob

superjoebob

    YM2612

  • New Member
  • 1515 posts

Posted 02 January 2010 - 08:14 PM

I've taken a look through the post so far, and it doesnt appear anyone has posted an example for an array based terrain system yet, so I suppose I'll take a shot at it.

Basically, the level consists of a large array of numbers (I used Game Maker's ds_grid system), one for every pixel on the screen. 0 would be air, 1 would be dirt, 2 could be stone, 3 could be water, etc. Once an array of numbers is created, it can be drawn using surfaces. Loading time is the only problem with this method, as each pixel must be drawn at the start of the level. This can be sped up considerably by loading full lines of terrain at a time when possible, etc.

This allows you to use a terrain texture that is prepetually tiled throughout the map, and makes it very easy to create different types of terrain. As for speed, I can get 60fps no problem on a less than desirable computer with only 3 seconds of extra load time (about 7 seconds total load time).

The only major problem i've run into is that you cannot make the level larger than about 2200 by 2200 (didn't test exact dimensions, could be a code error too, who knows), or the grid function fails (perhaps the number is too large for GM's grid system?). This can be solved by splitting the level into a number of arrays though.

Anyways, try it out for yourselves, left click to remove terrain, mouse wheel up and down changes size of terrain to remove. Press shift to change from removing to adding terrain, and press 1 and 2 to change between dirt and rock. Arrow keys move around the little ball.

Diggable Terrain

I'll upload a proper non-mediafire link once I get to my home computer, i'm actually on my laptop in an airport right now :).

EDIT: Oh yeah, forgot to mention, the example is a GM8 file which was originally written in GM7 and converted over. This method runs quickly in both but your gonna need GM8 to run the example, sorry :P.

Edited by superjoebob, 02 January 2010 - 08:22 PM.

  • 0

#70 xDanielx

xDanielx

    GMC Member

  • GMC Member
  • 1002 posts
  • Version:Unknown

Posted 02 January 2010 - 10:38 PM

I've taken a look through the post so far, and it doesnt appear anyone has posted an example for an array based terrain system yet, so I suppose I'll take a shot at it.

I can't run any of the demos from here, but what you describe sounds similar to the approach Sinaz took some time ago. Don't blame you for not digging through such an old and long topic.

I think it's one of the better techniques around, but what if you wanted to make an incision that wasn't in the shape of a circle or rectangle? Using repeated ds_grid_sets would be slow. We could cut down on interpreted code by decomposing a destruction mask into scan lines or quadtrees, but that would mean more preprocessing and still quite a few ds_grid calls. I suppose in practice people mostly just use circular subtractions, but often developers want non-circular additions (e.g., in Worms, falling presents mold with the terrain).

I still think the best general solution is to maintain both a surface and a sprite for the terrain. We perform mutations by drawing to the surface, then the sprite is reloaded from the surface and used for collision checking. Loading large sprites is slow, but we can get around this by dividing the terrain into segments. I implemented this here, but the idea long predates my implementation.

Edited by xDanielx, 02 January 2010 - 10:42 PM.

  • 0

#71 superjoebob

superjoebob

    YM2612

  • New Member
  • 1515 posts

Posted 02 January 2010 - 10:54 PM

I think it's one of the better techniques around, but what if you wanted to make an incision that wasn't in the shape of a circle or rectangle?


I actually never really thought of that :). EDIT: (upon re-reading your post, I found you already discussed this :P >>>)It could be done with a series of grid commands to cut out a certain shape, but I suppose that would be a pain to impliment, and it wouldn't be very flexible.

All that aside, I think the grid method is better than the surface/sprite method for a game like Clonk which uses multiple terrain types, which is the main reason I'm using it.

Edited by superjoebob, 02 January 2010 - 10:58 PM.

  • 0

#72 Obj_Control

Obj_Control

    GM Mentor

  • New Member
  • 2561 posts

Posted 03 January 2010 - 02:45 AM

Well, you could simply generate a "collision mask" before hand, into it's own grid. This would work by making a ds_grid with the dimensions of the sprites. 0 would mean transparent, and 1 would mean solid. Then you could just change the values on the terrain grid. (0: do nothing, 1:change value on terrain grid to 0.)
  • 0

#73 xDanielx

xDanielx

    GMC Member

  • GMC Member
  • 1002 posts
  • Version:Unknown

Posted 03 January 2010 - 09:46 AM

I guess if 0 is the empty spacial state, we could use create a subtraction mask where 0 indicates subtraction and 1 indicates no change, then use ds_grid_multiply_grid_region to perform the subtraction.

What about additions, though? We can't use ds_grid_set_grid_region, as we couldn't implement a "no change" value. We could use use 0 to encode "no change" and 1 to encode solidification, then apply ds_grid_add_grid_region, but then repeated additions would create larger and larger values in the grid. We would need to treat anything nonzero as solid, so we'd be limited to binary solid/empty states. (Admittedly, my preferred approach only works with binary states as well, unless we encode states as surface colors, which is a nasty hack.)

We need a ds_grid_combine_grid_region(id, source, x1, y1, x2, y2, xpos, ypos, binaryfunction)!
  • 0

#74 Obj_Control

Obj_Control

    GM Mentor

  • New Member
  • 2561 posts

Posted 03 January 2010 - 07:31 PM

Using a for loop to edit a region of values shouldn't slow the process down too much anyhow. Unless the region is unusually large, or the loop happens too often.
  • 0

#75 Ground Commander

Ground Commander

    GMC Member

  • GMC Member
  • 52 posts

Posted 06 January 2010 - 12:26 PM

Icuurd's example was pure brilliant, i never thought of that. Indecom's was better but he followed Icuurd. Both of them are great examples.
  • 0

#76 Robert3DG+

Robert3DG+

    Designer

  • GMC Member
  • 1925 posts
  • Version:GM:Studio

Posted 11 February 2010 - 03:47 AM

Just a thought, isn't there open source versions of Worms out there now? Hedge Wars comes to mind. Has anyone thought of poking through that code and seeing what could be salvaged?

If anything it's probably similar to Icuurd's example.
  • 0

#77 natebot13

natebot13

    GMC Member

  • New Member
  • 2 posts

Posted 07 September 2011 - 04:18 AM

i began making a game with destructable land, a while ago. the land was made of large blocks, and if it was hit, the large block would divide into 4 and if the divided object was hit it would divide into 4 and eventualy the last object would destroy, here is a link to the game
http://host-a.net/aa...troy_landex.gmk


how might i achieve this but only using one object and scaling it down?
  • 0

#78 SI II man

SI II man

    GMC Member

  • New Member
  • 83 posts

Posted 23 October 2011 - 12:36 PM

As far as I see it you could just quarter the land as required.
Don't understand? I'll explain.

the world is made form 20x20 blocks (or larger smaller whatever)
on collision with a projectile / player etc. it is destroyed and replaced with 4 10x10 blocks.
on the smaller blocks collision it breaks into 5x5 blocks
and on and on until you reach 1x1
on collision of the 1x1 it is destroyed leaving a hole. these holes added together form a shape in the world

it's easy to implement however is too slow to use in a large area.

EDIT: OK I tested that and my kick ass pc couldn't run it so ignore me please

Edited by SI II man, 23 October 2011 - 12:57 PM.

  • 0

#79 lethman427

lethman427

    GMC Member

  • New Member
  • 58 posts

Posted 06 February 2012 - 04:52 AM

For 2D destructible terrain withouth tunnels, it is fairly easy to use a single dimesion array of height values, then draw lines for terrain top and find a way to draw the lower stuff (triangles and rectangles?) To check if something is above terrain you could use some trig. For explosions and stuff my out of the blue idea is using some math to lower terrain points around explosion by a decreasing amount if the terrain points are within range. I'm not sure if this has been reccommended already, but I used this method in one of my unfinished games quite effectivley.
  • 0

#80 GLGMG

GLGMG

    GMC Member

  • New Member
  • 15 posts

Posted 12 March 2012 - 03:50 AM

For 2D destructible terrain withouth tunnels, it is fairly easy to use a single dimesion array of height values, then draw lines for terrain top and find a way to draw the lower stuff (triangles and rectangles?) To check if something is above terrain you could use some trig. For explosions and stuff my out of the blue idea is using some math to lower terrain points around explosion by a decreasing amount if the terrain points are within range. I'm not sure if this has been reccommended already, but I used this method in one of my unfinished games quite effectivley.

I know I've been inactive for a while and I myself am currently working on something similar. I don't want to spend a long time on the details so here's my SUPERPSUEDO code: Create the "end result" in the width of the affected area either as a surface or sprite. Now just lower an entire rectangle of the previous "undamaged" surface "revealing" the "end result" sprite/surface. If your texture is not too complex, it should look just fine as long as the "end result" has a higher depth. Then once the "falling" ends, just merge it with the whole land sprite. It's like a whole month late so I don't know if you've already achieved what your after but I am having a VERY tough time getting my system together and these threads are the closest/most similar thing to my engine that I can find on the net. :)
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users