예제 #1
0
 /// <summary>
 ///  Updates the State of a ship
 /// </summary>
 public void Update(Ship s, float elapsedTime)
 {
     Vector2 temp = Vector2.Zero;
     KeyboardState kb = Keyboard.GetState();
     MouseState ms = Mouse.GetState();
     s.Rotation = (float)Math.Atan2(ms.Y - s.Position.Y, ms.X - s.Position.X);
     if (kb.IsKeyDown(Keys.W))
     {
         temp.Y = -s.maxSpeed;
     }
     if (kb.IsKeyDown(Keys.A))
     {
         temp.X = -s.maxSpeed;
     }
     if (kb.IsKeyDown(Keys.S))
     {
         temp.Y = s.maxSpeed;
     }
     if (kb.IsKeyDown(Keys.D))
     {
         temp.X = s.maxSpeed;
     }
     s.DesiredVelocity = temp;
     if(kb.IsKeyDown(Keys.Space))
         s.Shoot(elapsedTime);
 }
예제 #2
0
        public GymEnvironment(Controller ctrl)
            : base(ctrl)
        {
            SpecialAbility special = new SpecialAbility();
            special.LoadTexture(contentManager, "bullet");
            special.Position = new Vector2(300.0f, 100.0f);
            special.DesiredVelocity = new Vector2(0.0f, 0.0f);
            AddChild(special);

            //	emit = new BulletEmitter(this, BulletEmitter.BulletStrength.Weak, true);
            //	emit = new BulletEmitter(this, BulletEmitter.BulletStrength.Medium, true);
            emit = new BulletEmitter(this, BulletEmitter.BulletStrength.Strong, true);

            emit.Position = new Vector2(210.0f, 300.0f);
            emit.Rotation = (float)3.14 * 3 / 2;
            AddChild(emit);

            for (int i = 0; i < 20; i++)
            {
                /*AddChild(new TestShip((float)r.NextDouble() * ctrl.Graphics.GraphicsDevice.Viewport.Width, (float)r.NextDouble() * ctrl.Graphics.GraphicsDevice.Viewport.Height,
                    0, 0,
                    (float)r.NextDouble() * ctrl.Graphics.GraphicsDevice.Viewport.Width, (float)r.NextDouble() * ctrl.Graphics.GraphicsDevice.Viewport.Height,
                    (float)r.NextDouble() * ctrl.Graphics.GraphicsDevice.Viewport.Width, (float)r.NextDouble() * ctrl.Graphics.GraphicsDevice.Viewport.Height,
                    this));*/

                Ship s = new Ship(null, this);
                s.TestShip((float)r.NextDouble() * ctrl.Graphics.GraphicsDevice.Viewport.Width, (float)r.NextDouble() * ctrl.Graphics.GraphicsDevice.Viewport.Height,
                    0, 0,
                    (float)r.NextDouble() * ctrl.Graphics.GraphicsDevice.Viewport.Width, (float)r.NextDouble() * ctrl.Graphics.GraphicsDevice.Viewport.Height,
                    (float)r.NextDouble() * ctrl.Graphics.GraphicsDevice.Viewport.Width, (float)r.NextDouble() * ctrl.Graphics.GraphicsDevice.Viewport.Height,
                    this);
                AddChild(s);
            }
            Ship s2 = new Ship(null, this);
            s2.TestShip(150, 150, 0, 0, this);
            AddChild(s2);
            //AddChild(new TestShip(150, 150, 0, 0, this));
            AddChild(new Crosshair(this));

            LoadMap("gym.tmx");
        }
