Пример #1
0
        /// <summary>
        /// Used for collision detection.  Grid is set up to determine what needs to check for collision.
        /// </summary>
        private static ShipDrone CollisionTest(ShipDrone ship)
        {
            ShipDrone collidedWith = null;

            /*
             * Check ship's collision
             */
            float[] shipCoord = ship.RenderShip();
            byte[] colId = AddCollisionBoxes(shipCoord[0], shipCoord[1], (int)shipCoord[3], new byte[] { ship.Id, 0 });

            // colId will only be not null if two objects share the same collision box
            if (colId != null)
            {
                // colId[n] = 0 is always a ship.  Anything higher would be one of the ship's projectiles.
                if (colId[1] > 0)
                {
                    // we will need to determine if a real collision has occurred.  We'll need to retrieve the size of the projectile.
                    // get the projectile, since we start projectiles at 1, we need to subtract 1
                    float[] projectile = ships[colId[0]].GetProjectile(colId[1] - 1);

                    //Console.WriteLine("Possible: Ship hit bullet.");

                    double distance = Math.Sqrt((shipCoord[0] - projectile[0]) * (shipCoord[0] - projectile[0]) + (shipCoord[1] - projectile[1]) * (shipCoord[1] - projectile[1]));
                    if (distance < shipCoord[3] + projectile[3])
                    {
                        // do not allow ship to collide if still at respawn point
                        if (!(ship.FreezeShipMovement && ship.Id == myShipID))
                        {
                            //Console.WriteLine("Ship hit bullet.");
                            float[] velShip = ship.GetShipMomentum();
                            float[] velProjectile = ships[colId[0]].GetProjectileMomentum(colId[1] - 1);
                            float vx = (velShip[0] * (velShip[2] - velProjectile[2]) + 2 * velProjectile[2] * velProjectile[0]) / (velShip[2] + velProjectile[2]);
                            float vy = (velShip[1] * (velShip[2] - velProjectile[2]) + 2 * velProjectile[2] * velProjectile[1]) / (velShip[2] + velProjectile[2]);

                            ship.SetShipVeloctiy(vx, vy);

                            float[] projectileToExplosion = ships[colId[0]].RemoveProjectile(colId[1] - 1);
                            explosions.Add(new Explosion(projectileToExplosion[0], projectileToExplosion[1], projectileToExplosion[2], EXPLOSION_STREAMS, EXPLOSION_SPAN, EXPLOSION_STRENGTH));

                            // if the main ship has lost all health and should be reset to respawn point
                            if (ship.Id == myShipID)
                            {
                                if (ship.ChangeHealth((-1) * ship.ProjectileDamage))
                                    RespawnShip();

                                text.RefreshTexture();
                                text.Update(0, "HEALTH " + (int)((ship.Health * 100) / S_HEALTH) + "%");
                                text.Update(1, "LIVES " + ship.Lives);
                            }
                        }
                    }
                }
                else
                {
                    //Console.WriteLine("Possible: Ships collided.");
                    float[] otherShipCoord = ships[colId[0]].RenderShip();
                    double distance = Math.Sqrt((shipCoord[0] - otherShipCoord[0]) * (shipCoord[0] - otherShipCoord[0]) + (shipCoord[1] - otherShipCoord[1]) * (shipCoord[1] - otherShipCoord[1]));
                    if (distance < shipCoord[3] + otherShipCoord[3])
                    {
                        // do not allow ships to collide if still at respawn point
                        if (!ship.FreezeShipMovement && !ships[colId[0]].FreezeShipMovement)
                        {
                            //Console.WriteLine("Ships collided.");
                            float[] velShip = ship.GetShipMomentum();
                            float[] velShip2 = ships[colId[0]].GetShipMomentum();
                            float vx1 = (velShip[0] * (velShip[2] - velShip2[2]) + 2 * velShip2[2] * velShip2[0]) / (velShip[2] + velShip2[2]);
                            float vx2 = (velShip2[0] * (velShip2[2] - velShip[2]) + 2 * velShip[2] * velShip[0]) / (velShip[2] + velShip2[2]);

                            float vy1 = (velShip[1] * (velShip[2] - velShip2[2]) + 2 * velShip2[2] * velShip2[1]) / (velShip[2] + velShip2[2]);
                            float vy2 = (velShip2[1] * (velShip2[2] - velShip[2]) + 2 * velShip[2] * velShip[1]) / (velShip[2] + velShip2[2]);

                            float averageX = (shipCoord[0] + otherShipCoord[0]) / 2;
                            float averageY = (shipCoord[1] + otherShipCoord[1]) / 2;
                            float combinedVel = (float)Math.Sqrt((velShip[0] - velShip2[0]) * (velShip[0] - velShip2[0]) + (velShip[1] - velShip2[1]) * (velShip[1] - velShip2[1]));
                            float angle = (float)(Math.Atan2(shipCoord[0] - otherShipCoord[0], shipCoord[1] - otherShipCoord[1]) * 180 / Math.PI);
                            //Console.WriteLine(combinedVel);

                            Explosion e1 = new Explosion(averageX, averageY, angle + 90, S_EXPLOSION_STREAMS, S_EXPLOSION_SPAN, (combinedVel / 1.4f));
                            Explosion e2 = new Explosion(averageX, averageY, angle - 90, S_EXPLOSION_STREAMS, S_EXPLOSION_SPAN, (combinedVel / 1.4f));
                            e1.Color = new byte[] { 255, 220, 150 };
                            e2.Color = new byte[] { 255, 220, 150 };
                            explosions.Add(e1);
                            explosions.Add(e2);

                            ship.SetShipVeloctiy(vx1, vy1);
                            ships[colId[0]].SetShipVeloctiy(vx2, vy2);

                            collidedWith = ships[colId[0]];

                            if (ships[colId[0]].Id == myShipID)
                            {
                                // if the main ship has lost all health and should be reset to respawn point
                                if (ships[colId[0]].ChangeHealth((-1) * combinedVel * MOMENTUM_DAMAGE_RATIO))
                                    RespawnShip();

                                text.RefreshTexture();
                                text.Update(0, "HEALTH " + (int)((ships[colId[0]].Health * 100) / S_HEALTH) + "%");
                                text.Update(1, "LIVES " + ships[colId[0]].Lives);
                            }

                            if (ship.Id == myShipID)
                            {
                                // if the main ship has lost all health and should be reset to respawn point
                                if (ship.ChangeHealth((-1) * combinedVel * MOMENTUM_DAMAGE_RATIO))
                                    RespawnShip();

                                text.RefreshTexture();
                                text.Update(0, "HEALTH " + (int)((ship.Health * 100) / S_HEALTH) + "%");
                                text.Update(1, "LIVES " + ship.Lives);
                            }
                        }
                    }
                }
            }
            /*
             * Check to make sure ship hasn't collided with edge of screen
             */
            // check width (x)
            if (shipCoord[0] < 0 || shipCoord[0] > mapWidth)
            {
                float[] velShip = ship.GetShipMomentum();
                float combinedVel = Math.Abs(velShip[0]);
                ship.SetShipVeloctiy(-velShip[0], velShip[1]);

                if (ship.Id == myShipID)
                {
                    // if the main ship has lost all health and should be reset to respawn point
                    if (ship.ChangeHealth((-1) * combinedVel * MOMENTUM_DAMAGE_RATIO))
                        RespawnShip();

                    text.RefreshTexture();
                    text.Update(0, "HEALTH " + (int)((ship.Health * 100) / S_HEALTH) + "%");
                    text.Update(1, "LIVES " + ship.Lives);
                }
            }
            // check height (y)
            if (shipCoord[1] < 0 || shipCoord[1] > mapHeight)
            {
                float[] velShip = ship.GetShipMomentum();
                float combinedVel = Math.Abs(velShip[1]);
                ship.SetShipVeloctiy(velShip[0], -velShip[1]);

                if (ship.Id == myShipID)
                {
                    // if the main ship has lost all health and should be reset to respawn point
                    if (ship.ChangeHealth((-1) * combinedVel * MOMENTUM_DAMAGE_RATIO))
                        RespawnShip();

                    text.RefreshTexture();
                    text.Update(0, "HEALTH " + (int)((ship.Health * 100) / S_HEALTH) + "%");
                    text.Update(1, "LIVES " + ship.Lives);
                }
            }

            /*
             * Test projectile's collision
             */
            List<float[]> projectiles = ship.RenderProjectiles();
            for (int i = 0; i < projectiles.Count; i++)
            {
                colId = AddCollisionBoxes(projectiles[i][0], projectiles[i][1], (int)projectiles[i][3], new byte[] { ship.Id, (byte)(i + 1) });
                if (colId != null)
                {
                    if (colId[1] > 0)
                    {
                        float[] otherProjectile = ships[colId[0]].GetProjectile(colId[1] - 1);
                        //Console.WriteLine("Possible: Bullets collided.");
                        double distance;
                        if (otherProjectile.Length == 0)
                            distance = 0;
                        else
                            distance = Math.Sqrt((otherProjectile[0] - projectiles[i][0]) * (otherProjectile[0] - projectiles[i][0]) + (otherProjectile[1] - projectiles[i][1]) * (otherProjectile[1] - projectiles[i][1]));
                        if (distance == 0 || distance < otherProjectile[3] + projectiles[i][3])
                        {
                            ships[colId[0]].RemoveProjectile(colId[1] - 1);
                            float[] projectileToExplosion = ship.RemoveProjectile(i);
                            //Console.WriteLine("Bullets collided.");

                            explosions.Add(new Explosion(projectileToExplosion[0], projectileToExplosion[1], projectileToExplosion[2], P_EXPLOSION_STREAMS, P_EXPLOSION_SPAN, P_EXPLOSION_STRENGTH));
                        }
                    }
                    else
                    {
                        //Console.WriteLine("Possible: Ship hit with bullet...");
                        shipCoord = ships[colId[0]].RenderShip();
                        double distance = Math.Sqrt((shipCoord[0] - projectiles[i][0]) * (shipCoord[0] - projectiles[i][0]) + (shipCoord[1] - projectiles[i][1]) * (shipCoord[1] - projectiles[i][1]));
                        if (distance < shipCoord[3] + projectiles[i][3])
                        {
                            // do not allow ship to collide if still at respawn point
                            if (!(ships[colId[0]].FreezeShipMovement && ships[colId[0]].Id == myShipID))
                            {
                                //Console.WriteLine("Ship hit with bullet.");
                                float[] velShip = ships[colId[0]].GetShipMomentum();
                                float[] velProjectile = ship.GetProjectileMomentum(i);
                                float vx = (velShip[0] * (velShip[2] - velProjectile[2]) + 2 * velProjectile[2] * velProjectile[0]) / (velShip[2] + velProjectile[2]);
                                float vy = (velShip[1] * (velShip[2] - velProjectile[2]) + 2 * velProjectile[2] * velProjectile[1]) / (velShip[2] + velProjectile[2]);

                                ships[colId[0]].SetShipVeloctiy(vx, vy);
                                float[] projectileToExplosion = ship.RemoveProjectile(i);
                                explosions.Add(new Explosion(projectileToExplosion[0], projectileToExplosion[1], projectileToExplosion[2], EXPLOSION_STREAMS, EXPLOSION_SPAN, EXPLOSION_STRENGTH));

                                if (ships[colId[0]].Id == myShipID)
                                {
                                    // if the main ship has lost all health and should be reset to respawn point
                                    if (ships[colId[0]].ChangeHealth((-1) * ships[colId[0]].ProjectileDamage))
                                        RespawnShip();

                                    text.RefreshTexture();
                                    text.Update(0, "HEALTH " + (int)((ships[colId[0]].Health * 100) / S_HEALTH) + "%");
                                    text.Update(1, "LIVES " + ships[colId[0]].Lives);
                                }

                                // test health level
                                //if (ships[colId[0]].Id == myShipID)
                                //    Console.WriteLine("Health3: " + ships[colId[0]].Health);
                            }
                        }
                    }
                }
            }
            return collidedWith;
        }
Пример #2
0
        /// <summary>
        /// Renders a given explosion.  The explosion takes on the color given in the parameter.
        /// </summary>
        private static void RenderExplosion(byte[] color, Explosion explosion)
        {
            List<float[]> streams = explosion.RenderStreams();

            foreach (float[] stream in streams)
            {
                float fromOrigin = stream[3] / 2;
                GL.LoadIdentity();
                GL.Translate(stream[0], stream[1], 0.0f);
                GL.Rotate(stream[2], 0.0f, 0.0f, 1.0f);

                // texture
                GL.Color3(color);
                GL.BindTexture(TextureTarget.Texture2D, explosionTex);

                GL.Begin(PrimitiveType.Quads);
                GL.TexCoord2(0, 0);
                GL.Vertex2(-fromOrigin, fromOrigin);

                GL.TexCoord2(1, 0);
                GL.Vertex2(fromOrigin, fromOrigin);

                GL.TexCoord2(1, 1);
                GL.Vertex2(fromOrigin, -fromOrigin);

                GL.TexCoord2(0, 1);
                GL.Vertex2(-fromOrigin, -fromOrigin);
                GL.End();

                GL.BindTexture(TextureTarget.Texture2D, 0);

            }
        }