Beispiel #1
0
        /// <summary>
        /// Sets Tank rotation increment given current input state.
        /// </summary>
        /// <param name="input">Player input.</param>
        /// <param name="tank">Player tank.</param>
        private void SetRotInc(AbstractInput input, Tank tank)
        {
            // check rotation
            if (input.Rotate)
            {
                // stop the tank
                // (player can't rotate AND translate at once)
                tank.XSpeed = tank.YSpeed = tank.RotIncrement = 0;

                // rotate clockwise
                if (input.Rotate && (input.Right || input.Down))
                {
                    tank.RotIncrement = Tank.RotInc;
                }

                // rotate counterclockwise
                else if (input.Rotate && (input.Left || input.Up))
                {
                    tank.RotIncrement = -Tank.RotInc;
                }
            }

            // not rotating, so must be translating
            else
            {
                // not rotating, reset rotation increment
                tank.RotIncrement = 0;
            }
        }
Beispiel #2
0
        /////////////////////////////////////////////////////////////////////////////
        // Player keyboard controls
        // NOTE: If one GamePad is connected, the keyboard controls are disabled
        // for player 1. If two GamePads are connected, both keyboard controls
        // are disabled.
        // General Game controls: P - pause game
        //                        Escape - quit game
        //                        N - new game
        //
        // Player 1 controls: Arrow keys - translational movement
        //                    Right-ctrl + Arrow key - rotate tank (can't translate)
        //                    Enter - fire
        //                    '/' key: switch weapon
        // Player 2 controls: WASD - translation movement
        //                    Left-shift + WASD key - rotate tank (can't translate)
        //                    Space - fire
        //                    Q key - switch weapon
        /////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Checks key up states, and
        /// applies input processing for the appropriate player.
        /// </summary>
        private void MainGame_KeyUp(object sender, KeyEventArgs e)
        {
            // send key up event to static input check
            AbstractInput.SetStaticInput(e);

            // don't do anything if the game is paused
            // (i.e. only static input is read from the keyboard while paused)
            if (_bGamePaused)
            {
                return;
            }

            // take a snapshot of the player inputs list
            List <AbstractInput> inputSnapshot;

            lock (_oInputLock)
            {
                inputSnapshot = new List <AbstractInput>(_lPlayerInputs);
            }

            // send key up event to each player input
            foreach (AbstractInput ab in inputSnapshot)
            {
                ab.SetKeyUpInput(e);
            }

            // update the player inputs list
            lock (_oInputLock)
            {
                _lPlayerInputs = new List <AbstractInput>(inputSnapshot);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Checks for fire input, and fires the player's gun
        /// </summary>
        /// <param name="input">Player input.</param>
        /// <param name="thisPlayer">Player data.</param>
        /// <param name="tank">Player tank.</param>
        /// <param name="movingShapes">Collection of moving shapes.</param>
        private void SetFireWeapon(AbstractInput input, PlayerData thisPlayer,
                                   Tank tank, List <DynamicShape> movingShapes)
        {
            if (input.Fire)
            {
                // check if not reloading
                if (thisPlayer.CheckReload())
                {
                    // get gunshot color (white by default)
                    Color shotColor = Color.White;
                    switch (thisPlayer.Player)
                    {
                    case PlayerNumber.One:
                        switch (thisPlayer.CurrentWeapon)
                        {
                        case GunType.MachineGun:
                            shotColor = _cPlayer1MGColor;
                            break;

                        case GunType.Rocket:
                            shotColor = _cPlayer1RocketColor;
                            break;
                        }
                        break;

                    case PlayerNumber.Two:
                        switch (thisPlayer.CurrentWeapon)
                        {
                        case GunType.MachineGun:
                            shotColor = _cPlayer2MGColor;
                            break;

                        case GunType.Rocket:
                            shotColor = _cPlayer2RocketColor;
                            break;
                        }
                        break;
                    }

                    // get a new gunshot
                    Gunfire newShot = new Gunfire(tank.Position, tank.Rotation,
                                                  thisPlayer.CurrentWeapon, shotColor, thisPlayer.Player);

                    // start reloading timer
                    thisPlayer.StartReloading();

                    //add new gunshot it to the list of moving shapes
                    movingShapes.Add(newShot);
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Initializes main form members.
        /// </summary>
        private void InitializeMembers(string XMLValue)
        {
            // initialize the level
            _lvGameLevel = new Level(XMLValue);

            // reset pause flag
            _bGamePaused = false;

            // initialize players
            PlayerData p1 = new PlayerData(PlayerNumber.One);
            PlayerData p2 = new PlayerData(PlayerNumber.Two);

            // initialize abstract inputs
            AbstractInput a1 = new AbstractInput(PlayerNumber.One);
            AbstractInput a2 = new AbstractInput(PlayerNumber.Two);

            // tank 1 starts at a random spawn point
            PointF startP1 = _lvGameLevel._respawnPoints[_rng.Next(0, _lvGameLevel._respawnPoints.Count)];

            // tank 2 starts as far from player 1 as possible
            PointF startP2 = GetFurthestSpawn(startP1);

            // initialize the tanks
            Tank t1 = new Tank(startP1, _cPlayer1Color, PlayerNumber.One);
            Tank t2 = new Tank(startP2, _cPlayer2Color, PlayerNumber.Two);

            // add inputs to input list
            _lPlayerInputs = new List <AbstractInput> {
                a1, a2
            };

            // add player data to data list
            _lPlayerData = new List <PlayerData> {
                p1, p2
            };

            // add tank shapes to dynamic shape list
            _lDynShapes = new List <DynamicShape> {
                t1, t2
            };

            // make wall list a copy of the level's walls
            _lWalls = new List <Wall>(_lvGameLevel.Walls);

            // make ammo drops a copy of the level's ammo drops
            _lAmmoDrops = new List <Ammo>(_lvGameLevel._ammoDrops);

            // start background input processing thread
            _tBackgroundProcessing = new Thread(TBackground);
        }
Beispiel #5
0
        /// <summary>
        /// Checks current input state, and switches weapon if necessary.
        /// </summary>
        /// <param name="input">Player input.</param>
        /// <param name="thisPlayer">Player data.</param>
        private void SetSwitchWeapon(AbstractInput input, PlayerData thisPlayer)
        {
            // Check weapon select
            if (input.SwitchWeapon)
            {
                // switch to the next weapon
                thisPlayer.SwitchWeapon();

                // issue callback to highlight weapon icon in game UI
                _modelessUI.Invoke(new GameUI.delVoidSwitchWeapon(_modelessUI.CBSwitchWeapon),
                                   input.Player, thisPlayer.CurrentWeapon);

                // signal the abstract input to reset the SwitchWeapon flag
                input.ResetSwitchWeapon();
            }
        }
Beispiel #6
0
        /// <summary>
        /// Sets Tank X and Y speeds based on current input.
        /// </summary>
        /// <param name="input">
        /// Player input.
        /// </param>
        /// <param name="tank">
        /// Player tank.
        /// </param>
        private void SetTranslation(AbstractInput input, Tank tank)
        {
            // can't translate during rotations
            if (input.Rotate)
            {
                return;
            }

            // check up AND down
            if (input.Up && input.Down)
            {
                // trigger motor interlock
                tank.YSpeed = 0;
            }

            // check up OR down
            else
            {
                // moving straight up
                if (input.Up && !(input.Left || input.Right))
                {
                    tank.YSpeed = -Tank.Speed;
                }

                // moving straight down
                else if (input.Down && !(input.Left || input.Right))
                {
                    tank.YSpeed = Tank.Speed;
                }

                // moving up diagonally
                else if (input.Up && (input.Left || input.Right))
                {
                    double angle = 45 * Math.PI / 180;
                    tank.YSpeed = -(float)Math.Sqrt(Math.Pow(Tank.Speed, 2) -
                                                    Math.Pow(Tank.Speed * Math.Sin(angle), 2));
                }

                // moving down diagonally
                else if (input.Down && (input.Left || input.Right))
                {
                    double angle = 45 * Math.PI / 180;
                    tank.YSpeed = (float)Math.Sqrt(Math.Pow(Tank.Speed, 2) -
                                                   Math.Pow(Tank.Speed * Math.Sin(angle), 2));
                }

                // no vertical movement input
                else
                {
                    tank.YSpeed = 0;
                }
            }

            // Check left AND right
            if (input.Right && input.Left)
            {
                // trigger motor interlock
                tank.XSpeed = 0;
            }

            // Check left OR right
            else
            {
                // moving straight right
                if (input.Right && !(input.Up || input.Down))
                {
                    tank.XSpeed = Tank.Speed;
                }

                // moving straight left
                else if (input.Left && !(input.Up || input.Down))
                {
                    tank.XSpeed = -Tank.Speed;
                }

                // moving right diagonally
                else if (input.Right && (input.Up || input.Down))
                {
                    double angle = 45 * Math.PI / 180;
                    tank.XSpeed = (float)Math.Sqrt(Math.Pow(Tank.Speed, 2) -
                                                   Math.Pow(Tank.Speed * Math.Cos(angle), 2));
                }

                // moving left diagonally
                else if (input.Left && (input.Up || input.Down))
                {
                    double angle = 45 * Math.PI / 180;
                    tank.XSpeed = -(float)Math.Sqrt(Math.Pow(Tank.Speed, 2) -
                                                    Math.Pow(Tank.Speed * Math.Cos(angle), 2));
                }

                // no horizontal movement input
                else
                {
                    tank.XSpeed = 0;
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Checks input field values, and
        /// updates Tank properties accordingly.
        /// </summary>
        /// <param name="input">
        /// Player input.
        /// </param>
        private void ApplyInput(AbstractInput input)
        {
            // player tank and data locals
            Tank       tank;
            PlayerData thisPlayer;

            // copy moving shape and player data collections
            List <DynamicShape> movingShapesSnapshot;
            List <PlayerData>   playerListSnapshot;

            lock (_oRenderLock)
            {
                movingShapesSnapshot = new List <DynamicShape>(_lDynShapes);
                playerListSnapshot   = new List <PlayerData>(_lPlayerData);
            }

            // get tank and player data
            tank       = movingShapesSnapshot.Find(dn => dn is Tank && dn.Player == input.Player) as Tank;
            thisPlayer = playerListSnapshot.Find(p => p.Player == input.Player);

            // check rotation
            SetRotInc(input, tank);

            // check translation
            SetTranslation(input, tank);

            // Check weapon select
            SetSwitchWeapon(input, thisPlayer);

            // Check fire cannon
            SetFireWeapon(input, thisPlayer, tank, movingShapesSnapshot);

            // update moving shape list
            lock (_oRenderLock)
            {
                _lDynShapes = new List <DynamicShape>(movingShapesSnapshot);
            }

            // Check for pause
            if (AbstractInput.Pause)
            {
                // set pause flag
                _bGamePaused = true;
            }

            // pause flag is false -- unpause the game
            else
            {
                _bGamePaused = false;
            }

            // check quit game
            if (AbstractInput.Quit)
            {
                // shutdown the game
                Application.Exit();

                // kill thread to prevent it from
                // accessing the graphics as it's being disposed of
                _tBackgroundProcessing.Abort();
            }

            // check new game
            if (AbstractInput.NewGame)
            {
                Application.Restart();
                _tBackgroundProcessing.Abort();
            }
        }