don't click here

Sonic the Hedgehog movement algorithm

Discussion in 'General Sonic Discussion' started by Cyberblade, Sep 17, 2008.

Thread Status:
Not open for further replies.
  1. Cyberblade

    Cyberblade

    Can't catch me ya bastard! Member
    146
    0
    16
    Ohio
    Sonic Shift
    I've been attempting to plan out a Sonic game engine for what seems like forever now, with the impression that the movement physics would likely be the most difficult thing to figure out. So I've been focusing on developing a movement algorithm that will allow for loops and etc, and I've come up with something, but I somehow doubt it's the best method out there to do this. Anyways, I wanted to show what I came up with, and ask if anyone has some better ideas, or perhaps a suggestion to help better it.

    ------------------------------------------------

    [​IMG]

    A picture is worth a thousand words, so I'll start with that. Theres a basic legend, and an arbitrary distance measurement in place just for reference. I kinda stopped with the arrows halfway through, but because it's all color coded it should still be easy enough to read.

    Moving a character to a point x is the most simple movement I can think of, so what I've tried to do here is expand upon that. If the point of collision moves to a point where there is no collision, it assumes that it is above it, and moves the y point down until in collision. If the point moves to where there is a collision, it assumes the point is above it, and moves the y point up until its no longer in collision. This works great until we come to a point where the next point is vertical or greater. To fix this, I only allow the y point to go up as far as the x point has moved, then this new point moves back towards the x point until it is no longer in collision.

    At this point, I assume that we're moving vertically, and thus swap my movements. I move similarly based off y, -x, until once again I find myself looping back, then move -x, -y, then -y, x, and back to x, y. I am aware however, that in the current state running on the outside of a loop becomes a bit awkward. I'm not entirely sure how to overcome this yet, though I'm still thinking about it.

    --------------------------------------------

    I'm not entirely sure that I've explained what I've thought here too well, which is why I've included the picture as well. I'm always open to re-explain it if I've done a poor job the first time. Is there a better way of doing this I'm just not seeing, or do you have thoughts on how to better this idea?
     
  2. jman2050

    jman2050

    Teh Sonik Haker Tech Member
    634
    4
    18
    Are you aiming to replicate the Genesis games?

    Cause downloading the disassemblies and reverse engineering the code would probably be the best bet for doing that.

    As for this, some important variables that I didn't notice in your explanation was the orientation of the character and the angle of a given piece of terrain. I think that would be helpful in developing a good algorithm :P
     
  3. Cyberblade

    Cyberblade

    Can't catch me ya bastard! Member
    146
    0
    16
    Ohio
    Sonic Shift
    Well, I've given a look at the disassemblies, but I don't have much if any experience reading ASM code. So, at least until I learn some ASM, reverse engineering it is out. This is just my attempt at coming up with something that works.

    As for the orientation, given this algorithm it doesn't become too difficult to figure out the angle of the character with a bit of trig. Granted, it becomes a very close approximation of the characters angle, but when going full speed nobody should notice such an imperfection. I was trying to keep the angle of the terrain out of it really, and work out a way for the game to figure out where its going on its own. In that way I could use practically any sort of terrain I wanted without having to keep track of what terrain has what angle, and just let the game do its work.

    I'll keep those in mind and see what else I can't come up with though. Thanks for some input. ^^
     
  4. Lostgame

    Lostgame

    producer/turnablist. homebrew dev. cosplayer. Oldbie
    4,134
    58
    28
    Toronto, ON
    The O.I.C.
    If you're worried about the angle being too precise, could you not use a function like floor/round?
     
  5. Dr. Ivo

    Dr. Ivo

    Professional Reverse Engineer Tech Member
    Cyberblade,

    What you have described is essentially the way that it works in the original engine. However, in the real engine, instead of always moving the player directly up, left, right or down according to path velocity -- the "movement" of the player (deltas across both axes) will be adjusted so that the velocity is applied according to the ANGLE of the current block at the original point where movement began. After this, the player sprite is adjusted so that it adheres to the "edge" of the height map for the destination "tile."

    In other words, just replace the green straight lines in your diagram that are the result of player velocity (but leave the straight red lines that are part of player->edge adjustment.) Replace those green lines with angled lines of the same effective magnitude, but with an angle equal to the "slope" of the original point.

    You have one "point of Sonic collision" listed. In the original engine, when Sonic is moving, there are multiple points of collision. There are always at least two that are sensitive to "vertical" collision, and one that is sensitive to "horizontal" collision, respective to Sonics orientation. These points will be adjusted (flipped/mirrored) based on the angle value of the ground tile upon which Sonic is currently traversing.

    There are obviously plenty of details that I've glossed over, but this information should get you going in the right direction.
     
  6. jman2050

    jman2050

    Teh Sonik Haker Tech Member
    634
    4
    18
    Dr. Ivo: The wrinkle is that Cyberblade wants his movement engine to function without the need of specifying terrain angles manually.
     
  7. Dr. Ivo

    Dr. Ivo

    Professional Reverse Engineer Tech Member
    While we're at it, let's try our hand at a sprite collision detection algorithm, except we won't involve any "extra" properties of the object that we "don't want to 'manually' store" like height and width. Let's just compute those on the fly, based on a live pixel-by-pixel evaluation of the object. That should work out perfectly from the standpoint of efficiency and sensibility.


    Hell, why are we even storing height maps for playfield solidity? We can rely on graphical data for everything! Who needs an extra layer of abstraction? That never solved anything in the field of computer science.
     
  8. DimensionWarped

    DimensionWarped

    Erinaceous! Oldbie
    Yeah, real-time angle finding is a hefty processor rape. But it isn't like I can't see why he would want to do it that way. It does save a significant amount of time for putting most tiles together. If he were designing for the least amount of processing it would be another story.
     
  9. jman2050

    jman2050

    Teh Sonik Haker Tech Member
    634
    4
    18
    There is never any one perfect implementation for anything in computer science, and if he thinks there's a use in developing an algorithm that doesn't need that layer of abstraction then so be it. I don't think it's a good idea personally, but I find it interesting if only for academic purposes.

    Also keep in mind that while we look at the Genesis Sonic physics as the "right" way of doing things, many of things they did probably weren't provoked by preference, but rather by need; the Genesis isn't exactly cutting-edge hardware after all. If there are ways that produce better results, I see no reason why they must be shied away from. On the other hand, it's not easy to think of something that produces better results because the original programming really did do a lot of things right.

    Regardless, that's what he wants to do. I don't think a discussion of whether his method is worthwhile if he's dead set on removing angle data. Of course, since he hasn't replied in a while, I'm not sure if that's the case.
     
  10. Cyberblade

    Cyberblade

    Can't catch me ya bastard! Member
    146
    0
    16
    Ohio
    Sonic Shift
    Sorry for the lack of reply. Been really busy with school and everything else.

    Anyways, I'm not against the idea of keeping track of abstract data such as angles and height maps, I see their use quite clearly in making games run fast with little processing power. However, I'd like to avoid as much of that as possible as I want to create very detailed levels that use a lot of different graphics and shapes. Essentially I want a limitless amount of slopes and shapes that Sonic can run across, and as you increase the number of tiles for each of those shapes, you're increasing the number of angles and heightmaps at an equal rate, and if I want no limits to the shape of the tiles, I'm going to be figuring out angles and heightmaps for quite a while.

    Granted I'm aware that this algorithm isn't perfect, and I've come up with at least two others since I came up with this one, they all share the trait they're not going to be light on the processor.

    The reason I made this topic was not so I'd proclaim myself hard set on one method or another. I made it for feedback on the method I came up with, and to hear about other methods that could provide me with similar or equal results.

    Dr Ivo's suggestion sounds interesting, though I need to give it more thought.
     
  11. Shadow Hog

    Shadow Hog

    "I'm a superdog!" Member
    Okay, question time.

    I have, in the past, attempted to make a pixel-perfect angle-detection algorithm (given 64x64 tiles which are defined by a few basic math functions; ie: "if pixel being checked is in this tile, return true, return false, return true if under line y=x, return true if under line y=-x", etc). It didn't really work out. As such, I'm interested in setting the angles directly into the tiles themselves (and probably breaking them down into smaller tiles, like the Sonic engine does). However, I've noticed one unusual discrepancy.

    First off, here's the basic gist of what I'm trying to do. In picture form!

    [​IMG]

    Hopefully that's a sufficient explanation, but if you still don't get it: think of what Sonic Xtreme was being billed as. Namely, the whole "level rotates as you start walking on walls" aspect (and less the "first 3D Sonic ever" aspect). That's what I'm shooting for.

    Now, obviously, this looks and probably feels a lot like Sonic's engine, albeit gravity is now the normal of the surface you're walking on, and not constantly down (and as such, you don't experience deceleration/acceleration on curves and such - but this isn't going to be a Sonic game, so that alteration is more forgivable). Thus, the more I yank from that design, the better - and the tile-based angles, while born from necessity in the Genesis games (because the Genesis isn't using a dual core processor like I am), is still probably the most efficient way to go. But this is where I encounter the problem I mentioned earlier.

    Namely, tiles you can stand on from various angles. Observe!

    [​IMG]

    Notice how, for this one tile, you can, according to the game concept, legally walk on both the left side and the top side of this tile. And yet, I can only assign one angle to this block. This tile is actually used all around the sides, too, so there are no less than four distinct angles that can be considered "correct" here (0, 90, 180, 270), and, depending on the level design, a single tile of this sort can be used for all four at once (ie: a single tile floating out in space, which allows you to walk on all sides of it depending on the angle you came at it from).

    Any ideas on how to handle a situation like that? I'm sure the answer is staring me in the face, but I'm not sure what it is.
     
  12. Upthorn

    Upthorn

    TAS Tech Member
    239
    0
    0
    Sorry this is so late in coming (I haven't checked the forums regularly for a while), but the answer is pretty simple, and you'll probably kick yourself when you think of it.
    Just add the player's current angle to the angle of the block and subtract 360 if the result is greater. Or, depending on exactly what the terrain angle represents, subtract the player's angle, and add 360 if the result is negative.
     
  13. Dr. Ivo

    Dr. Ivo

    Professional Reverse Engineer Tech Member
    Since this topic is somewhat focused on the original solution to these problems...

    In the original Sonic engine, there are four "all solid" tiles, each of which have a different angle asssigned to them (0, 90, 180, 270.) As a general rule, there aren't any game paths that are less than two 16x16 tiles thick. If there's something small that you can stand on, it is probably an "object." The engine is actually very limited. The best solution to problems within a game engine whose solution would reqire large amounts of code or processing time is to prevent that situation from happening by enforcing a "design rule."
     
  14. Shadow Hog

    Shadow Hog

    "I'm a superdog!" Member
    So in other words, the desired behavior isn't even possible. Right, then I guess I'll have to take the slow, "calculate your angle every frame" route, then. Bleh.

    Also, Upthorn... huh? Why are you subtracting/adding 360? The question was what constant value to give a tile that could have four separate, distinct values. I appreciate your attempt to help, but what you've got sounds more like a way to find an angle difference between the player and a tile, which wouldn't be a hassle.
     
  15. Rolken

    Rolken

    Tech Member
    To add to the original topic, aside from the technical issues, graphics-based collision detection is also a bad idea for Sonic games because it just means ground-level effects like grass and railings won't work unless you spend that same effort you would've saved not marking collision masks on separating out graphical flourishes into noncolliding objects instead. Better to just make a collision editing tool that lets you mark a few points and be done.
     
  16. Upthorn

    Upthorn

    TAS Tech Member
    239
    0
    0
    The point is that you can give the blocks one static angle, if the collision calculation "rotates" by the current gravity angle (which is also the current player angle). The adding/subtracting 360 is so that the angle doesn't go below 0 or above 360 degrees.
    Take for instance a block with an angle of 0. If the current gravity angle is 90, you subtract 90, getting -90, then add 360 (cause it's below 0) getting 270. The block has gone from acting as a flat walkable surface to acting as a wall. Meanwhile a block with the angle of 90 would go to 0, changing from a wall into a flat walkable surface. In this way a square 16x16 block could placed hanging in the air, and each side become walkable or non-walkable as needed by gravity.
     
Thread Status:
Not open for further replies.