torque中文教程--武器伤害
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
教程:武器伤害
Tutorial: Weapons Damage
作者:吴波
Author:Wu Bo
描述:在射击游戏中,当玩家和机器人被子弹击中时会产生“掉血”等伤害,这个教程将告诉这一功能是如何实现的。
同时我们也将了解到如何计算伤害范围,也就是说当玩家没有被直接击中时,也会被火箭筒的爆炸所伤害。
Description:This tutorial demonstrates how to apply weapons damage to both players and bots when a weapon's projectile collides with them. We'll also cover how to calculate "radius damage", which will allow an exploding projectile like a rocket or a missile to damage a player even though it doesn't make direct contact.
注意:这个教程是一个高级合成教程,不仅需要“Tutorial Base”的工作路径,还需要其他已经做好的教程作为前期工作,本教程需要预先完成“武器”和“AI巡逻”这两个教程,并把两个教程合并在一个任务编辑器中。
Note: This tutorial is an advanced composite tutorial, which not only requires
the “Tutorial Base” application as its starting place, but also requires the addition of one or more other tutorials to build up from. This particular tutorial requires the addition of the “Weapons”and“ Bot Path-Finding” tutorials to be completed properly.
1.在你开始前,还是要先备份工作文件夹("example"下的"tutorial.base"目录)以防文件损坏。
Before you start, make a back-up copy of your "tutorial.base" directory, which is located in the "example" directory of your Torque install (i.e. C:\Torque\SDK\example). This way you can start over fresh if something goes wrong.
2.合并“武器”和“AI巡逻”两个教程,合并完成后的教程应该是玩家已经配备了武器,并且在任务编辑器中有个BOT在沿着指定的路径奔跑。
Combine the "Weapons" and "Bot Path-Finding" tutorials together. Once you've completed combining these two tutorials together you should have a Torque demo where the player is armed with a rocket launcher and a single Bot is running around in a circle. When that's done, return to this tutorial.
3.复制素材文件夹下的"radiusDamage.cs"和"shapeBase.cs"到"tutorial.base/server"目录下。
Copy the "radiusDamage.cs" and "shapeBase.cs" scripts to your "tutorial.base/server" directory.
注意:这两个脚本文件是从"starter.fps"示例游戏中拷贝出来的,去除了不必要的代码。
These two script files were taken from the "starter.fps" example that ships with the Torque engine. To avoid confusion, these scripts may have been modified slightly to remove any unneeded code.
4.打开"tutorial.base/server"下的"game.cs",在onServerCreated()功能区下加入以下语句:
exec("./radiusDamage.cs");
exec("./shapeBase.cs");
你应该看到很多条exec()语句,把这两行放在最后一行就可以了。
Open the "game.cs" script file located in the "tutorial.base/server" directory and add the following line of script to the onServerCreated() function.
exec("./radiusDamage.cs");
exec("./shapeBase.cs");
You should see several other calls to the exec() function there as well. Just add yours to the end of the list. This will simply cause our scripts to get loaded when the game's server starts up.
5.从“素材”文件夹中,复制动画文件"player_dieknees.dsq"到
"\tutorial.base\data\shapes\player"目录下。
Copy the "player_dieknees.dsq" animation file to your
"\tutorial.base\data\shapes\player" directory.
6.打开"\tutorial.base\data\shapes\player" 目录下的"player.cs"脚本文件,在TSShapeConstructor数据块中增加一行语句:
datablock TSShapeConstructor(PlayerDts)
{
baseShape = "./player.dts";
sequence0 = "./player_root.dsq root";
sequence1 = "./player_forward.dsq run";
sequence2 = "./player_back.dsq back";
sequence3 = "./player_side.dsq side";
sequence4 = "./player_fall.dsq fall";
sequence5 = "./player_land.dsq land";
sequence6 = "./player_jump.dsq jump";
sequence7 = "./player_standjump.dsq standjump";
sequence8 = "./player_lookde.dsq look";
sequence9 = "./player_head.dsq head";
sequence10 = "./player_headside.dsq headside";
sequence11 = "./player_celwave.dsq celwave";
sequence12 = "./player_dieknees.dsq die";
};
这个语句将给我们的玩家和机器人造型赋予一个死亡的动画。
这是"player.cs"的最后修改,存盘,我们继续往下做。
Open the "player.cs" script file located in the "\tutorial.base\data\shapes\player" directory and add the following highlighted line of script to the TSShapeConstructor datablock.
datablock TSShapeConstructor(PlayerDts)
{
baseShape = "./player.dts";
sequence0 = "./player_root.dsq root";
sequence1 = "./player_forward.dsq run";
sequence2 = "./player_back.dsq back";
sequence3 = "./player_side.dsq side";
sequence4 = "./player_fall.dsq fall";
sequence5 = "./player_land.dsq land";
sequence6 = "./player_jump.dsq jump";
sequence7 = "./player_standjump.dsq standjump";
sequence8 = "./player_lookde.dsq look";
sequence9 = "./player_head.dsq head";
sequence10 = "./player_headside.dsq headside";
sequence11 = "./player_celwave.dsq celwave";
sequence12 = "./player_dieknees.dsq die";
};
This will give our player model a new death animation to play when we finish
him off with a rocket.
This is the last change to "player.cs". Go ahead and save the file and close it.
7.打开"tutorial.base/server"目录下的"player.cs"脚本文件,将:
datablock TSShapeConstructor(PlayerDts)
{
baseShape = "~/data/shapes/player/player.dts";
sequence0 = "~/data/shapes/player/player_root.dsq root";
sequence1 = "~/data/shapes/player/player_forward.dsq run";
sequence2 = "~/data/shapes/player/player_back.dsq back";
sequence3 = "~/data/shapes/player/player_side.dsq side";
sequence4 = "~/data/shapes/player/player_fall.dsq fall";
sequence5 = "~/data/shapes/player/player_land.dsq land";
sequence6 = "~/data/shapes/player/player_jump.dsq jump";
sequence7 = "~/data/shapes/player/player_standjump.dsq standjump"; sequence8 = "~/data/shapes/player/player_lookde.dsq look";
sequence9 = "~/data/shapes/player/player_head.dsq head";
sequence10 = "~/data/shapes/player/player_headside.dsq headside"; sequence11 = "~/data/shapes/player/player_celwave.dsq celwave"; };
替换成:
exec("~/data/shapes/player/player.cs");
在PlayerBody 数据块中,于
shapeFile = "~/data/shapes/player/player.dts";
句前加入标记成黄色的语句:
datablock PlayerData(PlayerBody)
{
className = Armor;
...
将Armor设定为className的变量,目的是使所有的游戏者和机器人均被Armor名空间功能所定义。
接下来的几步将修改"player.cs"脚本,因此一直保持该文件打开状态,直至我们全部修改完。
Open the "player.cs" script file located in the "tutorial.base/server" directory and add the following line of script to the PlayerShape datablock. Please note that this file is not the same file as above in step 6. They have the same name but contain different code.
datablock PlayerData(PlayerBody)
{
className = Armor;
...
Setting the className variable to Armor will cause all players and bots to inherit all functions defined by the Armor name space.
The next several steps will be modifying the "player.cs" script so just keep that file open for a bit until we're done.
8.接下来,在"player.cs"脚本文件底部增加这个功能区:
function Player::playDeathAnimation( %this )
{
%this.setActionThread( "die" );
}
这样就为游戏者和BOT增加了死亡时的动画。
Next, add this function to the bottom of the "player.cs" script.
function Player::playDeathAnimation( %this )
{
%this.setActionThread( "die" );
}
This will be called when are player or bot needs to play one of its death animations. In this tutorial, we have it hard-coded to play our new "die" animation sequence that we added earlier.
9.在第8步的功能下,增加以下部分:
function Armor::damage(%this,%obj,%sourceObject,%position,%damage, %damageType )
{
// If we're already dead, don't bother with it...
if( %obj.getState() $= "Dead" )
return;
%obj.applyDamage( %damage );
echo( "Damage Type = " @ %damageType );
// Deal with client callbacks here because we don't have this information
// in the onDamage or onDisabled methods
%client = %obj.client;
%sourceClient = %sourceObject ? %sourceObject.client : 0;
if( %obj.getState() $= "Dead" )
%client.onDeath(%sourceObject,%sourceClient,%damageType,
%location );
}
Add this function below the function listed in step 8.
function Armor::damage(%this,%obj,%sourceObject,%position,%damage, %damageType )
{
// If we're already dead, don't bother with it...
if( %obj.getState() $= "Dead" )
return;
%obj.applyDamage( %damage );
echo( "Damage Type = " @ %damageType );
// Deal with client callbacks here because we don't have this information
// in the onDamage or onDisabled methods
%client = %obj.client;
%sourceClient = %sourceObject ? %sourceObject.client : 0;
if( %obj.getState() $= "Dead" )
%client.onDeath(%sourceObject,%sourceClient,%damageType,
%location );
}
This function is invoked by ShapeBase state management code whenever another object or function is requesting to apply damage to this object. Here's where we decide how to handle incoming damage requests.
Note: This function will not be called correctly for our players and bots unless we add it to the ShapeBase name space. This is why we had to add a file named "shapeBase.cs" to you "tutorial.base/server" directory.
10.在第9步之后增加以下功能:
function Armor::onDisabled( %this, %obj, %state )
{
// If we want to deal with the damage information that actually caused // this death, then we would have to move this code into the script // "damage" method.
%obj.playDeathAnimation();
// Release the main weapon trigger.
%obj.setImageTrigger( 0, false );
// Schedule time and duration of fade-out for dead players.
%obj.schedule( 6000, "startFade", 1000, 0, true );
// Schedule deletion for dead players.
%obj.schedule( 8000, "delete" );
}
这是最后"player.cs"文件最后的修改,可以保存并关闭文件了。
Add this function below the function listed in step 9.
function Armor::onDisabled( %this, %obj, %state )
{
// If we want to deal with the damage information that actually caused // this death, then we would have to move this code into the script // "damage" method.
%obj.playDeathAnimation();
// Release the main weapon trigger.
%obj.setImageTrigger( 0, false );
// Schedule time and duration of fade-out for dead players.
%obj.schedule( 6000, "startFade", 1000, 0, true );
// Schedule deletion for dead players.
%obj.schedule( 8000, "delete" );
}
This method is invoked by ShapeBase state management code whenever our object is disabled. In our case, the object is our are player or bot and "disabled" means "dead", which means if we get this call, we need to die!
This is the last change to "player.cs". Go ahead and save the file and close it. 11.打开"tutorial.base/server"下的"rocket_launcher.cs"脚本文件,按以下语句进行修改:
datablock ProjectileData( RocketProjectile )
{
...
directDamage = 50;
radiusDamage = 25;
damageRadius = 1.5;
...
然后修改RocketProjectile::onCollision下的功能为:
function RocketProjectile::onCollision( %this, %obj, %col, %fade,
%pos, %normal )
{
echo("RocketProjectile::onCollision called!
----------------------------");
// For direct hits... apply damage to all shape base objects
if( %col.getType() & $TypeMasks::ShapeBaseObjectType )
%col.damage( %obj, %pos, %this.directDamage, "Rocket" );
// F or radius damage hits... use the radiusDamage utility function defined
// by the radiusDamage.cs script to see if we our player or bot will take
// any damage.
radiusDamage( %obj, VectorAdd(%pos, VectorScale(%normal, 0.01)), %this.damageRadius, %this.radiusDamage, "Radius", 40 );
}
完成后可以存盘退出了。
Open the "rocket_launcher.cs" script file located in the "tutorial.base/server" directory and modify the RocketProjectile datablock like so:
datablock ProjectileData( RocketProjectile )
{
...
directDamage = 50;
radiusDamage = 25;
damageRadius = 1.5;
...
Then modify the RocketProjectile::onCollision function to look this:
function RocketProjectile::onCollision( %this, %obj, %col, %fade, %pos, %normal )
{
echo("RocketProjectile::onCollision called! ----------------");
// For direct hits... apply damage to all shape base objects
if( %col.getType() & $TypeMasks::ShapeBaseObjectType )
%col.damage( %obj, %pos, %this.directDamage, "Rocket" );
// F or radius damage hits... use the radiusDamage utility function defined
// by the radiusDamage.cs script to see if we our player or bot will take
// any damage.
radiusDamage( %obj, VectorAdd(%pos, VectorScale(%normal, 0.01)), %this.damageRadius, %this.radiusDamage, "Radius", 40 );
}
That's it for "rocket_launcher.cs". Go ahead and save the file and close it. 12.运行"example"下的"torqueDemo.exe"文件。
你可以设计场景中的BOT,或者向自己脚下射击,看看效果,(游戏者死后不能重新复活!!试着自己解决这个问题)。
Run the test application by double-clicking "torqueDemo.exe", which is located in the "example" directory. You should now be able to shoot and kill the path-finding bot as well as blow your self up by shooting at your player's feet.
13.射击几次后,按"~"键看下控制台,炮弹碰到机器人后的提示语句如下:
RocketProjectile::onCollision called! --------------------Damage Type = Rocket
RocketProjectile::onCollision called! --------------------radiusDamage called!
Damage Type = Radius
RocketProjectile::onCollision called! --------------------radiusDamage called!
Damage Type = Radius
RocketProjectile::onCollision called! --------------------radiusDamage called!
Damage Type = Radius
...
After you've fired a few rockets at the bot, hit the "~" key and take a look at the messages that our new functions are issuing as our rockets hit the bot. You should see something like the following in your console:
...
RocketProjectile::onCollision called!
----------------------------
Damage Type = Rocket
RocketProjectile::onCollision called!
----------------------------
radiusDamage called!
Damage Type = Radius
RocketProjectile::onCollision called!
----------------------------
radiusDamage called!
Damage Type = Radius
RocketProjectile::onCollision called!
----------------------------
radiusDamage called!
Damage Type = Radius
...
14.好了,这部分的教程到此全部结束了,此教程的大部分代码来自start.fps 示例文件,还有很多属性需要大家继续学习。