Jump to content


Photo

Object Counting Script Help


  • Please log in to reply
20 replies to this topic

#1 Arison

Arison

    GMC Member

  • New Member
  • 10 posts
  • Version:GM:Studio

Posted 25 March 2016 - 07:12 AM

I need a function that can check the amount of instances of a specific object touching the script caller.

 

I have no ideas on how.


  • 0

#2 flyingsaucerinvasion

flyingsaucerinvasion

    GMC Member

  • GMC Member
  • 720 posts
  • Version:GM:Studio

Posted 25 March 2016 - 07:13 AM

instance_number(obj)

https://docs.yoyogam...nce_number.html

 

OOps.. didn't read your post carefully enough it seems.

 

I'm assuming you mean instances in direct contact with the calling instance, and not connected via a chain of instances?

 

var count = 0;

with (some_object_type_goes_here)

{

    if place_meeting(x,y,other) count++;

}

 

https://docs.yoyogam...ce_meeting.html


Edited by flyingsaucerinvasion, 25 March 2016 - 07:19 AM.

  • 0

#3 Purplebeard

Purplebeard

    GMC Member

  • New Member
  • 17 posts
  • Version:GM:Studio

Posted 25 March 2016 - 07:41 AM

I believe this should work:

var inst,count;
count=0;
inst = instance_place(x,y,other);
if(inst!=noone){
     count=instance_number(inst);
}
return count;

If you put it in a script it should return the number of instances on collision.


  • 0

#4 Arison

Arison

    GMC Member

  • New Member
  • 10 posts
  • Version:GM:Studio

Posted 27 March 2016 - 03:33 AM

Ok, so I've tried to using flyingsaucerinvasion's script with my own, changing it slightly and now I've got this:

var i;
if place_meeting(x,y,!obj_floor_unset) i = 1;
for(i = 1; i = 2; i++){
var fl = 0;
var wa = 0;
{
    if place_meeting(x,y,obj_floor_set) fl++;
    if place_meeting(x,y,obj_wall) wa++;
}
// fl = the number of set floors touching
// wa = the number of walls touching
var z = random(1);
if (z+(0.05*fl)-(0.05*wa))>0.5 {
    instance_destroy();
} else {
    instance_change(obj_wall, true);
}}

I can't figure out why this isn't working. The obj_floor_unset is either not running the script properly, or it's just turning into obj_floor_set all the time. Please help me.


  • 0

#5 flyingsaucerinvasion

flyingsaucerinvasion

    GMC Member

  • GMC Member
  • 720 posts
  • Version:GM:Studio

Posted 27 March 2016 - 03:52 AM

Whoa... there are a lot of problems going on there.  It's hard to figure out what you are trying to do. 

 

Can you describe what that code is supposed to be doing?


Edited by flyingsaucerinvasion, 27 March 2016 - 03:52 AM.

  • 0

#6 Arison

Arison

    GMC Member

  • New Member
  • 10 posts
  • Version:GM:Studio

Posted 27 March 2016 - 06:06 AM

Whoa... there are a lot of problems going on there.  It's hard to figure out what you are trying to do. 

 

Can you describe what that code is supposed to be doing?

It's meant to check the exact amount of walls and the exact amount of floors set around it. It's meant to activate once there is something other than an unset floor touching it. From there it takes a random number between 1 and 0 and then adds 0.05 times the number of floors and 0.05 times the number of walls and then checks if it's higher or lower than 0.5 to determine whether it becomes a set floor or wall.

I'm trying to use it as a random map generator.


  • 0

#7 TheouAegis

TheouAegis

    GMC Member

  • GMC Member
  • 13885 posts
  • Version:GM:Studio

Posted 27 March 2016 - 06:47 AM

flyingsaucerinvasion wasn't using plain English, he was giving you actual code.

var count = 0;
with (obj_floor_set)
{
    if place_meeting(x,y,other.id) count++;
}
with (obj_wall)
{
    if place_meeting(x,y,other.id) count++;
}

Pretty sure just using "other" doesn't work, but even if it does, you shouldn't use it by itself. It's a pointer, not a pronoun.

 