예제 #3
0
        private float waitTimer; //countdown timer for ships to stay inert while neutral

        #endregion Fields

        #region Constructors

        /// <summary>
        ///  Creates a new AI with given spawnpoint and given environment
        ///  Initial state is Neutral
        /// </summary>
        public AIController(SpawnPoint sp, GameEnvironment e)
        {
            timeSinceLastStateChange = 0;
            spawn = sp;
            env = e;
            nextState = State.Neutral;
            currentState = State.Neutral;
            target = null;
            answeringDistressCall = false;
            lookingFor = null;
            currentShip = null;
            timeSinceHitWall = 0; ;
            timeSinceChangedTargets = 0;
            waitTimer = 0;
            patrolPoints = new List<Vector2>();
            patrolPoints.Add(randomPatrolPoint());
            oldTarget = null;
            timeSinceMoved = 0;
            oldPosition = new Vector2(-1000, 1000);//I hope this is improbable
            timeSinceSawTarget = 0;
            timeSinceAnsweredDistressCall = 0;
            targetList = new List<GameEntity>();
        }
예제 #4
0
 public void GotShotBy(Ship s, GameEntity f)
 {
     if (controlled is TriangulusShip)
     {
         foreach (TriangulusShip t in m_env.triangles)
         {
             t.ai.DistressCall(controlled, f);
         }
     }
     else if (controlled is SquaretopiaShip)
     {
         foreach (SquaretopiaShip sq in m_env.squares)
         {
             sq.ai.DistressCall(controlled, f);
         }
     }
     else if (controlled is CircloidShip)
     {
         foreach (CircloidShip c in m_env.circles)
         {
             c.ai.DistressCall(controlled, f);
         }
     }
 }
예제 #5
0
 public void DistressCall(Ship s, GameEntity f)
 {
     //Player doesn't care about distress calls
 }
