Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (741)
Games in Android Showcase (225)
games submitted by our members
Games in WIP (823)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  looking for good way to make colisions with slopes and gravity  (Read 1036 times)
0 Members and 1 Guest are viewing this topic.
Offline pavul

Junior Devvie


Medals: 3
Exp: 4 years



« Posted 2017-08-14 03:12:11 »

i have several collision methods, between rectangles, poing circles, etc, etc, but im struggling when im making some 2d games with gravity, some times the sprite is stuck ( because of gravity ) and if i want to implement slopes as well im not making sprite to over those slopes.
any guidance will be appreciated.

its better not know why it works, that know why is not working
Offline KevinWorkman

« JGO Plugged Duke »


Medals: 270
Projects: 12
Exp: 12 years


HappyCoding.io - Coding Tutorials!


« Reply #1 - Posted 2017-08-14 03:57:39 »

Have you considered using a physics engine like Box2D?

HappyCoding.io - Coding Tutorials!
Happy Coding forum - Come say hello!
Offline pavul

Junior Devvie


Medals: 3
Exp: 4 years



« Reply #2 - Posted 2017-08-14 19:26:40 »

yes, but Box2D increases learning curve and for simple games sometimes with box collisions is necessary, for now I want to understand how collision works in deep, to implement better engines like Box2D, I have been implemented gravity, but when I want to move my sprite to the left it get stuck, If I quit gravity force once im touching the ground, it wont fall if im a platform. im figuring out that.

its better not know why it works, that know why is not working
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline orangepascal
« Reply #3 - Posted 2017-08-15 07:33:39 »

yeah no need to do this with Box2D Smiley  it's terrifying to me to see how many people just use box2d for all the simple stuff, that's overkill on math!

this article has good info on any collision detection in platforms:
https://www.gamedev.net/articles/programming/general-and-gameplay-programming/the-guide-to-implementing-2d-platformers-r2936

one extra tip I would give: The order is important, so make sure to do one-direction at a time. 
in code that means:

1. move X to new location
2. detect horizontal walls  (if moved into a wall, revert to correct location in front of wall)
3. move Y to new location
4. detect vertical walls (and correct if needed)

a problem often seen with new devs is doing this:

1. move X,Y to new location
2. detect horizontal walls
3. detect vertical walls

which makes a lot of little bugs happen like suddenly jumping a few pixels, or moving half into tiles, etc.

but most is explained in that article Smiley

the guy behind Orangepixel | twitter@orangepascal
http://www.orangepixel.net
Offline pavul

Junior Devvie


Medals: 3
Exp: 4 years



« Reply #4 - Posted 2017-08-18 15:01:07 »

yeah no need to do this with Box2D Smiley  it's terrifying to me to see how many people just use box2d for all the simple stuff, that's overkill on math!

this article has good info on any collision detection in platforms:
https://www.gamedev.net/articles/programming/general-and-gameplay-programming/the-guide-to-implementing-2d-platformers-r2936

one extra tip I would give: The order is important, so make sure to do one-direction at a time. 
in code that means:

1. move X to new location
2. detect horizontal walls  (if moved into a wall, revert to correct location in front of wall)
3. move Y to new location
4. detect vertical walls (and correct if needed)

a problem often seen with new devs is doing this:

1. move X,Y to new location
2. detect horizontal walls
3. detect vertical walls

which makes a lot of little bugs happen like suddenly jumping a few pixels, or moving half into tiles, etc.

but most is explained in that article Smiley


you know what, now you mention that is what is happening, im moving two axis instead of one, and actually that is happening because the collision is first evaluation X axis and then Y( it get stuck when I move that on left ), and actually I have like a week seesking the correct way to implement that, lets see you article and thanks so much @orangepascal

its better not know why it works, that know why is not working
Offline pavul

Junior Devvie


Medals: 3
Exp: 4 years



« Reply #5 - Posted 2017-08-19 03:14:13 »


simply i cannot do gravity correctly, i have the next things:

( Sprite ) player width:24, height;32

array of tiles:
0 means free
1 means solid tile ( it will  make collision with this )
tile width and height are 16 px

 int [] tileColisionMap = {
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   
     0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0   
     };


