Game Development Community

Having problems with collisions

by Dave "Jellybit" Freeman · in Torque Game Builder · 04/11/2005 (2:08 am) · 22 replies

Ok. First of all, I'm attempting to make a pacman clone, to help myself understand how this engine works. I know nothing of programming (though I can make a mean Commodore 64 text adventure). I went through the shooter demo tutorial. I hit a few snags. Some from the way the tutorial was written, some my fault. But I got through it, and understood each line.

So I started off by going through Matt Langley's physics tutorial. I don't need physics for pacman, so I skipped a few parts of the datablock creation in that. I didn't turn on physics, and I didn't set physics-specific settings. Anyway... I'll show you what I've come up with.


This is my immovable solid wall, awaiting Pac's gentle touch:
%wall = new fxStaticSprite2D () { scenegraph = t2dSceneGraph;};
	%wall.setPosition ("108 -245");
	%wall.setSize ("18 50");
	%wall.setImageMap (wall);
	%wall.setGroup( 1 );
	%wall.setLayer( 1 );
	%wall.setCollisionMasks( BIT(1), BIT(1) );
	%wall.setCollisionActive (false, true);
	%wall.setCollisionCallback( true );
	%wall.setImmovable();

And this is my player:
$player = new fxStaticSprite2D () { scenegraph = t2dSceneGraph;};
	$player.setPosition ("0 0");
	$player.setSize ("46 48");
	$player.setImageMap (player);
	
	// Set player's collision info:
	$player.setGroup( 1 );
	$player.setLayer( 1 );
	$player.setCollisionActive (true, true);
	$player.setCollisionMaterial( standardMaterial );
	$player.setCollisionMasks( BIT(1), BIT(1) );
	$player.setDebugOn( BIT(5) );
	$player.setCollisionCallback( true );

Now, let me say that I've tried with and without the layers and bits, hoping that it'd default to assuming everything was on the same layer unless told otherwise. I also tried specifying the material, and ignoring it. Always has the same effect. Here's what I have set up to happen when the objects collide:
function fxSceneObject2D::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts )
{
	if(%dstObj.type $= wall)
	{
		%srcObj.setAtRest();
	}
}

And I've tried simplifying it down to this:
function fxSceneObject2D::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts )
{
	$player.setAtRest();
}

What happens is, the object passes right through the wall. Pacman has become the ghost :(, exactly what he hates the most in life. It's unfair to him, and I'd like to correct this. Can anyone help? Ah, also, there's not a single error in the console.log. Silly, huh.
Page «Previous 1 2
#1
04/11/2005 (2:43 am)
Shouldn't it be:

if(%dstObj.type $= "wall")
And you'll have to forgive me if I've got this wrong, as I'm not really a coder, but you're not actually setting %dstObj.type.

In your wall definition, you'll want something like:
%wall.type="wall";
Personally, when creating sprites and objects, I use:
%objectname.tag = "nameofthing";

Then I can use %srcObj.tag and %dstObj.tag to figure out what has collided with what. Your .type value should provide you with exactly the same functionality if you set it up.
#2
04/11/2005 (6:11 am)
Philip pretty much has it nailed for you :)
#3
04/11/2005 (10:31 am)
Thank you, Philip. But I also tried simplifying it down to:

function fxSceneObject2D::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts )
{
   $player.setAtRest();
}

So in that case, object type and name doesn't matter. But, I will definitely try what you said immediately. Thank you!
#4
04/11/2005 (10:49 am)
You could do

function fxSceneObject2D::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts )
{	
	if(%srcObj.tag $= "player")
   {
		if(%dstObj.type $= "wall")
		{
			%srcObj.setAtRest();
		}
	} elseif(%dstObj.tag $= "player")
	{
		if(%srcObj.type $= "wall")
		{
			%dstObj.setAtRest();
		}
	}
     
}

or if you don't want to use tags
function fxSceneObject2D::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts )
{    
	if(%srcObj == $player)
   {
		if(%dstObj.type $= "wall")
		{
			%srcObj.setAtRest();
		}
	} elseif(%dstObj == $player)
	{
		if(%srcObj.type $= "wall")
		{
			%dstObj.setAtRest();
		}
	}
     
     
}
#5
04/11/2005 (10:50 am)
That way it should trigger if either src or dst is player
#6
04/11/2005 (11:01 am)
Matt, I tried the second bit of code you posted. Still no go. If I don't give a layer or BIT number, it should all default on the same layer, right?

Like I said though, I dumbed it down to:

function fxSceneObject2D::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts )
{
   $player.setAtRest();
}

So, I do thank you for the new code you posted, but it's overkill for now. I'm just trying to make it collide. At this time, I don't care what the object is that's colliding, and which is getting colided with. I just want the player to stop when ANY collision happens (just to make sure I'm on the right track). So I dumbed it down to the above code, and it STILL doesn't work. I did try your code, but it of course didn't work (since the dumbed down version didn't even work). I'm still trying to track down what the problem could be...

Thanks again.
#7
04/11/2005 (11:03 am)
Sorry just tweaked the code a bit for efficiency, try the new code ( if you want to :)

if you don't give a layer or BIT number in the setMasks ? it will default to layer 0 I think
#8
04/11/2005 (11:06 am)
Hmmm... lets try something lol... I don't give up easy

set your wall up like this

