First Actor and Second Actor Blocks

After much time and doubt I think I finally figured out an use of these blocks but I need to know if It would work. Basically when two actors of the same type collide I want them to merge into a bigger actor. To do this I was thinking about using the first actor second actor blocks. And just have the first actor in the collision create the actor. However it needs to be consistent so that both are registering themselves as the first actor? So basically the actors can't say the same thing which is I'm the first actor your the second actor. Will this work?

Alexin

  • *
  • Posts: 3130
I don't follow you.
"Find the fun"
alexin@stencyl.com

Alexin

  • *
  • Posts: 3130
I don't know either but there's a simple solution. Use a boolean attribute that both actors can set to true. The first one to do so will basically tell the other he's second, because the flag will already be to true by the first one.

It's a race condition - the first one to get there wins.
"Find the fun"
alexin@stencyl.com

RandomJibberish

  • Posts: 82
How does the whole first actor second actor thing work anyway? It doesn't make much sense to me, since there isn't a "first" object to collide when two objects collide with each other :/

Greg

  • *
  • Posts: 1260
The first and second actor of the collision don't refer to the order in which the collision happened.  They are just ways to get the 2 actors that were involved in the collision event.  Think of them as Actor attributes that are set when two actors collide. 

Joe

  • *
  • Posts: 2480
Yeah, as Greg said, the order is arbitrary. The only use case I can think of for using the first and second blocks is if you want to create your own collision response using, for instance, the collision normal.

HNF

  • Posts: 232
My guess is that when Box2D goes through each step checking for collisions, it will read the earlier created actor as being in a collision and mark that as the first actor. More recent created actors will be the second actor.

Epic428

  • Posts: 1118
Actually to the best of my knowledge, the first/second actors represent who initiated the collision and who it collided with, however, they are not always the same.

For example: I have a block sitting on the ground, I drop a block on top of that one, First and Second Actor could be either one of those two actors. It is not always guaranteed that the one falling will be the first, or the one on the ground will be the first.

I realized this because when I made my first Flash Game, I used Box2D. And because the game was a Match 3 type game, I needed to figure out which actor collided first and which one collided second, then I needed to set variables depending on the results provided.

Here is a sample of my BeginContact function in the Custom Contact Listener class I created to get this information.

Code: [Select]
override public function BeginContact(contact:b2Contact):void
{
// getting the fixtures that collided
setFixtures(contact);
setVelocity();

if ( (fixtureA.GetUserData() == "wood" && objectB is MarbleActor) ||
(fixtureB.GetUserData() == "wood" && objectA is MarbleActor) )
{
if ( CheckVelocity(true, false) )
{
var highestV : Number = getHighestVel()

Sounds.PlayWoodHit( highestV );
}
}

if ( objectA is MarbleActor && objectB is MarbleActor)
{
var marbleA:MarbleActor = objectA;
var marbleB:MarbleActor = objectB;

if ( CheckVelocity(true, true) )
{
var highestV : Number = getHighestVel()

Sounds.PlayMarbleClick( highestV );
}

if (marbleA._marbleType < 8 && marbleB._marbleType < 8)
{
if (marbleB._marbleType == marbleA._marbleType && marbleA.group[0] != marbleB.group[0])
{
marbleA.contacts.push(marbleB);
marbleB.contacts.push(marbleA);

marbleA.group = marbleA.group.concat(marbleB.group);

marbleA.shareGroup();

if (marbleA.group.length >= MIN_GROUP_SIZE)
{
StatScreen.addMatchStat(marbleA);

for (var i = 0; i < marbleA.group.length; i++)
{
marbleA.group[i].removeMe = true;
}
}
}
}
else if (marbleA._marbleType == 8 && marbleB._marbleType != 8 ||
marbleB._marbleType == 8 && marbleA._marbleType != 8 )
{
var rand:int = int(Math.random() * 100);
var min: int = Math.ceil(100 - LevelData.LEVEL + 1);
var max: int = Math.ceil(0 + LevelData.LEVEL - 1);

if (rand <= max || rand >= min)
{
(marbleA._marbleType != 8) ? marbleA.blackBall = true : marbleB.blackBall = true
}
}
}

if ( ((objectA is MarbleActor && objectB is PegActor) ||
  (objectB is MarbleActor && objectA is PegActor)) )
{
var peg:PegActor;
var marble:MarbleActor;

peg = (objectA is PegActor) ? objectA : objectB;
marble = (objectA is MarbleActor) ? objectA : objectB;

if (peg.pegType == marble._marbleType)
{
peg.pegIsHit = true;
}
}
super.BeginContact(contact);
}

Edit: just to show a live example, Take a look at this section in particular :
Code: [Select]
if ( ((objectA is MarbleActor && objectB is PegActor) ||
(objectB is MarbleActor && objectA is PegActor)) )

My Peg Actors were stationary objects. the Marbles were free moving objects. I had to check both possible scenarios otherwise the code might not run at least half the time.

« Last Edit: April 27, 2011, 07:19:09 pm by Epic428 »
James Moore - Official Support & Documentation.
We cannot and will not respond to PM's asking questions. Please make a new thread in the forums if you have any questions, Thank you.
For better support and faster response times, please post your logs regarding any Stencyl related issues. Debug > Logs > Generate Logs

Alexin

  • *
  • Posts: 3130
I should have said form the start that first and second actor are only nomenclatures.

Create a boolean that both actor can access. It can probably be a Game Attribute. When there's a collision, one of the actors sets the attribute to true only, and only if, its value is false - he'll know he's the "first actor". Likewise, an actor that tries to set the value and verifies its value is true will know he's the "second actor".
After the order has been determined and the attribute is no longer necessary, reset it to false for the next collision.
"Find the fun"
alexin@stencyl.com

Alexin

  • *
  • Posts: 3130
Not tested but it should work.
"Find the fun"
alexin@stencyl.com