Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

270 Neutral

About Horscht

  • Rank

Personal Information

  • Interests

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I think for that I misused my MainForm as a giant "Service Locator" ;D With tons of properties for getting a reference to anything and a static "GetInstance" so from anywhere I could just type MainForm.GetInstance().ActiveTool to, for instance, get or change the active tool from anywhere... It kind of worked but there was basically almost no encapsulation whatsoever.
  2. Well my cycle is something like this: Get the desire to make a game, start a new project and program for a few weeks, hit a brickwall, get a feeling that I'm doing it all wrong, ask on some forum, still can't figure it out, give up, pause for 2 years and then it starts all over ;P I've mostly programmed small stuff, where I don't need a big complex system working together. (Chrome extensions, an addon for world of warcraft, a level editor (in C# .Net) for my last attempt at making a game). The only thing I never understood is how to seperate everything out logically to not have one monolithic class and then wire it back together. A level class that loads a level from file, player class that takes care of moving, shooting etc, enemy class with some AI... Somehow I always end up with the same structure everytime where everything needs a reference to everything else where I might as well put EVERYTHING in Singleton classes...
  3. Thanks for all that learning material, I'll look into it over the next few days, but I think before I'll try to make my own ECS from scratch I'll start by just using an existing, well designed and tested one to get a feel for how it all fits together.
  4. The Caves of Qud video was informative but the other one waaaaay too complicated, especially since it involves template metaprogramming which is super hardcore hard and I have no experience at all with that.
  5. I tried making something with Unity to get an understanding of how an entity component system works, but to me it looks a lot like spaghetti-wiring everything together "Oh how will this object talk to the environment? Whatever just put a reference to it in there, done!" It's so much easier when you can just drag + drop one object from the editor onto a script to give it a reference to it. What would be the equivalent of this in code? Instantiating everything in the "main scope" and then passing it along like "objA->child->child->childThatNeedsObjB->referenceToObjB = &objB"? Well thanks for the videos I'm going to watch them now Somehow I always have a feeling I'm missing something completely obvious/fundamental.
  6. 2 few years have passed since I last tried to make my own game and like always I had to give up because I encountered an unsolvable problem. And here I go again, hitting the same brickwall with no solution in sight. My question is: How exactly do I design all my classes so that coupling is minimal when they need to talk to one another somehow. Let's look at one prime example: The player exists inside a "world", an environment, where other entities also reside, enemies, obstacles, chests, whatever. Now the question is, who is responsible for moving the player? The player class itself in something like Player::Update()? But then how does it know if it hit an obstacle or walks on an ice-tile or got pushed back by a boulder that hit him? For that it would somehow need to talk to the world class, or the boulder class would need to talk to the player and tell it "hey I hit you please move back 3 tiles"? Last time I tried to create a game I had huuuuuge "pass down" chains where class D was instantiated inside C but class D needed class F so I also needed to pass an instance of that into C, which didn't need it itself and since it was created inside class B, class B also needed that instance of class F. So I passed that instance along like 10 levels deep in each constructor... Not confusing at all, right? Or maybe should the "world"/level class somehow coordinate everything, move everything, since it knows where everything is, but then how does it know the objects movement logic? How does separation of concerns fall into this, since optimally, every class should only have 1 responsibility. So what should each one do? I don't even know how to describe it properly, hopefully you can understand what I mean. Can someone give me a graph of how everything should be "connected"? Which class should "own"/instantiate what, should the player be instantiated by/inside the world class, or from outside and then passed in? But then in what part of the code should he get instantiated, the main loop? I tried looking for open source projects so I can see how they did it but all of them are wayyyyy too big and I don't even know in which of the 50000 files I need to start looking. Does anyone maybe know a very simple open source game with a similar structure that I can study? (Platformer, or something like zelda, something with a world/obstalces/player etc).
  7. So I should call ServiceLocator::GetRenderer() every update/render, instead of storing it once in the constructor? Isn't that kind of inefficient? But other than that it sounds interesting, but also like a lot of extra work and complexity. Implementing NullSound, NullRender etc, and designing the system around being able to run in a "null" state. I can imagine it becoming kind of complicated when functions return something, like a null version of TextureCache::LoadTexture(), it would have to return a NullTexture, or some kind of default texture... hmm...   Whatever, I think I will probably give ServiceLocator a try. I have to rewrite the whole render code anyway, since I did not think ahead. @haegarr: How would I go about checking the state of Player inside of PlayerController? Provide accessors for every member, like GetPosition() etc, or declare PlayerController a friend class, or something else? Should I also seperate logic for sound playing etc into something like PlayerSoundController, or put it all into one PlayerController? Some kind of messaging system sounds like it would make things easier, but I'm not sure if I can come up with a good one. I coded in different scripting languages for different games (like coding Addons for World of Warcraft) and there it was always soooo easy Register for an event, through a global variable and then just pass a function to play a sound, like event.Register(PLAYER_TAKE_DAMAGE, playMySound). Boom, done! I really need to learn more about decoupling and abstraction... that's one of my weaknesses, everything in my code is so "direct".
  8. I agree and I have a hard time thinking outside the box. My current approach is to have all the logic related to the player inside one class: Player. In Player::Update() I check if the jump button has been pressed, using a reference to InputDevice that got passed into the constructor and saved as a member, then play the sound the same way, but instead with a SoundPlayer. If I had more things for whoknowswhat I would also put it there I don't really know how to really do it from "outside" since I would have to expose a million different things like position, velocity, state etc (which would be the hardest since the Player class itself uses kind of a state machine pattern instead of a variable).   Reminds me of this one: http://gameprogrammingpatterns.com/service-locator.html But I don't really see how it is much different from a static singleton. It just goes through one more class to actually fetch the service. The only upside I see is, it can dynamically return different derived classes. (Like the NullSound example).   Let's make sure we are talking about the same things here, could you explain what exactly you mean by layers and levels, up and down? The way I see it is, a layer is a scope, like the function body of main() or the scope of a class like GameState. Up is main() and down is something like statemanager.gamestate.level.player, right? So if the Player wants to be drawn, it should not interact with the Renderer but instead the Renderer should "collect" all Renderables "below" it, or the class that owns Renderer should feed the renderer the Sprites/Renderables? So something like: void GameState::Render() { _renderer.Render(_level.GetPlayer().GetSprite()); _renderer.Render(_level.GetEnemy().GetSprite()); _renderer.Render(_level.GetPickup().GetSprite()); } Of course that would need to be made more general, maybe through an Interface with a recursive function like GetAllRenderables() or whatever :) I don't know it's just an idea. The way I do it is kind of the opposite, I call stateManager.Render() which calls gameState.Render() which calls level.Render() which calls player.Render() which then gets a pointer to the DirectX device directly and does all its drawing directly in low level code hahaha :) But once I wanted different graphic-layers, for UI and debug output, it became clear that this is not a very good way to do it.
  9. When I started programming one of the biggest mysteries to me was how to provide access to things like SoundPlayer, Renderer, ErrorLog, StateMachine etc to very deeply "nested" objects, like the player. Let's say I create my StateMachine in main(), inside the constructor of StateMachine I initialize it's member: GameState, which in turn initializes it's member Level which in turn initializes it's member Player. Player wants to play a sound when he jumps, so he would need to call soundPlayer.playSound(SOUND_JUMP). But Player doesn't have a reference to a SoundPlayer object. He also wants to draw himself at the center of the screen, so he needs a reference to a Renderer and the Window, to get it's dimensions. What do? After a lot of inconclusive articles (or failure to understand them), I decided to just use a static global class, since I wanted to generate results as fast as possible and I kinda got stuck with it. Actually, I used a mixture of dependency injection through constructors, dependecy injection through methods and global variables... Here is an example (not actual code): class Player {     private:         SoundPlayer& _soundPlayer;         Sprite _sprite;     public:     Player(SoundPlayer& soundPlayer) :_soundPlayer(soundPlayer) {} // Dependency injection, storing the reference inside the object     void Render()     {         Renderer* renderer = Renderer::GetInstance(); // Global static horrible singleton!         renderer->Render(_sprite);     }     void Shoot(ParticleSpawner& particleSpawner) // Dependency injection through function argument, not stored     {         particleSpawner.Spawn(PARTICLE_BULLET);     } }; What I really don't like, are the static GetInstance() function calls everywhere. It just isn't clear that this class depends on the other, it just hides somewhere inside of a random method. At least in the constructor it's clear, you can't even create an instance if you don't pass it's dependency in. Inside the methods parameters it's already a little more awkward, because you're happy you could create an instance of the object, but then it suddenly needs an instance of another class.   The worst part is when I have a deep "component hierarchy" or whatever it's called. I read the term "call-tree" before and think it fits quite well. Player needs a reference to an instance of SoundPlayer, otherwise it can't be created, so it's owner ALSO needs that reference to pass it in, but it itself DOESN'T need it, except for creating the player, so it also puts it into its constructor as a required parameter, so now THIS class ALSO needs a reference to SoundPlayer, even though it has no intention of ever using it, but one of its components needs it, to in turn construct one of its components, which in turn needs it to construct one of its components, which in turn... feels kind of wrong to me :|   I got so tired of typing it all out that My state machine just has a #define to pass it all in. Kind of like this: class StateMachine {     private:         Renderer& _renderer;         SoundPlayer& _soundPlayer;         ErrorLog& _errorLog;         FileSystem& _fileSystem;         NetworkSystem& _networkSystem;         InputDevice& _inputDevice;         BreadMakingSystem& _breadMakingSystem;         SystemsManager& _systemsManager;         // ...         State* _gameState;     public:         StateMachine(Renderer& renderer, SoundPlayer& soundPlayer, ErrorLog& errorLog, FileSystem& fileSystem, NetworkSystem& networkSystem, InputDevice& inputDevice, BreadMakingSystem& breadMakingSystem, SystemsManager& systemsManager):             _renderer(renderer),             _soundPlayer(soundPlayer),             _errorLog(errorLog),             _fileSystem(fileSystem),             _networkSystem(networkSystem),             _inputDevice(inputDevice),             _breadMakingSystem(breadMakingSystem),             _systemsManager(systemsManager)         {         }         enum StateType         {             STATE_GAME,             STATE_INTRO,             STATE_TITLE,             STATE_OPTIONS         };         void SwitchState(StateType state)         { #define STUFF_TO_PASS renderer, soundPlayer, errorLog, fileSystem, networkSystem, inputDevice, breadMakingSystem, systemsManager             switch (state)             {                 case STATE_GAME:                     _state = new GameState(STUFF_TO_PASS);                     break;                 case STATE_INTRO:                     _state = new IntroState(STUFF_TO_PASS);                     break;                 case STATE_TITLE:                     _state = new TitleState(STUFF_TO_PASS);                     break;                 case STATE_OPTIONS:                     _state = new OptionsState(STUFF_TO_PASS);                     break;             }         } }; And inside of the GameStates constructor, again a #define to keep passing it on to it's children.   I was asking myself what the best way to do all of this would be, while refactoring Renderer::GetInstance() out and instead rewriting 100 constructors to accept a reference to Renderer instead. I just thought "What the hell am I doing? Is this really better?!"   Before I go and rewrite everything I want to make sure I do it correctly this time. This is something that really irritates me about programming, there never seems to be a definitive correct way and I'm only satisfied with perfection, even though I'm nowhere good enough to even achieve anything close to it :P Should I just leave it like this or is there a better way?
  10. But what if the solution is inside the box, it's just too small or too obvious to see it? Like when your looking for your glasses but you have them on already :) Then stepping out of the box would be a mistake ;) That's another problem I often have, not knowing if I'm moving in the right direction. Should I keep going, am I close to a solution? Or am I heading into a dead end and should rather turn around, look for another way? My current approach seems to be kind of working and my gut tells me I just need to fine-tune it somehow, it's likely just some minor mistake that messes everything up. Like an "off by one" error. (i.e. > instead of >=). Found one just yesterday, after a long time of not noticing it at all. A big problem is that I currently have no real idea how to catch bugs that happen in real time, like when my game is running at 60 fps and from one frame to the other, suddenly the player falls through the floor. I can't go back in time and look at all the possible states the player was in, and I can't set a breakpoint if I don't know when, why or where in the code it happens. If I set a breakpoint before collision resolution happens, it will break EVERYtime, even when the resolution works correctly. Displaying the coordinates etc on the screen is also useless because it changes way too fast. Maybe I need to implement some way to only move one timestep per keypress or a giant array of past states of everything, I don't know.   I have read a few articles explaining algorithms like GJK, SAT, minkowski sum/diff in the past but somehow I find it hard to get a good intuition for it and putting it together into a working system. But I don't think I will need any of those more advanced algorithms anyway in a "simple" project like mine, I will never have any polygons or rotated rectangles, just plain old AABBs. Simple arithmetic on position, size and velocity should be enough, like braindigitalis suggested, or am I wrong? It's just a matter of correct order of operations, update first, then check for collisions, or check before moving, solve collsion A first then B or other way around, if solved, start a new iteration of collision checks or keep going etc...   Well, I will keep trying, I guess it's just a matter of trial and error. By the way, thanks for all your input, everyone :)
  11. @Randy Gaul Thanks, I'll take a look at the slides. Yeah that's a video of what my "game" actually looks like :) (I wish I could call it a game but I dont seem to be able to advance past the collision part...) It may look like a lot is going wrong because of floats, but I don't think it actually is. Through all my debugging I never found the floats to be a problem. At least not anymore, one change that fixed most bugs was changing the representation of my rectangle class to x,y for the top left corner and width and height instead of x2,y2 for the bottom right corner. Maybe I'm wrong and am just missing some sneaky cases. But I think the main reason why its not working is because of the order the collisions get resolved in. Especially when I have to skip some collisions for special tiles/obstacles, like ladders.   I already had some kind of tile based system but then I realized I wanted freely moving platforms etc, so I rewrote everything. Another reason why I wanted to rewrite it is because I thought tile based would be too restrictive and I might as well go with the "real" thing.     @CC Ricers Hmm I think I tried something like that and a few things didn't work out, thats why I switched to calculating the "time of impact" instead of penetration amount checking. One of the things was the same thing that's being adressed in the article: Wrong resolutions. But I'm not sure If I tried it with the correct ordering. Maybe I could try swapping the techniques around and do it with the least penetration amount technique again.   I'm kind of sick of fiddling around with it. For two years I am stuck with this problem now and I'm making next to no progress... soooooo frustrating argh... But of course I didn't work 2 years non-stop on it. Otherwise I would already have gone insane Have been procrastinating a lot because I have absolutely no idea what to do anymore and I'm kind of lazy and demotivated.
  12. Oh my god, my system is so extremely poorly designed... I have absolutely no idea how to do it right. Right now I'm wondering how to transition into the "falling" state of the player. Before I just checked if the velocity of the body is positive, if yes, change state to "falling". But after realizing I cannot stand still on a ladder, because gravity is still pulling me down I had to rewrite the code a little bit. Before, I added gravity to the players body in player::update(), AFTER doing the specific PlayerState::update() (like standing, walking, sliding etc). This way, vel.y was always 0 inside of the substates, because collision resolution happened before. But this way I cannot set vel.y to zero in "climbing" state, because right after that, gravity would be applied. So I changed the order, now gravity gets applied FIRST, then PlayerClimbing::update() runs, which sets it back to zero. But now in PlayerWalking::update() vel.y will ALWAYS be positive, because gravity got already applied, and therefore it transitions immediately into the falling state. I have no idea what the correct order would be in a good system. So instead I now have to actually check if the players body is "touching" any collidable bodies from above. What a mess... Just look at this: void PlayerWalking::update() { //... RectEx footRect = player.GetBoundingBox(); footRect.ResizeSides(0, -footRect.GetHeight()-1, 0, 0); footRect.MoveBy(0, 1.0f); auto tiles = player.level.GetTilesInRect(footRect);         // I could also ask the world instead, and get generic bodies back instead of the actual tiles/platforms etc.         // but then I would have to convert them to Tile* or something first. bool onFloor = false; for each (auto tile in tiles) { if (tile.second->IsSolid()) { onFloor = true; } } if (!onFloor) player.ChangeState(player.states.falling); //... } Is there a better way of keeping track when bodies come in conact and lose it again? Thinking of it more like callbacks/events "OnContactBegin(...)" and "OnContactEnd(...)" instead of non-stop polling/checking.   I also have huge problems correlating bodies to their actual owners. For instance if I check inside PlayerWalking::resolveCollision() against the body, how do I know what it actually is? Is it a platform? An enemy? A bullet? All I have is a pointer to a body. For now I did it kind of like the Box2D library where every body has a "void* userData" that can be assigned anything. So for now everytime I create a body I save a pointer to its owner in there. But casting it back and checking then becomes a mess. Should I give the body class a "GetType" function, which returns a value of an enum? Something like: enum BodyOwnerType {     TYPE_PLAYER,     TYPE_PLATFORM,     TYPE_GIANT_ROBOT_ENEMY,     TYPE_SMALL_ROBOT_ENEMY,     //... }; player.body->SetType(TYPE_PLAYER); // so later I can do huge chunks of checking in PlayerWalking::resolveCollsion like this: //... // inside PlayerWalking::ReactToCollsion(Body* body, CollsionInfo info) if (body->GetType() == TYPE_GIANT_ROBOT_ENEMY) { GiantRobotEnemy* enemy = reinterpret_cast<GiantRobotEnemy*>(body->GetUserData()); player.takeDamage(enemy.GetDamage()); } else if (body->GetType() == TYPE_PLATFORM) { Platform* platform = reinterpret_cast<Platform*>(body->GetUserData()); if (platform.IsSolid()) vel.y = 0; } //... Are there any good tutorials on how to actually design a GOOD "system" or whatever its called? Software engineering for 2d platforming games? I just don't think I can come up with something good on my own. My own design feels like a way too complicated rube goldberg machine that does something that should be relatively simple, way too complicated and indirectly. Or is it not possible to do it any better? Should I stick with this or try to make it better?
  13. @Randy Gaul: That's definitely what it feels like I'm doing: trying to do something that's almost impossibly difficult. Maybe I'll just have to design levels with big enough gaps and forget about falling into "1 tile" big gaps. I'm still using tile based layout, but I'm not doing collisions in a grid or something because I want moving platforms and enemies and the player will move freely anyways, so why not just make everything be free of the restrictions that a tile based system would put in place.   @jHaskell: Yes I tried it, but I don't like it. It just doesn't really work well if you want pixel precise movement and if there are many "tiles" beside each other, walking over them causes the player to hop over the "seams" between them. So in order to prevent that I would have to basically either add ghost vertices on every side for every body, or create some kind of chain shapes, or somehow merge multiple bodies whose sides are colinear into one big body. And that would really only work if they are the same type, with the same behaviour. So if one was some kind of ice-tile and the other maybe rubber, I would not really be able to make them into one body. Except if I make some kind of "split-body" type, which then defines regions inside of it, and check if the collision happened on the left half of it, it would react like ice, and if it happened on the right, like rubber. Those are just ugly workarounds/hacks. Box2D really is more of a physics simulation library for more dynamic movements where pixel precision doesn't really matter.   This is from the official Box2D FAQ: And #2 is what I want :) I don't want the character to sometimes stop 1 pixel in front of a wall, other times 2, or 0. I want consistent behaviour. No jittering. Otherwise it just feels "cheap".     Right now after kind of randomly changing the code, I seem to be able to fall into gaps, but sometimes I just walk through walls, especially when objects are involved that should be not be collidable and just return false in HandleCollision(), returning false should mean "ignore this collision"... Heres a little demo what it looks like: (the white things are supposed to be ladders, pass through, except when standing on the last rung of the ladder on top, like a platform).
  14. @JeffCarp: Wow, thanks, nice find. Checked out a few videos today, but since I didn't watch all the previous videos it's kind of hard to just jump in and understand whats going on. I'll try to watch more in the coming days. The video for Day 50 seems to be what has the most relevant information for my problem. At the end of it it kind of seems to work, but who knows, I'm sure I'll find a problem with it ;) I am never satisfied... One problem that I already see is that hes doing it all in one place, so the player kind of is the collison system and handler at the same time? Maybe he seperates it and makes a more generalized collision system in a future episode, I don't know, I need to check out more of his videos.   @Glass_Knife: Yep probably read it in the past, just skimmed over it right now because I don't need it, but thanks. I'm already pretty happy with my collision detection code, detecting is not the problem, the only problem is, now that I know what collides with what, when and how, what do I do to prevent the collision and set the objects to their correct location and correct their velocities? And where should I do it? How should the "World" or collision system, that does all the moving and checking, interact with classes that actually "own" the bodies? I think I want the behaviour defined inside of the different entities/objects like player, enemy, bullet etc. But how can they both work together? As explained in my original post, currently every body has a CollisionHandler assigned to it and when system detects a collision it calls the bodies CollisionHandler to pretty much tell the player or whatever "Hey you're going to collide, change your position and velocity yourself however you want to react to it". I'm not sure if it's a good idea to manipulate the pos/vel directly, would it be better to just return some kind of "desired position/velocity change" struct and have the world take care of actually updating the values? One of my main problems right now is that solving ONE collision works perfectly but as soon as there are more than one collisions per timeframe, it doesn't work like I want it to. Here is one example. The player is on the ground and starts walking left, his velocity is slightly downward because of gravity. If I change the velocity after the first collision, It won't "slide into" the gap, because the Y velocity is now zero. He would end up on the other side of the gap instead of falling into the deathhole ;) The excpected behaviour would be that he gets stuck on the edge and starts falling down next frame: But THIS method has as a side effect that he will get stuck when walking: So the problem is kind of with the ordering when handling multiple collisions in the same timestep and the needed correction of position and velocity. I actually had a tile based system before, where in this case I could just easily check if there is an adjacent solid tile, if so, don't count the X collision. But now I have a tile-free system where objects can be anywhere and any size and thats where this simple check doesn't work anymore. Somehow I need to check for two cases basically, one: the gap is smaller than the player, then ignore the X collision and walk over it or two: the gap is big enough for the player to slide/fall into. But I need to do these checks only if the Y coordinates are exactly the same, otherwise he SHOULD always get stuck, if there is a little bump. I'm thinking of maybe a ton of raycasting and conditional checking... Is there a better way?     Edit: A bit of info of how I detect collisions. I basically just extend bounding box A by its velocity (swept), then do a check which other bodies intersect with that rect, those are the POSSIBLE collisions. Then I divide the velocity by the distance to get the "time of impact": toi < 0 collision happened before this frame. 0 < toi < 1 collision happening sometime this timestep (0.5 would mean halfway through movement) 1 < toi collision will happen in a future timestep I get that for every axis, then I move the rect by velocity * toiX or toiY respectively and a little more to actually move it INTO the other rect and then check if it is intersecting. If both are colliding, which toi is smaller (x or y) determines where the collision happens first. So I can figure out for instance, that 33% (toiX = 0.33) into the movement, bodyA collides into bodyB from the right side, since vel.x is negative (moving left).
  15. I have been struggling with collision resolution forever. I always wanted to create a platforming game but never managed to get past the collision resolution part. Usually I would start programming a game, and after a while when it comes to collisions, I just sit there for days and weeks, fiddle around with the code and NOTHING works, absolutely nothing. I work less and less on it because it's just nothing except pure frustration and then I kind of let it die. A few months or years later I start trying again, hit the brickwall again and the same thing goes on forever... I even procrastinated like crazy until I decided to make this post but I don't even know where to start and how I should even formulate my questions. Sometimes I just have a feeling I may be just too stupid for game development and I will never understand it. My brain just doesn't come up with any solutions anymore. Most of the time I just sit there, looking at the code and after 30 minutes of thinking and not coming up with anything new I just go do something else, this repeats forever, so here I am asking you!   I have read almost every article that I could find on google, a lot of sites links to the same old stuff that doesn't even really explain anything, or just doesn't fit my game. I'm still trying to create some kind of megaman clone, or maybe like shovel knight or mario. Simple 2D collisions without fancy physics. Just 2D box shapes, no rotations, no polygons or circles or whatever. There are articles that don't cover tunneling, others only try to solve 1 body vs 1 body collisions, others have weird behaviour like jittering on the floor, falling of the edge of a platform, because there is only one "collision point" on the bottom of the player, or when there are 2 points on the right and left foot, fall through blocks if they are narrower than the two points. Player can't be smaller than n x m, can't be faster than x pixels per seconds etc... There doesn't seem to be anything out there that fits my idea of a good collision system. But there HAS to be a solution because there are TONS of good games out there that don't seem to have all those restrictions. All I want is a consistent collision resolution system for axis aligned bounding boxes without tunneling, pixel perfect movement, no jittering, or any strange behaviour, because I want the game to be difficult, and when the player suddenly falls through the floor and has to start all over again just because the collision system encountered a rare condition in which it fails, it's going to be extremely annoying and frustrating, especially when it could happen again anytime. Same goes for suddenly getting pushed through walls, that would make the game too easy ;)   A lot of those articels also don't cover how a "collision system" should be designed in general or how entities/objects/whatever can check and react to collisions, or check their surroundings (like if they are touching the floor or whatever). I want to have a system where I can easily react to At first when I started I put all of my code in the Player class, had a reference to a class called World, which basically was just a collection of Tiles, with functions to ask something like: class Player { //... private: World& _world; //... public: Player(World& world):_world(world){} //... } void Player::Update(float dt) { if(_world.GetTileAt(x,y).IsSolid()) // Do something if(_world.GetTilesInRect(this->GetBoundingBox()).count() == 0) velocity.y += gravity * dt; // Or whatever, just an example position += velocity * dt; } But then I realized this is going to result in a lot of duplicate code when I want to have the same collision resolution for enemies or pushable boxes or whatever.   So I generalized it, In hopes to be able to just have to implement a function like "HandleCollision(...)" in whatever class I would like to be a part of "the World".   So here are the classes that I have: Body - Holds information like position, velocity, size, and has a function GetCollisionInfo(Body* other) which returns a struct of data describing when and how this body is going to collide with the other body, by comparing position, size, velocity etc... CollisionHandler - An Interface that specifies the function HandleCollision(Body* other, CollisionInfo colInfo) Player - Implements CollisionHandler, holds a reference to it's Body created using World::CreateBody(), then sets body->SetCollisionHandler(this) World - Keeps a list of all bodies and provides a function CreateBody() which inserts a new body into a vector or whatever and returns a pointer to it.   In my gameloop, world.update() gets called, which then loops over all bodies, asks each body to get a collision info of it and the other body, puts all colliding bodies in a list, orders it by timeOfImpact and then calls body->HandleCollision(other, colInfo) on the first object ("other" is whichever the body collides with first) which delegates the call to player->HandleCollision or whatever has been set as the collisionHandler. And there I do checks like these: // Gets called by World::Update() bool PlayerWalking::HandleCollision(CollisionInfo colInfo, Body* other) { Vector2D newVel = player.body->GetVelocity(); Vector2D pos = player.body->GetPosition(); RECT obsRect = other->GetBoundingBox(); switch (colInfo.impactSide) { case CollisionInfo::Side::LEFT: newVel.x = 0.0f; player.body->SetPosition(obsRect.left - player.GetBoundingBox().GetWidth(), pos.y); break; case CollisionInfo::Side::TOP: newVel.y = 0.0f; player.body->SetPosition(pos.x, obsRect.top - player.GetBoundingBox().GetHeight()); break; case CollisionInfo::Side::RIGHT: newVel.x = 0.0f; player.body->SetPosition(obsRect.right, pos.y); break; case CollisionInfo::Side::BOTTOM: /*newVel.y = 0.0f; player.body->SetPosition(pos.x, obsRect.bottom);*/ break; } player.body->SetVelocity(newVel); return true; } So this then modifies the velocites or position and at last, the world class increments the position by velocity * timestep, or whatever. This way I can change how the timestepping works in one place: World::Update(float dt) instead of the objects like player/enemy etc. So you're probably wondering why I'm even complaining, right? Because it just doesn't work like I want it to and I have a feeling no matter how much I fiddle with the code I will never figure out how to do this correctly. With this method, what happens in the following scenario? The first collision that will get handled is the one with the right block. It cancels out the y velocity, then comes another iteration of checking the velocity against other bodies and since we are now only moving straight left, we move OVER the gap instead of into it. This is what should have happened (all happening in one frame, animation just for clarification): So this is what I DONT want! NO SLIDING over gaps! Of course I could solve this by NOT initiating a NEW iteration of collision checks and instead continue with the one that would happen next. Instead of checking again, I say I already know we would collide with the left block, so we handle that and place the block at the right side of it. (Forgot to make a picture for this case, just imagine the "player" a little more to the left, so its left side is aligned at the right side of the left blue rectangle) Now for this case you COULD say, well thats ok, the player will just start falling down the hole the next frame, right? Sure, but what if there is no gap? Just 2 blocks next to each other (ground)? Yep, the goold old "player gets stuck when walking over tiles" problem because he gets blocked by the left one..... *sigh* So all I can do is shuffle the code around, do it in a different order and jump from one problem to another one, without ever being able to eliminate ALL of them at once.   These are the two solutuons that I came up with and none of them work: // Handle all of the collisions one after another, this one places the block on the right side and stops floor-movement for (auto it = toiOrderedList.begin(); it != toiOrderedList.end(); it++) { bodyA->HandleCollision(it->second, it->first); } // And this one only handles the first collision, then starts another iteration of checks with the new velocities, // this one makes the player be able to move over gaps/holes and prevents being able to move into a space in a wall, // because the body just slides past it. if (!toiOrderedList.empty()) { bodyA->HandleCollision(toiOrderedList[0].second, toiOrderedList[0].first); } The only thing I can think of is splitting this movement up into 3 different velocity vectors. The first one until it hits the right block, then "slide" it to the left until it hits the edge, then create another vector that moves it left+down again, once the first block doesn't block downward movement anymore. But that seems insanely complicated, and I am 100% certain this will NOT work or create 5 new problems and I'm just going to waste my time... Another thing this brings up is, how should it look like if I wanted to check if one body is "touching" another body, or "at the edge" or something?   What does a GOOD collision system design look like? Should the player modify the position/velocity of it's body directly or return some kind of "desired" correction, which then gets evaluated by the "physics system"? Should It all have some kind of generalized behaviour that it just sets up at the beginning? body->SetBehaviour(FALL_ONTO_FROM_ABOVE, SLIDE_ALONG) or something like that instead of having a HandleCollision() which modifies position etc itself?   Btw the reason I'm not using Box2D is, first of all, I want to understand this stuff and be able to do it myself and second of all it just doesn't work very well with pixel-precise movement. Jittering on the floor, having to parse my level and create ghost vertices everywhere two bodies are side by side etc... I tried It and it was ugly. Why should I use a physics library and then program workarounds for the "physics"-part anyway, then why use physics simulation in the first place? Shovel Knight uses it apparently, that's why I tried it.
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!