Hello Guest, please login or register.
Did you miss your activation email?
Login with username, password and session length.

Pages: [1]   Go Down

Author Topic: Currently working on [Collision with Tiles]  (Read 3021 times)

0 Members and 1 Guest are viewing this topic.
Currently working on [Collision with Tiles]
« on: October 26, 2011, 07:43:23 pm »
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Posts: 5
I've been messing around with trying to find an efficient way to insert collision with tiles in my engine. So far I've gotten pretty far with getting my player to collide with the tiles, but before I move on any farther and try to implement corner-cutting, I'd like to know if what I'm doing right now is acceptable.

Here is the link to the file.
http://www.sendspace.com/file/rlvngv

Screenshot:
Logged
Re: Currently working on [Collision with Tiles]
« Reply #1 on: October 27, 2011, 04:07:19 am »
  • AKA "Micah DS"
  • *
  • Reputation: +9/-0
  • Offline Offline
  • Gender: Male
  • Posts: 1347
First, welcome to ZFGC, associateSum9! XD

Anyway, for some reason if you are up against a row of blocks and you hold up and left simultaneously it will move left as it should but it will stop moving to the left when it is lined up perfectly with a block. This is the only problem that I see; besides that it seems very solid and it is recognizing the tile ids properly.

Interesting approach to coding collisions btw.

Edit: Figured I'd give a picture to show the glitch spoke of above:

