// // returns time it took to swap buffers // public override void Render() { updateCount++; GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); // // Setup Game World // GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); GL.Ortho(-1000, 1000, -1000, 1000, -1000, 1000); GL.MatrixMode(MatrixMode.Projection); Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, new Vector3(0f, 0f, -1f) /*Vector3.UnitZ*/, Vector3.UnitY); GL.LoadMatrix(ref modelview); // // Rotate the game world // GL.PushMatrix(); GL.Rotate(worldSpinAngle, Vector3d.UnitZ); GL.Scale(1 + worldZoom, 1 + worldZoom, 1); // // Draw Regions // float degreesPerRegion = 360f / (float)currentRegionCount; float tangentOfRegionHalfAngle = (float)Math.Tan(Math.PI / (double)currentRegionCount); float regionHeight = 1500; float regionHalfWidth = regionHeight * tangentOfRegionHalfAngle; for (int i = 0; i < currentRegionCount; i++) { if (i % 2 == 0 && i != currentPlayerRegion) { continue; } GL.PushMatrix(); GL.Rotate(i * degreesPerRegion, Vector3d.UnitZ); GL.Begin(BeginMode.Quads); if (i == currentPlayerRegion) { GL.Color4(1f, 1f, 1f, .05f); } else { GL.Color4(0f, 0f, 0f, .3f); } GL.Vertex2(0, 0); GL.Vertex2(-regionHalfWidth, regionHeight); GL.Vertex2(regionHalfWidth, regionHeight); GL.Vertex2(0, 0); GL.End(); GL.PopMatrix(); } // // Draw the barriers // for (int i = barriers.Count - 1; i >= 0; i--) { Barrier barrier = barriers[i]; barrier.Draw(currentBarrierColor); } // // Draw the center piece // float centerpieceHeight = 150; float centerpieceHalfWidth = centerpieceHeight * tangentOfRegionHalfAngle; if (playerCollision) { GL.Color4(1f, 0f, 0f, 1f); } else { GL.Color4(0f, 0f, 0f, 1f); } for (int i = 0; i < currentRegionCount; i++) { GL.PushMatrix(); GL.Rotate(i * degreesPerRegion, Vector3d.UnitZ); GL.Begin(BeginMode.Quads); GL.Vertex2(0, 0); GL.Vertex2(-centerpieceHalfWidth, centerpieceHeight); GL.Vertex2(centerpieceHalfWidth, centerpieceHeight); GL.Vertex2(0, 0); GL.End(); GL.PopMatrix(); } // // Draw Player Triangle // GL.PushMatrix(); GL.Rotate(playerAngle, Vector3d.UnitZ); GL.Begin(BeginMode.Triangles); GL.Color4(1.0f, 1.0f, 0.0f, .3f); GL.Vertex2(-20, 206); GL.Color4(1.0f, 0.0f, 0.0f, .3f); GL.Vertex2(0, 240); GL.Color4(0.2f, 0.9f, 1.0f, .3f); GL.Vertex2(20, 206); GL.End(); GL.Begin(BeginMode.Quads); GL.Color4(1f, 1f, 1f, .5f); GL.Vertex2(-20, 206); GL.Vertex2(-33, 206); GL.Vertex2(0, 256); GL.Vertex2(0, 240); GL.Vertex2(20, 206); GL.Vertex2(33, 206); GL.Vertex2(0, 256); GL.Vertex2(0, 240); GL.Vertex2(-35, 197); GL.Vertex2(-33, 206); GL.Vertex2(33, 206); GL.Vertex2(35, 197); // Color the player point if (playerCollision) { GL.Color3(1f, 0f, 0f); } else { GL.Color3(1f, 1f, 1f); } GL.Vertex2(-5, 210); GL.Vertex2(-5, 220); GL.Vertex2(5, 220); GL.Vertex2(5, 210); GL.End(); GL.PopMatrix(); GL.PopMatrix(); // // Draw Current Time // GL.Color4(1f, 1f, 1f, 1f); String currentSecondsString = (nonCollisionMicros / 1000000f).ToString("F2"); gameFont.Draw(currentSecondsString, -gameFont.GetWidth(currentSecondsString.Length) / 2, 8); gameFont.Draw("seconds", -gameFont.GetWidth("seconds".Length) / 2, -gameFont.charHeight - 8); // // Setup HUD // GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); GL.Ortho(0, ClientRectangle.Width, 0, ClientRectangle.Height, -100, 100); GL.Begin(BeginMode.Quads); GL.Color4(0f, 0f, 0f, .6f); GL.Vertex2(5, 5); GL.Vertex2(5, 28); GL.Vertex2(ClientRectangle.Width - 5, 28); GL.Vertex2(ClientRectangle.Width - 5, 5); GL.End(); averageUpdateTimeDiffMicros.CalulateAverage(); long averageUpdateTimeDiffMicrosValue = (long)averageUpdateTimeDiffMicros.LastAverageCalculated; gameStatsLabel.SetText(String.Format("Angle {0,3:F0} Region {1} FPS Max {2:F1} Avg:{3:F1}", playerAngle, currentPlayerRegion, 1000f / (float)minMillisPerFrame, 1000000f / (float)averageUpdateTimeDiffMicrosValue)); userInterfaceHud.DrawComponent(); //GL.Color4(1f, 1f, 1f, 1f); //smallFont.Draw((nonCollisionMicros / 1000000f).ToString("F2") + " seconds", ClientRectangle.Width / 2 - 100, ClientRectangle.Height / 2 - 30); smallFont.Draw("Best: " + (maxNonCollisionMicros / 1000000f).ToString("F2") + " seconds", ClientRectangle.Width / 2 - 100, ClientRectangle.Height - 30); }
// return true to exit public override System.Boolean Update(Int64 nowMicros, Int32 diffMicros) { if (Keyboard[Key.Escape]) { return(true); } // // Controls // Int32 minMillisPerFrameControlValue = minMillisPerFrameControl.GetControl(Keyboard); if (minMillisPerFrameControlValue < 0) { minMillisPerFrame--; if (minMillisPerFrame <= 1) { minMillisPerFrame = 1; } } else if (minMillisPerFrameControlValue > 0) { minMillisPerFrame++; if (minMillisPerFrame >= 200) { minMillisPerFrame = 200; } } Int32 playerAngleControlValue = playerAngleControl.GetControl(Keyboard); if (playerAngleControlValue != 0) { if (playerAngleControlValue > 0) { playerAngle -= diffMicros * DegreesPerMicrosecond; if (playerAngle < 0) { playerAngle += 360; } } else if (playerAngleControlValue < 0) { playerAngle += diffMicros * DegreesPerMicrosecond; if (playerAngle >= 360) { playerAngle -= 360; } } // // Update player region // Int32 oldPlayerRegion = currentPlayerRegion; currentPlayerRegion = (Byte)Math.Floor((float)playerAngle * (float)currentRegionCount / 360f + .5f); if (currentPlayerRegion >= currentRegionCount) { currentPlayerRegion = 0; } if (currentPlayerRegion != oldPlayerRegion) { //Console.WriteLine("Player Region {0} (Angle {1})", currentPlayerRegion, playerAngle); } } // // Update Barriers // System.Boolean oldPlayerCollision = playerCollision; playerCollision = false; for (int i = 0; i < barriers.Count; i++) { Barrier barrier = barriers[i]; barrier.distanceTo -= barrierDistancePerMicrosecond * diffMicros; if (barrier.distanceTo <= BarrierCollisionHeight) { // Check for collision if (barrier.region == currentPlayerRegion && barrier.distanceTo + barrier.height >= BarrierCollisionHeight) { barrier.highlight = true; playerCollision = true; } else { barrier.highlight = false; } // // Check if barrier should be removed // if (barrier.distanceTo + barrier.height <= 0) { barriers.RemoveAt(i); i--; } } } // Update NonCollision Times if (playerCollision != oldPlayerCollision) { if (playerCollision) { nonCollisionMicros = 0; } else { lastNonCollisionTimeMicros = nowMicros; } } if (!playerCollision) { nonCollisionMicros = nowMicros - lastNonCollisionTimeMicros; if (nonCollisionMicros > maxNonCollisionMicros) { maxNonCollisionMicros = nonCollisionMicros; } } // // Generate Barriers if needed // GenerateBarriers(); // // Update World Shift Variables // // World Zoom worldZoom = .1f * worldZoomPulser.PulseValue(diffMicros); // World Spin Angle microsLeftOfCurrentWorldSpinVelocity = microsLeftOfCurrentWorldSpinVelocity - (float)diffMicros; if (microsLeftOfCurrentWorldSpinVelocity <= 0) { microsLeftOfCurrentWorldSpinVelocity = 1000000 * (3 + random.Next() % 3); Int32 randomValue = random.Next(); currentWorldSpinRotationsPerSecond = .1f + .1f * (float)(randomValue % 3); if ((randomValue & 1) == 1) { currentWorldSpinRotationsPerSecond *= -1; } //Console.WriteLine("New Spin {0}", currentWorldSpinRotationsPerSecond); } worldSpinAngle += currentWorldSpinRotationsPerSecond * 360f * ((float)diffMicros / 1000000f); // // Update Background Color // if (playerCollision) { GL.ClearColor(Color.Red); } else { if (backgroundColorChanger.InColorChange()) { currentBackgroundColor = backgroundColorChanger.GetColor(nowMicros); currentBarrierColor = new Color4( currentBackgroundColor.R + .75f, currentBackgroundColor.G + .75f, currentBackgroundColor.B + .75f, 1.0f); GL.ClearColor(currentBackgroundColor); } else { Int32 randomColor = random.Next(); Color4 nextRandomColor = new Color4( (float)((randomColor & 0xFF0000) >> 16) / 256 / 4, (float)((randomColor & 0x00FF00) >> 8) / 256 / 4, (float)((randomColor & 0x0000FF)) / 256 / 4, 1.0f); backgroundColorChanger.SetColorChange(nowMicros + 1000 * (random.Next() % 1024), 1000000, nextRandomColor); } } return(false); }