How to link a projectile with attack
by Ryan Jones · in TGB Platformer Kit · 12/17/2008 (4:54 pm) · 4 replies
Using the shooter tutorial I have mapped keyboard z to shoot a projectile which works. The problem is I would like the character to shoot something at the end of the attack animation. Within PlayerMethods.cs I placed this bit of code as a test...
Within a new class called playerMissile.cs I have this code...
#1 I can't set attack and this to the same key. If I do then playerMissiles take priority and the animation doens't play.
#2 If I try to put %this.playerMissile.fire() anywhere else in the code whenever it does work it takes priority over and once again the animation doesn't play.
I'm baffled on this one, any help would be nice.
function PlayerClass::onLevelLoaded(%this, %scenegraph)
{ $pShip = %this;
$pShip.missileSpeed = 150;
moveMap.bindCmd(keyboard, "z", "$pShip.fireMissile();", "");
}
function PlayerClass::fireMissile(%this)
{ %this.playerMissile = new t2dStaticSprite()
{ scenegraph = %this.scenegraph;
class = PlayerMissile;
missileSpeed = %this.missileSpeed;
player = %this;
};
%this.playerMissile.fire();
}Within a new class called playerMissile.cs I have this code...
function PlayerMissile::fire(%this)
{ // Pick the image and set its size
%this.setImageMap(playerMissileImageMap);
%this.setSize(4.5, 3);
// Set the missile position to where the player is, plus
// a small offset so that the missile lines up with missile
// launcher in the player ship image
%this.setPositionX(%this.player.getPositionX() + 1);
%this.setPositionY(%this.player.getPositionY() + 1);
%this.setLinearVelocityX(%this.missileSpeed);
}#1 I can't set attack and this to the same key. If I do then playerMissiles take priority and the animation doens't play.
#2 If I try to put %this.playerMissile.fire() anywhere else in the code whenever it does work it takes priority over and once again the animation doesn't play.
I'm baffled on this one, any help would be nice.
About the author
Creator and project manager of Lightsire Entertainment. http://www.lightsire.com
#2
01/14/2009 (11:01 am)
Careful of my code, I need to make it less object specific, if you use the ActorBehavior with another object your main character will get screwey.
#3
01/15/2009 (11:59 am)
Nevermind, for some reason it stop being screwy.
#4
Why is it that when I find something that might be helpful, it doesn't apply? The ActorBehavior is not in the PSK anymore. It's in the "Legacy" folder!
07/18/2009 (9:24 am)
GRRRRRRR!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Why is it that when I find something that might be helpful, it doesn't apply? The ActorBehavior is not in the PSK anymore. It's in the "Legacy" folder!
Torque 3D Owner Ryan Jones
Lightsire Entertainment
Note that my playable character's name is Player.
First within the scene create an object that will be used as an attack (in this case I used a Contra 3 bullet). Resize it to how big you want it to and add any behaviors you want to it (you can do the behaviors also at the end since it's not required for firing). Place this object outside the view of the camera and give the object a name.
Within ActorBehavior first add an additional template near the top.
This is will make it so that you can easily clone a projectile that you already have setup with it's proper behaviors and everything. This object does not need any type of linear acceleration because that will be taken care of.
Modify the top of the following to this:
function ActorBehavior::attack(%this, %val) { /* if (%val == 0) { cancel(%this.fireSchedule); return; } if (!isObject(%this.projectile)) return; */ %projectile = %this.projectile.cloneWithBehaviors(); %projectile.setPositionX(Player.getPositionX() + Player.distance); %projectile.setPositionY(Player.getPositionY() + 4); %projectile.setLinearVelocityPolar(Player.control, 150); /* if (!isEventPending(%this.fireSchedule)) %this.fireSchedule = %this.schedule(%this.fireRate * 1000, "attack", 1); */X is how far left or right the object will spawn from the player. I made a variable called Player.distance which will be needed to determine the offest needed per direction the player is facing. Y is always 4 since I always want the shot to be that detrmined height.Player.control is a variable and will hold an angle that determines what angle the shot will fire, in this case 270 = left, 90 = right.
Within ActorAnimationBehavior add the following at the top.
function ActorAnimationBehavior::onAddToScene(%this, %scenegraph) { Player.control = 0; Player.distance = 0;These variables need to be defined an absolute value or else the engine seems to get confused how to assign them later. Now change the following below.function ActorAnimationBehavior::updateAnimation(%this) { // Grab the possible state eval("%targetState = " @ %this.CurrentState @ "State::execute(%this);"); // Set new state %this.setState(%targetState); // If we're dead or spawning, just return if (%this.CurrentState $= "die" || %this.CurrentState $= "spawn") return; // If there is a sound playing, make sure we update the volume %soundCue = %this.getSoundHandle(); if (getIsLooping(%soundCue)) %this.setHandleVolume(%soundCue); // Make sure we face in the correct direction if (!(isObject(%this.SlideAnim) && %this.CurrentState $= "slide")) { if (%this.Owner.Controller.Direction.X > 0 || %this.Owner.ActorBehavior.Climbing) [b] { %this.Owner.FlipX = false; Player.control = 90; Player.distance = 10; } else if (%this.Owner.Controller.Direction.X < 0) { %this.Owner.FlipX = true; Player.control = 270; Player.distance = -10; } [/b] } else { %moveSpeed = %this.Owner.ActorBehavior.MoveSpeed.X; %inheritedVelocity = %this.Owner.ActorBehavior.InheritedVelocity.X; %groundVelocity = %this.Owner.ActorBehavior.GroundObject.LinearVelocity.X; %this.Owner.FlipX = (%moveSpeed + %inheritedVelocity - %groundVelocity < 0); } }So when the object named Player (what the person is controlling) is facing right it sets Player.control = 90 to shoot right and offsets the shot over to the right a bit with Player.distance = 10. Adversely if the player is facing left it sets Player.control = 270 to shoot left and offsets the shot over to the left a bit with Player.distance = -10.It has to be here so it will update the values in real time. So reload the project and under ActorBehaviors you'll now have a section called Projectile with a drop down box. Just select your Projectile you wish to use.
Now you have a bullet firing from a gun. If you want to do melee attacks you would have to hard code in some world limits for the shot so a punch would more so be short ranged invisible bullet. I haven't tried yet but I assume the code is someting similar to what is used the Shooter tutorial.
My code was done so that when you push attack one bullet comes out. I've commented out the lines needed if you want to just hold down the attack button and for it to fire consistently.