Jump to content


Photo

Checking nearest left and right of same object


  • Please log in to reply
4 replies to this topic

#1 Data-Fi

Data-Fi

    GMC Member

  • GMC Member
  • 36 posts
  • Version:Unknown

Posted 29 August 2011 - 11:38 PM

hello,
I'm trying to create a view system using markers in my game, in this example there are horizontal view markers(horviewmark)
which should make the view fallow the character's x coordinates and snap the view to a line between the markers. My real problem
lies in trying to return the id's of the nearest marker to the left and right. If I were to use the two nearest objects using instance_nth_nearest()
it would sometimes refer to two markers to one side, if the markers aren't perfectly placed. I am new to the 'do' statement, and all my efforts
in writing script have lead to glitches and crashes. My most recent attempt, much simpler than older ones, looks like this:
do
{if instance_nearest(pixeler.x, pixeler.y, horviewmark).x > pixeler.x && instance_nearest(pixeler.x, pixeler.y, horviewmark).x > instance_nth_nearest(pixeler.x, pixeler.y, horviewmark, viewskip).x or instance_nearest(pixeler.x, pixeler.y, horviewmark).x < pixeler.x && instance_nearest(pixeler.x, pixeler.y, horviewmark).x < instance_nth_nearest(pixeler.x, pixeler.y, horviewmark, viewskip).x
{view_yview = instance_nearest(pixeler.x, pixeler.y, horviewmark).y - (instance_nearest(pixeler.x, pixeler.y, horviewmark).y - instance_nth_nearest(pixeler.x, pixeler.y, horviewmark, viewskip).y)*(point_distance(pixeler.x, 0, instance_nearest(pixeler.x, pixeler.y, horviewmark).x, 0)/point_distance(pixeler.x, 0, instance_nth_nearest(pixeler.x, pixeler.y, horviewmark, viewskip).x, 0)/2) - view_hview/2}
else
{viewskip = viewskip + 1}}
until instance_nearest(pixeler.x, pixeler.y, horviewmark).x > pixeler.x && instance_nearest(pixeler.x, pixeler.y, horviewmark).x > instance_nth_nearest(pixeler.x, pixeler.y, horviewmark, viewskip).x or instance_nearest(pixeler.x, pixeler.y, horviewmark).x < pixeler.x && instance_nearest(pixeler.x, pixeler.y, horviewmark).x < instance_nth_nearest(pixeler.x, pixeler.y, horviewmark, viewskip).x
view_xview = pixeler.x - view_wview/2

pixeler is the name of the player
I know these are loooong lines it basically uses the variable viewskip to keep testing the next nearest viewmarker's x until it is greater or lesser than the nearest viewmarker depending on if pixeler(player)'s x is greater or lesser than the nearest. this crashes on me apparently
when the nearest marker shifts to another. I just scratched my other script today and wrote this one, so I assume the glitch in this code is pretty easy to see, but I think I have the wrong idea entirely of how to check the nearest left and right object.

thanks for the help in advance!
  • 0

#2 Uniquebum

Uniquebum

    GMC Member

  • New Member
  • 317 posts

Posted 30 August 2011 - 12:50 AM

I read the post twice and had a good glance on the code but just can't seem to figure out what you're trying to achieve. Are there only 2 of those objects in the whole map? If so, the check doesn't need to be that accurate.

You could just do
leftmarker = instance_nearest(pixeler.x-5, pixeler.y, horviewmark);
rightmarker = instance_nearest(pixeler.x+5, pixeler.y, horviewmark);or something similiar.



  • 0

#3 Data-Fi

Data-Fi

    GMC Member

  • GMC Member
  • 36 posts
  • Version:Unknown

Posted 30 August 2011 - 12:58 AM

I read the post twice and had a good glance on the code but just can't seem to figure out what you're trying to achieve. Are there only 2 of those objects in the whole map? If so, the check doesn't need to be that accurate.

You could just do
leftmarker = instance_nearest(pixeler.x-5, pixeler.y, horviewmark);
rightmarker = instance_nearest(pixeler.x+5, pixeler.y, horviewmark);or something similiar.



sorry if I wasn't clear, I have many of these viewmarkers they basically are being used in my level editor to direct the view to fallow the character horizontally but vertically they are snapped to a line.
that is a really good idea with the pixeler.x - 5 , but there could still be glitches if two markers are very close and one is far. I plan for this
level editor to be used by others, so it shouldn't have glitches like that. For a while I was using a repeating statement to find the right and left markers by adding and subtracting from pixeler.x until it reached a marker. but whenever I use the do statements I have problems. Thanks for the help uniquebum
  • 0

#4 IceMetalPunk

IceMetalPunk

    InfiniteIMPerfection

  • Retired Staff
  • 9260 posts
  • Version:Unknown

Posted 30 August 2011 - 01:23 AM

To be more efficient than checking each pixel or cell until you find a marker, I'd suggest you use a priority queue to sort all horviewmarks by x-coordinate, then cut into it from both ends until you reach the player's position.

markers = ds_priority_create();

/* Add all markers to the queue, ordered by x-coordinate */
with (horviewmark) {
  ds_priority_add(other.markers, id, x);
}

left=noone;
right=noone;

foundleft=0;
foundright=0;

/* Since you're checking top and bottom simultaneously, you only need N/2 iterations max */
for (p = 0; p < ds_priority_size(markers)/2 && ds_priority_size(markers)>0; p += 1) {

  /* If the leftmost instance on the queue is to the right of the player, we're done. */
  if (ds_priority_find_min(markers).x > player.x) {
    foundleft=1;
  }

  /* If not, mark the leftmost instance on the queue as our "left" and remove it. */
  else { left = ds_priority_delete_min(markers); }

  /* Repeat for the rightmost */
  if (ds_priority_find_max(markers).x < player.x) {
    foundright=1;
  }
  else if (!foundright) { right = ds_priority_delete_max(markers); }

}

ds_priority_destroy(markers);

That should leave you with left holding the ID of the nearest marker to the player's left, and right holding the ID of the nearest marker to the player's right. If either doesn't exist (i.e. you're to the left of the leftmost or to the right of the rightmost marker), the corresponding variable will hold noone.

-IMP

Edited by IceMetalPunk, 30 August 2011 - 01:33 AM.

  • 0

#5 Data-Fi

Data-Fi

    GMC Member

  • GMC Member
  • 36 posts
  • Version:Unknown

Posted 30 August 2011 - 01:49 AM

sweet thanks IMP
I'm going to try that out right now!

I ended up using this:
leftmarkers = ds_priority_create();
rightmarkers = ds_priority_create()
with (horviewmark) {
if x < pixeler.x
  {ds_priority_add(other.leftmarkers, id, x);}
if x > pixeler.x
{ds_priority_add(other.rightmarkers, id, x);}
}
left = ds_priority_find_max(leftmarkers)
right = ds_priority_find_min(rightmarkers)

ds_priority_destroy(leftmarkers);
ds_priority_destroy(rightmarkers)

I never used ds_priority before now it's pretty cool. what you gave me before almost worked
but it seemed to miss the mid portion of markers. maybe because it was deleting markers
from the list. Anyway I never would have looked towards the ds_priority without ya imp thanks!

Edited by Mr. Skellington, 30 August 2011 - 05:13 AM.

  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users