/// <summary> /// Performs a collision test for two polygons. /// </summary> /// <param name="p1">Polygon 1</param> /// <param name="p2">Polygon 2</param> /// <returns>true if a collision</returns> public bool Test(Polygon p1, Polygon p2) { poly1 = null; poly2 = null; depth = 0; // Symmetrical search for an edge that segments the two... if (!TestLR(p1, p2)) return false; if (!TestLR(p2, p1)) return false; // We know we have a collision. Determine the vertex and edge that // are involved. p1inp2 = true; if (!TestVE(p1, p2)) { if(!TestVE(p2, p1)) return false; p1inp2 = false; } if (poly1 == null || depth == 0) { // No actual collision... return false; } return true; }
/// <summary> /// Test of all vertices in p1 against all edges in p2. /// This is looking for a vertex in c1 that is inside c2, a /// symmetrical problem to the above tests. /// </summary> /// <param name="p1">Polygon 1</param> /// <param name="p2">Polygon 2</param> /// <returns>true if the collision point was found.</returns> private bool TestVE(Polygon p1, Polygon p2) { List<Vector2> v1 = p1.Vertices; List<Vector2> v2 = p2.Vertices; // // Loop over all of the vertices. // We are looking for the one vertex that // is most deeply embedded in the object. // bool anyVert = false; // Until we know float bestVertR = 0.0f; // Looking for deepest, so start low Vector2 bestVertN = new Vector2(); // Best intersection normal foreach (Vector2 v1a in v1) { bool possible = true; // Candidate vertex // // Loop over all of the edges. Is this vertex contained by all? // // Last vertex in v2 Vector2 v2a = (Vector2)v2[v2.Count - 1]; float bestR = 1e10f; // Least penetration for this vertex Vector2 bestN = new Vector2(); // Best intersection normal foreach (Vector2 v2b in v2) { // Compute the edge line function float a = v2a.Y - v2b.Y; float b = v2b.X - v2a.X; // Normalize these values float len = (float)Math.Sqrt(a * a + b * b); a /= len; b /= len; // Compute c and r... float c = -a * v2a.X - b * v2a.Y; float r = a * v1a.X + b * v1a.Y + c; // If r <= zero, we're on the inside side of the line. if (r > 0) { possible = false; break; } else if (-r < bestR) { bestR = -r; bestN.X = a; bestN.Y = b; } // Make this the end point for the next pass v2a = v2b; } // The possibility this vertex is inside never got cleared. // It must be actually inside. if (possible && bestR > bestVertR) { bestVertN = bestN; bestVertR = bestR; anyVert = true; } } if (anyVert) { poly1 = p1; poly2 = p2; n = bestVertN; depth = bestVertR; return true; } // If no penetrating vertex is found. return false; }
// Test of all vertices in c1 against all edges in c2. // Returns false if there is an edge that separates the two // True simply means potential for an overlap private bool TestLR(Polygon p1, Polygon p2) { List<Vector2> v1 = p1.Vertices; List<Vector2> v2 = p2.Vertices; // Last vertex in v2 Vector2 v2a = (Vector2)v2[v2.Count - 1]; int cnt2 = 0; // Edge counter foreach (Vector2 v2b in v2) { // Compute the edge line function float a = v2a.Y - v2b.Y; float b = v2b.X - v2a.X; float c = -a * v2a.X - b * v2a.Y; bool possible = true; int cnt1 = 0; // Vertex counter foreach (Vector2 v1a in v1) { float r = a * v1a.X + b * v1a.Y + c; // If r <= zero, we're on the wrong side of the line. // This can't be a separator line. if (r <= 0) { possible = false; break; } cnt1++; } // If the possibility that this is a separator line never got cleared, // it just me one. if (possible) { // We have a separator line. This is our witness, save it return false; } // Make this the end point for the next pass v2a = v2b; cnt2++; } // If no separating edges have been found, we potentially have an overlap return true; }
public Game() { InitializeComponent(); if (!InitializeDirect3D()) return; vertices = new VertexBuffer(typeof(CustomVertex.PositionColored), // Type of vertex 4, // How many device, // What device 0, // No special usage CustomVertex.PositionColored.Format, Pool.Managed); background = new Background(device, playingW, playingH); score = new Score(device); lives = new Lives(device); lives.lives_number = 3; game_over = new GameOver(device); //create the font font = new Microsoft.DirectX.Direct3D.Font(device, // Device we are drawing on 20, // Font height in pixels 0, // Font width in pixels or zero to match height FontWeight.Bold, // Font weight (Normal, Bold, etc.) 0, // mip levels (0 for default) false, // italics? CharacterSet.Default, // Character set to use Precision.Default, // The font precision, try some of them... FontQuality.Default, // Quality? PitchAndFamily.FamilyDoNotCare, // Pitch and family, we don't care "Arial"); // And the name of the font // Determine the last time stopwatch.Start(); lastTime = stopwatch.ElapsedMilliseconds; Polygon floor = new Polygon(); floor.AddVertex(new Vector2(0, 1)); floor.AddVertex(new Vector2(playingW, 1)); floor.AddVertex(new Vector2(playingW, 0.9f)); floor.AddVertex(new Vector2(0, 0.9f)); floor.Color = Color.CornflowerBlue; world.Add(floor); AddObstacle(2, 3, 1.7f, 1.9f, Color.Crimson); AddObstacle(4, 4.2f, 1, 2.1f, Color.Coral); AddObstacle(5, 6, 2.2f, 2.4f, Color.BurlyWood); AddObstacle(5.5f, 6.5f, 3.2f, 3.4f, Color.PeachPuff); AddObstacle(6.5f, 7.5f, 2.5f, 2.7f, Color.Chocolate); Platform platform = new Platform(); platform.AddVertex(new Vector2(3.2f, 2)); platform.AddVertex(new Vector2(3.9f, 2)); platform.AddVertex(new Vector2(3.9f, 1.8f)); platform.AddVertex(new Vector2(3.2f, 1.8f)); platform.Color = Color.CornflowerBlue; world.Add(platform); Texture texture = TextureLoader.FromFile(device, "../../stone08.bmp"); PolygonTextured pt = new PolygonTextured(); pt.Tex = texture; pt.AddVertex(new Vector2(1.2f, 3.5f)); pt.AddTex(new Vector2(0, 1)); pt.AddVertex(new Vector2(1.9f, 3.5f)); pt.AddTex(new Vector2(0, 0)); pt.AddVertex(new Vector2(1.9f, 3.3f)); pt.AddTex(new Vector2(1, 0)); pt.AddVertex(new Vector2(1.2f, 3.3f)); pt.AddTex(new Vector2(1, 1)); pt.Color = Color.Transparent; world.Add(pt); Texture spritetexture = TextureLoader.FromFile(device, "../../guy8.bmp"); player.P = new Vector2(0.5f, 1); player.Tex = spritetexture; player.Transparent = true; player.AddVertex(new Vector2(-0.2f, 0)); player.AddTex(new Vector2(0, 1)); player.AddVertex(new Vector2(-0.2f, 1)); player.AddTex(new Vector2(0, 0)); player.AddVertex(new Vector2(0.2f, 1)); player.AddTex(new Vector2(0.125f, 0)); player.AddVertex(new Vector2(0.2f, 0)); player.AddTex(new Vector2(0.125f, 1)); player.Color = Color.Transparent; stood = true; }
public void AddObstacle(float left, float right, float bottom, float top, Color color) { Polygon newpoly = new Polygon(); newpoly.AddVertex(new Vector2(left, bottom)); newpoly.AddVertex(new Vector2(left, top)); newpoly.AddVertex(new Vector2(right, top)); newpoly.AddVertex(new Vector2(right, bottom)); newpoly.Color = color; world.Add(newpoly); }
//constructor public Game() { InitializeComponent(); if (!InitializeDirect3D()) { return; } font = new Microsoft.DirectX.Direct3D.Font(device, // Device we are drawing on 20, // Font height in pixels 0, // Font width in pixels or zero to match height FontWeight.Bold, // Font weight (Normal, Bold, etc.) 0, // mip levels (0 for default) false, // italics? CharacterSet.Default, // Character set to use Precision.Default, // The font precision, try some of them... FontQuality.Default, // Quality? PitchAndFamily.FamilyDoNotCare, // Pitch and family, we don't care "Arial"); // And the name of the font vertices = new VertexBuffer(typeof(CustomVertex.PositionColored), // Type of vertex 4, // How many device, // What device 0, // No special usage CustomVertex.PositionColored.Format, Pool.Managed); background = new Background(device, playingW, playingH); // Determine the last time stopwatch.Start(); lastTime = stopwatch.ElapsedMilliseconds; Polygon floor = new Polygon(); floor.AddVertex(new Vector2(0, 1)); floor.AddVertex(new Vector2(playingW, 1)); floor.AddVertex(new Vector2(playingW, 0.9f)); floor.AddVertex(new Vector2(0, 0.9f)); floor.Color = Color.CornflowerBlue; world.Add(floor); AddObstacle(2, 3, 1.7f, 1.9f, Color.Crimson); AddObstacle(4, 4.2f, 1, 2.1f, Color.Coral); AddObstacle(5, 6, 2.2f, 2.4f, Color.BurlyWood); AddObstacle(5.5f, 6.5f, 3.2f, 3.4f, Color.PeachPuff); AddObstacle(6.5f, 7.5f, 2.5f, 2.7f, Color.Chocolate); //create a platform AddPlatform(3.2f, 3.9f, 1.8f, 2, Color.CornflowerBlue); //load the texture and create an object Texture texture = TextureLoader.FromFile(device, "../../../stone08.bmp"); AddTexture(1.2f, 1.9f, 3.3f, 3.5f, Color.Transparent, texture, 0, 1, 0, 1); Texture spritetexture = TextureLoader.FromFile(device, "../../../guy8.bmp"); player.Tex = spritetexture; player.AddVertex(new Vector2(-0.2f, 0)); player.AddTex(new Vector2(0, 1)); player.AddVertex(new Vector2(-0.2f, 1)); player.AddTex(new Vector2(0, 0)); player.AddVertex(new Vector2(0.2f, 1)); player.AddTex(new Vector2(0.125f, 0)); player.AddVertex(new Vector2(0.2f, 0)); player.AddTex(new Vector2(0.125f, 1)); player.Color = Color.Transparent; player.Transparent = true; player.P = new Vector2(0.5f, 1); AddNgon(); }