public static void Main(string[] args) { // set starting stage stageNumber = 0; randomator = new Random(); explosions = new List<Explosion>(); //// build ships // ships = new List<ShipDrone>(); // build secondary ship ShipDrone otherShip = new ShipDrone(VEL, ACC, ROT_VEL, ROT_ACC, SHIP_RADIUS, S_HEALTH, S_LIVES); otherShip.SetProjectile(PROJECTILE_ROF, PROJECTILE_VEL, PROJECTILE_RADIUS, PROJECTILE_MASS, PROJECTILE_DAMAGE); otherShip.Color = new byte[] { 255, 255, 255 }; otherShip.ProjectileColor = new byte[] { 170, 170, 255 }; otherShip.Id = 0; otherShip.SetShip(S0_START_X, S0_START_Y, S0_START_R); ships.Add(otherShip); // build main ship ShipDrone mainShip = new ShipDrone(VEL, ACC, ROT_VEL, ROT_ACC, SHIP_RADIUS, S_HEALTH, S_LIVES); mainShip.SetProjectile(PROJECTILE_ROF, PROJECTILE_VEL, PROJECTILE_RADIUS, PROJECTILE_MASS, PROJECTILE_DAMAGE); mainShip.Color = new byte[] { 255, 255, 255 }; mainShip.ProjectileColor = new byte[] { 255, 255, 0 }; mainShip.Id = 1; myShipID = mainShip.Id; mainShip.SetShip(S1_START_X, S1_START_Y, S1_START_R); ships.Add(mainShip); //// connect to server // connectedToServer = false; tcpConnection = new ClientTCP(); try { if (args.Length < 1) { tcpConnection.ConnectToServer(SERVER_IP_ADDRESS, SERVER_PORT); Console.WriteLine("Connected to server at: " + SERVER_IP_ADDRESS + ":" + SERVER_PORT); } else { tcpConnection.ConnectToServer(args[0], SERVER_PORT); Console.WriteLine("Connected to server at: " + args[0] + ":" + SERVER_PORT); } connectedToServer = true; new GraphicsWindow(tcpConnection); } catch (Exception e) { Console.WriteLine("Unable to connect to server: \n" + e.ToString()); } // send main ship information to server if(connectedToServer) { float[] shipSpecs = mainShip.RenderShip(); tcpConnection.SendMessage("Join: DRONE x: " + shipSpecs[0] + " y: " + shipSpecs[1] + " r: " + shipSpecs[2] + "\n"); } //// Main // using (var game = new GameWindow((int)(1600 / 1.25), (int)(1000 / 1.25))) { game.Load += (sender, e) => { game.VSync = VSyncMode.On; // determine map size mapWidth = TILE_SIZE * TILE_COUNT_WIDTH; mapHeight = TILE_SIZE * TILE_COUNT_HEIGHT; Console.WriteLine("Game started at: " + game.Width + "x" + game.Height + "on a " + mapWidth + "x" + mapHeight + " map."); // collision detection grid collisionGrid = new byte[TILE_COUNT_WIDTH + 1, TILE_COUNT_HEIGHT + 1][]; // set up star field starField = CreateStarField(mapWidth, mapHeight, 1000, mapWidth * 2, mapWidth / 2); //// Graphics // // make background color the color of null space GL.ClearColor(0.1f, 0.1f, 0.1f, 1.0f); // Set background color to black and opaque // load textures droneShipTex = LoadTexture("t_drone_ship1_shadow.png"); explosionTex = LoadTexture("t_explosion1.png"); carrierShipTex = LoadTexture("t_carrier_ship1.png"); starTex = LoadTexture("t_star1.png"); carrierShipUpperTex = LoadTexture("t_carrier_ship1_upper.png"); carrierShipLowerTex = LoadTexture("t_carrier_ship1_lower.png"); number1Tex = LoadTexture("t_1.png"); number2Tex = LoadTexture("t_2.png"); number3Tex = LoadTexture("t_3.png"); loseTex = LoadTexture("t_lose.png"); winTex = LoadTexture("t_win.png"); droneShip2Tex = LoadTexture("t_drone_ship2_shadow.png"); carrierShip2Tex = LoadTexture("t_carrier_ship2.png"); carrierShip2UpperTex = LoadTexture("t_carrier_ship2_upper.png"); carrierShip2LowerTex = LoadTexture("t_carrier_ship2_lower.png"); waitingTex = LoadTexture("t_waiting.png"); countdown = new Countdown(new int[] { number3Tex, number2Tex, number1Tex }, 160, 160); // 160 is dimension of number-pngs in pixels GL.Enable(EnableCap.Texture2D); // enable transparency // ready the text text = new TextRender(new Size(game.Width, game.Height), new Size(300, 100), new Font(FontFamily.GenericMonospace, 15.0f)); text.AddLine("HEALTH " + (int) ((ships[myShipID].Health * 100) / S_HEALTH) + "%", new PointF(10, 10), new SolidBrush(Color.Red)); text.AddLine("LIVES " + ships[myShipID].Lives, new PointF(10, 40), new SolidBrush(Color.Red)); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); // GL.Disable(EnableCap.DepthTest); }; //// Game resize? // game.Resize += (sender, e) => { GL.Viewport(0, 0, game.Width, game.Height); }; //// Physics recalculation and keyboard updates // game.UpdateFrame += (sender, e) => { // collision detection grid collisionGrid = new byte[TILE_COUNT_WIDTH + 1, TILE_COUNT_HEIGHT + 1][]; if (game.Keyboard[Key.Escape]) { if (connectedToServer) { connectedToServer = false; tcpConnection.Shutdown(); tcpConnection = null; } game.Exit(); } if (game.Keyboard[Key.Up]) { if(stageNumber == 1) ships[myShipID].ThrottleOn(); } if (game.Keyboard[Key.Left]) { if (!ships[myShipID].FreezeShipMovement && stageNumber == 1) ships[myShipID].TurnLeft(); } if (game.Keyboard[Key.Right]) { if (!ships[myShipID].FreezeShipMovement && stageNumber == 1) ships[myShipID].TurnRight(); } if (game.Keyboard[Key.Enter]) { if (!ships[myShipID].FreezeShipMovement && stageNumber == 1) ships[myShipID].FireProjectile(); //ships[0].FireShotgun(); } if (game.Keyboard[Key.W]) { if(myShipID == 0) ships[1].ThrottleOn(); else ships[0].ThrottleOn(); } if (game.Keyboard[Key.A]) { if (myShipID == 0) ships[1].TurnLeft(); else ships[0].TurnLeft(); } if (game.Keyboard[Key.D]) { if (myShipID == 0) ships[1].TurnRight(); else ships[0].TurnRight(); } if (game.Keyboard[Key.Space]) { if (myShipID == 0) ships[1].FireProjectile(); else ships[0].FireProjectile(); } if(connectedToServer) mainShip.CalculatePhysics(mapWidth, mapHeight); else foreach (ShipDrone ship in ships) { ship.CalculatePhysics(mapWidth, mapHeight); } foreach (ShipDrone ship in ships) { // if the ship collides with another ship, sometimes they get stuck, have them separate one to // allow them to get unstuck ShipDrone collidedWith = CollisionTest(ship); if (collidedWith != null) { ship.CalculatePhysics(mapWidth, mapHeight); collidedWith.CalculatePhysics(mapWidth, mapHeight); } } // determine if ship is ready to move after respawn if (ships[myShipID].FreezeShipMovement) { float[] xy = ships[myShipID].GetShipPosition(); double distance = Math.Sqrt((xy[0] - ships[myShipID].StartingCoordinates[0]) * (xy[0] - ships[myShipID].StartingCoordinates[0]) + (xy[1] - ships[myShipID].StartingCoordinates[1]) * (xy[1] - ships[myShipID].StartingCoordinates[1])); if (distance > DISTANCE_UNFREEZE) ships[myShipID].FreezeShipMovement = false; } for (int i = 0; i < explosions.Count; i++) { if (!(explosions[i].CalculateStreams())) explosions.RemoveAt(i); } // advance the countdown frame, start the game when ready. if (stageNumber == 0) if (countdown.OneFrame()) stageNumber = 1; // tell server of updates. // specifically of main ship's coordinates and projectiles if(connectedToServer) { //Console.WriteLine("Sending..."); StringBuilder sb = new StringBuilder(); float[] shipSpecs = mainShip.RenderShip(); foreach(float[] projectileSpecs in mainShip.GetNewProjectiles()) { // missing [3], [4], [5] sb.Append(" P: " + projectileSpecs[0] + " " + projectileSpecs[1] + " " + projectileSpecs[2]); } mainShip.ClearNewProjectiles(); tcpConnection.SendMessage("Update: DRONE x: " + shipSpecs[0] + " y: " + shipSpecs[1] + " r: " + shipSpecs[2] + sb.ToString() + "\n"); } }; //// Render game // game.RenderFrame += (sender, e) => { // always begins with GL.Clear() and ends with a call to SwapBuffers GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); // game window follows the ship float[] shipCoord = ships[myShipID].RenderShip(); GL.Ortho(shipCoord[0] - game.Width / 2, shipCoord[0] + game.Width / 2, shipCoord[1] - game.Height / 2, shipCoord[1] + game.Height / 2, -1.0, 0.0); //GL.Ortho(0, game.Width, 0, game.Height, -1.0, 0.0); GL.MatrixMode(MatrixMode.Modelview); //text.Draw(); RenderBackground(mapWidth, mapHeight); foreach (ShipDrone ship in ships) { if (ship.FreezeShipMovement) { //// The main drone ship should be wedged between the top part of the carrier and the carrier's bay // RenderCarrierShip("lower", ship); RenderParticles(ship.RenderShipParticles()); RenderDroneShip(ship.Color, ship); RenderCarrierShip("upper", ship); } else { RenderCarrierShip(ship); } } foreach (ShipDrone ship in ships) { // do not render drone ship if in carrier. Previously rendered. if (!ship.FreezeShipMovement) RenderParticles(ship.RenderShipParticles()); } foreach (ShipDrone ship in ships) { RenderProjectiles(ship.ProjectileColor, ship); // do not render drone ship if in carrier. Previously rendered. if (!ship.FreezeShipMovement) RenderDroneShip(ship.Color, ship); } /*if (ships[myShipID].FreezeShipMovement) { // RenderCollisionGrid(); //// The main drone ship should be wedged between the top part of the carrier and the carrier's bay // RenderCarrierShip("lower", ships[0]); RenderParticles(ships[myShipID].RenderShipParticles()); RenderDroneShip(ships[myShipID].Color, ships[myShipID]); RenderCarrierShip("upper", ships[0]); foreach (ShipDrone ship in ships) { // do not render player's drone ship's exhaust particles, rendered previously if (ship.Id != myShipID) RenderParticles(ship.RenderShipParticles()); RenderParticles(ship.RenderProjectileParticles()); } foreach (ShipDrone ship in ships) { RenderProjectiles(ship.ProjectileColor, ship); // do not render player's drone ship, rendered previously if (ship.Id != myShipID) RenderDroneShip(ship.Color, ship); } } else { RenderCarrierShip(ships[0]); // RenderCollisionGrid(); foreach (ShipDrone ship in ships) { RenderParticles(ship.RenderShipParticles()); RenderParticles(ship.RenderProjectileParticles()); } foreach (ShipDrone ship in ships) { RenderProjectiles(ship.ProjectileColor, ship); RenderDroneShip(ship.Color, ship); } } */ foreach (Explosion explosion in explosions) { RenderParticles(explosion.RenderParticles()); RenderExplosion(explosion.Color, explosion); } // render text, anything drawn after text will be in relation to the screen and not the game grid text.Draw(); if (stageNumber == 0) RenderCountdown(game.Width, game.Height); if (stageNumber == 2) RenderEndScreen(game.Width, game.Height); game.SwapBuffers(); // draw the new matrix }; // Run the game at 60 updates per second game.Run(60.0); } }