Also as flyin-- as the guy said, your code has tons of errors in it.

 

var i;
if place_meeting(x,y,!obj_floor_unset) i = 1;

 

Your code simply checks if the first object in the Resource Tree is at position (x,y). You can't use ! like that. That i=1 after it just doesn't even make sense in the context of the rest of your code, either.

for(i = 1; i = 2; i++){

 

i will never increase and the code after the bracket will never even run because i never equals 2. You probably meant to use i<3 or set i to 0 and use i<2. Even then, though...

 

var fl = 0;
var wa = 0;
{
if place_meeting(x,y,obj_floor_set) fl++;
if place_meeting(x,y,obj_wall) wa++;

}

 

You aren't using flyi- that guy's suggestion. This will only find 1 instance of obj_floor_set and 1 instance of obj_wall touching this instance, so fl and wa will only ever be 1.
 

var z = random(1);
if (z+(0.05*fl)-(0.05*wa))>0.5 {
instance_destroy();
} else {
instance_change(obj_wall, true);
}}

 

This may or may not be fine. Syntactically, it's okay. Semantically, only you can know.


Edited by TheouAegis, 27 March 2016 - 06:48 AM.

  • 0

"The problem with object-oriented languages is that they've got all this implicit environment that they carry around with them. You wanted a banana but what you've got is a gorilla holding the banana and the entire jungle." -Joe Armstrong

 

"It goes against the grain of modern education to teach children to program. What fun is there in making plans, acquiring discipline in organizing thoughts, devoting attention to detail and learning to be self-critical?" -Alan Perlis

 

"Do not think about where you want to be and how to get there; think about what you want to do and how to do it." -Theou Aegis


#8 Arison

Arison

    GMC Member

  • New Member
  • 10 posts
  • Version:GM:Studio

Posted 27 March 2016 - 08:16 AM

flyingsaucerinvasion wasn't using plain English, he was giving you actual code.

var count = 0;
with (obj_floor_set)
{
    if place_meeting(x,y,other.id) count++;
}
with (obj_wall)
{
    if place_meeting(x,y,other.id) count++;
}

Pretty sure just using "other" doesn't work, but even if it does, you shouldn't use it by itself. It's a pointer, not a pronoun.

 

Also as flyin-- as the guy said, your code has tons of errors in it.

 

var i;
if place_meeting(x,y,!obj_floor_unset) i = 1;

 

Your code simply checks if the first object in the Resource Tree is at position (x,y). You can't use ! like that. That i=1 after it just doesn't even make sense in the context of the rest of your code, either.

for(i = 1; i = 2; i++){

 

i will never increase and the code after the bracket will never even run because i never equals 2. You probably meant to use i<3 or set i to 0 and use i<2. Even then, though...

 

var fl = 0;
var wa = 0;
{
if place_meeting(x,y,obj_floor_set) fl++;
if place_meeting(x,y,obj_wall) wa++;

}

 

You aren't using flyi- that guy's suggestion. This will only find 1 instance of obj_floor_set and 1 instance of obj_wall touching this instance, so fl and wa will only ever be 1.
 

var z = random(1);
if (z+(0.05*fl)-(0.05*wa))>0.5 {
instance_destroy();
} else {
instance_change(obj_wall, true);
}}

 

This may or may not be fine. Syntactically, it's okay. Semantically, only you can know.

Actually, this all makes sense, and I think with the code provided by that guy will be useful in taking away the rest of bad stuff. That last part is the thing I wrote to just increase the chance of getting a wall if there are more walls around or increase the chance of getting a floor if there are more floors around.


var count = 0;
with (obj_floor_set or obj_wall)
{
    if place_meeting(x,y,obj_floor_set) count++;
}
with (obj_wall)
{
    if place_meeting(x,y,obj_wall) count--;
}
var z = random(1);
if (z+(0.05*count)>0.5 {
    instance_change(obj_floor_set, true);
} else {
    instance_change(obj_wall, true);
}}

I hope this follows syntax and can actually make sense to you guys.


  • 0

#9 flyingsaucerinvasion

