Jump to content

  • Log In with Google      Sign In   
  • Create Account

Psychopathetica

Member Since 05 Apr 2011
Offline Last Active Yesterday, 02:36 PM
-----

Topics I've Started

Sweep AABB 2D Revisited

12 June 2013 - 02:19 PM

Its been awhile since I last posted, and I did a ton of research trying to get this right. And quite frankly theres very little information out there on this, and to a degree, even some misinformation. In fact I have yet to find a correct Sweep AABB 2D article that not only shows step by step of what the code does, which they do, but show what to do with the information you have rather than just give you a class and be like, "here ya go! Good luck to ya!" God I hate that.

 

For example. Take this gamedev article:

http://www.gamedev.net/page/resources/_/technical/game-programming/swept-aabb-collision-detection-and-response-r3084

 

Its a good article but has flaws. For starters, only one object can move. The other has to be a non moving object such as a wall. But for a game like pong, this will only work half the time, as long as your paddle is not moving since the ball is. Another thing is that both objects have to be the same size in order for that to work. I did a small demonstration by creating a stupid pong simulation, only instead of a paddle, I created a giant box thats 100x100 pixels in size, with the ball being a square 20x20 pixels in size. It fails because of this:

 

xInvEntry = b2.x - (b1.x + b1.w)

 

And lets say b1 is the Paddle, and b2 is the ball. Bare in mind, both objects are different sizes. I made the paddle approach a non moving ball and the xInvEntry went negative when it went close to the ball with a nice gap between rather than when it passes its touching point. But if both were the same width, it would do as it was intended and go negative once it passes its touching point. Another thing that bothered me was what he did with the information he got from his code:

 

float entryTime = std::max(xEntry, yEntry);
float exitTime = std::min(xExit, yExit);

 

This to me doesnt make any sense. Now I ran into another article over here:

http://techny.tumblr.com/post/42125198333/3d-collision-detection-and-resolution-using-sweeping

 

And ok, thats better. The biggest difference between the 2 is that this article allows both objects to move by simple Vector subtraction: V = VA - VB, and both objects can be different sizes, only this time the entry and exits works with half widths and half heights for both objects: DX = (B.x - HS.x) - (A.x + HS.x), which to me is a huge leap from the other article I say. So now I have this code to work with:

Public Function Sweep_Collision_Detection(Obj1 As Sprite_Type, Obj2 As Sprite_Type) As Single

    Dim Velocity1 As D3DVECTOR2
    Dim Velocity2 As D3DVECTOR2
    
    Dim Velocity As D3DVECTOR2
    
    Dim Collision_Entry As D3DVECTOR2
    Dim Collision_Exit As D3DVECTOR2
    
    Dim Entry_Time As D3DVECTOR2
    Dim Exit_Time As D3DVECTOR2
    
    Velocity1 = Vector_Subtract(Obj1.Position, Obj1.Old_Position)
    Velocity2 = Vector_Subtract(Obj2.Position, Obj2.Old_Position)
    
    Velocity = Vector_Subtract(Velocity1, Velocity2)
    
    If Velocity.X > 0 Then
        Collision_Entry.X = (Obj2.Position.X - Obj2.Half_Width) - (Obj1.Position.X + Obj1.Half_Width)
        Collision_Exit.X = (Obj2.Position.X + Obj2.Half_Width) - (Obj1.Position.X - Obj1.Half_Width)
    
        Entry_Time.X = (Collision_Entry.X / Velocity.X)
        Exit_Time.X = (Collision_Exit.X / Velocity.X)
    ElseIf Velocity.X < 0 Then
        Collision_Entry.X = (Obj2.Position.X + Obj2.Half_Width) - (Obj1.Position.X - Obj1.Half_Width)
        Collision_Exit.X = (Obj2.Position.X - Obj2.Half_Width) - (Obj1.Position.X + Obj1.Half_Width)
    
        Entry_Time.X = (Collision_Entry.X / Velocity.X)
        Exit_Time.X = (Collision_Exit.X / Velocity.X)
    End If
    
    If Velocity.Y > 0 Then
        Collision_Entry.Y = (Obj2.Position.Y - Obj2.Half_Height) - (Obj1.Position.Y + Obj1.Half_Height)
        Collision_Exit.Y = (Obj2.Position.Y + Obj2.Half_Height) - (Obj1.Position.Y - Obj1.Half_Height)
  
        Entry_Time.Y = (Collision_Entry.Y / Velocity.Y)
        Exit_Time.Y = (Collision_Exit.Y / Velocity.Y)
    ElseIf Velocity.Y < 0 Then
        Collision_Entry.Y = (Obj2.Position.Y + Obj2.Half_Height) - (Obj1.Position.Y - Obj1.Half_Height)
        Collision_Exit.Y = (Obj2.Position.Y - Obj2.Half_Height) - (Obj1.Position.Y + Obj1.Half_Height)

        Entry_Time.Y = (Collision_Entry.Y / Velocity.Y)
        Exit_Time.Y = (Collision_Exit.Y / Velocity.Y)
    End If
    