(the block stays in this position as I hold up and left simultaneously)
(note: the id says "0" because I couldn't screen capture with those keys pressed, so I had to let off the keys to screenshot it ;P)
« Last Edit: October 27, 2011, 04:12:46 am by Frozenç‚Ž »
Logged
  • My Music
Re: Currently working on [Collision with Tiles]
« Reply #2 on: October 28, 2011, 06:15:54 pm »
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Posts: 5
Hey there, thanks for the welcome, and thanks for trying my source. I tried to recreate the glitch you found but sadly was unable to. :( But thanks again! Now I just need to figure out the corner-cutting part. I'll post an update when I am able to figure it out.
Logged
Re: Currently working on [Collision with Tiles]
« Reply #3 on: October 28, 2011, 06:30:45 pm »
  • *
  • Reputation: +8/-0
  • Offline Offline
  • Gender: Male
  • Posts: 6604
The corner-cutting is actually simple if all the collisions you are working with are squares, it is even easier if you know the width of what is running into the tile. If your object is 16 x 16 and the tiles are 16 x 16, you can at most only be running into 2 tiles at once. Oh, and it helps to divide up collision detection so that you are looking at both halves the of the object's collision mask. For example, if moving up/down, you check the left/right halves of the collision mask, if both halves collide with something then stop, if just one do corner-cutting, if none then move as usual.

I did something in the GM Minish Cap Engine involving tile collisions and I probably improved upon it later.
Logged
Re: Currently working on [Collision with Tiles]
« Reply #4 on: October 28, 2011, 07:53:26 pm »
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Posts: 5
Here is my version with corner-cutting so far.
http://www.sendspace.com/file/ea1d7v

@4Sword - That sounds like an efficient way to do it. Currently my code is pretty messy, and I have set my sprites origin in the center yet (which I should have done at the very beginning). I'll try fixing my code to fit your description unless I've already done what you've just told me. :P
Logged
Re: Currently working on [Collision with Tiles]
« Reply #5 on: October 30, 2011, 08:30:19 am »
  • *
  • Reputation: +8/-0
  • Offline Offline
  • Gender: Male
  • Posts: 6604
I can't remember if I worked with your previous file or the more recent one you posted but I did the folllowing.

1. Altered the msk1 sprite so that it had an origin of 8,8
2. Created an object called objGreen and gave it the following event stuff

Create Event:
Code: [Select]
//******************************************************************************
//*                           VARIABLE DICTIONARY                              *
//*                                                                            *
//* X                                                                          *
//*  able_x - able to move on x-axis                                           *
//*  step_x - amount to move each step on x-axis                               *
//*  move_x - "speed" at which to move each step on x-axis                     *
//*  maxi_x - max "speed" at which to move each step on x-axis                 *
//* Y                                                                          *
//*  able_y - able to move on y-axis                                           *
//*  step_y - amount to move each step on y-axis                               *
//*  move_y - "speed" at which to move each step on y-axis                     *
//*  maxi_y - max "speed" at which to move each step on y-axis                 *
//* OTHER                                                                      *
//*  ROOT_ADD - the fractional part of the square root of 2                    *
//******************************************************************************

able_x = true;
step_x = 0;
move_x = 0;
maxi_x = 2;

able_y = true;
step_y = 0;
move_y = 0;
maxi_y = 2;

ROOT_ADD = 0.41421356237309;
Step Event:
Code: [Select]
//******************************************************************************
//*                            TEMPORARY VARIABLES                             *
//*                                                                            *
//* KEYS                                                                       *
//*  hold_l - the left key                                                     *
//*  hold_r - the right key                                                    *
//*  hold_u - the up key                                                       *
//*  hold_d - the down key                                                     *
//* MATH SIMPLICIFICATIONS                                                     *
//*  absv_x - the absolute value of move_x                                     *
//*  absv_y - the absolute value of move_y                                     *
//*  line_v - the calculated horizontal or vertical distance from mask origin  *
//*  move_v - if move_x/move_y is < 0, it is -1, if > 0 it is +1               *
//*  temp_c - used for termining loop_c and how much potential corner-cutting  *
//*  loop_c - the amount of x/y pixels to move                                 *
//*  move_f - movement factor, if linear movement it is 1, if diagonal sqrt(2) *
//* OBSTACLES                                                                  *
//*  obst_a - the left/up collision tile                                       *
//*  obst_b - the right/down collision tile                                    *
//******************************************************************************

var hold_l,hold_r,hold_u,hold_d,
    absv_x,absv_y,line_v,move_v,
    temp_c,loop_c,move_f,
    obst_a,obst_b;

// Initialize the key states
hold_l = keyboard_check(vk_left);
hold_r = keyboard_check(vk_right);
hold_u = keyboard_check(vk_up);
hold_d = keyboard_check(vk_down);

// If left and right(or up and down) keys are pressed simultaneously, cancel
// their values out to signify keys "aren't being held"
if (hold_l && hold_r){
  hold_l = false;
  hold_r = false;
}   
if (hold_u && hold_d){
  hold_u = false;
  hold_d = false;
}

// If able to move on x-axis/y-axis then set the movement "speed"
if (able_x)
  move_x = (hold_r - hold_l) * maxi_x;
if (able_y)
  move_y = (hold_d - hold_u) * maxi_y;
 
// Store the absolute values of move_x/move_y for later calculation
absv_x = abs(move_x);
absv_y = abs(move_y); 
 
//********************************************************************
//* LOGIC STEPS                                                      *
//*  1. Set move_f = 1                                               *
//*  2. If moving diagonally, adjust move_f to sqrt(2)               *
//*   a. If move_x or move_y (absx_x/absv_y) are at their max (this  *
//*      either means the -max or max), then set step_x = step_y so  *
//*      that it doesn't appear as though movement "stair-steps"     *
//*  3. Otherwise if just moving linearly on x-axis at max speed,    *
//*     reset step_x so that nothing fractional left in it disrupts  *
//*     how linear movement is done                                  *
//*  3. Otherwise (do 3. but for y)                                  *
//********************************************************************

move_f = 1;
if (absv_x && absv_y){
  move_f += ROOT_ADD;
  if (absv_x == maxi_x && absv_y == maxi_y)
    step_x = step_y;
}
else if (absv_x == maxi_x)
  step_x = 0;
else if (absv_y == maxi_y)
  step_y = 0;
 
// If x-axis movement
if (absv_x){
  // Determine if that movement is positive or negative in inclination,
  // set the line_v based on the horizontal distance to the edge of the,
  // bounding box for the direction of movement, and add new speed to
  // the step_x counter
  move_v = (move_x > 0) - (move_x < 0);
  line_v = 7 - (!move_v * 15);
  step_x += absv_x;
 
  // Determine how many pixels on the x-axis to move
  loop_c = 0;
  temp_c = step_x;
  while (temp_c >= 1){
    loop_c += 1;
    temp_c -= move_f;
  }
   
  // If movement is still to occur
  if (loop_c){
    // Decrement the step_x relative to how much will be moved
    step_x -= move_f * loop_c;
   
    // Determine if obstacles are being run into
    obst_a = tile_layer_find(1000000,x + line_v + move_v * loop_c,bbox_top);
    obst_b = tile_layer_find(1000000,x + line_v + move_v * loop_c,bbox_bottom);
   
    //********************************************************************
    //* LOGIC STEPS                                                      *
    //*  1. If obstacle to top and bottom for x movement                 *
    //*   a. Set x position relative to either tile                      *
    //*  2. Else if just obstacle to top                                 *
    //*   a. Set x position relative to top tile                         *
    //*   b. If not trying to move on y-axis and objGreen is over about  *
    //*      halfway to the collision tile, then do corner-cutting       *
    //*    1. If no tile to the bottom of objGreen move there if able.   *
    //*       The potential to move is based on how much objGreen moved  *
    //*       along x-axis, but adjusted via ROOT_ADD + 1 because the    *
    //*       actual corner-cutting is considered a form of diagonal     *
    //*       movement.                                                  *
    //*  3. Else if just obstacle to bottom (do 2. but for obst_b)       *
    //*  4. Else movement is not blocked so move normally                *
    //* (Do 1.-4. but for y movement                                     *
    //********************************************************************
   
    if (obst_a && obst_b){
      x = tile_get_x(obst_a);
      x += (move_v == -1) * 16 - (move_v == 1) - line_v;     
    }
    else if (obst_a){
      x = tile_get_x(obst_a);
      x += (move_v == -1) * 16 - (move_v == 1) - line_v;
      if (!absv_y && y + 1 > tile_get_y(obst_a) + 16){
        temp_c = step_x + move_f * loop_c;
        while (temp_c >= 1){
          y += !tile_layer_find(1000000,x,y + 7);
          if (bbox_top + 1 > tile_get_y(obst_a) + 16)
            break;
          temp_c -= ROOT_ADD + 1;
        }
      }
    }
    else if (obst_b){
      x = tile_get_x(obst_b);
      x += (move_v == -1) * 16 - (move_v == 1) - line_v;
      if (!absv_y && y - 1 < tile_get_y(obst_b)){
        temp_c = step_x + move_f * loop_c;
        while (temp_c >= 1){
          y -= !tile_layer_find(1000000,x,y - 8);
          if (bbox_bottom - 1 < tile_get_y(obst_b))
            break;
          temp_c -= ROOT_ADD + 1;
        }
      }
    }
    else
      x += move_v * loop_c;
  }
}
 
if (absv_y){
  move_v = (move_y > 0) - (move_y < 0);
  line_v = 7 - (!move_v * 15);
  step_y += absv_y;

  loop_c = 0;
  temp_c = step_y;
  while (temp_c >= 1){
    loop_c += 1;
    temp_c -= move_f;
  } 
   
  if (loop_c){
    step_y -= move_f * loop_c;
    obst_a = tile_layer_find(1000000,bbox_left,y + line_v + move_v * loop_c);
    obst_b = tile_layer_find(1000000,bbox_right,y + line_v + move_v * loop_c);
    if (obst_a && obst_b){
      y = tile_get_y(obst_a);
      y += (move_v == -1) * 16 - (move_v == 1) - line_v;
    }
    else if (obst_a){
      y = tile_get_y(obst_a);
      y += (move_v == -1) * 16 - (move_v == 1) - line_v;
      if (!absv_x && x + 1 > tile_get_x(obst_a) + 16){
        temp_c = step_y + move_f * loop_c;
        while (temp_c >= 1){
          x += !tile_layer_find(1000000,x + 7,y);
          if (bbox_left + 1 > tile_get_x(obst_a) + 16)
            break;
          temp_c -= ROOT_ADD + 1;
        }
      }
    }
    else if (obst_b){
      y = tile_get_y(obst_b);
      y += (move_v == -1) * 16 - (move_v == 1) - line_v;
      if (!absv_x && x - 1 < tile_get_x(obst_b)){
        temp_c = step_y + move_f * loop_c;
        while (temp_c >= 1){
          x -= !tile_layer_find(1000000,x - 8,y);
          if (bbox_right - 1 < tile_get_x(obst_b))
            break;
          temp_c -= ROOT_ADD + 1;
        }
      }
    }
    else
      y += move_v * loop_c;
  } 
}

That fixes the flaws with diagonal movement speed you had and should do corner-cutting appropriately enough.
Logged
Re: Currently working on [Collision with Tiles]
« Reply #6 on: October 31, 2011, 08:49:21 pm »
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Posts: 5
Here is my new example now. Also added a link sprite with animations : )
http://www.sendspace.com/file/4lrewi

@4Sword, I'm currently trying to understand you logic with the code you posted. So far so good I suppose. : ) Thanks for willing to help me out by the way.
Logged
Re: Currently working on [Collision with Tiles]
« Reply #7 on: November 01, 2011, 11:19:23 am »
  • *
  • Reputation: +8/-0
  • Offline Offline
  • Gender: Male
  • Posts: 6604
The collision code that I posted was actually simplified down from the code I used on the GM Minish Cap Engine; again, when you add diagonals and blocks with certain properties that move you will need collision objects (my system used both collision tiles and obstacle objects).

I am not sure what about my code's logic you didn't understand but it probably would not be too difficult to explain.
Logged
Re: Currently working on [Collision with Tiles]
« Reply #8 on: November 01, 2011, 05:40:37 pm »
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Posts: 5
It's not that I don't understand, I meant I haven't fully read through it all yet. I pretty much understand everything I've read so far though.
Logged
Pages: [1]   Go Up

 


Contact Us | Legal | Advertise Here
2013 © ZFGC, All Rights Reserved



Page created in 0.058 seconds with 53 queries.

anything