예제 #6
0
        /// <summary>
        ///  Updates the State of a ship
        /// </summary>
        public void Update(Ship s, float elapsedTime)
        {
            const float k_aimRadius = 250.0f;

            s.ResetMaxRotVel();
            controlled = s;

            GamePadState gamepad = GamePad.GetState(PlayerIndex.One);

            // Get keyboard state.
            Vector2 movement = Vector2.Zero;

            Vector2 aimPosition = Vector2.Zero;
            float aimDirection;

            Vector2 specialPosition = Vector2.Zero;
            float specialDirection;

            bool detachPressed = false;

            bool useSpecialPressed = false;
            bool useSpecialHeld = false;

            bool shoot = false;

            if (!gamepad.IsConnected) {
                KeyboardState keyboard = Keyboard.GetState();
                MouseState mouse = Mouse.GetState();
                MouseState oldMouse = OldMouse.GetState();

                if (keyboard.IsKeyDown(Keys.W)) movement.Y -= 1.0f;
                if (keyboard.IsKeyDown(Keys.A)) movement.X -= 1.0f;
                if (keyboard.IsKeyDown(Keys.S)) movement.Y += 1.0f;
                if (keyboard.IsKeyDown(Keys.D)) movement.X += 1.0f;

                // Aiming.
                Vector2 mousePos = m_env.Camera.ScreenToWorld(new Vector2(mouse.X, mouse.Y)) - m_env.Camera.Position;
                if (mousePos.Length() > k_aimRadius) {
                    mousePos.Normalize();
                    mousePos *= k_aimRadius;
                }

                specialPosition = Vector2.Normalize(mousePos) * k_aimRadius + s.Position;
                aimDirection = Angle.Direction(Vector2.Zero, mousePos);
                specialDirection = aimDirection;

                m_env.HUD.Cursor.Rotation = specialDirection + MathHelper.PiOver2;
                m_env.HUD.Cursor.Position = mousePos / 3.0f + m_env.Camera.WorldToScreen(s.Position);
                m_env.HUD.Cursor.Visible = true;

                {
                    // Reset mouse position to center.
                    Vector2 screenCenter = m_env.Camera.WorldToScreen(m_env.Camera.Position + mousePos);
                    if (s_captureMouse) Mouse.SetPosition((int) Math.Round(screenCenter.X), (int) Math.Round(screenCenter.Y));
                    m_env.Controller.IsMouseVisible = !s_captureMouse;
                }

                // Detach.
                detachPressed = (keyboard.IsKeyDown(Keys.Space) && !OldKeyboard.GetState().IsKeyDown(Keys.Space));

                // Use special.
                useSpecialHeld = (mouse.RightButton == ButtonState.Pressed && oldMouse.RightButton == ButtonState.Pressed);
                useSpecialPressed = (mouse.RightButton == ButtonState.Pressed && oldMouse.RightButton != ButtonState.Pressed);

                // Shoot.
                shoot = (mouse.LeftButton == ButtonState.Pressed);

                // Debug. F3 toggles mouse capture.
                if (keyboard.IsKeyDown(Keys.F3) && !OldKeyboard.GetState().IsKeyDown(Keys.F3)) {
                    s_captureMouse = !s_captureMouse;
                }

            } else {
                GamePadState oldGamepad = OldGamePad.GetState();
                Vector2 invertY = new Vector2(1.0f, -1.0f);

                // Gamepad.
                movement = gamepad.ThumbSticks.Left * invertY;
                aimDirection = Angle.Direction(Vector2.Zero, gamepad.ThumbSticks.Right * k_aimRadius * invertY);
                specialPosition = Angle.Vector(s.DesiredRotation) * k_aimRadius + s.Position;
                specialDirection = s.DesiredRotation;

                m_env.HUD.Cursor.Rotation = aimDirection + MathHelper.PiOver2;
                m_env.HUD.Cursor.Position = Angle.Vector(aimDirection) * k_aimRadius / 3.0f + m_env.Camera.WorldToScreen(s.Position);

                // Detach.
                detachPressed = (gamepad.IsButtonDown(Buttons.B) && !oldGamepad.IsButtonDown(Buttons.B));

                // Use special.
                useSpecialHeld = (gamepad.IsButtonDown(Buttons.LeftShoulder) && oldGamepad.IsButtonDown(Buttons.LeftShoulder))
                                    || (gamepad.IsButtonDown(Buttons.RightShoulder) && oldGamepad.IsButtonDown(Buttons.RightShoulder));
                useSpecialPressed = (gamepad.IsButtonDown(Buttons.LeftShoulder) && !oldGamepad.IsButtonDown(Buttons.LeftShoulder))
                                    || (gamepad.IsButtonDown(Buttons.RightShoulder) && !oldGamepad.IsButtonDown(Buttons.RightShoulder));

                // Shoot.
                shoot = (gamepad.ThumbSticks.Right.Length() > 0.1f);
                m_env.HUD.Cursor.Visible = shoot;
            }

            // Act on input.
            s.shooterRotation = aimDirection;

            if(!(s is TriangulusShip)) {
                if (itemBeingTractored != null)
                {
                    CancelTractorBeam();
                }
            }

            // Detach from ship.
            if (detachPressed)
            {
                s.Detach();
                // If i am tractoring something, and i detach from it, then they should go back to normal.
                if(itemBeingTractored != null) {
                    CancelTractorBeam();
                }
            }

            // The item I am tractoring died.
            if (itemBeingTractored != null && !itemBeingTractored.IsTractored) {
                CancelTractorBeam();
            }

            // Update tractored entity's position.
            if (itemBeingTractored != null) {
                if (m_justTeleported) ((Entity) itemBeingTractored).Position = specialPosition;
                itemBeingTractored.UpdateTractor(specialPosition);
                TractorBeamModifier.Position = s.Position;
                m_env.TractorBeamEffect.Trigger(((Entity) itemBeingTractored).Position);
            }

            m_justTeleported = false;

            s.DesiredVelocity = (movement != Vector2.Zero) ? Vector2.Normalize(movement) * s.maxSpeed : Vector2.Zero;
            if (s.DesiredVelocity != Vector2.Zero) {
                s.DesiredRotation = Angle.Direction(Vector2.Zero, s.DesiredVelocity);
            }

            // need to check if sputnik is in a ship or not before you can shoot.
            if (shoot) s.Shoot(elapsedTime);

            if(useSpecialHeld) {
                if(s is CircloidShip) {
                    if (!creatingBlackHole) {
                        m_playerBlackHoles = BlackHole.CreatePair(m_env, specialPosition);
                        creatingBlackHole = true;
                    }
                    if(creatingBlackHole && !((BlackHole)m_playerBlackHoles.First.Entity).fullyFormed) {
                        m_playerBlackHoles.First.Entity.Position = specialPosition;
                    }

                    // This code will execute if you succeed in creating the black hole.
                    if(((BlackHole)m_playerBlackHoles.First.Entity).fullyFormed) {
                        if (previousBlackHoles != null) previousBlackHoles.Destroy();
                        previousBlackHoles = m_playerBlackHoles;
                        creatingBlackHole = false;
                    }
                }
            } else {
                if(creatingBlackHole) {
                    m_playerBlackHoles.Destroy();
                }
                creatingBlackHole = false;
            }

            // Will spawn a blackhole when we first pressdown our right mouse button.
            // if a blackhole has already been spawned this way, then the other one will be removed.
            if(useSpecialPressed) {
                if(s is TriangulusShip) {
                    // if we are tractoring something right now, then we arent allowed to tractor anything else
                    // we can shoot now.
                    if (itemBeingTractored == null) {
                        List<Entity> list = VisionHelper.FindAll(m_env, s.Position, specialDirection, MathHelper.ToRadians(120.0f), 500.0f);
                        IOrderedEnumerable<Entity> sortedList = list.OrderBy(ent => Vector2.DistanceSquared(s.Position, ent.Position));
                        SquaretopiaShip ship = null;
                        Entity collided = sortedList.FirstOrDefault(ent =>
                        {
                            if (ent is TakesDamage && ((TakesDamage) ent).IsFriendly()) return false;
                            if(ent is SquaretopiaShip) ship = (SquaretopiaShip)ent;
                            return (ent is Tractorable);
                        });

                        if(collided is Tractorable) {
                            ((Tractorable)collided).Tractored(s); // Disable ship
                            itemBeingTractored = (Tractorable) collided;
                            m_tractorSound = Sound.PlayCue("tractor_beam");
                        }
                        if(ship != null) {
                            ship.TakeHit(0);
                        }
                    } else {
                        CancelTractorBeam();
                    }
                } else if(s is SquaretopiaShip) {
                    ForceField ff = new ForceField(m_env, s.shooter.Position, specialDirection, controlled);
                    m_env.AddChild(ff);
                }
            }
        }
