Game Development Community

Graphic Layers change with Collision?

by Brian A. · in Torque Game Builder · 03/16/2005 (12:10 pm) · 14 replies

I think i am having problems with graphic layers in my program.

I created a basic "Star Scroller" function, player and enemy sprites. The Stars scroll and both the player and enemy work with no problem. However, as soon as I set up collision functions my Star Scroller images hides my player and enemy. I am not sure if it is something with my Star Scroller or Collision function. I have tried changing the order of the "Call Function" settings, but it still does not work. Any ideas on why the order changes as soon as I include a collision function? Thanks for your help!

(see code below)

#1
03/16/2005 (12:12 pm)
//Load datablock
exec("./datablocks.cs");

// Call Functions
CreateNebula();
CreateStarScroll();
CreatePlayer();
CreateEnemy();
}

// ************************************************************************

// ---------------------------------------------------------------------
// Player Section
// ---------------------------------------------------------------------

function CreatePlayer()
{
// Create the player's ship sprite
$playerShip = new fxAnimatedSprite2D() { scenegraph = t2dSceneGraph; };
$playerShip.setPosition("-35 0");
$playerShip.setSize( "5 4" );
$playerShip.playAnimation(PlayerForward);
$playerShip.fireLinkPoint = $playerShip.addLinkPoint( "0 -0.5" );
$playerShip.setWorldLimit( clamp, "-49 -37 49 37" );
attachThruster( $playerShip, "-0 .3", 0 );

// Set player's collision info:
$playerShip.setGroup( 1 );
$playerShip.setLayer( 1 );
$playerShip.setCollisionActive( true, false );
$playerShip.setCollisionMaterial( standardMaterial );
$playerShip.setCollisionPolyCustom( 4, "-1 0 -0.1 -0.6 0.98 0.15 -0.1 0.7" );
$playerShip.setCollisionMasks( BIT(2), BIT(2) );
$playerShip.setCollisionCallback( true );

// Create a new action map.
new ActionMap(playerMap);

// Bind keys to actions.
playerMap.bindCmd(keyboard, "w", "playerUp();", "playerUpStop();");
playerMap.bindCmd(keyboard, "s", "playerDown();", "playerDownStop();");
playerMap.bindCmd(keyboard, "a", "playerLeft();", "playerLeftStop();");
playerMap.bindCmd(keyboard, "d", "playerRight();", "playerRightStop();");
playerMap.bindCmd(keyboard, "space", "playerFire();", "");

// Activate the action map.
playerMap.push();
}
function playerUp()
 {    
 // Set the player moving up.    
 $playerShip.setLinearVelocityY( -30 );
 $playerShip.setSize( "4 3" ); 
 } 
 
 function playerUpStop()
{
// If we're moving up then nullify any upward movement.
if ( $playerShip.getLinearVelocityY() < 0 )
$playerShip.setLinearVelocityY( 0 );
$playerShip.playAnimation(PlayerForward);
$playerShip.setSize( "5 4" );
}

function playerDown()
{
// Set the player moving down.
$playerShip.setLinearVelocityY( 30 );
$playerShip.setSize( "6 5" );
}

function playerDownStop()
{
// If we're moving down then nullify any downward movement.
if ( $playerShip.getLinearVelocityY() > 0 )
$playerShip.setLinearVelocityY( 0 );
$playerShip.playAnimation(PlayerForward);
$playerShip.setSize( "5 4" );
}

function playerLeft()
{
// Set the player moving left.
$playerShip.setLinearVelocityX( -30 );
$playerShip.playAnimation(playerTrunLeft);
}

function playerLeftStop()
{
// If we're moving left then nullify any leftward movement.
if ( $playerShip.getLinearVelocityX() < 0 )
$playerShip.setLinearVelocityX( 0 );
$playerShip.playAnimation(PlayerForward);
}

function playerRight()
{
// Set the player moving right.
$playerShip.setLinearVelocityX( 30 );
$playerShip.playAnimation(playerTurnRight);
}

function playerRightStop()
{
// If we're moving right then nullify any rightward movement.
if ( $playerShip.getLinearVelocityX() > 0 )
$playerShip.setLinearVelocityX( 0 );
$playerShip.playAnimation(PlayerForward);
}