on the update loop i have the next things
{
input : i can move the sprite 2 pixels left and other 2 pixels right

//process gravity for the player
// jump value = 5 &
jumpvalue = -5;
 jumpValue += gravity;
 gravity = 0.37f;           
   
         //every tick the jump get a limit
                if( jumpValue >= jumpForce )
                {
                    jumpValue = jumpForce;
                }
            y += jumpValue;



//after set gravity im checking a collision against each solid tile
//defined in above array

 //this check tile colision against player
                       //basically is puting the solid tiles of the whole level
                       //enemies, usable objects and players may check this colisions
                       if( Collision.getInstance().checkColsionTile(
                       player,
                       tileColisionMap,
                       columns,
                       rows,
                       tileWidth,
                       tileHeigth ).equals( Config.COLISION_BOTTOM ) )
                       {
                             player.setJump( false );
//                             player.setY( player.getY( ) - player.getJumpValue() );
                             System.out.println("::: inside collision "+player.getY() );
                       }//




}


inside that method we have the next code:


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
public  String checkColsionTile(Sprite spr,
                int[] colisionMap,
                int cols,
                int rows,
                int tileWidth,
                int tileHeight)
        {
            String side= Config.COLISION_NONE;
            String aux="";
            if(cols <=0 || rows <= 0)
            {
                //arrojar excepcion aqui
            return side;
            }
       
        int mapIndex = 0;
        int totalTiles = cols * rows;
       
        int tilewidth = tileWidth;
        int tileHeigth = tileHeight;
     
      //for de renglones
         for( int i = 0;i < rows; i++ )
            {
                int tiley = i * tileHeigth;
           
                    //for de columnas
                    for( int j = 0 ; j < cols ; j++ )
                    {
                       
                       
                   //@TODO check here if the tile to compute is
                    //near the sprite to collide, to avoid extra process...
                       
                       
                    if( colisionMap[ mapIndex ] == 1)
                     {
                         int tilex = j * tilewidth;
                         
                        side = blockRectangle(spr, tilex, tiley, tilewidth,tileHeigth);
                        if (side.equals(Config.COLISION_BOTTOM))
                        {
                        aux=Config.COLISION_BOTTOM;
                        }
                     
                     }//if validacion si se checa colision
                 
                      if( mapIndex < totalTiles )
                      mapIndex++;
                     
                     
                    }//for cols
            }//for rows
     
//          System.out.println("-checkColsionTile se regreso SIDE: "+side);
       
          if(!aux.equals(""))
          {
          side=aux;
          }
         
          return side;
        }//checkcolisiontile
       


public String blockRectangle(Sprite s1,int x, int y, int width,int height)
   {
            int halfWidth = width / 2;
            int halfHeigth = height / 2;
            int centerX = x + halfWidth;
            int centerY = y + halfHeigth;
           
      String side = Config.COLISION_NONE;        
               
                //get distance vectors
      float vx=s1.getCenterX()-centerX;
      float vy=s1.getCenterY()-centerY;
     
               
      float combinedHalfWidth = s1.getHalfWidth()+halfWidth;
      float combinedHalfHeight = s1.getHalfHeight()+halfHeigth;
           
               
                //collision on x axis
                if( Math.abs(vx) < combinedHalfWidth )
      {
                    //collision on y axis
         if(Math.abs(vy) < combinedHalfHeight)
         {
                           
                            //collision made
                           
            float overlapX=combinedHalfWidth-Math.abs(vx);
            float overlapY=combinedHalfHeight-Math.abs(vy);
     
                            if( overlapX < overlapY )
                                    {
               
               if( vx > 0 )
               {
                                            s1.setX( s1.getX()+overlapX );
                                            return Config.COLISION_LEFT;
               }
               else
               {
                                            s1.setX( s1.getX()-overlapX );
                                            return Config.COLISION_RIGHT;
               }

                                    }//
                                else
   
            {

                                    if( vy > 0 )
               {
                                            s1.setY( s1.getY()+overlapY );
                                            return Config.COLISION_TOP;
                                        }
                                    else
               {
                                           s1.setY( s1.getY()  - overlapY );
                                            return Config.COLISION_BOTTOM;
               }

            }
             


         }//height

                       
      }//width
               
      return side;
     
   }//colision con rectangulos, pero    
       



that collision tile method is supposed to check bottom collision and to put the sprite in the correct place ( must align the player along solid tile )


