// Use this for initialization protected virtual void Start() { initialLocalPosition = transform.localPosition; initialScaleX = transform.localScale.x; parentCircle = transform.parent.GetComponent <PhysCircle>(); }
protected void OnCollisionExit2D(Collision2D hit) { PhysCircle hitCircle = hit.gameObject.GetComponent <PhysCircle>(); if (hitCircle) { hitRegistry.Remove(hitCircle); } }
void onClockTimeout() { Vector3 pos = transform.position; pos.x = transform.position.x + (Random.value - 0.5f) * transform.localScale.x; PhysCircle newCircle = Instantiate(pool.getCircle(), pos, Quaternion.identity); newCircle.rb.velocity = initialVelocity; }
protected virtual void OnCollisionEnter2D(Collision2D hit) { //The PhysCircle we just collided with PhysCircle hitCircle = hit.gameObject.GetComponent <PhysCircle>(); //If the hitCircle exists... if (hitCircle /*&& !hitCircle.hitList.Contains(this)*/) { //Represents the position of hitCircle relative to this physcircle Vector2 relativePosition = hitCircle.rb.position - rb.position; //The magnitude of the velocity vector projected onto a vector between both PhysCircles centers float VPM = oldVelocity.magnitude * Mathf.Cos(Mathf.Deg2Rad * Vector2.Angle(relativePosition, oldVelocity)); //Add this circle and its VPM to the hit PhysCircles hit registry hitCircle.hitRegistry.Add(this, VPM); //If we have the other circle in our hit registry, use the VPM associated with it //to deal collision damage to both PhysCircles' health bars; whichever ones have them if (hitRegistry.ContainsKey(hitCircle)) { float massTotal = rb.mass + hitCircle.rb.mass; float collisionVPM = VPM + hitRegistry[hitCircle]; //The objects' combined masses times their combined VPMs float baseDamage = massTotal * collisionVPM; //Deal damage to any existing health bars if (hb) { hb.takeDamage(globalDamageMultiplier * baseDamage * (hitCircle.rb.mass / massTotal)); } if (hitCircle.hb) { hitCircle.hb.takeDamage(globalDamageMultiplier * baseDamage * (rb.mass / massTotal)); } } } else //If the collision is with terrain (or any other non-PhysCircle collider) { if (hb) { ContactPoint2D[] points = new ContactPoint2D[1]; hit.GetContacts(points); Vector2 normal = points[0].normal; float VPM = oldVelocity.magnitude * Mathf.Cos(Mathf.Deg2Rad * Vector2.Angle(normal, oldVelocity)); float baseDamage = Mathf.Abs(VPM) * rb.mass; hb.takeDamage(baseDamage * globalDamageMultiplier); } } }
//Use getCircle to get a random PhysCircle, instantiate a clone of it (If it exists) and return a reference to it public PhysCircle spawnRandom(Transform parent) { PhysCircle newCircle = getCircle(); if (newCircle) { return(Instantiate(newCircle, parent.position, Quaternion.identity)); } else { return(null); } }
private static Collision CircleVsCircle( PhysCircle bodyA, PhysCircle bodyB, float elapsed ) { Collision result = new Collision(); Vector2 normal; // if intersecting at t = 0 Vector2 popoutPos = Vector2.Zero; bool popout = false; float totalRadius = bodyA.Radius + bodyB.Radius; if ( Vector2.DistanceSquared( bodyA.Position, bodyB.Position ) < .95f * ( totalRadius * totalRadius ) ) { if ( !bodyA.Flags.HasFlags( BodyFlags.Ghost ) && !bodyB.Flags.HasFlags( BodyFlags.Ghost ) ) { normal = Vector2.Normalize( bodyA.Position - bodyB.Position ); popoutPos = bodyB.Position + 1.0001f * totalRadius * normal - bodyA.Velocity * elapsed; popout = true; } else { return new Collision( true, 0f, bodyA, bodyB, Vector2.Zero, Vector2.Zero ); } } // if not intersecting at t = 0 Vector2 relVel = Vector2.Subtract( bodyA.Velocity, bodyB.Velocity ); Vector2 relVelByT = Vector2.Multiply( relVel, elapsed ); Vector2 posAtT = Vector2.Add( bodyA.Position, relVelByT ); float time; if ( Geometry.SegmentVsCircle( out time, out normal, bodyA.Position, posAtT, bodyB.Position, bodyA.Radius + bodyB.Radius ) ) { float timeStep = Math.Max( 0f, time * elapsed ); result.Time = timeStep; result.Collided = true; result.Normal = normal; result.BodyA = bodyA; result.BodyB = bodyB; Vector2 dispAtCollision = ( bodyB.Position + bodyB.Velocity * timeStep ) - ( bodyA.Position + bodyA.Velocity * timeStep ); result.Intersection = bodyA.Position + ( bodyA.Radius / ( bodyA.Radius + bodyB.Radius ) ) * dispAtCollision; } if ( popout && !result.Collided ) bodyA.Position = popoutPos; return result; }
private Powerup( GameplayScreen screen ) : base(screen) { Body = new PhysCircle( 1f, Vector2.Zero, 1f ); Body.Flags = BodyFlags.Anchored | BodyFlags.Ghost; Body.Parent = this; Oscillator = new SpringInterpolater( 1, 10, 0 ); SizeSpring = new SpringInterpolater( 1, 200, .15f * SpringInterpolater.GetCriticalDamping( 200 ) ); LockToPlayerSpring = new SpringInterpolater( 2, 100, SpringInterpolater.GetCriticalDamping( 100 ) ); RotationSpring = new SpringInterpolater( 1, 15, SpringInterpolater.GetCriticalDamping( 15 ) ); Oscillator.Active = true; SizeSpring.Active = true; LockToPlayerSpring.Active = true; RotationSpring.Active = true; DrawOrder = 6; }
void Awake() { fuseTimer = fuse; circle = GetComponent <PhysCircle>(); col = GetComponent <CircleCollider2D>(); }
private static Collision CircleVsPolygon( PhysCircle bodyA, PhysPolygon bodyB, float elapsed ) { Vector2 relVel, relVelByT, posAtT; Vector2.Subtract( ref bodyA.Velocity, ref bodyB.Velocity, out relVel ); Vector2.Multiply( ref relVel, elapsed, out relVelByT ); Vector2.Add( ref bodyA.Position, ref relVelByT, out posAtT ); Vector2[] verts = bodyB.TransformedVertices; Vector2 lastVert = verts.Last(); Collision bestResult = new Collision(); bestResult.Time = float.MaxValue; Vector2 popoutPos = Vector2.Zero; Vector2 popoutNormal = Vector2.Zero; Vector2 popoutIsect = Vector2.Zero; int popoutPriority = 0; int nVerts = verts.Length; for ( int i = 0; i < nVerts; ++i ) { Vector2 vert = verts[i]; Vector2 edge = Vector2.Subtract( vert, lastVert ); Vector2 n = new Vector2( edge.Y, -edge.X ); float time; Vector2 normal; // ball is moving towards the segment if ( Vector2.Dot( n, relVel ) < 0.0f ) { n.Normalize(); Vector2 offset = Vector2.Multiply( n, bodyA.Radius ); Vector2 q0 = lastVert + offset; Vector2 q1 = vert + offset; // check if intersecting segment at elapsed = 0 if ( Geometry.SegmentVsCircle( out time, out normal, lastVert, vert, bodyA.Position, bodyA.Radius ) ) { if ( time < .95f && popoutPriority != 1 ) { float dot = Vector2.Dot( normal, -n ); if ( dot > 0f ) { popoutNormal = -normal; popoutIsect = edge * time; popoutPos = bodyA.Position + n * 1.0001f * bodyA.Radius * ( 1f - dot ) - bodyA.Velocity * elapsed; popoutPriority = 1; } } } if ( Geometry.SegmentVsSegment( out time, bodyA.Position, posAtT, q0, q1 ) ) { // if collision with segment (and polygon is convex), we're done if ( bodyB.Convex ) return new Collision( true, time * elapsed, bodyA, bodyB, n, bodyA.Position + elapsed * time * ( bodyA.Velocity ) - n * bodyA.Radius ); else if ( time * elapsed < bestResult.Time ) bestResult = new Collision( true, time * elapsed, bodyA, bodyB, n, bodyA.Position + elapsed * time * ( bodyA.Velocity ) - n * bodyA.Radius ); } } // CHECK CORNER // inside circle? if ( Vector2.DistanceSquared( bodyA.Position, vert ) < ( bodyA.Radius * bodyA.Radius ) ) { if ( popoutPriority == 0 ) { popoutPriority = 2; normal = Vector2.Normalize( bodyA.Position - vert ); popoutPos = vert + bodyA.Radius * normal; popoutNormal = normal; popoutIsect = vert; } } // intersecting circle if ( Geometry.SegmentVsCircle( out time, out normal, bodyA.Position, posAtT, vert, bodyA.Radius ) ) { // additional checks to see if hitting correct sector of circle if ( Vector2.Dot( normal, edge ) > 0.0f ) { Vector2 nextVert = verts[( i + 1 ) % nVerts]; Vector2 edge2; Vector2.Subtract( ref nextVert, ref vert, out edge2 ); if ( Vector2.Dot( normal, edge2 ) < 0.0f ) { if ( bodyB.Convex ) return new Collision( true, time * elapsed, bodyA, bodyB, normal, vert + elapsed * time * bodyB.Velocity ); else if ( time * elapsed < bestResult.Time ) bestResult = new Collision( true, time * elapsed, bodyA, bodyB, normal, vert + elapsed * time * bodyB.Velocity ); } } } lastVert = vert; } // hack to keep objects from penetrating in rare cases if ( !bestResult.Collided && popoutPriority != 0 ) { if ( !bodyA.Flags.HasFlags( BodyFlags.Ghost ) && !bodyB.Flags.HasFlags( BodyFlags.Ghost ) ) bodyA.Position = popoutPos; else return new Collision( true, 0, bodyA, bodyB, popoutNormal, popoutIsect ); } return bestResult; }
void Start() { circle = GetComponent <PhysCircle>(); energy = maxEnergy; }
private void Jump( PhysCircle circle ) { circle.Velocity += 2f * circle.TouchNormal; glowSpring.SetSource( 1f ); glow.Color.R = 255; glow.Color.G = 225; glow.Color.B = 0; }
public Player( GameplayScreen screen, int playerNumber, PlayerIndex playerIndex, Avatar avatar, Vector2 pos, uint id ) : base(screen) { WheelModel = screen.Content.Load<CustomModel>( "Models/hamsterBall" ); foreach ( CustomModelSample.CustomModel.ModelPart part in WheelModel.ModelParts ) { part.Effect.CurrentTechnique = part.Effect.Techniques["Color"]; part.Effect.Parameters["Color"].SetValue( new Vector4( .8f, .7f, 1f, .225f ) ); part.Effect.Parameters["SpecularPower"].SetValue( 400 ); part.Effect.Parameters["Mask"].SetValue( MaskHelper.MotionBlur( 1 ) ); } DrawOrder = 8; WinState = PlayerWinState.None; soundPosition = Vector3.Zero; soundVelocity = Vector3.Zero; float depth = screen.Camera.Position.Z; DeathLine = depth * (float)Math.Tan( screen.Camera.Fov / 2f ); RespawnTime = float.MaxValue; shrinkBegin = 0; Scale = 1f; ScaleSpring = new SpringInterpolater( 1, 200, SpringInterpolater.GetCriticalDamping( 200 ) ); ScaleSpring.Active = true; ScaleSpring.SetSource( Scale ); ScaleSpring.SetDest( Scale ); PlayerIndex = playerIndex; PlayerNumber = playerNumber; BoostBurnRate = 1f; BoostRechargeRate = .25f; Avatar = avatar; BoundingCircle = new PhysCircle( Size / 2f, pos, 10f ); BoundingCircle.Parent = this; BoundingCircle.Elasticity = .4f; BoundingCircle.Friction = .5f; BoundingCircle.Collided += HandleCollision; BoundingCircle.Responded += HandleCollisionResponse; screen.PhysicsSpace.AddBody( BoundingCircle ); walkAnim = CustomAvatarAnimationData.GetAvatarAnimationData( "Walk", Screen.Content ); runAnim = CustomAvatarAnimationData.GetAvatarAnimationData( "Run", Screen.Content ); // pre-load animations for podium screen avatar.SetAnimation( AvatarAnimationPreset.Celebrate ); avatar.SetAnimation( AvatarAnimationPreset.Clap ); avatar.SetAnimation( AvatarAnimationPreset.FemaleAngry ); avatar.SetAnimation( AvatarAnimationPreset.MaleCry ); standAnim = (AvatarAnimationPreset)( (int)AvatarAnimationPreset.Stand0 + random.Next( 8 ) ); avatar.SetAnimation( standAnim ); if ( playerIndex >= PlayerIndex.One ) { HUD = new PlayerHUD( this, SignedInGamer.SignedInGamers[playerIndex] ); } else { HUD = new PlayerHUD( this, null ); playerAI = new PlayerAI( this ); } vertexDeclaration = new VertexDeclaration( screen.ScreenManager.GraphicsDevice, VertexPositionNormalTexture.VertexElements ); boosterSound = GameCore.Instance.AudioManager.Play2DCue( "booster", 1f ); boosterSound.Pause(); glow = new CircularGlow( new Vector3( BoundingCircle.Position, 0 ), Color.OrangeRed, Size ); glow.Player = this; screen.ObjectTable.Add( glow ); glowSpring = new SpringInterpolater( 1, 500, .75f * SpringInterpolater.GetCriticalDamping( 500 ) ); glowSpring.Active = true; glowSpring.SetSource( 0 ); glowSpring.SetDest( 0 ); Tag = new PlayerTag( this, screen.Content.Load<SpriteFont>( "Fonts/playerTagFont" ) ); SetID( id ); }