function playerFire()
{
// Create player projectile.
%projectile = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
%projectile.setPosition( $playerShip.getLinkPoint($playerShip.fireLinkPoint) );
%projectile.setSize( ".4 2.8" );
%projectile.setImageMap( playerMissileImageMap );
%projectile.setWorldLimit( kill, "-52 -40 52 40" );
%projectile.setLinearVelocityY( -45 );
//attachFloom( %projectile, "-1 .1", 0);

// Setup collision info
%projectile.setGroup( 1 );
%projectile.setLayer( 2 );
%projectile.setCollisionActive(true, true);
%projectile.setCollisionMaterial(projectileMaterial);
%projectile.setCollisionScale("0.9 0.5");
%projectile.setCollisionMasks( BIT(2), BIT(2));
%projectile.setCollisionCallback( true );

}
#2
03/16/2005 (12:13 pm)
function attachThruster(%mountObj, %mountPosition, %angle)
{
// Create Player Thruster.
%thruster = new fxParticleEffect2D() { scenegraph = t2dSceneGraph; };
%thruster.loadEffect("~/client/effects/miniThruster.eff");
%thruster.mount( %mountObj, %mountPosition, 0, false );
%angle = -90;
%thruster.setSize( "0 1" );
%thruster.setRotation( %angle );
%thruster.playEffect();
}

// ---------------------------------------------------------------------
// Enemy Section
// ---------------------------------------------------------------------

function CreateEnemy()
{
// Create an enemy ship
%enemySpider = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
%enemySpider.setSize ("7 7");
%enemySpider.setPosition((-40 + (getRandom() * 60) SPC "-30"));
%enemySpider.setImageMap (enemySpiderImageMap);
attachThruster( %enemySpider, "0 -1.2", 180 );


// Set enemy collision info
%enemySpider.setGroup( 2 );
%enemySpider.setLayer( 2 );
%enemySpider.setCollisionActive( true, true );
%enemySpider.setCollisionMaterial( standardMaterial );
%enemySpider.setCollisionPolyCustom( 5, "-0.9 0 0 -0.6 1 -0.3 1 0.3 0 0.5" );
%enemySpider.setCollisionMasks( BIT(1), BIT(1) );
%enemySpider.setCollisionCallback( true );

//move the enemy towards us
%enemySpider.setLinearVelocityY(13);
%enemySpider.setWorldLimit( kill, "-60 -40 60 40" );

// Create and enemy missle and fire it
%enemyFire = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
%enemyFire.setPosition( %enemySpider.getPosition() );
%enemyFire.setSize( ".4 2.8" );
%enemyFire.setImageMap( playerMissileImageMap );
%enemyFire.setLinearVelocityY( 35 );
%enemyFire.setWorldLimit( kill, "-60 -40 60 40" );

// Set up collision info
%enemyFire.setGroup( 2 );
%enemyFire.setLayer( 2 );
%enemyFire.setCollisionActive( true, true );
%enemyFire.setCollisionMaterial( standardMaterial );
%enemyFire.setCollisionScale("0.9 0.5");
%enemyFire.setCollisionMasks( BIT(1), BIT(1) );
%enemyFire.setCollisionCallback( true );

schedule(2000, 0, "CreateEnemy");
}

// Kill Player
function KillPlayer()
{
$playerShip.setVisible( false );
playerMap.pop();
schedule(2000, 0, "ResetPlayer");
echo("*** Player Killed");
}

function ResetPlayer()
{
$playerShip.setPosition("-35 0");
$playerShip.setVisible(true);
playerMap.push();
}

// Kill Enemy
function killEnemy()
{
echo("*** Enemy Killed");
}

function fxSceneObject2D::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts )
{
if (%srcObj == $playerShip)
{
KillPlayer();
%dstObj.safeDelete();
}
else if (%dstObj == $playerShip)
{
KillPlayer();
%srcObj.safeDelete();
}
else
{
killEnemy();
%srcObj.safeDelete();
%dstObj.safeDelete();
}
}

// ---------------------------------------------------------------------
// Star Scroll Section
// ---------------------------------------------------------------------