flyingsaucerinvasion

    GMC Member

  • GMC Member
  • 720 posts
  • Version:GM:Studio

Posted 27 March 2016 - 07:50 PM

you can't use the keyword or like that as the argument in a with statement.

 

It's still not clear to me what you are doing.  In your opening post you said you were trying to count all instances of an object that are overlapping a calling instance.  Yet the code you posted most recently doesn't seem to reflect that at all.

 

If you really want to count instances colliding with the calling instance, you can use my original suggestion, which I just tested to make sure actually works.  And this is the exact code I used:

//counting instances of obj_collider which are colliding with this instance
var count = 0;
with (obj_collider)
    if place_meeting(x,y,other)
        count++;

I don't understand TheouAgegis's objection to the keyword other, because in this context it is the id of the calling instance, which is exactly what the original post was asking for.


Edited by flyingsaucerinvasion, 27 March 2016 - 07:54 PM.

  • 0

#10 TheouAegis

TheouAegis

    GMC Member

  • GMC Member
  • 13885 posts
  • Version:GM:Studio

Posted 27 March 2016 - 08:09 PM

He has an object obj_floor_unset. It is placed in the room. If obj_floor_unset is next to an obj_floor_set or next to an obj_wall, the odds of it becoming an obj_floor_set are higher. Something about the number of obj_walls touching another obj_wall increases the chance of it becoming a wall.

 

The issue of his code now, in addition to him using or even though I explicitly showed him how to count collisions with 2 different objects, is that new with(obj_wall) he added in. I think the idea is to count the obj_walls that are in contact with the obj_floor_unset. Instead, his code is checking ALL obj_wall, which will ultimately lead to count being a negative value 99% of the time (the 1% is in the first few times this code is run).

 

Also, it just occurred to me if the objects are tiled across the room, they shouldn't even be in a collision, so place_meeting() should return false...

var count = 0;
with obj_floor_set
{
    if distance_to_object(other.id) < 2
        with obj_floor_set
            if id != other.id
                if distance_to_object(other.id) < 2
                {
                    count++;
                    break;
                }
}
with obj_wall
{
    if distance_to_object(other.id) < 2
        with obj_wall
        {
            count++;
            if id != other.id
                if distance_to_object(other.id) < 2
                {
                    count--;
                    break;
                }
    }
}

What this code should do is first count how many adjacent obj_floor_set have an adjacent obj_floor_set. This increases the likelihood the current instance will become obj_floor_set. Then it finds an adjacent obj_wall and increases the likelihood that the current instance will become obj_floor_set, however if there is AT LEAST 1 obj_wall adjacent to that obj_wall, it decreases the chance. Note that this code is actually weighted in favor of becoming obj_floor_set. If you want to weight in favor of walls, remove the break from the obj_wall check.


  • 0

"The problem with object-oriented languages is that they've got all this implicit environment that they carry around with them. You wanted a banana but what you've got is a gorilla holding the banana and the entire jungle." -Joe Armstrong

 

"It goes against the grain of modern education to teach children to program. What fun is there in making plans, acquiring discipline in organizing thoughts, devoting attention to detail and learning to be self-critical?" -Alan Perlis

 

"Do not think about where you want to be and how to get there; think about what you want to do and how to do it." -Theou Aegis


#11 flyingsaucerinvasion

flyingsaucerinvasion

    GMC Member

  • GMC Member
  • 720 posts
  • Version:GM:Studio

Posted 27 March 2016 - 08:22 PM

I was assuming he was using some kind of a moving cursor to build the map, which explained in my mind why he was looking to count instances overlapping it. 

 

If the instances are tiled, uniform in size, arranged in a grid, and not overlapping, it seems to be the most efficient thing to do would be to check the 8 positions surrounding each tile.

//w and h are the width and height of each tile cell.
//In other words, the distance along each axis between a part of one tile and the same part of its nearest neighbors
var w = 32;
var h = 32;
var floor_set_count = 0;
var wall_count = 0;
for      (var c = -1; c < 2; c ++)
     for (var r = -1; r < 2; r += 1 + (c == 0))
     {
          floor_set_count += place_meeting(x + c * w, y + r * h, obj_floor_set);
          wall_count +=      place_meeting(x + c * w, y + r * h, obj_wall);
     }

