/// <summary> /// Removes this element in the collison layer. /// </summary> public void RemoveInLayer() { if (parentLayer != null) { parentLayer.RemoveCollide(this); parentLayer = null; } }
/// <summary> /// Creates a new collision layer using the name. /// </summary> /// <param name="name">The layer name</param> public CollisionLayer AddLayer(string name) { CollisionLayer newLayer = new CollisionLayer(); newLayer.Name = name; newLayer.MakeId(); collideLayerContainer.Add(newLayer); return(newLayer); }
/// <summary> /// It tests for collision among the collision elements which /// have been registered to the collision layer and returns the result. /// </summary> /// <param name="collide">Source collsion element</param> /// <param name="targetLayer">Target collison layer</param> /// <param name="resultType">type of result</param> /// <returns>A result report</returns> public CollisionResult HitTest(CollideElement collide, ref CollisionLayer targetLayer, ResultType resultType) { CollisionResult result = null; tempResult.Clear(); totalCollidingCount = 0; if (activeOn == false) { return(null); } if (collide == null) { throw new ArgumentNullException("collide"); } if (targetLayer == null) { throw new ArgumentNullException("targetLayer"); } // checking all collisions in current collision layer for (int i = 0; i < targetLayer.CollideCount; i++) { CollideElement targetCollide = targetLayer.GetCollide(i); // Skip ifself if (collide.Equals(targetCollide)) { continue; } else if (collide.Id != 0 && targetCollide.Id != 0) { if (collide.Id == targetCollide.Id) { continue; } } // If source collision is BoundingSphere if (collide is CollideSphere) { CollideSphere sourceCollideSphere = collide as CollideSphere; // Test with target sphere if (targetCollide is CollideSphere) { CollideSphere targetCollideSphere = targetCollide as CollideSphere; TestSphereintersectSphere(sourceCollideSphere, targetCollideSphere, ref tempResult); } // Test with target model else if (targetCollide is CollideModel) { CollideModel targetCollideModel = targetCollide as CollideModel; TestSphereintersectModel(sourceCollideSphere, targetCollideModel, ref tempResult); } // Test with target box else if (targetCollide is CollideBox) { CollideBox targetCollideBox = targetCollide as CollideBox; TestSphereintersectBox(sourceCollideSphere, targetCollideBox, ref tempResult); } // Test with target ray if (targetCollide is CollideRay) { CollideRay targetCollideRay = targetCollide as CollideRay; TestRayintersectSphere(targetCollideRay, sourceCollideSphere, ref tempResult); } } // If source collision is Ray else if (collide is CollideRay) { CollideRay sourceCollideRay = collide as CollideRay; // Test with target model if (targetCollide is CollideModel) { CollideModel targetCollideModel = targetCollide as CollideModel; TestRayintersectModel(sourceCollideRay, targetCollideModel, ref tempResult); } // Test with target sphere else if (targetCollide is CollideSphere) { CollideSphere targetCollideSphere = targetCollide as CollideSphere; TestRayintersectSphere(sourceCollideRay, targetCollideSphere, ref tempResult); } // Test with target box else if (targetCollide is CollideBox) { CollideBox targetCollideBox = targetCollide as CollideBox; TestRayintersectBox(sourceCollideRay, targetCollideBox, ref tempResult); } } // If source collision is Ray else if (collide is CollideBox) { CollideBox sourceCollideBox = collide as CollideBox; // Test with target sphere if (targetCollide is CollideSphere) { CollideSphere targetCollideSphere = targetCollide as CollideSphere; TestSphereintersectBox(targetCollideSphere, sourceCollideBox, ref tempResult); } // Test with target box else if (targetCollide is CollideBox) { CollideBox targetCollideBox = targetCollide as CollideBox; TestBoxintersectBox(sourceCollideBox, targetCollideBox, ref tempResult); } // Test with target ray else if (targetCollide is CollideRay) { CollideRay targetCollideRay = targetCollide as CollideRay; TestRayintersectBox(targetCollideRay, sourceCollideBox, ref tempResult); } } // To find the nearest detected collision. if (resultType == ResultType.NearestOne) { if (tempResult.collideCount > 0) { if (result == null) { result = new CollisionResult(); result.distance = float.MaxValue; } if (result.distance > tempResult.distance) { tempResult.CopyTo(ref result); } } } } return(result); }
/// <summary> /// It tests for collision among the collision elements which /// have been registered to the collision layer and returns the result. /// </summary> /// <param name="collide">Source collsion element</param> /// <param name="targetLayer">Target collison layer</param> /// <param name="resultType">type of result</param> /// <returns>A result report</returns> public CollisionResult HitTest(CollideElement collide, ref CollisionLayer targetLayer, ResultType resultType) { CollisionResult result = null; tempResult.Clear(); totalCollidingCount = 0; if (activeOn == false) return null; if (collide == null) { throw new ArgumentNullException("collide"); } if (targetLayer == null) { throw new ArgumentNullException("targetLayer"); } // checking all collisions in current collision layer for (int i = 0; i < targetLayer.CollideCount; i++) { CollideElement targetCollide = targetLayer.GetCollide(i); // Skip ifself if (collide.Equals(targetCollide)) { continue; } else if (collide.Id != 0 && targetCollide.Id != 0) { if (collide.Id == targetCollide.Id) continue; } // If source collision is BoundingSphere if (collide is CollideSphere) { CollideSphere sourceCollideSphere = collide as CollideSphere; // Test with target sphere if (targetCollide is CollideSphere) { CollideSphere targetCollideSphere = targetCollide as CollideSphere; TestSphereintersectSphere(sourceCollideSphere, targetCollideSphere, ref tempResult); } // Test with target model else if (targetCollide is CollideModel) { CollideModel targetCollideModel = targetCollide as CollideModel; TestSphereintersectModel(sourceCollideSphere, targetCollideModel, ref tempResult); } // Test with target box else if (targetCollide is CollideBox) { CollideBox targetCollideBox = targetCollide as CollideBox; TestSphereintersectBox(sourceCollideSphere, targetCollideBox, ref tempResult); } // Test with target ray if (targetCollide is CollideRay) { CollideRay targetCollideRay = targetCollide as CollideRay; TestRayintersectSphere(targetCollideRay, sourceCollideSphere, ref tempResult); } } // If source collision is Ray else if (collide is CollideRay) { CollideRay sourceCollideRay = collide as CollideRay; // Test with target model if (targetCollide is CollideModel) { CollideModel targetCollideModel = targetCollide as CollideModel; TestRayintersectModel(sourceCollideRay, targetCollideModel, ref tempResult); } // Test with target sphere else if (targetCollide is CollideSphere) { CollideSphere targetCollideSphere = targetCollide as CollideSphere; TestRayintersectSphere(sourceCollideRay, targetCollideSphere, ref tempResult); } // Test with target box else if (targetCollide is CollideBox) { CollideBox targetCollideBox = targetCollide as CollideBox; TestRayintersectBox(sourceCollideRay, targetCollideBox, ref tempResult); } } // If source collision is Ray else if (collide is CollideBox) { CollideBox sourceCollideBox = collide as CollideBox; // Test with target sphere if (targetCollide is CollideSphere) { CollideSphere targetCollideSphere = targetCollide as CollideSphere; TestSphereintersectBox(targetCollideSphere, sourceCollideBox, ref tempResult); } // Test with target box else if (targetCollide is CollideBox) { CollideBox targetCollideBox = targetCollide as CollideBox; TestBoxintersectBox(sourceCollideBox, targetCollideBox, ref tempResult); } // Test with target ray else if (targetCollide is CollideRay) { CollideRay targetCollideRay = targetCollide as CollideRay; TestRayintersectBox(targetCollideRay, sourceCollideBox, ref tempResult); } } // To find the nearest detected collision. if (resultType == ResultType.NearestOne) { if (tempResult.collideCount > 0) { if(result == null) { result = new CollisionResult(); result.distance = float.MaxValue; } if (result.distance > tempResult.distance) { tempResult.CopyTo(ref result); } } } } return result; }
/// <summary> /// Creates a new collision layer using the name. /// </summary> /// <param name="name">The layer name</param> public CollisionLayer AddLayer(string name) { CollisionLayer newLayer = new CollisionLayer(); newLayer.Name = name; newLayer.MakeId(); collideLayerContainer.Add(newLayer); return newLayer; }
/// <summary> /// drops weapon at specified position. /// </summary> /// <param name="position">new drop position</param> /// <param name="parent">new scene node</param> /// <param name="layer">new collision layer</param> public void Drop(Vector3 position, NodeBase parent, CollisionLayer layer) { // Detached scene node from owner AttachOwner(parent); // Add a collision if( layer != null) layer.AddCollide(this.Collide); DroppedModel.SetRootAxis( Matrix.CreateRotationX(MathHelper.ToRadians(-90.0f))); this.Position = position; this.isDropped = true; this.Enabled = true; this.Visible = true; }
/// <summary> /// checks for the collision at the aiming angle. /// If it collides with an enemy mech, calls ActionHit() function. /// Weapon’s collision checks the world and enemy both. /// When playing firing particle, the number of the weapon’s model /// must be considered. /// Since the player’s weapon is a dual weapon system, there are two models. /// However, for enemies, there are enemies with single weapon system. /// Therefore, it plays firing particle at the gun point /// as many as the number of models. /// </summary> /// <param name="position">the start position of firing</param> /// <param name="direction">the direction of firing</param> /// <param name="distance">the range of firing</param> /// <param name="targetCollisionLayer">target collision layer</param> /// <param name="worldCollisionLayer">world collision layer</param> /// <param name="fireBone1">the fire matrix of first weapon</param> /// <param name="fireBone2">the fire matrix of second weapon</param> /// <returns></returns> public bool Fire(Vector3 position, Vector3 direction, float distance, ref CollisionLayer targetCollisionLayer, ref CollisionLayer worldCollisionLayer, Matrix? fireBone1, Matrix? fireBone2) { bool hit = false; Vector3 firePosition = Vector3.Zero; Vector3 targetPosition = position + (direction * distance); SoundTrack fireSound = SoundTrack.Count; ParticleType fireParticle = ParticleType.Count; ParticleType unitHitParticle = ParticleType.Count; ParticleType worldHitParticle = ParticleType.Count; Matrix fixedAxis = Matrix.CreateRotationX(MathHelper.ToRadians(-90.0f)); this.state = WeaponState.Firing; if (this.currentAmmo <= 0) return hit; // Reduces a bullet. this.currentAmmo--; switch (this.WeaponType) { case WeaponType.PlayerMachineGun: { fireSound = SoundTrack.PlayerMachineGunFire; fireParticle = ParticleType.PlayerMachineGunFire; unitHitParticle = ParticleType.PlayerMachineGunUnitHit; worldHitParticle = ParticleType.PlayerMachineGunWorldHit; } break; case WeaponType.PlayerShotgun: { fireSound = SoundTrack.PlayerShotgunFire; fireParticle = ParticleType.PlayerShotgunFire; unitHitParticle = ParticleType.PlayerShotgunUnitHit; worldHitParticle = ParticleType.PlayerShotgunWorldHit; } break; case WeaponType.PlayerHandgun: { fireSound = SoundTrack.PlayerHandgunFire; fireParticle = ParticleType.PlayerHandgunFire; unitHitParticle = ParticleType.PlayerHandgunUnitHit; worldHitParticle = ParticleType.PlayerHandgunWorldHit; } break; case WeaponType.CameleerGun: { fireSound = SoundTrack.CameleerFire; fireParticle = ParticleType.EnemyGunFire; unitHitParticle = ParticleType.EnemyGunUnitHit; worldHitParticle = ParticleType.EnemyGunWorldHit; } break; case WeaponType.MaomingGun: { fireSound = SoundTrack.MaomingFire; fireParticle = ParticleType.PlayerMachineGunFire; unitHitParticle = ParticleType.EnemyGunUnitHit; worldHitParticle = ParticleType.EnemyGunWorldHit; } break; case WeaponType.DuskmasCannon: { fireSound = SoundTrack.DuskmasFire; fireParticle = ParticleType.EnemyCannonFire; unitHitParticle = ParticleType.EnemyCannonUnitHit; worldHitParticle = ParticleType.EnemyCannonWorldHit; } break; case WeaponType.TigerCannon: { fireSound = SoundTrack.TankFire; fireParticle = ParticleType.EnemyCannonFire; unitHitParticle = ParticleType.EnemyCannonUnitHit; worldHitParticle = ParticleType.EnemyCannonWorldHit; } break; case WeaponType.HammerCannon: { fireSound = SoundTrack.HammerFire; fireParticle = ParticleType.EnemyCannonFire; unitHitParticle = ParticleType.EnemyCannonUnitHit; worldHitParticle = ParticleType.EnemyCannonWorldHit; } break; case WeaponType.PhantomMelee: { fireSound = SoundTrack.BossMelee; fireParticle = ParticleType.Count; unitHitParticle = ParticleType.EnemyMeleeUnitHit; worldHitParticle = ParticleType.EnemyCannonWorldHit; } break; } if (this.WeaponType != WeaponType.PlayerShotgun && this.WeaponType != WeaponType.PlayerHandgun) { StopFireSound(); } // Play a weapon firing sound if (RobotGameGame.CurrentGameLevel.Info.GamePlayType == GamePlayTypeId.Versus) { soundFire = GameSound.Play3D(fireSound, RobotGameGame.SinglePlayer.Emitter); } else { soundFire = GameSound.Play3D(fireSound, this.OwnerUnit.Emitter); } // Play firing particles if (specData.ModelAlone ) { // Multi fire if (this.SpecData.FireCount == 1) { for (int i = 0; i < SpecData.ModelCount; i++) { int boneIdx = indexWeaponFireDummy[i]; Matrix boneTransform = modelWeapon[i].BoneTransforms[boneIdx]; GameParticle.PlayParticle(fireParticle, boneTransform, fixedAxis); } // In case of two handed weapons, the index is changed // so that the tracer bullet will fire alternatively. if (dummySwichingIndex == 0) dummySwichingIndex = 1; else dummySwichingIndex = 0; int boneIndex = indexWeaponFireDummy[dummySwichingIndex]; firePosition = modelWeapon[dummySwichingIndex].BoneTransforms[ boneIndex].Translation; } // Delayed fire else { if (this.fireCount == 0) { GameParticle.PlayParticle(fireParticle, this.RightFireBone, fixedAxis); firePosition = this.RightFireBone.Translation; } else if (this.fireCount == 1) { GameParticle.PlayParticle(fireParticle, this.LeftFireBone, fixedAxis); firePosition = this.LeftFireBone.Translation; } } } else { Matrix fireMatrix = Matrix.Identity; if (fireBone1 != null) GameParticle.PlayParticle(fireParticle, (Matrix)fireBone1, fixedAxis); if (fireBone2 != null) GameParticle.PlayParticle(fireParticle, (Matrix)fireBone2, fixedAxis); if (fireBone1 != null && fireBone2 != null) { // In case of two handed weapons, the index is changed // so that the tracer bullet will fire alternatively. if (dummySwichingIndex == 0) { fireMatrix = (Matrix)fireBone1; dummySwichingIndex = 1; } else { fireMatrix = (Matrix)fireBone2; dummySwichingIndex = 0; } } else if( fireBone1 != null) fireMatrix = (Matrix)fireBone1; else if (fireBone2 != null) fireMatrix = (Matrix)fireBone2; firePosition = fireMatrix.Translation; } // Hit testing CollisionResult collideResult = FireHitTest(position, direction, distance, ref targetCollisionLayer, ref worldCollisionLayer); if (collideResult != null) { // Play hitting particle { ParticleType hitParticle = ParticleType.Count; // To player if (collideResult.detectedCollide.Owner is GameUnit) { GameUnit detectGameUnit = collideResult.detectedCollide.Owner as GameUnit; // Calculate a random intersect point for // hitting particle in unit sphere CollideSphere sphere = collideResult.detectedCollide as CollideSphere; switch (this.WeaponType) { case WeaponType.PlayerMachineGun: case WeaponType.PlayerShotgun: case WeaponType.PlayerHandgun: case WeaponType.CameleerGun: case WeaponType.MaomingGun: { Vector3 dir = this.OwnerUnit.Position - detectGameUnit.Position; dir.Normalize(); dir.X += HelperMath.RandomNormal2(); dir.Y += HelperMath.RandomNormal2(); dir.Normalize(); collideResult.normal = (Vector3)dir; collideResult.intersect = sphere.BoundingSphere.Center + ((Vector3)dir * sphere.Radius); } break; case WeaponType.DuskmasCannon: case WeaponType.HammerCannon: case WeaponType.TigerCannon: case WeaponType.PhantomMelee: { Vector3 dir = this.OwnerUnit.Position - sphere.BoundingSphere.Center; dir.Normalize(); collideResult.normal = (Vector3)dir; collideResult.intersect = sphere.BoundingSphere.Center; } break; } hitParticle = unitHitParticle; targetPosition = (Vector3)collideResult.intersect; } // To world else { hitParticle = worldHitParticle; targetPosition = (Vector3)collideResult.intersect; } if (collideResult.normal != null) { GameParticle.PlayParticle(hitParticle, (Vector3)collideResult.intersect, (Vector3)collideResult.normal, Matrix.CreateRotationX(MathHelper.ToRadians(-90.0f))); } else { GameParticle.PlayParticle(hitParticle, Matrix.CreateTranslation((Vector3)collideResult.intersect), Matrix.CreateRotationX(MathHelper.ToRadians(-90.0f))); } } // Hit to other mech if (collideResult.detectedCollide.Owner is GameUnit) { GameUnit HitUnit = (GameUnit)collideResult.detectedCollide.Owner; // Call hit function to unit HitUnit.ActionHit(this.OwnerUnit); if (HitUnit.IsDead ) { if (this.OwnerUnit is GamePlayer) { // If the versus mode, you'll be get kill point if( RobotGameGame.CurrentStage is VersusStageScreen) { VersusStageScreen stage = RobotGameGame.CurrentStage as VersusStageScreen; GamePlayer player = this.OwnerUnit as GamePlayer; player.KillPoint++; stage.DisplayKillPoint((int)player.PlayerIndex, player.KillPoint); } } } hit = true; } } // Fire the tracer bullet particle if( this.specData.TracerBulletFire ) { RobotGameGame.CurrentStage.TracerBulletManager.Fire(0, firePosition, targetPosition, this.specData.TracerBulletSpeed, this.specData.TracerBulletLength, this.specData.TracerBulletThickness, true); } // Cannot fire return hit; }
/// <summary> /// checks for the weapon firing collision. /// When collision check succeeds, returns a result report. /// If not, returns null. /// </summary> /// <param name="position">the start position of firing</param> /// <param name="direction">the direction of firing</param> /// <param name="distance">the range of firing</param> /// <param name="targetCollisionLayer">target collision layer</param> /// <param name="worldCollisionLayer">world collision layer</param> /// <returns>result report</returns> protected static CollisionResult FireHitTest(Vector3 position, Vector3 direction, float distance, ref CollisionLayer targetCollisionLayer, ref CollisionLayer worldCollisionLayer) { bool doHit = false; CollideRay collideRay = new CollideRay(position, direction); // checks with enemies. CollisionResult fireResult = FrameworkCore.CollisionContext.HitTest( collideRay, ref targetCollisionLayer, ResultType.NearestOne); if (fireResult != null) { if (fireResult.distance <= distance) { // Hit unit doHit = true; } } // checks with world. CollisionResult worldResult = FrameworkCore.CollisionContext.HitTest( collideRay, ref worldCollisionLayer, ResultType.NearestOne); if (worldResult != null) { // Hit world if (worldResult.distance <= distance) { if (doHit) { // closer world if (worldResult.distance < fireResult.distance) { return worldResult; } } else { return worldResult; } } } if (doHit) { return fireResult; } return null; }
/// <summary> /// initializes with collison layer and creates a simple shadow. /// </summary> public override void Initialize() { base.Initialize(); colLayerMoveWorld = RobotGameGame.CurrentGameLevel.CollisionLayerMoveWorld; colLayerHitWorld = RobotGameGame.CurrentGameLevel.CollisionLayerHitWorld; colLayerFriendlyMech = RobotGameGame.CurrentGameLevel.CollisionLayerFriendlyMech; colLayerEnemyMech = RobotGameGame.CurrentGameLevel.CollisionLayerEnemyMech; colLayerAllMech = RobotGameGame.CurrentGameLevel.CollisionLayerAllMech; colLayerItems = RobotGameGame.CurrentGameLevel.CollisionLayerItems; colLayerVersusTeam = RobotGameGame.CurrentGameLevel.CollisionVersusTeam; // creates a simple shadow. GameResourceTexture2D resource = FrameworkCore.ResourceManager.LoadTexture("Textures/shadow"); simpleShadow = new GameQuad(new Vector3(0.0f, 0.02f, 0.0f), Vector3.Up, Vector3.Forward, 3.0f, 3.0f); simpleShadow.Name = "simple shadow"; simpleShadow.Texture = resource.Texture2D; simpleShadow.LightingEnabled = false; simpleShadow.Alpha = 0.6f; simpleShadow.AlphaBlendEnable = true; simpleShadow.ReferenceAlpha = 0; simpleShadow.DepthBufferEnable = true; simpleShadow.DepthBufferWriteEnable = true; simpleShadow.DepthBufferFunction = CompareFunction.Less; simpleShadow.SourceBlend = Blend.SourceAlpha; simpleShadow.DestinationBlend = Blend.InverseSourceAlpha; simpleShadow.BlendFunction = BlendFunction.Add; simpleShadow.AlphaFunction = CompareFunction.Greater; simpleShadow.CullMode = CullMode.CullCounterClockwiseFace; this.AddChild(simpleShadow); }