예제 #7
0
 /// <summary>
 ///  Updates the State of a ship
 /// </summary>
 public void Update(Ship s, float elapsedTime)
 {
     Vector2 destination;
     if (goingStart)
         destination = start;
     else
         destination = finish;
     // Changed from: float wantedDirection = (float)Math.Atan2(destination.Y - s.position.Y, destination.X - s.position.X);
     float wantedDirection = (float)Math.Atan2(destination.Y - s.Position.Y, destination.X - s.Position.X);
     while (wantedDirection < 0)
         wantedDirection += MathHelper.Pi * 2.0f;
     // Changed from while (s.direction < 0)
     while (s.Rotation < 0)
         s.Rotation += MathHelper.Pi * 2.0f;
     s.Rotation %= MathHelper.Pi * 2.0f;
     wantedDirection %= MathHelper.Pi * 2.0f;
     if (Vector2.Distance(s.Position, destination) < s.maxSpeed/env.FPS) //This number needs tweaking, 0 does not work
     {
         goingStart = !goingStart;
         // Changed from: s.velocity = Vector2.Zero;
         s.DesiredVelocity = Vector2.Zero;
     }
     else if (Math.Abs(wantedDirection-s.Rotation) < s.maxTurn)
     {
         // changed from: s.velocity = new Vector2((float)Math.Cos(s.direction) * s.maxSpeed, (float)Math.Sin(s.direction) * s.maxSpeed);
         s.DesiredVelocity = new Vector2((float)Math.Cos(s.Rotation) * s.maxSpeed, (float)Math.Sin(s.Rotation) * s.maxSpeed);
         //s.SetPhysicsVelocityOnce(new Vector2((float)Math.Cos(s.Rotation) * s.maxSpeed, (float)Math.Sin(s.Rotation) * s.maxSpeed));
     }
     else
     {
         // Changed from: s.velocity = Vector2.Zero;
         s.DesiredVelocity = Vector2.Zero;
         float counterclockwiseDistance = Math.Abs(wantedDirection - (s.Rotation + s.maxTurn)%(MathHelper.Pi * 2));
         float clockwiseDistance = Math.Abs(wantedDirection - (s.Rotation - s.maxTurn + MathHelper.Pi * 2) % (MathHelper.Pi * 2));
         if (counterclockwiseDistance < clockwiseDistance)
         {
             if (counterclockwiseDistance < s.maxTurn)
             {
                 s.Rotation = wantedDirection;
             }
             else
             {
                 s.Rotation += s.maxTurn;
             }
         }
         else
         {
             if (clockwiseDistance < s.maxTurn)
             {
                 s.Rotation = wantedDirection;
             }
             else
             {
                 s.Rotation -= s.maxTurn;
             }
         }
     }
     //Theoretically I should shoot when player is in front, but this is funner
     Random r = new Random();
     // Changed from: s.shoot = r.NextDouble() < 0.5;
     if (r.NextDouble() < 0.5)
         s.Shoot(elapsedTime);
 }