%wall = new fxStaticSprite2D () { scenegraph = t2dSceneGraph;};
   %wall.setPosition ("108 -245");
   %wall.setSize ("18 50");
   %wall.setImageMap (wall);
   %wall.setCollisionActive (false, true);
   %wall.setImmovable();

player coming up here...
#9
04/11/2005 (11:07 am)
Set your player up like this

$player = new fxStaticSprite2D () { scenegraph = t2dSceneGraph;};
   $player.setPosition ("0 0");
   $player.setSize ("46 48");
   $player.setImageMap (player);
   
   // Set player's collision info:
   $player.setCollisionActive (true, true);
   $player.setCollisionMaterial( standardMaterial );
   $player.setCollisionMasks( BIT(0), BIT(0) );
   $player.setDebugOn( BIT(5) );
   $player.setCollisionCallback( true );
#10
04/11/2005 (11:08 am)
It should default to 0 if not specified... you also don't need a callback on your wall... that way you can always just just the %srcObj for collision
#11
04/11/2005 (11:08 am)
Heh, Using Matt's code, I just got this in the console.log:
>>> Advanced script error report.  Line 323.
>>> Some error context, with ## on sides of error halt:
function fxSceneObject2D::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %no rmal,## ##%contactCount, %contacts ) {      if((%srcObj == $player) || (%dstObj == $player))
>>> Error report complete.

I don't even HAVE a line 323. It goes up to 220. I never knew what "with # # on sides of error halt" meant either.

EDIT: Scratch that. I forgot to fix the carriage return on the pasted code. Now it gives no error message, but doesn't work. Just like last night :)
#12
04/11/2005 (11:09 am)
Add

%wall.tag = "wall";

to your wall also
#13
04/11/2005 (11:10 am)
Ooops, forgot to warn you, when pasting code from these boards it screws up when things are sent down because of length

so ensure you backspace it back to a proper function
#14
04/11/2005 (11:11 am)
Like this

function fxSceneObject2D::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts )

basically becomes this

function fxSceneObject2D::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %

normal, %contactCount, %contacts )

so simply go in front of "normal" and back space it together with the function :)
#15
04/11/2005 (11:16 am)
Yes, I found out that the carriage return was added there. And yes, I had that %wall.tag line in all of my walls. Thank you. For an update on my code, here's what I have (I changed a few things, trying to get it to work):

Wall:
%wall = new fxStaticSprite2D () { scenegraph = t2dSceneGraph;};
	%wall.setPosition ("108 -245");
	%wall.setSize ("18 50");
	%wall.setImageMap (wall);
	%wall.type="wall";
	%wall.setCollisionMaterial( standardMaterial );
	%wall.setCollisionActive (false, true);
	%wall.setImmovable();

Player:
$player = new fxStaticSprite2D () { scenegraph = t2dSceneGraph;};
	$player.setPosition ("0 0");
	$player.setSize ("46 48");
	$player.setImageMap (player);
	
	// Set player's collision info:
	// $player.setGroup( 1 );
	// $player.setLayer( 1 );
	$player.setCollisionActive (true, true);
	$player.setCollisionMaterial( standardMaterial );
	// $player.setCollisionMasks( BIT(1), BIT(1) );
	$player.setDebugOn( BIT(5) );
	$player.setCollisionCallback( true );

And collision:
function fxSceneObject2D::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts )
{
     if((%srcObj == $player) || (%dstObj == $player))
     {
            if((%srcObj.type $= "wall") || (%dstObj.type $= "wall"))
            {
                  %srcObj.setAtRest();
                  %dstObj.setAtRest();
            }
     }
}

Again, no error in the console.log. Only refusal to collide.
#16
04/11/2005 (11:21 am)
Need to set player

// $player.setCollisionMasks( BIT(1), BIT(1) );
to

$player.setCollisionMasks( BIT(0), BIT(0) );
#17
04/11/2005 (11:22 am)
I just tested

%wall = new fxStaticSprite2D () { scenegraph = t2dSceneGraph;};
   %wall.setPosition ("108 -245");
   %wall.setSize ("18 50");
   %wall.setImageMap (wall);
   %wall.setCollisionActive (false, true);
   %wall.setImmovable();
   %wall.tag = "wall";

$player = new fxStaticSprite2D () { scenegraph = t2dSceneGraph;};
   $player.setPosition ("0 0");
   $player.setSize ("46 48");
   $player.setImageMap (player);
   
   // Set player's collision info:
   $player.setCollisionActive (true, true);
   $player.setCollisionMaterial( standardMaterial );
   $player.setCollisionMasks( BIT(0), BIT(0) );
   $player.setDebugOn( BIT(5) );
   $player.setCollisionCallback( true );



function fxSceneObject2D::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %no
rmal, %contactCount, %contacts )
{    
   if(%srcObj == $player)
   {
      if(%dstObj.tag $= "wall")
      {
         echo("player at rest");
         %srcObj.setAtRest();
      }
   }      
     
}
and the echo comes up
#18
04/11/2005 (11:23 am)
Sorry for the confusion... I meant if you didnt set a layer it defaults to 0
#19
04/11/2005 (11:25 am)
@Matt
WOO!!! Changing the bits to 0 worked! Collision SO happened. Pacman thanks you, and so do I.
#20
04/11/2005 (11:27 am)
Woo!! glad it works! Lol sorry for the confusion, think you always need to set collisionMasks... though dont always have to set layers or groups :)
Page «Previous 1 2