End Function

Bare in mind this is an incomplete example. The only problem is, I have no freaking clue what to do with this information. The code is correct at least but heres the deal. Lets say I do check if it passes the other object cause it moved so fast and this Sweep collision found it passed through it. After checking it did, I changed the position of the object like the article says to where it was suppose to collide. Problem is when I moved away from the ball after it displaced the paddle, it put the freaking paddle on the other side of the ball. As though the freaking thing was glued to it, and it was moving around it while stuck. Like I said I have no clue what to do with the Entry Times and Exit Times in this code. I see people doing different things with it like checking if its larger than 0, or less than 1, or even something stupid like checking if its greater or less than the Y Entry and Exit Times. And even then, how can I even setup the if statements with the information left over? Whats the correct way of doing this? If the article had a beautiful elegant simplified example, then just maybe I could have had a general idea. So for the sake of a pong collision style example, how can I correctly implement Sweep AABB for fast objects in 2D? I hope I was clear, and yes I saw other articles, but these seemed to have been the most clear. Thanks in advance.


Sweep AABB Collision/Response

11 May 2013 - 12:22 AM

Hi, I'm working on a pong style game thats gonna be a blend of Pong and Air Hockey in 2D with some realistic physics. However I ran into a speed bump...collision. Sure everythings all find and dandy using Bounding Box, or even Separation Axis Theorum, but when the puck goes too fast, it'll go through the paddle and not register a collision. I was fully aware at the time that using Sweep collision would be the solution, but I cannot find a decent piece of source code on Google worth using in my game. Now I recently saw this article found here:

 

http://www.gamedev.net/page/resources/_/technical/game-programming/swept-aabb-collision-detection-and-response-r3084

 

Looked very promising, however when I spliced his code into mine, it was awful. The puck slowed down as it got closer to the paddle, and got slower and slower, until it stopped at the paddle. Even when I shut off the physics, and just had the puck move at a constant rate of whatever value I gave vx multiplied by the collision time, it did the same thing. Also theres a limitation in his code, and he did admit there were limitations. It only works if one object is moving and the other is static. However in my game, I have 2 objects moving. The puck as well as what could be the paddle. Maybe if theres an SAT version of sweep collision and response out there. If anyone has any bright ideas on how I can successfully pull this off or knows of any other articles / links, I would appreciate it. Thanks in advance.


Accurate Texture Rendering When Stretching Window

09 February 2013 - 12:43 PM

I created a Nintendo Emulator using DirectX. And how I plotted the pixels was to create a texture using D3DXCreateTexture so I don't use a file, locked the texture, copied the array to the texture and unlocked. Just one problem. When I created the texture using D3DXCreateTexture, I had no choice but to make the size 256 x 256 since the NES's resolution is 256x240. Any bigger and I'll end up seeing weird anomalies such as double screen squashed up on top. Now as for the polygon size, it's perfect at 256 x 256, 512x512, etc. but if I make it any other size, it stretches the pixels weird and doesn't look right. Like a pixelated atari version of Mario. Ive messed with other NES emulators where stretching was perfect no matter what size and was wondering if I'm lacking a certain filter or setting to where it'll be perfect no matter what I stretch it to. Thanks in advance.

 