but the error is that the sprite is stuck when i want to move left
































its better not know why it works, that know why is not working
Offline orangepascal
« Reply #6 - Posted 2017-08-19 08:39:41 »

there's no need to check all tiles every time Smiley

maybe this example helps you get there:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
public final static void example()
{
   int tilex;
   int tileY;

   // sprite horizontal position+speed+width
   int x=24;
   int xSpeed=2;
   int width=16;   // can be any size
   
   // sprite vertical position+speed+height
   int y=64;
   int ySpeed=2;
   int height=16; // can be any size
   
   x+=xSpeed;
   
   // for horizontal movement I usually take the waste-height of my character
   // and check on that..  99% of the time that works, in some case you might want to test at the feet or head height
   // remember, this is for horizontal movement, we aren't testing vertical collisions yet!
   tileY = (y + (height / 2) / 16);
   
   // which direction are we moving in?
   if (xSpeed>0)
   {
      // moving to the right, so check if our right edge hits a wall
      tileX = (x+w) / 16;  // we divide our sprite's right-edge by 16 since our tiles are 16x16 pixels wide
     
      if (tilemap[tileX + (tileY * tilemapwidth)] == solidtile)
      {
         // we hit a solid tile!
         // so correct our position, obviously we couldn't move this far to the right
         // we reset the player on the left edge of the tile we just hit, minus the player's width
         x = (tileX * 16) - width;
      }
   }
   else if (xSpeed<0)
   {
      // moving to the left, so check if our left edge hits a wall
      tileX = (x / 16);  // we divide our sprite's left-edge by 16 since our tiles are 16x16 pixels wide
     
      if (tilemap[tileX + (tileY * tilemapwidth)] == solidtile)
      {
         // we hit a solid tile!
         // so correct our position, obviously we couldn't move this far to the left
         // we reset the player on the right edge of the tile we just hit
         x = (tileX * 16)+16;
      }      
   }
}




Now write a function to do vertical testing, almost the same way, except for the Y-axis Smiley

If you have that up and running, you might want to improve your checking by making the vertical function check not on the sprite's-xAxis-center, but on both the left and right foot.. but don't worry about that too much for now, just try get this up and running!


oh and in case you need some live example, here's one of my opensource projects:
https://bitbucket.org/orangepixel/planet-busters

the guy behind Orangepixel | twitter@orangepascal
http://www.orangepixel.net
Offline pavul

Junior Devvie


Medals: 3
Exp: 4 years



« Reply #7 - Posted 2017-08-21 15:26:13 »

Now write a function to do vertical testing, almost the same way, except for the Y-axis Smiley

If you have that up and running, you might want to improve your checking by making the vertical function check not on the sprite's-xAxis-center, but on both the left and right foot.. but don't worry about that too much for now, just try get this up and running!


oh and in case you need some live example, here's one of my opensource projects:
https://bitbucket.org/orangepixel/planet-busters


now my example is working I had to create another function that is checking if the sprite is in the air and if is, I will process gravity again.

its better not know why it works, that know why is not working
Pages: [1]
  ignore  |  Print  
 
 

 
Ecumene (110 views)
2017-09-30 02:57:34

theagentd (136 views)
2017-09-26 18:23:31

cybrmynd (245 views)
2017-08-02 12:28:51

cybrmynd (241 views)
2017-08-02 12:19:43

cybrmynd (240 views)
2017-08-02 12:18:09

Sralse (254 views)
2017-07-25 17:13:48

Archive (864 views)
2017-04-27 17:45:51

buddyBro (1008 views)
2017-04-05 03:38:00

CopyableCougar4 (1569 views)
2017-03-24 15:39:42

theagentd (1373 views)
2017-03-24 15:32:08
List of Learning Resources
by elect
2017-03-13 14:05:44

List of Learning Resources
by elect
2017-03-13 14:04:45

SF/X Libraries
by philfrei
2017-03-02 08:45:19

SF/X Libraries
by philfrei
2017-03-02 08:44:05

SF/X Libraries
by SkyAphid
2017-03-02 06:38:56

SF/X Libraries
by SkyAphid
2017-03-02 06:38:32

SF/X Libraries
by SkyAphid
2017-03-02 06:38:05

SF/X Libraries
by SkyAphid
2017-03-02 06:37:51
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!