예제 #8
0
        /// <summary>
        ///  Call when sputnik's controlled ship (s) gets shot by f
        /// </summary>
        public void DistressCall(Ship s, GameEntity f)
        {
            if(currentState == State.Allied)
            {
                targetList.Insert(0, f);
            }

            //Don't answer distress calls too often or if you are a circloid ship and the shooter is a boss
            else if (timeSinceAnsweredDistressCall > 5 && !(currentShip is CircloidShip && f is SaphereBoss))
            {
                timeSinceAnsweredDistressCall = 0;
                if (currentState == State.Neutral && !s.IsAllied((TakesDamage)f)) //Only non busy ships (neutral) answer
                {//Don't answer of some weird civil war is going on
                    if (CanSee(currentShip, s))//If i can see sputniks ship, go help him
                    {
                        changeToAllied(s);
                        targetList.Insert(0, f);
                    }
                    else  //If I can't see Sputnik's ship, go look for it.
                    {
                        changeToConfused(s, true);
                        targetList.Insert(0, f);
                    }
                }
            }
        }
예제 #9
0
 /// <summary>
 ///  Updates the State of a ship
 /// </summary>
 public void Update(Ship s, float elapsedTime)
 {
     currentShip = s;
     currentState = nextState;
     currentShip.ResetMaxRotVel();//For the turning speed slowdown of neutral state
     if ((oldPosition.Equals(new Vector2(-1000, 1000)) || !oldPosition.Equals(currentShip.Position)))
     {
         timeSinceMoved = 0;
         oldPosition = currentShip.Position;
     }
     else
     {
         timeSinceMoved += elapsedTime;
     }
     timeSinceHitWall += elapsedTime;
     timeSinceChangedTargets += elapsedTime;
     timeSinceLastStateChange += elapsedTime;
     timeSinceAnsweredDistressCall += elapsedTime;
     switch (currentState)
     {
         case State.Allied:
             Allied(elapsedTime);
             break;
         case State.Neutral:
             Neutral(elapsedTime);
             break;
         case State.Alert:
             Alert(elapsedTime);
             break;
         case State.Confused:
             Confused(elapsedTime);
             break;
         case State.Disabled:
             Disabled(elapsedTime);
             break;
         case State.Hostile:
             Hostile(elapsedTime);
             break;
     }
 }