function CreateStarScroll()
{
// Create Main        
%StarScroll = new fxScroller2D() { scenegraph = t2dSceneGraph; };
%StarScroll.setImageMap( StarScrollImageMap );
%StarScroll.setSize("100 200");
%StarScroll.setRepeat ("1 1");
%StarScroll.setScroll( "0 -4" );
Echo("*** StarScroll ***");

// Stars A
%StarScrollA = new fxScroller2D() { scenegraph = t2dSceneGraph; };
%StarScrollA.setImageMap( StarScrollImageMapA );
%StarScrollA.setSize("100 200");
%StarScrollA.setRepeat ("1 1");
%StarScrollA.setScroll( "0 -8" );
Echo("*** StarScroll A ***");

// Stars B
%StarScrollA = new fxScroller2D() { scenegraph = t2dSceneGraph; };
%StarScrollA.setImageMap( StarScrollImageMapB );
%StarScrollA.setSize("100 200");
%StarScrollA.setRepeat ("1 1");
%StarScrollA.setScroll( "0 -5" );
Echo("*** StarScroll B***");
}
#3
03/16/2005 (12:19 pm)
First thing I notice is that your players fire is i group 1 layer 2. You have it so that enemyspiders can only collide with things in group1, layer1. So might want to change that to BIT(1), BIT(1)|BIT(2). I dont think that could make things invisible though.
#4
03/16/2005 (12:37 pm)
I just changed this, however the player and enemy are still behind the star scroll.

Any other ideas?
#5
03/16/2005 (12:45 pm)
Have you tried
%StarScrollA.setLayer ( 0 );

That is, assuming if layer 0 is valid (which I have no idea if it is or not).

If that dosen't work, you could try moving the player to Layer 2, the enemy to Layer 3, and have the stars as Layer 1. =P

Just a thought.

EDIT: spelling
#6
03/16/2005 (1:16 pm)
I'm pretty sure the layer draw order is low->high. So if the stars are on layer 0 (the default), they'll get drawn in front of everything else. Try setting the stars' layer to something relatively high like 20 and see if that makes a difference.
#7
03/16/2005 (2:20 pm)
Makes sense. I just tested my theory by disabling collisions on the player in the shooterdemo and changing it's layer to 0, but it rendered over everything else instead of behind.
#8
03/16/2005 (7:27 pm)
Cool it worked... well, sort of. When I changed the setLayer nothing really happened. However, when I changed the setGroup it seemed to work. Does this make any sence? Another strange thing is if I set ANY setLayer to 2 or above it displays the image under the StarScroll image (ie playerShip, Projectile, EnemySpider ect.) It seems like it should work the other way around?!?


Here is what I changed to make it work:

// Set player's collision info:
$playerShip.setGroup( 10 );
$playerShip.setLayer( 1 );

// Setup collision info
%projectile.setGroup( 10 );
%projectile.setLayer( 1 );

%enemySpider.setGroup( 20 );
%enemySpider.setLayer( 1 );

%enemyFire.setGroup( 20 );
%enemyFire.setLayer( 1 );

%StarScroll.setGroup (1);
%StarScroll.setLayer (1);

%StarScrollA.setGroup (1);
%StarScrollA.setLayer (1);

%StarScrollB.setGroup (1);
%StarScrollB.setLayer (1);
#9
03/17/2005 (12:18 am)
Brian,

Layer 0 = Front
Layer 31 = Back.

If you create objects in the same layer, the default is to place newer objects in-front of older objects but you can change this behaviour using "fxSceneGraph2D::initialise()" (lastInFrontSorted? option).

- Melv.
#10
03/17/2005 (8:47 pm)
On the same note: is it possible to force a sprite from say layer 5 to draw in front of a sprite on layer 4?
#11
03/18/2005 (12:13 am)
The sub-layer ordering can be controlled with the following functions...

setLayerDrawOrder()
setSceneDrawOrder()

You cannot currently specify the sub-layer order for one object relative to another though. You can move the object to the front/back/forward/backwards clamped within a layer or across the whole scene (all layers).

- Melv.
#12
03/18/2005 (12:25 am)
I'm not quite understand that last one melv. If you can help me that would be great.

Basically I want to create a 2d adventure game. the player needs to be able to walk around back of a bush or in front of the bush depending on how far north or south he walks.

To do this in something like game maker you would set the back ground layers to different numbers(usually really large numbers) and then change the players current layer up and down depending on which direction that yoiu are moving. That would give it the effect of being behind it or in front of it.

Am I understanding correctly that you cannot due that in 2td? I mean change the players layer on the fly?
#13
03/18/2005 (4:12 am)
@Charlie: That's the exact idea I'm trying for.
I assume we can %obj.setLayer() on the fly. That's what I was planning on doing but haven't had a chance to check it out (stinkin' school).
#14
03/18/2005 (4:55 am)
You can change ALL T2D properties on the fly. That's one of the great things about it.

Use "setLayer()" as much as you want, there is no performance impact for changing 90% of the core T2D properties.

- Melv.