/// <summary> /// Método de auxílio que calcula e define os limites do ator através de sua posição, escala e origem na propriedade Transform, como também /// os limites rotacionados através de sua rotação e origem. /// </summary> /// <param name="width">Informa e define o valor da largura do ator.</param> /// <param name="height">Informa e define o valor da altura do ator.</param> /// <param name="amountOriginX">Define o valor que deve ser incrementado a propriedade Transform.Origin no eixo X, se necessário.</param> /// <param name="amountOriginY">Define o valor que deve ser incrementado a propriedade Transform.Origin no eixo Y, se necessário.</param> protected void CalcBounds(int width, int height, float amountOriginX, float amountOriginY) { Transform.Size = new Point(width, height); //Posição int x = (int)Transform.X; int y = (int)Transform.Y; //Escala float sx = Transform.Xs; float sy = Transform.Ys; //Origem float ox = Transform.Xo; float oy = Transform.Yo; //Obtém uma matrix com a posição e escala através de sua origem Matrix m = Matrix.CreateTranslation(-ox + -amountOriginX, -oy + -amountOriginY, 0) * Matrix.CreateScale(sx, sy, 1) * Matrix.CreateTranslation(x, y, 0); //Os limites finais Rectangle rec = new Rectangle((int)m.Translation.X, (int)m.Translation.Y, (int)Transform.ScaledWidth, (int)Transform.ScaledHeight); bounds = rec; //Os limites rotacionados RotatedRectangle rotated = Rotation.GetRectangle(bounds, new Vector2(bounds.X + ox, bounds.Y + oy), Transform.Rotation); Polygon poly = new Polygon(); poly.Set(rotated); boundsR = poly; }
public RectangleOutline(RotatedRectangle rotRect, Color color, int width) : base(5, false) { this.color = color; this.width = width; lines = new List <Line>(); lines.Add(new Line(color, width, rotRect.LowerLeftCorner(), rotRect.LowerRightCorner(), 5)); lines.Add(new Line(color, width, rotRect.LowerLeftCorner(), rotRect.UpperLeftCorner(), 5)); lines.Add(new Line(color, width, rotRect.LowerRightCorner(), rotRect.UpperRightCorner(), 5)); lines.Add(new Line(color, width, rotRect.UpperLeftCorner(), rotRect.UpperRightCorner(), 5)); }
public RectangleOutline(RotatedRectangle rotRect, Color color, int width) : base(5, false) { this.color = color; this.width = width; lines = new List<Line>(); lines.Add(new Line(color, width, rotRect.LowerLeftCorner(), rotRect.LowerRightCorner(), 5)); lines.Add(new Line(color, width, rotRect.LowerLeftCorner(), rotRect.UpperLeftCorner(), 5)); lines.Add(new Line(color, width, rotRect.LowerRightCorner(), rotRect.UpperRightCorner(), 5)); lines.Add(new Line(color, width, rotRect.UpperLeftCorner(), rotRect.UpperRightCorner(), 5)); }
/// <summary> /// Gets all tiles that interesect with a rotated rectangle /// </summary> /// <param name="rectangle">The rectangle to check for inteserctions with.</param> /// <returns>An array of adjacent interesetcing tiles.</returns> public CollisionTile[] GetAdjacentTilesFromIntersection(RotatedRectangle rectangle) { // list of tiles List<CollisionTile> adjTiles = new List<CollisionTile>(); // the 8 cases, also checking to make sure that the 8 cases exist! int up = this.GridY - 1; int down = this.GridY + 1; int left = this.GridX - 1; int right = this.GridX + 1; if (up >= 0) if (rectangle.Intersects(grid[GridX, up].loc)) adjTiles.Add(grid[GridX, up]); if (down < grid.GetLength(1)) if (rectangle.Intersects(grid[GridX, down].loc)) adjTiles.Add(grid[GridX, down]); if (up >= 0 && left >= 0) if (rectangle.Intersects(grid[left, up].loc)) adjTiles.Add(grid[left, up]); if (down < grid.GetLength(1) && left >= 0) if (rectangle.Intersects(grid[left, down].loc)) adjTiles.Add(grid[left, down]); if (up >= 0 && right < grid.GetLength(0)) if (rectangle.Intersects(grid[right, up].loc)) adjTiles.Add(grid[right, up]); if (down < grid.GetLength(1) && right < grid.GetLength(0)) if (rectangle.Intersects(grid[right, down].loc)) adjTiles.Add(grid[right, down]); if (left >= 0) if (rectangle.Intersects(grid[left, GridY].loc)) adjTiles.Add(grid[left, GridY]); if (right < grid.GetLength(0)) if (rectangle.Intersects(grid[right, GridY].loc)) adjTiles.Add(grid[right, GridY]); if (rectangle.Intersects(this.loc)) adjTiles.Add(this); return adjTiles.ToArray(); }
public override void EvtDraw() { Color c = Color.White; Vector2?vp; vp = line_in_rectangle_rotated_nearest(new Vector2(200, 200), mouse, rr); if (vp.HasValue) { c = Color.Red; } draw_set_color(c); // draw_line(200f, 200f, mouse.X, mouse.Y); if (vp.HasValue) { // draw_circle_fast(vp.Value, 8, 24, Color.Red); } draw_set_color(Color.White); t2.Point1 = mouse; t2.Point2 = new Vector2(mouse.X + 100, mouse.Y); t2.Point3 = new Vector2(mouse.X + 50, mouse.Y - 50); List <Vector2> p = triangle_in_triangle_all(t1, t2); foreach (Vector2 v in p) { draw_circle_fast(v, 8, 24, Color.Red); } // draw_triangle(t1, true, 0); // draw_triangle(t2, true, 0); List <Vector2> sorted = convex_hull(randomVectors); for (int i = 0; i < randomVectors.Count; i++) { Vector2 v = randomVectors[i]; draw_set_color(Color.White); if (point_in_circle(v, mouse, 8)) { draw_set_color(Color.Lime); if (mouse_check_button_pressed(MouseButtons.Left)) { selected = v; } } if (v == selected) { v.X = mouse.X; v.Y = mouse.Y; randomVectors[i] = v; } draw_circle_fast(v, 16, 24, DrawGetColor()); } if (mouse_check_button_released(MouseButtons.Left)) { selected = Vector2.One; } Vector2 s = sorted[0]; Vector2 last = sorted[0]; draw_set_color(Color.Red); foreach (Vector2 v in sorted) { draw_line(s, v); s = v; } draw_line(s, last); draw_set_color(Color.White); Vector2 p1 = new Vector2(8, 8); Vector2 p4 = new Vector2(8, 24); Vector2 p2 = new Vector2(24, 8); Vector2 p3 = new Vector2(24, 24); RotatedRectangle r = new RotatedRectangle(p1, p2, p3, p4); var list = line_in_rectangle_rotated_all(new Vector2(0, 0), new Vector2(50, 50), r); draw_line(p1, p2); draw_line(p2, p3); draw_line(p3, p4); draw_line(p4, p1); draw_line(new Vector2(0, 0), new Vector2(50, 50)); // draw_triangle(100, 100, ); }
/* * To-do * - throw a rectangle in the direction entity is facing (faceDirection) * - check to see if this invis rectangle or the player intersects with anything * - use collision manager to get surrounding tiles from where this entity is. * - speedup: only check tiles that are in the same direction as the player (math here . 3.) * - once another ENTITY is found, call its action method (pass this entity as a param.) (NOT SURE ABOUT THIS...) * - closest to the player or first to find? */ // Douglas Gliner // spending too much time on making this versatile, this can only be 32 units away from player. public void Interact() { // ray cast RotatedRectangle rayCast = new RotatedRectangle(new FloatRectangle((location.Center.X + (((sprite.Texture.Width) * (float)Math.Cos(faceDirection - Math.PI / 2))) - (sprite.Texture.Width / 2)), (location.Center.Y + (((sprite.Texture.Height) * (float)Math.Sin(faceDirection - Math.PI / 2))) - (interactRange / 2)), sprite.Texture.Width, interactRange), faceDirection); //FloatRectangle rectangleToRotate = new FloatRectangle(location.X + 5 + (sprite.Texture.Width * (float)Math.Cos(faceDirection - Math.PI / 2)), location.Y + 5 + (sprite.Texture.Height * (float)Math.Sin(faceDirection - Math.PI / 2)), sprite.Texture.Width, interactRange); //FloatRectangle rectangleToRotate = new FloatRectangle(location.Center.X - sprite.Texture.Width / 2, location.Center.Y - interactRange / 2, sprite.Texture.Width, interactRange); //RotatedRectangle rayCast = new RotatedRectangle(rectangleToRotate, faceDirection); //Console.WriteLine("Radius: {0}", Vector2.Distance(location.Location, rayCast.UpperLeftCorner())); //Console.WriteLine("X: {0}, Y: {1} Theta: {2}", rayCast.X - location.X, rayCast.Y - location.Y, faceDirection); //Console.Write("ThisX: {0}, ThisY: {1}", location.X, locat) // tiles to do a check for entities CollisionTile[] intersectingTiles = CurrentCollisionTile.GetAdjacentTilesFromIntersection(rayCast); // foreach through each tile, foreach through each ent list and find ent closest to this ent. // starts with distance from edge midpoint closest to player to top left corner. // the closer items are to player, that item will be acted upon. //float shortestDistance = (float)Math.Sqrt((rayCast.Height * rayCast.Height) + ((rayCast.Width * rayCast.Width) / 4)); // start with longest distance possible which in this case is from center of player to a corner of raycast float shortestDistance = Vector2.Distance(this.location.Center, rayCast.UpperLeftCorner()); Entity entityToInteract = null; foreach (CollisionTile tile in intersectingTiles) { // only look at entities that interset with raycast bounds!! foreach (Entity ent in tile.EntitiesInTile.Where(ent => rayCast.Intersects(ent.location))) { if (ent == this) { continue; } // want to make sure ATLEAST more than the center is inside the check box!! float tmpDist = Vector2.Distance(ent.location.Center, this.location.Center); if (tmpDist < shortestDistance && ent.interactData != null) { entityToInteract = ent; shortestDistance = tmpDist; } } } // debug // if entity is null, return if (entityToInteract == null) { return; } //We need to fix this. entityToInteract.Action(this, ""); // do interact method here... (events or method?) Game1.Instance.renderManager.EmitParticle(new RectangleOutline(new RotatedRectangle(entityToInteract.location, 0), Color.Purple, 1)); Game1.Instance.renderManager.EmitParticle(new RectangleOutline(rayCast, Color.White, 1)); foreach (CollisionTile t in intersectingTiles) { Game1.Instance.renderManager.EmitParticle(new RectangleOutline(new RotatedRectangle(t.Rectangle, 0), Color.Red, 1)); } }
/* * To-do * - throw a rectangle in the direction entity is facing (faceDirection) * - check to see if this invis rectangle or the player intersects with anything * - use collision manager to get surrounding tiles from where this entity is. * - speedup: only check tiles that are in the same direction as the player (math here . 3.) * - once another ENTITY is found, call its action method (pass this entity as a param.) (NOT SURE ABOUT THIS...) * - closest to the player or first to find? */ // Douglas Gliner // spending too much time on making this versatile, this can only be 32 units away from player. public void Interact() { // ray cast RotatedRectangle rayCast = new RotatedRectangle(new FloatRectangle((location.Center.X + (((sprite.Texture.Width) * (float)Math.Cos(faceDirection - Math.PI / 2))) - (sprite.Texture.Width / 2)), (location.Center.Y + (((sprite.Texture.Height) * (float)Math.Sin(faceDirection - Math.PI / 2))) - (interactRange / 2)), sprite.Texture.Width, interactRange), faceDirection); //FloatRectangle rectangleToRotate = new FloatRectangle(location.X + 5 + (sprite.Texture.Width * (float)Math.Cos(faceDirection - Math.PI / 2)), location.Y + 5 + (sprite.Texture.Height * (float)Math.Sin(faceDirection - Math.PI / 2)), sprite.Texture.Width, interactRange); //FloatRectangle rectangleToRotate = new FloatRectangle(location.Center.X - sprite.Texture.Width / 2, location.Center.Y - interactRange / 2, sprite.Texture.Width, interactRange); //RotatedRectangle rayCast = new RotatedRectangle(rectangleToRotate, faceDirection); //Console.WriteLine("Radius: {0}", Vector2.Distance(location.Location, rayCast.UpperLeftCorner())); //Console.WriteLine("X: {0}, Y: {1} Theta: {2}", rayCast.X - location.X, rayCast.Y - location.Y, faceDirection); //Console.Write("ThisX: {0}, ThisY: {1}", location.X, locat) // tiles to do a check for entities CollisionTile[] intersectingTiles = CurrentCollisionTile.GetAdjacentTilesFromIntersection(rayCast); // foreach through each tile, foreach through each ent list and find ent closest to this ent. // starts with distance from edge midpoint closest to player to top left corner. // the closer items are to player, that item will be acted upon. //float shortestDistance = (float)Math.Sqrt((rayCast.Height * rayCast.Height) + ((rayCast.Width * rayCast.Width) / 4)); // start with longest distance possible which in this case is from center of player to a corner of raycast float shortestDistance = Vector2.Distance(this.location.Center, rayCast.UpperLeftCorner()); Entity entityToInteract = null; foreach (CollisionTile tile in intersectingTiles) { // only look at entities that interset with raycast bounds!! foreach (Entity ent in tile.EntitiesInTile.Where(ent => rayCast.Intersects(ent.location))) { if (ent == this) continue; // want to make sure ATLEAST more than the center is inside the check box!! float tmpDist = Vector2.Distance(ent.location.Center, this.location.Center); if (tmpDist < shortestDistance && ent.interactData != null) { entityToInteract = ent; shortestDistance = tmpDist; } } } // debug // if entity is null, return if (entityToInteract == null) return; //We need to fix this. entityToInteract.Action(this, ""); // do interact method here... (events or method?) Game1.Instance.renderManager.EmitParticle(new RectangleOutline(new RotatedRectangle(entityToInteract.location, 0), Color.Purple, 1)); Game1.Instance.renderManager.EmitParticle(new RectangleOutline(rayCast, Color.White, 1)); foreach (CollisionTile t in intersectingTiles) Game1.Instance.renderManager.EmitParticle(new RectangleOutline(new RotatedRectangle(t.Rectangle, 0), Color.Red, 1)); }
/// <summary> /// Will find the next obstacle in the beam's way /// </summary> /// <param name="obstacles">the array where to look for objects</param> /// <param name="start">the starting point of the beam</param> /// <param name="direction">the way in which we go on the direction</param> /// <param name="angle">the angle of the path to look for an object</param> /// <returns>the closest obstacle on the given path</returns> private Obstacle FindObject(Obstacle[] obstacles, Vector2 start, short direction, float angle) { //update 1300 with MaxWidth //the beam of light RotatedRectangle beam = new RotatedRectangle(new Rectangle((int)start.X, (int)start.Y, 1300, 2), angle); beam.Origin = new Vector2(beam.X, beam.Y); float dmin = 1300; float distance; Obstacle colidedObstacle = null; foreach (var obstacle in obstacles) { distance = Vector2.Distance(start, obstacle.Center); if (beam.Intersects(obstacle) && distance < dmin && distance > 0) { dmin = Vector2.Distance(start, obstacle.Center); colidedObstacle = obstacle; } } return colidedObstacle; }
/// <summary> /// Gets all tiles that interesect with a rotated rectangle /// </summary> /// <param name="rectangle">The rectangle to check for inteserctions with.</param> /// <returns>An array of adjacent interesetcing tiles.</returns> public CollisionTile[] GetAdjacentTilesFromIntersection(RotatedRectangle rectangle) { // list of tiles List <CollisionTile> adjTiles = new List <CollisionTile>(); // the 8 cases, also checking to make sure that the 8 cases exist! int up = this.GridY - 1; int down = this.GridY + 1; int left = this.GridX - 1; int right = this.GridX + 1; if (up >= 0) { if (rectangle.Intersects(grid[GridX, up].loc)) { adjTiles.Add(grid[GridX, up]); } } if (down < grid.GetLength(1)) { if (rectangle.Intersects(grid[GridX, down].loc)) { adjTiles.Add(grid[GridX, down]); } } if (up >= 0 && left >= 0) { if (rectangle.Intersects(grid[left, up].loc)) { adjTiles.Add(grid[left, up]); } } if (down < grid.GetLength(1) && left >= 0) { if (rectangle.Intersects(grid[left, down].loc)) { adjTiles.Add(grid[left, down]); } } if (up >= 0 && right < grid.GetLength(0)) { if (rectangle.Intersects(grid[right, up].loc)) { adjTiles.Add(grid[right, up]); } } if (down < grid.GetLength(1) && right < grid.GetLength(0)) { if (rectangle.Intersects(grid[right, down].loc)) { adjTiles.Add(grid[right, down]); } } if (left >= 0) { if (rectangle.Intersects(grid[left, GridY].loc)) { adjTiles.Add(grid[left, GridY]); } } if (right < grid.GetLength(0)) { if (rectangle.Intersects(grid[right, GridY].loc)) { adjTiles.Add(grid[right, GridY]); } } if (rectangle.Intersects(this.loc)) { adjTiles.Add(this); } return(adjTiles.ToArray()); }