Edited by flyingsaucerinvasion, 27 March 2016 - 09:32 PM.

  • 0

#12 Arison

Arison

    GMC Member

  • New Member
  • 10 posts
  • Version:GM:Studio

Posted 27 March 2016 - 10:11 PM

Ok, from what people are saying, there is clearly some confusion surrounding what I want done. This is how the map generation happens.

 

There are eight seed points that are set by a random number generator and one that the player starts on and so is always a set floor. The rest of the tiles around the room are unset floors. From there I want the unset floors to do something like this:

 

within a step event{

 

if it is adjacent to anything other than an unset floor{

count the number of set floors surrounding it and add 1 to the count variable

count the number of walls surrounding it and take 1 from the count variable

 

random number between one and zero and assign it to some variable

if that variable plus the count variable times 0.05 is less than 0.5{

make the instance become a wall

} else {

make the instance become a floor}

}

}

 

It looks like FSI's code would do it, but I could say the same for everything that has come up on this topic. I know very little about GML and actually have the docs open at all times when coding.


  • 0

#13 flyingsaucerinvasion

flyingsaucerinvasion

    GMC Member

  • GMC Member
  • 720 posts
  • Version:GM:Studio

Posted 27 March 2016 - 10:16 PM

so I'm assuming the tiles are layed out in a rectangular grid, which implies that any tile can have only eight neighbors (including four corners).  So the maximum count can only ever be 8.  8 times 0.05 is 0.4.  Therefore your test will always evaluate true, becuase 0.4 is less than 0.5.


Edited by flyingsaucerinvasion, 27 March 2016 - 10:22 PM.

  • 0

#14 Arison

Arison

    GMC Member

  • New Member
  • 10 posts
  • Version:GM:Studio

Posted 27 March 2016 - 10:31 PM

so I'm assuming the tiles are layed out in a rectangular grid, which implies that any tile can have only eight neighbors (including four corners).  So the maximum count can only ever be 8.  8 times 0.05 is 0.4.  Therefore your test will always evaluate true, becuase 0.4 is less than 0.5.

the minimum value at the maximum amount of floors is 0.4, which would set it to a wall, but there is the random number between 0 and 1. With an equal number of walls and floors surrounding the tile there should be only a half chance of it happening.


  • 0

#15 flyingsaucerinvasion

flyingsaucerinvasion

    GMC Member

  • GMC Member
  • 720 posts
  • Version:GM:Studio

Posted 27 March 2016 - 10:39 PM

Oh, oops.  I must have forgotten about the random number part.

 

if (random(1) + count * 0.05 > 0.5)

 

that translates into a probability for each possible value of count ranging from 0.1 (eight neighboring walls) to 0.9 (eight neighboring set floors).

 

Spoiler

  • 0

#16 Arison

Arison

    GMC Member

  • New Member
  • 10 posts
  • Version:GM:Studio

Posted 28 March 2016 - 12:51 AM

Oh, oops.  I must have forgotten about the random number part.

 

if (random(1) + count * 0.05 > 0.5)

 

that translates into a probability for each possible value of count ranging from 0.1 (eight neighboring walls) to 0.9 (eight neighboring set floors).

 

Spoiler

Which should, if I'm not mistaken, make it more likely to become a wall if there are more walls around it.


  • 0

#17 Arison

Arison

    GMC Member

  • New Member
  • 10 posts
  • Version:GM:Studio

Posted 28 March 2016 - 01:11 AM

It works. It actually works. Unfortunately, there's now a problem of it creating random invisible walls, or creating walls that look like floors. It might be a fun mechanic, but not one that I want. How do I get rid of that?

 

EDIT: Yeah, this is going to be a major problem if I cant fix it. Here is the whole script that the unset floor uses, and the wall and set floor have no actions at all.

