Character walk on terrain

Started by
3 comments, last by mr hooligan 14 years, 8 months ago
Sorry if this is the wrong forum or the topics covered. I didn't know what to search for since I'm using Flash. I have been working on sort of a worms clone in flash and there has been one thing that I just can't get right, the walking and jumping on the terrain. I get it to work but there is always something wrong with it. Some scenarios on the terrain go horribly wrong. I'm not sure how many people use Flash so I'll explain how my setup. I have a png file. The areas that are terrain are coloured in and the transparent areas the character can move freely. In Flash to detect there is not hittest on pixels you need to manually check the pixels to see in they have a colour value or not. e.g. if (engine.terrain.getPixel32(engine.camera.xToGlobal(x) + xVel, (engine.camera.yToGlobal(y) + yVel) - i) == 0) { This means character is in the air. The registration point of the character is the bottom center of the character image. I have access to the characters width and height etc. My biggest problem getting it right is that I don't think I'm taking every check into account like check the pixels above, adding characters width into the equation. Not being able to walk up steep slopes. I'm looking to have it work very similar to worms. You fall straight down when walking off a too high ledge. You can only jump up and off in the up 45 degree angles. Would anyone have any examples or algorithms I could look through to get an idea of what I'm doing wrong. Thanks [h]ooligan
Advertisement
I would make sure that your code structure is all componentized so that issues with the language you're using do not creep into your logic.

For example you should have very seperate and explicit collision detection functionality and character logic functionality. This way you can test them independently to see where the issue is.

Your collision detection routine should generate a list of contact points and contact normals between the player and the terrain. These contacts are then passed to the character physics logic for processing.

Your collision detection will be very flash dependent, but the character physics logic will be very generic and most people here will be able to help you easily with each independently, but together it just makes the problem overwelming to describe.

So is your code like I've described, at that every frame there is some function like so? If so I'm sure we can figure out something to make it work pretty reliably.

struct Contact {  Vector Point, Normal;};struct CharacterState {  Vector Position, Velocity;};struct CharacterInput {  bool Jump, Left, Right;};void UpdateCharacter(float deltaTime                    , Array<Contact> contacts                    , CharacterState state                    , CharacterInput input) {  bool onGround = false;  //check for on the ground  foreach (Contact c in contacts) {   if (Dot(c.Normal, worldUp) > groundThreshold) {    onGround = true;    break;   }  }}


*Note this is just psuedo code, where all params are passed by reference.
Yeah currently the character class detects a collision with the terrain image.

The way I do this is if the Character is moving left or right I place them in the correct position of the terrain instead of using gravity to force them down (to avoid jittery movement when the terrain goes down.

Here is a snippet of the move method. Its very very overkill. It works, its just when I start to implement jumping and falling it gets a little weird :)

if (!jumping && onGround) {      var yPos = null;   if (_dir == "right") {            scaleX = 1;            if (engine.terrain.getPixel32(x + (engine.camera.displayRect.x) + (width/2) + moveSpeed, y + (engine.camera.displayRect.y)) != 0) {						         onGround = true;         xVel = 0;         yVel = 0;						         //Check pixels up         for (var i:int = 0; i &lt; (height / 2); i++) {							            if (engine.terrain.getPixel32(x + (engine.camera.displayRect.x) + moveSpeed, y + (engine.camera.displayRect.y) - i) == 0) {								               trace("up");               yPos = y - i;               break;								            }							         }						      } else {						         var prevEmpty = false;						         //Check pixels down         for (var i:int = 0; i &lt; (height / 2); i++) {         if (engine.terrain.getPixel32(x + (engine.camera.displayRect.x) + moveSpeed, y + (engine.camera.displayRect.y) + i) != 0) {								            trace("down");								            if (prevEmpty) {               yPos = y + i - 1;               break;									            }								         } else {								            prevEmpty = true;								         }							      }							   }					   if (yPos != null) {							      y = yPos;      x += moveSpeed;						   }					}


So in your suggestion the Character would store a constantly changing array of Contact objects which are passed from the main GameEngine class? The contact object stores a Point and normal direction. This collision is detected if the next x,y step = a collision right, and the Character object simply loops through these objects for the collisions.

Thanks for your help.

[Edited by - Zahlman on August 17, 2009 1:11:40 AM]
*points at the sticky and coughs* Ahem. :)
Whoops :) thanks Zahlman.

This topic is closed to new replies.

Advertisement