public void CollisionResponse(Rigidbody2D RB, Collider2D collider, float DeltaTime, ref List <GameObjectComponent> CDs, Vector2 CollisionPos, bool ResetVelocity) //change this { if (collider is CircleCollider) { CircleCollider circle2 = collider as CircleCollider; Vector2 C2 = circle2.Center + circle2.gameObject.Transform.Position; gameObject.Transform.Position = C2 + (Radius + circle2.Radius) * -Vector2.Normalize(C2 - Center - CollisionPos); Vector2 Diff = MathCompanion.Abs(C2 - Center - gameObject.Transform.Position) / (Radius + circle2.Radius); RB.Velocity = new Vector2(RB.Velocity.X * Diff.Y, RB.Velocity.Y * Diff.X); } else if (collider is BoxCollider2D) { Rectangle IncomingCollider = (collider as BoxCollider2D).GetDynamicCollider(); /////////////////////////This code is heavily inspired by "OneLoneCoder" the youtuber/////////////////////// gameObject.Transform.Position = CollisionPos; // Statically resolve the collision gameObject.Transform.Position -= Vector2.Normalize(vRayToNearest) * fOverlap; if (gameObject.Transform.Position.Y + Center.Y > IncomingCollider.Top && gameObject.Transform.Position.Y + Center.Y < IncomingCollider.Bottom) { RB.Velocity.X = 0; } if (gameObject.Transform.Position.X + Center.X > IncomingCollider.Left && gameObject.Transform.Position.X + Center.X < IncomingCollider.Right) { RB.Velocity.Y = 0; } } }
//You may use the following two functions to create a texture and use it, not creating a texture every frame! public static Texture2D CreateCircleTexture(int Radius, Color color) { Radius = (int)MathCompanion.Clamp(Radius, 1, Radius); int Diameter = 2 * Radius; Color[] Pixels = new Color[Diameter * Diameter]; Vector2 PointIterator = Vector2.Zero; Vector2 Center = Radius * Vector2.One; for (int i = 0; i < Diameter; i++) { for (int j = 0; j < Diameter; j++) { PointIterator.X = j; PointIterator.Y = i; if ((Center - PointIterator).Length() <= Radius) { Pixels[i * Diameter + j] = color; } //else // Pixels[i * Diameter + j] = Color.Transparent; } } Texture2D texture = new Texture2D(Setup.GraphicsDevice, Diameter, Diameter); texture.SetData(Pixels); return(texture); }
public float GetRayToLineSegmentIntersection(LineOccluder lineOccluder) { //Direction.Normalize(); Vector2 v1 = Origin - lineOccluder.StartPoint; Vector2 v2 = lineOccluder.EndPoint - lineOccluder.StartPoint; Vector2 v3 = new Vector2(-Direction.Y, Direction.X); float dot = Vector2.Dot(v2, v3); if (Math.Abs(dot) < 0.000001f) { return(-1.0f); } float t1 = MathCompanion.CrossProduct(v2, v1) / dot; float t2 = Vector2.Dot(v1, v3) / dot; if (t1 >= 0.0f && t2 >= 0.0f && t2 <= 1.0f) { t = t1; HitSomething = true; return(t1); } return(-1.0f); }
// return the distance of ray origin to intersection point public float GetRayToLineSegmentIntersection(Vector2 P1, Vector2 P2) { //Direction.Normalize(); Vector2 v1 = Origin - P1; Vector2 v2 = P2 - P1; Vector2 v3 = new Vector2(-Direction.Y, Direction.X); float dot = Vector2.Dot(v2, v3); if (Math.Abs(dot) < 0.000001f) { return(-1.0f); } float t1 = MathCompanion.CrossProduct(v2, v1) / dot; float t2 = Vector2.Dot(v1, v3) / dot; if (t1 >= 0.0f && t2 >= 0.0f && t2 <= 1.0f) { t = t1; return(t1); } return(-1.0f); }
public static void BezierLine(Point Start, Point Control1, Point Control2, Point End, Color color, float Layer, int Quality = 10) { Point Auxilary = Point.Zero; Point PrevPoint = Point.Zero; // The Green Line int xa = getPt(Start.X, Control1.X, 0); int ya = getPt(Start.Y, Control1.Y, 0); int xb = getPt(Control1.X, Control2.X, 0); int yb = getPt(Control1.Y, Control2.Y, 0); int xc = getPt(Control2.X, End.X, 0); int yc = getPt(Control2.Y, End.Y, 0); // The Blue Line int xm = getPt(xa, xb, 0); int ym = getPt(ya, yb, 0); int xn = getPt(xb, xc, 0); int yn = getPt(yb, yc, 0); PrevPoint = Auxilary; // The Black Dot Auxilary.X = getPt(xm, xn, 0); Auxilary.Y = getPt(ym, yn, 0); for (float i = 1.0f / Quality; i <= 1.01f; i += 1.0f / Quality) { // The Green Line xa = getPt(Start.X, Control1.X, i); ya = getPt(Start.Y, Control1.Y, i); xb = getPt(Control1.X, Control2.X, i); yb = getPt(Control1.Y, Control2.Y, i); xc = getPt(Control2.X, End.X, i); yc = getPt(Control2.Y, End.Y, i); // The Blue Line xm = getPt(xa, xb, i); ym = getPt(ya, yb, i); xn = getPt(xb, xc, i); yn = getPt(yb, yc, i); PrevPoint = Auxilary; // The Black Dot Auxilary.X = getPt(xm, xn, i); Auxilary.Y = getPt(ym, yn, i); Rectangle Rect = Rectangle.Empty; Rect.Location = PrevPoint; Rect.Size = new Point((int)Math.Ceiling((Auxilary - PrevPoint).ToVector2().Length()), 3); DrawLine(Rect, color, MathCompanion.GetAngle(PrevPoint.ToVector2(), Auxilary.ToVector2()), Layer, Vector2.Zero); } }
public static bool AddLayer(string Name, int Value) { if (LayerWithValue.Count >= Maximum) { return(false); } if (LayerWithValue.ContainsValue(Value * 0.01f)) { return(false); } if (LayerWithValue.ContainsKey(Name)) { return(false); } LayerWithValue.Add(Name, MathCompanion.Clamp(Value * 0.01f, 0, 0.19f)); return(true); }
public void Update(GameTime gameTime) { if (!Finished) { if (!Paused) { TimeCounter = MathCompanion.Clamp(TimeCounter + (float)gameTime.ElapsedGameTime.TotalSeconds, 0, TimeDuration); } if (TimeCounter >= TimeDuration) { FinishedButIsLooping = false; Finished = true; if (ReverseAfterFinishing) { ReverseKeyFrame(); } if (PlayAfterFinishing) { Play(); PlayAfterFinishing = false; } if (IsLooping) { FinishedButIsLooping = true; Play(); } } } else if (ReverseAfterFinishing) { ReverseKeyFrame(); } }
public static void DrawLine(Vector2 Start, Vector2 End, Color color, int Thickness = 2) //Draw line { Rectangle Rect = Rectangle.Empty; Rect.Location = Start.ToPoint(); Rect.Width = (int)(End - Start).Length(); Rect.Height = Math.Clamp(Thickness, 1, 50); Setup.spriteBatch.Draw(_textureFilled, Rect, null, color, MathHelper.ToRadians(MathCompanion.GetAngle(Start, End)), Vector2.Zero, SpriteEffects.None, 0); }
public static void ApplyLighting() { //You probably need to add they XY coordinates of BiasScene in editor mode too (below two lines) //Ignore this for now Rectangle BiasScene = new Rectangle((int)(Setup.Camera.Position.X - Setup.graphics.PreferredBackBufferWidth * 0.5f), (int)(Setup.Camera.Position.Y - Setup.graphics.PreferredBackBufferHeight * 0.5f), Setup.graphics.PreferredBackBufferWidth, Setup.graphics.PreferredBackBufferHeight); if (FN_Editor.EditorScene.IsThisTheEditor) { BiasScene = new Rectangle((int)(0 + -Setup.graphics.PreferredBackBufferWidth * 0.5f + Setup.Camera.Position.X), (int)(0 - Setup.graphics.PreferredBackBufferHeight * 0.5f + Setup.Camera.Position.Y), (int)FN_Editor.GizmosVisualizer.SceneWindow.Z, (int)FN_Editor.GizmosVisualizer.SceneWindow.W); } Light[] LIGHTS = SceneManager.ActiveScene.FindGameObjectComponents <Light>(); if (LIGHTS == null || LIGHTS.Length == 0) { //Setup.GraphicsDevice.SetRenderTarget(null); //Setup.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Setup.Camera.GetViewTransformationMatrix()); //Setup.spriteBatch.Draw(RenderTarget2D, BiasScene.Location.ToVector2(), new Rectangle(Point.Zero, BiasScene.Size), Color.White); //Setup.spriteBatch.End(); return; } int LightCount = LIGHTS.Length; if (LightCount == 0) { return; } int CappedLightCount = LightCount > MAX_LIGHT_COUNT ? MAX_LIGHT_COUNT : LightCount; Vector3[] COLOR = new Vector3[CappedLightCount]; float[] InnerRadius = new float[CappedLightCount]; float[] Radius = new float[CappedLightCount]; float[] Attenuation = new float[CappedLightCount]; float[] X_Bias = new float[CappedLightCount]; float[] Y_Bias = new float[CappedLightCount]; float[] AngularRadius = new float[CappedLightCount]; float[] InnerIntensity = new float[CappedLightCount]; float[] ShadowIntensity = new float[CappedLightCount]; float[] CastShadow = new float[CappedLightCount]; HandyList.Clear(); Points.Clear(); //1- Needs some optimization, like if light is out of bounds of screen, it shouldn't be updated or sent to the light shader if (CastShadows_Global) { //Rendering ShadowMap Here Setup.GraphicsDevice.SetRenderTarget(ShadowMap); ShadowCaster[] Occluders = SceneManager.ActiveScene.FindGameObjectComponents <ShadowCaster>(); Ray ray = new Ray(); Vector2 Bias = -new Vector2(Setup.graphics.PreferredBackBufferWidth * 0.5f - Setup.Camera.Position.X, Setup.graphics.PreferredBackBufferHeight * 0.5f - Setup.Camera.Position.Y); if (Occluders != null) { Points.Add(Bias); Points.Add(Bias + Vector2.UnitX * Setup.graphics.PreferredBackBufferWidth); Points.Add(Bias + Vector2.UnitX * Setup.graphics.PreferredBackBufferWidth + Vector2.UnitY * Setup.graphics.PreferredBackBufferHeight); Points.Add(Bias + Vector2.UnitY * Setup.graphics.PreferredBackBufferHeight); BorderOccluders[0].SetOccluder(Bias, Vector2.UnitX * Setup.graphics.PreferredBackBufferWidth + Bias); BorderOccluders[1].SetOccluder(Bias + Vector2.UnitX * Setup.graphics.PreferredBackBufferWidth, new Vector2(Setup.graphics.PreferredBackBufferWidth, Setup.graphics.PreferredBackBufferHeight) + Bias); BorderOccluders[2].SetOccluder(Bias + Vector2.Zero, new Vector2(0, Setup.graphics.PreferredBackBufferHeight) + Bias); BorderOccluders[3].SetOccluder(Bias + new Vector2(0, Setup.graphics.PreferredBackBufferHeight), new Vector2(Setup.graphics.PreferredBackBufferWidth, Setup.graphics.PreferredBackBufferHeight) + Bias); HandyList.Add(BorderOccluders[0]); HandyList.Add(BorderOccluders[1]); HandyList.Add(BorderOccluders[2]); HandyList.Add(BorderOccluders[3]); Setup.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Setup.Camera.GetViewTransformationMatrix()); // -> Mandatory foreach (ShadowCaster SC in Occluders) { if (!SC.Enabled) { continue; } HitBoxDebuger.DrawRectangle(SC.gameObject.GetComponent <SpriteRenderer>().Sprite.DynamicScaledRect()); //HitBoxDebuger.DrawRectangle_Effect(SC.gameObject.GetComponent<SpriteRenderer>().Sprite.DynamicScaledRect()); LineOccluder[] LOCS = SC.ConvertToLineOccluders(); for (int i = 0; i < 4; i++) { Vector2 OccluderDirection = Vector2.Normalize(LOCS[i].EndPoint - LOCS[i].StartPoint); Points.Add(LOCS[i].StartPoint); Points.Add(LOCS[i].StartPoint - OccluderDirection * 0.5f); //Casting rays from the side of an object HandyList.Add(LOCS[i]); } } Setup.spriteBatch.End(); } if (HandyList.Count != 0) { for (int k = 0; k < LIGHTS.Length; k++) { PointsTriangle.Clear(); if (!LIGHTS[k].gameObject.IsActive() || !LIGHTS[k].Enabled) { continue; } foreach (Vector2 P in Points) { float ClosestIntersection = 100000000; //Dummy Number Vector2 FoundClosestPoint = Vector2.Zero; float Distance = -1; ray.Origin = LIGHTS[k].gameObject.Transform.Position; ray.Direction = P - ray.Origin; //Don't Normalize! foreach (LineOccluder LOC in HandyList) //Needs Optimization { Distance = ray.GetRayToLineSegmentIntersection(LOC); if (Distance != -1 && Distance < ClosestIntersection) { ClosestIntersection = Distance; FoundClosestPoint = ray.GetAPointAlongRay(Distance); } } if (ClosestIntersection != 100000000) //INTERSECTION { PointsTriangle.Add(FoundClosestPoint); } } PointsTriangle.Sort((x, y) => MathCompanion.GetAngle(x, LIGHTS[k].gameObject.Transform.Position).CompareTo(MathCompanion.GetAngle(y, LIGHTS[k].gameObject.Transform.Position))); Bias = -Bias; //DrawTriangles for (int i = 0; i < PointsTriangle.Count - 1; i++) { HitBoxDebuger.DrawTriangle(Bias + PointsTriangle[i], Bias + PointsTriangle[i + 1], Bias + LIGHTS[k].gameObject.Transform.Position); //White Color } HitBoxDebuger.DrawTriangle(Bias + PointsTriangle[PointsTriangle.Count - 1], Bias + PointsTriangle[0], Bias + LIGHTS[k].gameObject.Transform.Position); } } ShadowMap_param.SetValue(ShadowMap); Setup.GraphicsDevice.SetRenderTarget(RenderTarget2D); } for (int i = 0; i < CappedLightCount; i++) { if (LIGHTS[i].Enabled == false || LIGHTS[i].gameObject.IsActive() == false) { continue; } LIGHTS[i].gameObject.Transform.AdjustTransformation(); COLOR[i] = LIGHTS[i].color.ToVector3(); InnerRadius[i] = MathHelper.Clamp(LIGHTS[i].InnerRadius, 0, LIGHTS[i].OuterRadius) * Setup.Camera.Zoom; Radius[i] = MathHelper.Clamp(LIGHTS[i].OuterRadius, 0, 1) * Setup.Camera.Zoom; Attenuation[i] = MathHelper.Clamp(LIGHTS[i].Attenuation, 0, float.MaxValue); X_Bias[i] = (LIGHTS[i].gameObject.Transform.Position.X - Setup.Camera.Position.X) / Setup.graphics.PreferredBackBufferWidth; Y_Bias[i] = (LIGHTS[i].gameObject.Transform.Position.Y - Setup.Camera.Position.Y) / Setup.graphics.PreferredBackBufferHeight; AngularRadius[i] = MathHelper.Clamp(LIGHTS[i].AngularRadius, 0, 360); InnerIntensity[i] = MathHelper.Clamp(LIGHTS[i].InnerInensity, 1, float.MaxValue); ShadowIntensity[i] = MathHelper.Clamp(1 - LIGHTS[i].ShadowIntensity, 0, 1); CastShadow[i] = LIGHTS[i].CastShadow ? 1 : 0; if (LIGHTS[i].Type == LightTypes.Directional) //Bug here where directional intensity is set forever { DirectionalIntensity_param.SetValue(MathHelper.Clamp(LIGHTS[i].DirectionalIntensity, 0, 1)); InnerRadius[i] = 0; Radius[i] = 0; } } LightCount_param.SetValue(CappedLightCount); //CameraPosNorm_param.SetValue(new Vector2(Setup.Camera.Position.X / Setup.resolutionIndependentRenderer.VirtualWidth, Setup.Camera.Position.Y / Setup.resolutionIndependentRenderer.VirtualHeight)); AngularRadius_param.SetValue(AngularRadius); AngularRadius_param.SetValue(AngularRadius); X_Bias_param.SetValue(X_Bias); Y_Bias_param.SetValue(Y_Bias); YOverX_param.SetValue(YOVERX); Color_param.SetValue(COLOR); Radius_param.SetValue(Radius); InnerRadius_param.SetValue(InnerRadius); InnerIntensity_param.SetValue(InnerIntensity); Attenuation_param.SetValue(Attenuation); CastShadows_param.SetValue(CastShadows_Global); CastShadow_param.SetValue(CastShadow); ShadowConstant_param.SetValue(ShadowIntensity); //Setup.GraphicsDevice.SetRenderTarget(null); //Setup.GraphicsDevice.SetRenderTarget(RenderTarget2D); Setup.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, LightEffect, Setup.Camera.GetViewTransformationMatrix()); Setup.spriteBatch.Draw(RenderTarget2D, BiasScene.Location.ToVector2(), Color.White); Setup.spriteBatch.End(); }
public override void Update(GameTime gameTime) { SpawnRateCounter += (float)gameTime.ElapsedGameTime.TotalSeconds; if (SpawnRateCounter >= SpawnRate) { if (Particles.Count >= MaxParticles) { Particles.Dequeue(); } if (gameObject.Transform.Position - Lpos != Vector2.Zero) { Particle particle = new Particle(false); particle.FadeColor = FadeColor; particle.Position = Lpos + OffsetPosition; particle.LifeTime = VanishAfter; //if (RandomSize) // particle.Size = (int)(ParticleSize * random.NextDouble()); //else // particle.Size = ParticleSize; particle.ShrinkMode = ShrinkWithTime; if (RandomColor) { Color1 = Color.Multiply(ColorDefault, (float)random.NextDouble()); Color2 = Color.Multiply(ColorDefault, (float)random.NextDouble()); Color3 = Color.Multiply(ColorDefault, (float)random.NextDouble()); particle.Color.R = Color1.R; particle.Color.G = Color2.G; particle.Color.B = Color3.B; } else { particle.Color = Color; } particle.Rotation = MathCompanion.GetAngle(Lpos, gameObject.Transform.Position); particle.Length = 1 + (int)Math.Ceiling((gameObject.Transform.Position - Lpos).Length()); particle.Height = SegmentWidth; particle.Layer = gameObject.Layer; Particles.Enqueue(particle); } SpawnRateCounter = 0; } if (Particles.Count != 0) { if ((Particles.Peek() as Particle).Expired) { Particles.Dequeue(); } } foreach (Particle P in Particles) { P.Update(gameTime); } Lpos = gameObject.Transform.Position; }