var w = 32;
var h = 32;
var floor_set_count = 0;
var wall_count = 0;
for      (var c = -1; c < 2; c ++)
     for (var r = -1; r < 2; r += 1 + (c == 0))
     {
          floor_set_count += place_meeting(x + c * w, y + r * h, obj_floor_set);
          wall_count +=      place_meeting(x + c * w, y + r * h, obj_wall);
     }
var z = random(1);
if (z+(0.07*floor_set_count)-(0.03*wall_count)>0.5) {
    instance_change(obj_floor_set, true);
} else {
    instance_change(obj_wall, true);
}


Edited by Arison, 28 March 2016 - 01:22 AM.

  • 0

#18 flyingsaucerinvasion

flyingsaucerinvasion

    GMC Member

  • GMC Member
  • 720 posts
  • Version:GM:Studio

Posted 28 March 2016 - 03:12 AM

hmm... invisible floors?  Are you sure you're not accidentally stacking multiple objects on top of each other?  Otherwise I don't see anything else in the code you posted that could account for it.  It could be that your collision code is faulty. 

 

When I went out earlier, I realized half way across town that I got those probabilities backwards, and it has been bothering me the whole time!  Lol.


  • 0

#19 TheouAegis

TheouAegis

    GMC Member

  • GMC Member
  • 13885 posts
  • Version:GM:Studio

Posted 28 March 2016 - 03:20 AM

Wondering if you should add a mechanic into the algorithm that accounts for how many obj_floor_set+obj_floor_unset are around the player. If there are less than 2 obj_floor_set and obj_floor_unset (combined) adjacent to the player, then it should force obj_floor_set automatically, otherwise the player would be trapped or in a dead-end.


  • 0

"The problem with object-oriented languages is that they've got all this implicit environment that they carry around with them. You wanted a banana but what you've got is a gorilla holding the banana and the entire jungle." -Joe Armstrong

 

"It goes against the grain of modern education to teach children to program. What fun is there in making plans, acquiring discipline in organizing thoughts, devoting attention to detail and learning to be self-critical?" -Alan Perlis

 

"Do not think about where you want to be and how to get there; think about what you want to do and how to do it." -Theou Aegis


#20 Arison

Arison

    GMC Member

  • New Member
  • 10 posts
  • Version:GM:Studio

Posted 28 March 2016 - 05:39 AM

hmm... invisible floors?  Are you sure you're not accidentally stacking multiple objects on top of each other?  Otherwise I don't see anything else in the code you posted that could account for it.  It could be that your collision code is faulty. 

 

When I went out earlier, I realized half way across town that I got those probabilities backwards, and it has been bothering me the whole time!  Lol.

The collision code only checks to see if there is a wall in the way, and otherwise allows the movement. I'm thinking of just adding a little bug testing thing to the code that makes the walls and set floors draw their name on top of the object. It might help with the problem, but I just can't figure out what's going on.

 

Wondering if you should add a mechanic into the algorithm that accounts for how many obj_floor_set+obj_floor_unset are around the player. If there are less than 2 obj_floor_set and obj_floor_unset (combined) adjacent to the player, then it should force obj_floor_set automatically, otherwise the player would be trapped or in a dead-end.

I might add this, but it might not be worth it. I've changed the probabilities so the unset floors are more biased towards becoming floors and so that the seed points are more biased to becoming floors, and now I'm getting more mazey style generation which I was going for. I also know that it's not the seed points causing the problem because there are other points becoming invisible walls too.


  • 0

#21 TheouAegis

TheouAegis

    GMC Member

  • GMC Member
  • 13885 posts
  • Version:GM:Studio

Posted 29 March 2016 - 07:03 AM

Last time a guy had invisible walls, he was using a collision map. You're not using a collision map, are you?


  • 0

"The problem with object-oriented languages is that they've got all this implicit environment that they carry around with them. You wanted a banana but what you've got is a gorilla holding the banana and the entire jungle." -Joe Armstrong

 

"It goes against the grain of modern education to teach children to program. What fun is there in making plans, acquiring discipline in organizing thoughts, devoting attention to detail and learning to be self-critical?" -Alan Perlis

 

"Do not think about where you want to be and how to get there; think about what you want to do and how to do it." -Theou Aegis