예제 #10
0
 /// <summary>
 ///  Call when s gets shot by f, due to bosses not being ships, default to GameEntity
 /// </summary>
 public void GotShotBy(Ship s, GameEntity f)
 {
     if (currentState != State.Disabled && currentState != State.Allied) //Allied and Disabled ships don't react
     {
         if (CanSee(currentShip, f)) //If I can see the shooter
         {
             switch (currentState)
             {
                 case State.Neutral: //Currently I only become un-neutral when shot
                     changeToAlert(f);
                     break;
                 case State.Alert:  //Someone shot me, time to do something
                     if (f == target) //My target shot me, now Im mad
                     {
                         changeToHostile(f);
                     }
                     else  //Someone else shot me, time to get suspicious of them
                     {
                         //I actually might want to make this behavior more faction like
                         //If whoever shot me is the same faction as my previous target, I might just go hostile
                         //Take this up to the game creator gods.
                         changeToAlert(f);
                     }
                     break;
                 case State.Hostile:
                     if (timeSinceChangedTargets > 20) // If i haven't killed my target in 20 seconds, I should change to an easier target
                     {
                         changeToHostile(f);
                     }
                     break;
                 default:
                     //current do nothing if in Disabled or Hostile when shot
                     break;
             }
         }
         else
         {
             if (currentState == State.Hostile)
             {
                 if (timeSinceChangedTargets > 20) // If i haven't killed my target in 20 seconds, I should change to an easier target
                 {
                     changeToConfused(f, false);
                 }
             }
             else
             {
                 if (timeSinceChangedTargets > 10 || (s == currentShip && timeSinceChangedTargets > 5)) //Dont get confused too often, unless its me shot
                 {
                     changeToConfused(f, false);
                 }
             }
         }
     }
 }
예제 #11
0
파일: Ship.cs 프로젝트: jwmcglynn/TeamQ
        // Attach Sputnik to the ship
        public virtual void Attach(SputnikShip sp)
        {
            this.ai = sp.GetAI();
            this.attachedShip = sp;
            m_frozenCount = 0;
            if (this is Tractorable) ((Tractorable)this).IsTractored = false;
            sputnikDetached = false;
            timeSinceDetached = 0;
            Zindex = 0.26f;

            if (this.health < this.MaxHealth / 2)
                this.health = this.MaxHealth / 2;

            sp.SputnikAttach(this);
        }
예제 #12
0
파일: Ship.cs 프로젝트: jwmcglynn/TeamQ
        public virtual void Detach()
        {
            if (attachedShip == null) return;

            this.ai = this.m_originalAI;
            this.attachedShip.Detach();
            this.attachedShip = null;
            sputnikDetached = true;
            timeSinceDetached = 0;
            SpawnPoint.Position = Position;
            ai.gotDetached();
            ResetZIndex();
        }
예제 #13
0
파일: Asteroid.cs 프로젝트: jwmcglynn/TeamQ
        public void Tractored(Ship s)
        {
            tractoringShip = s;
            IsTractored = true;
            m_fling = false;

            // Destroy collision and re-create a static one so the asteroid can be moved.
            DestroyCollisionBody();
            CreateAsteroidCollision(false);

            // Give a random amount of angular impulse for cool unstable rotating!
            CollisionBody.ApplyAngularImpulse(CollisionBody.Mass * RandomUtil.NextFloat(-5.0f, 5.0f));
        }
예제 #14
0
        public void Tractored(Ship shipTractoring)
        {
            tractoringShip = shipTractoring;
            IsTractored = true;
            m_fling = false;
            ai.GotTractored(shipTractoring);

            if (CollisionBody == null) return;

            // Give a random amount of angular impulse for cool unstable rotating!
            CollisionBody.ApplyAngularImpulse(CollisionBody.Mass * RandomUtil.NextFloat(-5.0f, 5.0f));
        }