• Movement 8 Directions Problem
    19 replies, posted
Hey, I'm currently working on a Zelda game and I'm having problem with the movement system, it basicly works bit it's buggy as hell. I'm basically looking for a way to have a 8dir movement system that would do the job. [cpp]void CApp::OnKeyDown(SDLKey sym, SDLMod mod, Uint16 unicode) { switch(sym) { case SDLK_LEFT: { Player.MoveLeft = true; break; } case SDLK_DOWN: { Player.MoveDown = true; break; } case SDLK_RIGHT: { Player.MoveRight = true; break; } case SDLK_UP: { Player.MoveUp = true; break; } default: { } } } void CApp::OnKeyUp(SDLKey sym, SDLMod mod, Uint16 unicode) { switch(sym) { case SDLK_LEFT: { Player.MoveLeft = false; break; } case SDLK_DOWN: { Player.MoveDown = false; break; } case SDLK_RIGHT: { Player.MoveRight = false; break; } case SDLK_UP: { Player.MoveUp = false; break; } default: { } } }[/cpp] [cpp]void CEntity::OnLoop() { if(MoveLeft == false && MoveDown == false && MoveRight == false && MoveUp == false) { StopMove(); } if(MoveLeft) { AccelX = -0.5; }else if(MoveDown) { AccelY = 0.5; }else if(MoveRight) { AccelX = 0.5; }else if(MoveUp) { AccelY = -0.5; } if(Flags & ENTITY_FLAG_GRAVITY) { AccelY = 0.75f; } SpeedX += AccelX * CFPS::FPSControl.GetSpeedFactor(); SpeedY += AccelY * CFPS::FPSControl.GetSpeedFactor(); if(SpeedX > MaxSpeedX) SpeedX = MaxSpeedX; if(SpeedX < -MaxSpeedX) SpeedX = -MaxSpeedX; if(SpeedY > MaxSpeedY) SpeedY = MaxSpeedY; if(SpeedY < -MaxSpeedY) SpeedY = -MaxSpeedY; OnAnimate(); OnMove(SpeedX, SpeedY); }[/cpp] [cpp]void CEntity::OnMove(float MoveX, float MoveY) { if(MoveX == 0 && MoveY == 0) return; double NewX = 0; double NewY = 0; MoveX *= CFPS::FPSControl.GetSpeedFactor(); MoveY *= CFPS::FPSControl.GetSpeedFactor(); if(MoveX != 0) { if(MoveX >= 0) NewX = CFPS::FPSControl.GetSpeedFactor(); else NewX = -CFPS::FPSControl.GetSpeedFactor(); } if(MoveY != 0) { if(MoveY >= 0) NewY = CFPS::FPSControl.GetSpeedFactor(); else NewY = -CFPS::FPSControl.GetSpeedFactor(); } while(true) { if(Flags & ENTITY_FLAG_GHOST) { PosValid((int)(X + NewX), (int)(Y + NewY)); //We don’t care about collisions, but we need to send events to other entities X += NewX; Y += NewY; }else{ if(PosValid((int)(X + NewX), (int)(Y))) { X += NewX; }else{ SpeedX = 0; } if(PosValid((int)(X), (int)(Y + NewY))) { Y += NewY; }else{ SpeedY = 0; } } MoveX += -NewX; MoveY += -NewY; if(NewX > 0 && MoveX <= 0) NewX = 0; if(NewX < 0 && MoveX >= 0) NewX = 0; if(NewY > 0 && MoveY <= 0) NewY = 0; if(NewY < 0 && MoveY >= 0) NewY = 0; if(MoveX == 0) NewX = 0; if(MoveY == 0) NewY = 0; if(MoveX == 0 && MoveY == 0) break; if(NewX == 0 && NewY == 0) break; } }[/cpp]
Could you explain what problems in particular you are having?
What does "buggy as hell" mean?
This looks way more complicated than it needs to be. What I would do in this situation is keep track of a force vector that only changes upon keypresses/releases. Try to keep conditionals out of the picture. [cpp] //The change in force of a single directional control #define KEY_FORCE 5.0f #define FRICTION 0.8f struct Player { Vector2D force; //Force due to movement keys Vector2D velocity, position; float mass; //Whatever ... } player; //sym - SDLKey symbol //state - key press (true) or release (false) void OnKeyDown(SDLKey sym, bool state) { switch(sym) { case SDLK_LEFT: player.force.x -= (state?) KEY_FORCE : -KEY_FORCE; break; case SDLK_RIGHT: player.force.x += (state?) KEY_FORCE : -KEY_FORCE; break; case SDLK_UP: player.force.y += (state?) KEY_FORCE : -KEY_FORCE; break; case SDLK_DOWN: player.force.y -= (state?) KEY_FORCE : -KEY_FORCE; break; } } //Updates the position and velocity of the player based upon force from controls void Update_Player(void) { //Simple friction will just be proportional and opposing to velocity Vector2D force_fric (player.velocity * -FRICTION); Vector2D accel ((player.force + force_fric) / player.mass); player.velocity += accel * time_delta; //time delta is the time the last frame took to render player.position += player.velocity * time_delta; } [/cpp]
[QUOTE=nullsquared;16652614]What does "buggy as hell" mean?[/QUOTE] well the 4 basic directions are working perfectly but when I combine Up and Right for example it looks like Link is skating on ice :v:
[QUOTE=HiredK;16655594]when I combine Up and Right for example it looks like Link is skating on ice :v:[/QUOTE] What the fuck does that mean? If you want help, you're going to need to be descriptive - not funny.
[QUOTE=Cathbadh;16654290]This looks way more complicated than it needs to be. What I would do in this situation is keep track of a force vector that only changes upon keypresses/releases. Try to keep conditionals out of the picture. [cpp] //The change in force of a single directional control #define KEY_FORCE 5.0f #define FRICTION 0.8f struct Player { Vector2D force; //Force due to movement keys Vector2D velocity, position; float mass; //Whatever ... } player; //sym - SDLKey symbol //state - key press (true) or release (false) void OnKeyDown(SDLKey sym, bool state) { switch(sym) { case SDLK_LEFT: player.force.x -= (state?) KEY_FORCE : -KEY_FORCE; break; case SDLK_RIGHT: player.force.x += (state?) KEY_FORCE : -KEY_FORCE; break; case SDLK_UP: player.force.y += (state?) KEY_FORCE : -KEY_FORCE; break; case SDLK_DOWN: player.force.y -= (state?) KEY_FORCE : -KEY_FORCE; break; } } //Updates the position and velocity of the player based upon force from controls void Update_Player(void) { //Simple friction will just be proportional and opposing to velocity Vector2D force_fric (player.velocity * -FRICTION); Vector2D accel ((player.force + force_fric) * player.mass); player.velocity += accel * time_delta; //time delta is the time the last frame took to render player.position += player.velocity * time_delta; } [/cpp][/QUOTE] Looks like it could help me but I'm still a novice and I don't see how to incorporate this in my code. [editline]11:12PM[/editline] [QUOTE=nullsquared;16655637]What the fuck does that mean? If you want help, you're going to need to be descriptive - not funny.[/QUOTE] Well it seems that when I want to go diagonal such as Up Right, Link will continue sliding on the right for something like 5 pixel and then it'll execute the diagonal ... it seems like it's taking too long to recognize the Keys ... here's the full CEntity class: [cpp]#include "CEntity.h" std::vector<CEntity*> CEntity::EntityList; CEntity::CEntity() { Surf_Entity = NULL; X = 0; Y = 0; Width = 0; Height = 0; MoveLeft = false; MoveDown = false; MoveRight = false; MoveUp = false; Type = ENTITY_TYPE_GENERIC; Dead = false; Flags = 0; SpeedX = 0; SpeedY = 0; AccelX = 0; AccelY = 0; MaxSpeedX = 2; MaxSpeedY = 2; CurrentFrameCol = 0; CurrentFrameRow = 0; Col_X = 0; Col_Y = 0; Col_Width = 0; Col_Height = 0; } CEntity::~CEntity() { } bool CEntity::OnLoad(char* File, int Width, int Height, int MaxFrames, int FrameRate) { if((Surf_Entity = CSurface::OnLoad(File)) == NULL) { return false; } CSurface::Transparent(Surf_Entity, 255, 0, 255); this->Width = Width; this->Height = Height; Anim_Control.MaxFrames = MaxFrames; Anim_Control.SetFrameRate(FrameRate); return true; } void CEntity::OnLoop() { if(MoveLeft == false && MoveDown == false && MoveRight == false && MoveUp == false) { StopMove(); } if(MoveLeft) { AccelX = -0.5; }else if(MoveDown) { AccelY = 0.5; }else if(MoveRight) { AccelX = 0.5; }else if(MoveUp) { AccelY = -0.5; } if(Flags & ENTITY_FLAG_GRAVITY) { AccelY = 0.75f; } SpeedX += AccelX * CFPS::FPSControl.GetSpeedFactor(); SpeedY += AccelY * CFPS::FPSControl.GetSpeedFactor(); if(SpeedX > MaxSpeedX) SpeedX = MaxSpeedX; if(SpeedX < -MaxSpeedX) SpeedX = -MaxSpeedX; if(SpeedY > MaxSpeedY) SpeedY = MaxSpeedY; if(SpeedY < -MaxSpeedY) SpeedY = -MaxSpeedY; OnAnimate(); OnMove(SpeedX, SpeedY); } void CEntity::OnRender(SDL_Surface* Surf_Display) { if(Surf_Entity == NULL || Surf_Display == NULL) return; CSurface::OnDraw(Surf_Display, Surf_Entity, X - CCamera::CameraControl.GetX(), Y - CCamera::CameraControl.GetY(), CurrentFrameCol * Width, (CurrentFrameRow + Anim_Control.GetCurrentFrame()) * Height, Width, Height); } void CEntity::OnCleanup() { if(Surf_Entity) { SDL_FreeSurface(Surf_Entity); } Surf_Entity = NULL; } void CEntity::OnAnimate() { if(MoveLeft) { CurrentFrameCol = 0; }else if(MoveDown) { CurrentFrameCol = 1; }else if(MoveRight) { CurrentFrameCol = 2; }else if(MoveUp) { CurrentFrameCol = 3; } Anim_Control.OnAnimate(); } bool CEntity::OnCollision(CEntity* Entity) { return true; } void CEntity::OnMove(float MoveX, float MoveY) { if(MoveX == 0 && MoveY == 0) return; double NewX = 0; double NewY = 0; MoveX *= CFPS::FPSControl.GetSpeedFactor(); MoveY *= CFPS::FPSControl.GetSpeedFactor(); if(MoveX != 0) { if(MoveX >= 0) NewX = CFPS::FPSControl.GetSpeedFactor(); else NewX = -CFPS::FPSControl.GetSpeedFactor(); } if(MoveY != 0) { if(MoveY >= 0) NewY = CFPS::FPSControl.GetSpeedFactor(); else NewY = -CFPS::FPSControl.GetSpeedFactor(); } while(true) { if(Flags & ENTITY_FLAG_GHOST) { PosValid((int)(X + NewX), (int)(Y + NewY)); //We don&#8217;t care about collisions, but we need to send events to other entities X += NewX; Y += NewY; }else{ if(PosValid((int)(X + NewX), (int)(Y))) { X += NewX; }else{ SpeedX = 0; } if(PosValid((int)(X), (int)(Y + NewY))) { Y += NewY; }else{ SpeedY = 0; } } MoveX += -NewX; MoveY += -NewY; if(NewX > 0 && MoveX <= 0) NewX = 0; if(NewX < 0 && MoveX >= 0) NewX = 0; if(NewY > 0 && MoveY <= 0) NewY = 0; if(NewY < 0 && MoveY >= 0) NewY = 0; if(MoveX == 0) NewX = 0; if(MoveY == 0) NewY = 0; if(MoveX == 0 && MoveY == 0) break; if(NewX == 0 && NewY == 0) break; } } void CEntity::StopMove() { if(SpeedX > 0) { AccelX = -1; } if(SpeedY > 0) { AccelY = -1; } if(SpeedX < 0) { AccelX = 1; } if(SpeedY < 0) { AccelY = 1; } if(SpeedX < 2.0f && SpeedX > -2.0f) { AccelX = 0; SpeedX = 0; } if(SpeedY < 2.0f && SpeedY > -2.0f) { AccelY = 0; SpeedY = 0; } } bool CEntity::Collides(int oX, int oY, int oW, int oH) { int left1, left2; int right1, right2; int top1, top2; int bottom1, bottom2; int tX = (int)X + Col_X; int tY = (int)Y + Col_Y; left1 = tX; left2 = oX; right1 = left1 + Width - 1 - Col_Width; right2 = oX + oW - 5; top1 = tY; top2 = oY; bottom1 = top1 + Height - 1 - Col_Height; bottom2 = oY + oH - 1; if (bottom1 < top2) return false; if (top1 > bottom2) return false; if (right1 < left2) return false; if (left1 > right2) return false; return true; } bool CEntity::PosValid(int NewX, int NewY) { bool Return = true; int StartX = (NewX + Col_X) / TILE_SIZE; int StartY = (NewY + Col_Y) / TILE_SIZE; int EndX = ((NewX + Col_X) + Width - Col_Width - 1) / TILE_SIZE; int EndY = ((NewY + Col_Y) + Height - Col_Height - 1) / TILE_SIZE; for(int iY = StartY;iY <= EndY;iY++) { for(int iX = StartX;iX <= EndX;iX++) { CTile* Tile = CArea::AreaControl.GetTile(iX * TILE_SIZE, iY * TILE_SIZE); if(PosValidTile(Tile) == false) { Return = false; } } } if(Flags & ENTITY_FLAG_MAPONLY) { }else{ for(int i = 0;i < EntityList.size();i++) { if(PosValidEntity(EntityList[i], NewX, NewY) == false) { Return = false; } } } return Return; } bool CEntity::PosValidTile(CTile* Tile) { if(Tile == NULL) { return true; } if(Tile->TypeID == TILE_TYPE_BLOCK) { return false; } return true; } bool CEntity::PosValidEntity(CEntity* Entity, int NewX, int NewY) { if(this != Entity && Entity != NULL && Entity->Dead == false && Entity->Flags ^ ENTITY_FLAG_MAPONLY && Entity->Collides(NewX + Col_X, NewY + Col_Y, Width - Col_Width - 1, Height - Col_Height - 1) == true) { CEntityCol EntityCol; EntityCol.EntityA = this; EntityCol.EntityB = Entity; CEntityCol::EntityColList.push_back(EntityCol); return false; } return true; }[/cpp]
There is obviously a bug in this section of the code: [cpp] if(MoveLeft) { AccelX = -0.5; }else if(MoveDown) { AccelY = 0.5; }else if(MoveRight) { AccelX = 0.5; }else if(MoveUp) { AccelY = -0.5; } [/cpp] This clearly only allows for movement in an exclusive direction. For example, you can't go up and right at the same time. Again, your code is way to convoluted and complex the way it is. No wonder it is full of bugs. I suggest you scrap the code and rewrite it all over again. Believe me, it will be a million times easier the second time around.
I'd say you rewrite your code into a simpler form, you definitely don't need all those variables. Here is an example, this is essentially the core of my movement code. It's nothing fancy but it doesn't bug and it works pretty well and allows 8-Direction movement with no problem. [code] if(Window.GetInput().IsKeyDown(Key::W)) Position.y -= (float)SpeedCurrent * FrameTime; if(Window.GetInput().IsKeyDown(Key::S)) Position.y += (float)SpeedCurrent * FrameTime; if(Window.GetInput().IsKeyDown(Key::A)) Position.x -= (float)SpeedCurrent * FrameTime; if(Window.GetInput().IsKeyDown(Key::D)) Position.x += (float)SpeedCurrent * FrameTime; [/code]
don't do it in a fucking switch. break; <- lol. you aren't checking for more than one key at once.
[QUOTE=Cathbadh;16656605]There is obviously a bug in this section of the code: [cpp] if(MoveLeft) { AccelX = -0.5; }else if(MoveDown) { AccelY = 0.5; }else if(MoveRight) { AccelX = 0.5; }else if(MoveUp) { AccelY = -0.5; } [/cpp] This clearly only allows for movement in an exclusive direction. For example, you can't go up and right at the same time. Again, your code is way to convoluted and complex the way it is. No wonder it is full of bugs. I suggest you scrap the code and rewrite it all over again. Believe me, it will be a million times easier the second time around.[/QUOTE] This. I think it would work if you removed the else's, because the way you have it now, if one key is pressed, it doesnt check for the ones after.
[QUOTE=efeX;16657369]don't do it in a fucking switch. break; <- lol. you aren't checking for more than one key at once.[/QUOTE] But you still have to consider each key on its own. This event-based structure is still [I]way[/I] better than polling the keyboard.
[QUOTE=Cathbadh;16664811]But you still have to consider each key on its own. This event-based structure is still [I]way[/I] better than polling the keyboard.[/QUOTE] Yes I have a class that takes care of the event: [cpp]#include "CEvent.h" CEvent::CEvent() { } CEvent::~CEvent() { //Do nothing } void CEvent::OnEvent(SDL_Event* Event) { switch(Event->type) { case SDL_ACTIVEEVENT: { switch(Event->active.state) { case SDL_APPMOUSEFOCUS: { if ( Event->active.gain ) OnMouseFocus(); else OnMouseBlur(); break; } case SDL_APPINPUTFOCUS: { if ( Event->active.gain ) OnInputFocus(); else OnInputBlur(); break; } case SDL_APPACTIVE: { if ( Event->active.gain ) OnRestore(); else OnMinimize(); break; } } break; } case SDL_KEYDOWN: { OnKeyDown(Event->key.keysym.sym,Event->key.keysym.mod,Event->key.keysym.unicode); break; } case SDL_KEYUP: { OnKeyUp(Event->key.keysym.sym,Event->key.keysym.mod,Event->key.keysym.unicode); break; } case SDL_MOUSEMOTION: { OnMouseMove(Event->motion.x,Event->motion.y,Event->motion.xrel,Event->motion.yrel,(Event->motion.state&SDL_BUTTON(SDL_BUTTON_LEFT))!=0,(Event->motion.state&SDL_BUTTON(SDL_BUTTON_RIGHT))!=0,(Event->motion.state&SDL_BUTTON(SDL_BUTTON_MIDDLE))!=0); break; } case SDL_MOUSEBUTTONDOWN: { switch(Event->button.button) { case SDL_BUTTON_LEFT: { OnLButtonDown(Event->button.x,Event->button.y); break; } case SDL_BUTTON_RIGHT: { OnRButtonDown(Event->button.x,Event->button.y); break; } case SDL_BUTTON_MIDDLE: { OnMButtonDown(Event->button.x,Event->button.y); break; } } break; } case SDL_MOUSEBUTTONUP: { switch(Event->button.button) { case SDL_BUTTON_LEFT: { OnLButtonUp(Event->button.x,Event->button.y); break; } case SDL_BUTTON_RIGHT: { OnRButtonUp(Event->button.x,Event->button.y); break; } case SDL_BUTTON_MIDDLE: { OnMButtonUp(Event->button.x,Event->button.y); break; } } break; } case SDL_QUIT: { OnExit(); break; } case SDL_SYSWMEVENT: { //Ignore break; } case SDL_VIDEORESIZE: { OnResize(Event->resize.w,Event->resize.h); break; } case SDL_VIDEOEXPOSE: { OnExpose(); break; } default: { OnUser(Event->user.type,Event->user.code,Event->user.data1,Event->user.data2); break; } } } void CEvent::OnInputFocus() { //Pure virtual, do nothing } void CEvent::OnInputBlur() { //Pure virtual, do nothing } void CEvent::OnKeyDown(SDLKey sym, SDLMod mod, Uint16 unicode) { //Pure virtual, do nothing } void CEvent::OnKeyUp(SDLKey sym, SDLMod mod, Uint16 unicode) { //Pure virtual, do nothing } void CEvent::OnMouseFocus() { //Pure virtual, do nothing } void CEvent::OnMouseBlur() { //Pure virtual, do nothing } void CEvent::OnMouseMove(int mX, int mY, int relX, int relY, bool Left,bool Right,bool Middle) { //Pure virtual, do nothing } void CEvent::OnMouseWheel(bool Up, bool Down) { //Pure virtual, do nothing } void CEvent::OnLButtonDown(int mX, int mY) { //Pure virtual, do nothing } void CEvent::OnLButtonUp(int mX, int mY) { //Pure virtual, do nothing } void CEvent::OnRButtonDown(int mX, int mY) { //Pure virtual, do nothing } void CEvent::OnRButtonUp(int mX, int mY) { //Pure virtual, do nothing } void CEvent::OnMButtonDown(int mX, int mY) { //Pure virtual, do nothing } void CEvent::OnMButtonUp(int mX, int mY) { //Pure virtual, do nothing } void CEvent::OnMinimize() { //Pure virtual, do nothing } void CEvent::OnRestore() { //Pure virtual, do nothing } void CEvent::OnResize(int w,int h) { //Pure virtual, do nothing } void CEvent::OnExpose() { //Pure virtual, do nothing } void CEvent::OnExit() { //Pure virtual, do nothing } void CEvent::OnUser(Uint8 type, int code, void* data1, void* data2) { //Pure virtual, do nothing }[/cpp] and a class that handle the event that I'm using in the game on the main loop: [cpp]#include "CApp.h" void CApp::OnEvent(SDL_Event* Event) { CEvent::OnEvent(Event); } void CApp::OnKeyDown(SDLKey sym, SDLMod mod, Uint16 unicode) { switch(sym) { case SDLK_LEFT: { Player.MoveLeft = true; break; } case SDLK_DOWN: { Player.MoveDown = true; break; } case SDLK_RIGHT: { Player.MoveRight = true; break; } case SDLK_UP: { Player.MoveUp = true; break; } default: { } } } void CApp::OnKeyUp(SDLKey sym, SDLMod mod, Uint16 unicode) { switch(sym) { case SDLK_LEFT: { Player.MoveLeft = false; break; } case SDLK_DOWN: { Player.MoveDown = false; break; } case SDLK_RIGHT: { Player.MoveRight = false; break; } case SDLK_UP: { Player.MoveUp = false; break; } default: { } } } void CApp::OnExit() { Running = false; }[/cpp] I don't think re-writing would be a good move, at least not yet ... this may appear overloaded but except the movement the engine is working flawlessly. Basically I'm looking for a way to re-check the key-input every time there's a change on the keyboard. To be a little more exact on the actual problem, the Up and Right work but when releasing the Right key for example it remains as if I was still pressing Right and Link's going side-way. I think that this if statement as a lot to do with the problem. [cpp]# if(MoveLeft == false && MoveDown == false && MoveRight == false && MoveUp == false) { # StopMove(); # } [/cpp] tried to change to [cpp]# if(MoveLeft == false || MoveDown == false || MoveRight == false || MoveUp == false) { # StopMove(); # } [/cpp] The "Up-Right" problem is fixed but now there's another problem, Link is walking half the speed and the animation is not catching on just as if the var SpeedX or SpeedY never increase ...
For much shorter, prettier (in my opinion anyway) and faster code, you could make an array of function pointers where the [url=http://www.libsdl.org/tmp/SDL-1.3-docs/SDL__events_8h-source.html]SDL_EventType[/url] is the index for a function pointer like this: [cpp]typedef void (*SDL_EventHandler)(SDL_Event* event);[/cpp] The lookup would be constant: [cpp]EventHandlers[event->type](event);[/cpp] You wouldn't be able to have "fancy" arguments like in your handling code (every event handler would need to get those from the event themselves), but your handling does a lot of dereferencing and such that you don't know whether the handler will even use.
I finally fixed it [cpp]void CEntity::OnLoop() { if(MoveLeft) { AccelX = -0.5; } if(MoveDown) { AccelY = 0.5; } if(MoveRight) { AccelX = 0.5; } if(MoveUp) { AccelY = -0.5; } if(!MoveLeft && !MoveRight) { AccelX = 0; SpeedX = 0; } if(!MoveDown && !MoveUp) { AccelY = 0; SpeedY = 0; } if(Flags & ENTITY_FLAG_GRAVITY) { AccelY = 0.75f; } SpeedX += AccelX * CFPS::FPSControl.GetSpeedFactor(); SpeedY += AccelY * CFPS::FPSControl.GetSpeedFactor(); if(SpeedX > MaxSpeedX) SpeedX = MaxSpeedX; if(SpeedX < -MaxSpeedX) SpeedX = -MaxSpeedX; if(SpeedY > MaxSpeedY) SpeedY = MaxSpeedY; if(SpeedY < -MaxSpeedY) SpeedY = -MaxSpeedY; OnAnimate(); OnMove(SpeedX, SpeedY); }[/cpp]
You could shorten the first part a lot by doing this: [cpp] AccelX = (MoveRight - MoveLeft) * 0.5f; AccelY = (MoveDown - MoveUp) * 0.5f; [/cpp]
"It already works" is one of the weakest reasons any programmer can use for not fixing code. If it is too long or too complex, it is broken. No 2 ways about it. Your code has way more conditionals than are necessary, and this is gonna strain the processor pipeline (because branches are resolved relatively late in the pipeline, meaning that if the branch predictor failed, you just wasted a good 30 cycles of execution)
[QUOTE=Cathbadh;16694622]"It already works" is one of the weakest reasons any programmer can use for not fixing code. If it is too long or too complex, it is broken. No 2 ways about it. Your code has way more conditionals than are necessary, and this is gonna strain the processor pipeline (because branches are resolved relatively late in the pipeline, meaning that if the branch predictor failed, you just wasted a good 30 cycles of execution)[/QUOTE] He's not conditionally jumping out of the current function, so that's probably not going to be a problem here. Far worse is it because it is a lot more error-prone to have unnecessarily long and/or too complex code, and is going to take much longer to scale. My way with function pointers is many times more effective in terms of speed; and you also get to center the code involving one event in one location instead of two; unlike his way.
[QUOTE=Cathbadh;16694622]"It already works" is one of the weakest reasons any programmer can use for not fixing code. If it is too long or too complex, it is broken. No 2 ways about it. Your code has way more conditionals than are necessary, and this is gonna strain the processor pipeline (because branches are resolved relatively late in the pipeline, meaning that if the branch predictor failed, you just wasted a good 30 cycles of execution)[/QUOTE] I perfectly know what you're talking about but this code as already been re-written many times and this one is the best so far, and as I said before it looks very overloaded but it as the movement engine, the collision engine, the entity collision engine, the map engine and right know it's working perfectly ... and tbh I'm not too concern about the optimization right know since I'm emulating a game boy game (But I'll optimize it later on when I'll be adding more stuff) Oh and by the way thanks for helping me with this problem :v: [editline]05:25PM[/editline] [QUOTE=DeltaOps101;16693387]You could shorten the first part a lot by doing this: [cpp] AccelX = (MoveRight - MoveLeft) * 0.5f; AccelY = (MoveDown - MoveUp) * 0.5f; [/cpp][/QUOTE] Tried that be I've had a problem when using opposite keys such as Up and Down ... It just continue straight up :v:
[QUOTE=HiredK;16695378]Tried that be I've had a problem when using opposite keys such as Up and Down ... It just continue straight up :v:[/QUOTE] When both keys are down, the [I]acceleration[/I] will be 0, but the speed won't change. You would need to either keep your opposite-key checks that set the speed to 0, or apply some sort of friction to the speed.
Sorry, you need to Log In to post a reply to this thread.