Also note I'm only currently using this:

 

    Device.SetTextureStageState 0, D3DTSS_MINFILTER, D3DTEXF_POINT
    Device.SetTextureStageState 0, D3DTSS_MAGFILTER, D3DTEXF_POINT


Speeding Up A* Pathfinding Idea

07 January 2013 - 11:58 PM

Ok basically I have a solid 2D tile engine where I can make the worlds as huge as I want with zero slowdown, a solid A* pathfinding algorithm, a solid A* pathfollowing method, and a solid game in general. Now comes an issue. Lets say I have a pretty hefty size dungeon and I end up pulling a hundred sprites and they all end up chasing after me throughout the dungeon. This obviously causes some massive slowdown cause they all have to go through the dungeon like a maze. Each node is on each tile. In a sense this could be a bad thing, considering the hundreds upon hundreds of nodes each sprite has to follow. However after staring at the nodes I visually have drawn, I noticed something. Many of the nodes don't even need to be there! The only time a node really needs placed is when a new direction is gonna happen as the sprite travels node to node. Yet I have no clue how I can even code this new idea of mine. If anything, it would be possible to truly pull a hundred sprites with next to no slowdown. I would probably be cutting the number of nodes by 75-90%. Any bright ideas how I could pull this off? Thanks in advance everyone.


A-Star Path Following Questions

18 December 2012 - 03:40 PM

Hi. Im currently working on a 2D RPG with a tile engine, and got a pretty solid A* Pathfinding engine, but as for A* pathfollowing, I ran into some issues. Ok before I begin, I have two sprites. One is the player than you can freely move across in the tile engine and the other is the monster that is moving node to node with the A* path. Currently I'm using this pseudo code to help the sprite follow the path:

[source lang="cpp"]speed_per_tick = 1; //constant speed you want the object to move atdelta_x = x_goal - x_current;delta_y = y_goal - y_current;goal_dist = sqrt((delta_x * delta_x) + (delta_y * delta_y));if (goal_dist > speed_per_tick){ Ratio = speed_per_tick / goal_dist; x_move = Ratio * delta_x; y_move = Ratio * delta_y; new_x_pos = x_move + x_current; new_y_pos = y_move + y_current;}Else{ new_x_pos = x_goal; new_y_pos = y_goal;}[/source]

It works great when the player isn't moving, but when he does move, it seems ok for a bit but sometimes once in awhile I'll notice some jitteryness with the monster as its following the path when the A* Path gets cleared or changed. Which leaves some questions I can't seem to find on google.

First of all, when the player moves and passes the next node, I obviously need to clear the A* Path and recalculate, but do I need to also clear and recalculate it when the monster reaches the next node?

Secondly It seems the path following code shown above doesn't work too well with diagnal cause the monster gets locked in between the two nodes and bounces back and forth as the player moves, but stops when the player stands still and the monster continues following the path as nortmal. And believe me, Its not the A* pathfinding code I have thats causing this cause the last following code I used didnt lock the sprite between nodes. Yet I had to change it cause I had too many problems with the last code I used.

Third, I found that using the top left of every tile as a node brought about too many problems. Moving right and down is normal. But when moving left and up, it tends to skip tiles, or drags against the wall when about to turn. I basically had to rethink this, draw some tiles on a sheet of paper, make little thick squares, and solve this on my own. My solution was to use the center of the tiles as nodes. As a result it moved normal in all 8 directions. In other words, any side of the player passing the center of a tile will be the next node. My question is that would this be the correct way of doing this? I'm sure many of you had similar problems. And I'm looking for solutions. Thanks in advance. Posted Image

PARTNERS