I prefer the third pic, I think it suits best for Jump n' Run, The second one has too much straight ways.
An idea: as it's often done in race game, you could provide two ways to win the match, one shorter but more difficult and the standard one.
I've done some littles works this weekend. I've reimplemented Timer in Pawn, Start/Stop/Consume Volume, I also implemented the first powerup item (inspired from health vial). I created a simple HUD which display remaining time and a bar on the upper left corner.
ConsumeVolume is based on DamageVolume but I still don't understand
why health has to be linked to time???. My ConsumeVolume takes only the timer of PhysicsVolume, no damage is done to the player when entering this volume for now.
What do you think?
![Posted Image](http://img511.imageshack.us/img511/8976/timersystem0mo4.jpg)
![Posted Image](http://img511.imageshack.us/img511/8976/timersystem0mo4.f2c749b055.jpg)
class FiveWeekPawn extends UTPawn;
var int totalTime;
var float remainingTime;
var bool isTimerStarted;
simulated event PostBeginPlay()
{
`log("Pawn Type is 5week");
super.PostBeginPlay();
}
//function TakeFallingDamage()
//{
//Over-ridden to prevent falling damage
//}
//Timer Methods ============================================================
function startTimer()
{
remainingTime = totalTime;
isTimerStarted=true;
LogInternal("StartTimer");
}
function stopTimer()
{
isTimerStarted=false;
LogInternal("StopTimer");
}
function increaseTimer(int amountSeconds)
{
LogInternal("increase timer: "$amountSeconds);
if(isTimerStarted)
{
remainingTime += amountSeconds;
}
}
function decreaseTimer(int amountSeconds)
{
LogInternal("idecrease timer: "$amountSeconds);
if(isTimerStarted)
{
remainingTime -= amountSeconds;
checkTime();
}
}
function checkTime()
{
if(remainingTime <= 0)
stopTimer();
LogInternal("remainingTime: "$remainingTime);
}
defaultproperties
{
GroundSpeed=550
WaterSpeed=330
AirSpeed=550
JumpZ=433
AirControl=0.35
WalkingPct=0.4
CrouchedPct=0.4
AccelRate=256
totalTime=100
}
class FiveWeek_StartVolume extends PhysicsVolume
placeable;
simulated event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
{
if(FiveWeekPawn(Other) != None && !FiveWeekPawn(Other).isTimerStarted)
FiveWeekPawn(Other).startTimer();
}
class FiveWeek_StopVolume extends PhysicsVolume
placeable;
simulated event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
{
if(FiveWeekPawn(Other) != None && FiveWeekPawn(Other).isTimerStarted)
FiveWeekPawn(Other).stopTimer();
}
class FiveWeek_ConsumeVolume extends PhysicsVolume
placeable;
var() int LossSecondsPerSec;
function CausePainTo(Actor Other)
{
//decrease the Actor timer id FiveWeekPawn
if(FiveWeekPawn(Other) != None && FiveWeekPawn(Other).isTimerStarted)
FiveWeekPawn(Other).decreaseTimer(LossSecondsPerSec);
}
defaultproperties
{
LossSecondsPerSec = 1;
bPainCausing = true;
}
class FiveWeek_BonusTime extends UTItemPickupFactory
placeable;
var() int timeBonusAmount;
//method call when item picked up
simulated static function UpdateHUD(UTHUD H)
{
super.UpdateHUD(H);
}
function float BotDesireability(Pawn P, Controller C)
{
return super.BotDesireability(P, C);
}
function SpawnCopyFor( Pawn Recipient )
{
super.SpawnCopyFor(Recipient);
if(FiveWeekPawn(Recipient) != None)
FiveWeekPawn(Recipient).increaseTimer(timeBonusAmount);
}
auto state Pickup
{
/* DetourWeight()
value of this path to take a quick detour (usually 0, used when on route to distant objective, but want to grab inventory for example)
*/
function float DetourWeight(Pawn Other,float PathWeight)
{
return 0;
}
/* ValidTouch()
Validate touch (if valid return true to let other pick me up and trigger event).
*/
function bool ValidTouch( Pawn Other )
{
if ( !Super.ValidTouch(Other) )
{
return false;
}
return true;
}
}
defaultproperties
{
bMovable=FALSE
bStatic=FALSE
PickupStatName=Pickups_BonusTime
BaseBrightEmissive=(R=2.0,G=50.0,B=10.0,A=1.0)
BaseDimEmissive=(R=0.20,G=5.0,B=1.0,A=0.0)
RespawnSound=SoundCue'A_Pickups.Health.Cue.A_Pickups_Health_Respawn_Cue'
Begin Object class=StaticMeshComponent Name=TimePickUpMesh
CastShadow=FALSE
bCastDynamicShadow=FALSE
bAcceptsLights=TRUE
bForceDirectLightMap=TRUE
LightEnvironment=PickupLightEnvironment
AlwaysLoadOnClient=true
AlwaysLoadOnServer=true
CollideActors=false
BlockActors=false
BlockRigidBody=false
CullDistance=4500
bUseAsOccluder=FALSE
StaticMesh=StaticMesh'Pickups.Health_Small.Mesh.S_Pickups_Health_Small'
Scale3D=(X=1.0,Y=1.0,Z=1.0)
End Object
PickupMesh=TimePickUpMesh
Components.Add(TimePickUpMesh)
bIsSuperItem=false
RespawnTime=5.000000
MaxDesireability=0.3
PickupSound=SoundCue'A_Pickups.Health.Cue.A_Pickups_Health_Small_Cue_Modulated'
bRotatingPickup=true
YawRotationRate=32000
bFloatingPickup=true
bRandomStart=false
Begin Object name=CollisionCylinder
CollisionRadius=+00030.000000
CollisionHeight=+00020.000000
CollideActors=true
End Object
//default class field value
timeBonusAmount=5
}
Edited by xiongmao, 13 April 2008 - 10:35 PM.