public GameVelocity TryGetLaunchVelocity(CameraInfo cameraInfo) { GameVelocity result = null; if (this.Projectile == null) { throw new Exception("Trying to launch without a ball"); } // Move the catapult to make sure that it is moved at least once before launch (prevent NaN in launch direction) this.Move(cameraInfo); var stretchNormalized = DigitExtensions.Clamp((this.stretch - this.properties.MinStretch) / (this.properties.MaxStretch - this.properties.MinStretch), 0.0, 1.0); // this is a lerp var velocity = (float)(this.properties.MinVelocity * (1d - stretchNormalized) + this.properties.MaxVelocity * stretchNormalized); var launchDir = SCNVector3.Normalize(this.pullOrigin.WorldPosition - this.Projectile.WorldPosition); if (!launchDir.HasNaN()) { var liftFactor = 0.05f * Math.Abs(1f - SCNVector3.Dot(launchDir, SCNVector3.UnitY)); // used to keep ball in air longer var lift = SCNVector3.UnitY * velocity * liftFactor; result = new GameVelocity(this.Projectile.WorldPosition, launchDir * velocity + lift); } return(result); }
public void PlayLaunch(Catapult catapult, GameVelocity velocity, bool playHaptic) { if (playHaptic) { this.hapticsGenerator.GenerateNotificationFeedback(UINotificationFeedbackType.Success); } catapult.AudioPlayer.PlayLaunch(velocity); }
public void PlayLaunch(GameVelocity velocity) { // For the launch, we will play two sounds: a launch twang and a swish var length = velocity.Vector.Length; length = float.IsNaN(length) ? 0 : DigitExtensions.Clamp(length, 0, 1); var launchVel = (byte)(length * 30 + 80); this.Play(Note.Launch, launchVel); var swishVel = (byte)(length * 63 + 64); this.After(() => this.Play(Note.LaunchSwish, swishVel), 1); }
public void SlingBall(Catapult catapult, GameVelocity velocity) { if (this.Delegate == null) { throw new Exception("No delegate"); } var newProjectile = this.Delegate.SpawnProjectile(); newProjectile.Team = catapult.Team; this.Delegate.AddNodeToLevel(newProjectile.ObjectRootNode); // The lifeTime of projectile needed to sustain the pool is defined by: // (Catapult Count) * (1 + (lifeTime) / (cooldownTime)) = (Pool Count) var poolCount = this.Delegate.GameObjectPoolCount(); var lifeTime = (double)(poolCount / this.catapults.Count - 1) * catapult.CoolDownTime; newProjectile.Launch(velocity, lifeTime, this.Delegate.ProjectileDelegate); // assign the catapult source to this ball if (newProjectile.PhysicsNode?.PhysicsBody != null) { newProjectile.PhysicsNode.SetValueForKey(NSObject.FromObject(catapult.CatapultId), new NSString("Source")); newProjectile.PhysicsNode.PhysicsBody.CollisionBitMask = (int)(CollisionMask.RigidBody | CollisionMask.GlitterObject); if (catapult.Team == Team.TeamA) { var collisionMask = (CollisionMask)(int)(newProjectile.PhysicsNode.PhysicsBody.CollisionBitMask); newProjectile.PhysicsNode.PhysicsBody.CollisionBitMask = (nuint)(int)(collisionMask | CollisionMask.CatapultTeamB); var categoryBitMask = (CollisionMask)(int)(newProjectile.PhysicsNode.PhysicsBody.CategoryBitMask); newProjectile.PhysicsNode.PhysicsBody.CategoryBitMask = (nuint)(int)(categoryBitMask | CollisionMask.CatapultTeamA); } else { var collisionMask = (CollisionMask)(int)(newProjectile.PhysicsNode.PhysicsBody.CollisionBitMask); newProjectile.PhysicsNode.PhysicsBody.CollisionBitMask = (nuint)(int)(collisionMask | CollisionMask.CatapultTeamA); var categoryBitMask = (CollisionMask)(int)(newProjectile.PhysicsNode.PhysicsBody.CategoryBitMask); newProjectile.PhysicsNode.PhysicsBody.CategoryBitMask = (nuint)(int)(categoryBitMask | CollisionMask.CatapultTeamB); } } }
public virtual void Launch(GameVelocity velocity, double lifeTime, IProjectileDelegate @delegate) { this.startTime = GameTime.Time; this.isLaunched = true; this.lifeTime = lifeTime; this.Delegate = @delegate; if (this.PhysicsNode != null && this.PhysicsBody != null) { this.PhysicsBody.VelocityFactor = SCNVector3.One; this.PhysicsBody.AngularVelocityFactor = SCNVector3.One; this.PhysicsBody.Velocity = velocity.Vector; this.PhysicsNode.Name = "ball"; this.PhysicsNode.WorldPosition = velocity.Origin; this.PhysicsBody.ResetTransform(); } else { throw new System.Exception("Projectile not setup"); } }
public void OnLaunch(GameVelocity velocity) { if (this.isGrabbed) { // can't grab again until the cooldown animations play ballCanBeGrabbed = false; // update local information for current player if that is what is pulling the catapult // start the launch animation this.rope.LaunchBall(); // must reset the move to distance 0 before the launch, otherwise it will start a new // stretch sound. this.Delegate?.DidMove(this, 0f, 0f); this.Delegate?.DidLaunch(this, velocity); // set the ball to invisible this.BallVisible = BallVisible.Hidden; // record the last launch time, and enforce a cooldown before ball reappears (need an update call then?) this.lastLaunchTime = GameTime.Time; } }
public SlingData(int catapultId, ProjectileType projectileType, GameVelocity velocity) { CatapultId = catapultId; ProjectileType = projectileType; Velocity = velocity; }
public override void Launch(GameVelocity velocity, double lifeTime, IProjectileDelegate @delegate) { base.Launch(velocity, lifeTime, @delegate); this.AddTrail(); }