XNA Creators Club Online
Page 1 of 1 (11 items)
Sort Posts: Previous Next

2D Side Scroller Drawing/Collisions - Node Proximity

Last post 7/7/2009 10:11 PM by zissakos. 10 replies.
  • 5/12/2009 12:48 AM

    2D Side Scroller Drawing/Collisions - Node Proximity

    Writing a 2d side scroller and thinking about the drawing aspect and collision aspect.  Its not classic tile based, but instead in the map editor you can place a node at any position in the map (not restricted to placing in a tile), with modifiable rotation/scale.  There are multiple layers within a map and each layer can have multiple nodes.   So there is a List of Layers, and a List of Nodes within each layer. 
    (For a better idea of the map editor I made, it is something along the lines of this: Editor )

    Just to give an idea of how the data is structured, this is what the layer lists and node lists could look like
    Layer List { Layer 1, Layer 2 }
    Layer 1 Node List{ Node@228x459, Node@105x322, Node@892x370} 3 nodes in this layer
    Layer 2 Node List{ Node@500x250 } 1 node in this layer

    Question:  Drawing the nodes
    When drawing the nodes I don't want to draw each node within each layer since some of the nodes may be off the screen.  Unfortunately since I am not using the classic tile implementation I can't just iterate through the tiles that are currently within the retangular view of the camera and draw only those tiles in each layer.  So my idea is to create a grid of the entire map that associates each of the grid squares with the nodes that are contained within the square.  The data structure would be an Array of Node Arrays.  Each element in the array is associated with a specific grid square (maybe 128x128 pixels) and there could be multiple nodes that are part of that grid square. 

    For example:
    Consider a map that is 256x256 and were using 128x128 grid squares.  this means the data structure will be 4 elements (the map is split in a 2x2 grid)
    A[0] = {N0, N1} upper left square, node 0 and node 1 are in this square
    A[1] = {N0} upper right square
    A[2] = {} lower left square, empty
    A[3] = {N1} lower right square

    Lets say the camera's viewport was set up to only view 256x128 pixels. If it was currently viewing the bottom part of the map (grid square 2, and grid square 3), we would look at the nodes in A[2] and A[3] , meaning we would only draw N1.

    This also speeds up collision detection as I will only do collision detection on entities that are part of the same grid squares.

    Let me know if this makes sense, if I need to explain it more, or if there is a much better way to accomplish this task.


  • 5/13/2009 7:11 PM In reply to

    Re: 2D Side Scroller Drawing/Collisions - Node Proximity

    Any thoughts?
  • 5/14/2009 1:41 PM In reply to

    Re: 2D Side Scroller Drawing/Collisions - Node Proximity

    I am also trying to make such an editor for my game.

    I heven't got to that stage yet, but what I would do is the following:

    I wouldn't consider additional logic like grid etc. since I think you already have what you need: Every Node has a position and a bounding rectangle, right?
    (If not, add a way to keep a bounding rectangle, since you will need that later for collision detection - or are you using a physics engine?).

    Now, the only thing you have to do is get each Layer to know the visible part of the world, e.g. through a Rectangle visibleRect. This can be done in many ways, e.g. in its update() method, where you would have to supply the current visible rectangle of the world, which in turn you could obtain from your Camera class.

    Then, in the draw() method of a Layer you check if the bounding rectangle of a node you want to draw collides with visibleRect and draw it only then:


    if (visibleRect.Intersects(node.boundingrect))
    {
        node.draw();
    }

    That's roughly how I would do that.


    My Games:
    Konfuzion (currently in Playtest)

    My Tools:
    GLEED2D - Generic Level Editor 2D
  • 5/14/2009 4:41 PM In reply to

    Re: 2D Side Scroller Drawing/Collisions - Node Proximity

    I do have bounding rectangles for each of my nodes.  Yours definitely seems like the more natural and logical way to do it, but wouldn't this add extra work for the cpu while drawing during run time of the game? Also you would need a more complex check for intersection if you are allowing rotation of your nodes.  If there are no rotations, this method probably would be fast enough to do during the game.  Unless you think the amount of time required to do the intersection check (with rotations) is negligible?

    My method does add logic and complication like you say, but it creates the data structure in the map editor, so when your drawing in game, all you have to do is check which grid squares are visible and then draw the nodes associated with them.  


  • 5/14/2009 5:14 PM In reply to

    Re: 2D Side Scroller Drawing/Collisions - Node Proximity

    I'm actually working on this exact same thing at the moment, and what I'm currently doing is building out a quad-tree within each object layer.  Using that I just apply my camera view area to the tree and get back all of the current objects I need to draw.  It's very fast and has some perks like being able to recursively apply a delegate to every object in a node and its children nodes.  Something to consider.
  • 5/14/2009 7:42 PM In reply to

    Re: 2D Side Scroller Drawing/Collisions - Node Proximity

    Interesting. Would it be a uniform quadtree where the entire map is subdivided equally? Also would the quadtree only contain static objects (terrain), or would you include players/enemies/moving objects?  Though I guess you could do both, just generate all the static terrain data for the quadtree when creating the map, and then add the other objects to the tree during the game. (Just thinking aloud)

    I'll give this a try, thanks for the suggestion.
  • 5/14/2009 7:48 PM In reply to

    help

    how do i make a game :-( plez
  • 5/16/2009 9:06 AM In reply to

    Re: 2D Side Scroller Drawing/Collisions - Node Proximity

    Since I tackled this problem a few months ago with a solution similar to yours, I figure I'll share the source code with you in case it's useful:

    http://code.google.com/p/fracture/source/browse/trunk/Squared/GameLib/SpatialCollection.cs

    The basic idea is similar to what you describe: The entire coordinate space is subdivided into equal-sized squares, and for all the items held within the container, their bounding box is computed (with the help of a single-member interface) and used to determine which squares they occupy.

    A few key details:
    Internally the container is a pair of synchronized containers: A Dictionary<T, ItemInfo> that contains cached information on items (hash code, bounding box, etc) in order to make lookups on items more efficient once they're added, and a Dictionary<SectorIndex, Sector> that contains all the sectors that have items in them. This is designed to make the common cases (iterating over all the items within the container, iterating over all the items within a sector, and iterating over all the items within a group of sectors) as fast as possible without imposing significant overhead on the less common cases, like adding items and moving existing items.
    Also, for a given item, every sector it touches contains a reference to the item. This allows you to only iterate the sectors touching a region in order to do rendering and collision detection passes within a region. This means that iterating over all the items within a list of multiple sectors imposes some overhead for the removal of duplicates from the sequence, but it also means that you're guaranteed to get all the items that touch a sector when you iterate it.
    The use of a dictionary for storing sectors means that a SpatialCollection containing only a few items remains extremely small, regardless of how much space separates them. Note that large objects consume space in the collection based on the number of sectors they occupy, so you still have some storage concerns using this container. The ability to tune the sector size on a per-instance basis provides an easy way to get a good balance of memory usage and efficiency.
    If an item within the container's bounding box moves or changes size, it is your responsibility to call SpatialCollection<T>.UpdateItemBounds(obj) so that the container can update the occupied sectors and bounding information.
    SpatialCollection is designed to generate relatively little garbage, so it should be well-suited for use on both PC and XBox 360.
    Kevin Gadd, Squared Interactive
    Development Blog | Twitter
    Help playtest my game, Inferus!
  • 7/7/2009 8:26 AM In reply to

    Re: 2D Side Scroller Drawing/Collisions - Node Proximity

    Hi fkassad,

    so how is your editor going? I just released mine (called GLEED2D - Generic Level Editor 2D):

    http://forums.xna.com/forums/t/34306.aspx


    My Games:
    Konfuzion (currently in Playtest)

    My Tools:
    GLEED2D - Generic Level Editor 2D
  • 7/7/2009 6:39 PM In reply to

    Re: 2D Side Scroller Drawing/Collisions - Node Proximity

    Hey zissakos,

    Took a look at your editor.  Looks great.  Your winforms programming experience is leagues and leagues ahead of mine.  Actually, watching your videos makes me want to go back and make mine more aesthetically pleasing.  Our editors do a lot of the same thing, but yours has some more advanced functions mine does not, and definitely prettier.  Well done, really.  (Your programming is much cleaner too)

    I ended up using quadtrees to display the nodes in a layer.  When drawing, the program just compares the cameras bounding rectangle to each layer's quadtree (constucted at the start of the program) and just draws all the nodes that comprise the intersecting quadrants of the quadtree.  Also have a separate collision layer that consists of rectangles and circles.

    I finished my editor mostly and I added sprite sheets to draw more efficiently.  Lately I have been focusing my attention on sprites and sprite animations.  Made a sprite editor and a sprite animation editor.  Have sprites running around in the levels (but still not working the way I want it to).

    Your tutorials are in multiple parts, are they complete yet? Or are you still working on that.  All I see are the part 1s.
  • 7/7/2009 10:11 PM In reply to

    Re: 2D Side Scroller Drawing/Collisions - Node Proximity

    Thanks. Glad you like it. So you got it to work on your machine? Good. Yes, they are complete. You can find the other parts when you click on "More from: gleed2d" in youtube. I also updated the post here in the forums. Now there are links to all the parts.
    My Games:
    Konfuzion (currently in Playtest)

    My Tools:
    GLEED2D - Generic Level Editor 2D
Page 1 of 1 (11 items) Previous Next