예제 #1
0
    void FixedUpdate()
    {
        if (Dead)
        {
            return;
        }

        Quaternion destinationTilt = Quaternion.identity;

        var gamepadInput = GamepadsManager.Instance.Any;

        var lsP = gamepadInput.LeftStick.Position;

        if (lsP.sqrMagnitude != 0)
        {
            lsP = Vector2.Lerp(lsP, lsP.normalized, lsP.sqrMagnitude);
        }

        var horizAxis = Mathf.Clamp(lsP.x +
                                    (gamepadInput.DPad.Left.State.IsDown() || Keyboard.GetKeyState(KeyCode.LeftArrow).State.IsDown() ? -1 : 0) +
                                    (gamepadInput.DPad.Right.State.IsDown() || Keyboard.GetKeyState(KeyCode.RightArrow).State.IsDown() ? 1 : 0), -1, 1);

        var vertAxis = Mathf.Clamp(lsP.y +
                                   (gamepadInput.DPad.Down.State.IsDown() || Keyboard.GetKeyState(KeyCode.DownArrow).State.IsDown() ? -1 : 0) +
                                   (gamepadInput.DPad.Up.State.IsDown() || Keyboard.GetKeyState(KeyCode.UpArrow).State.IsDown() ? 1 : 0), -1, 1);

        if (horizAxis != 0)
        {
            Velocity        += Vector3.right * Time.deltaTime * MovingSpeed * horizAxis;
            destinationTilt *= Quaternion.AngleAxis(TiltDegrees * horizAxis, Vector3.up);
        }
        if (vertAxis != 0)
        {
            Velocity += Vector3.up * Time.deltaTime * MovingSpeed * vertAxis;
        }

        Tilt = Quaternion.Slerp(Tilt, destinationTilt, 0.25f);

        // Apply
        transform.position += Velocity;
        transform.rotation  = Tilt;

        // Friction
        Velocity *= 0.55f;

        // Limit
        transform.position = Vector3.Min(new Vector3(ScreenSize * Camera.main.aspect, ScreenSize, 0), transform.position);
        transform.position = Vector3.Max(new Vector3(-ScreenSize * Camera.main.aspect, -ScreenSize, 0), transform.position);
    }
예제 #2
0
 void Update()
 {
     if (Gamepads.Any.Start.State == ComplexButtonState.Pressed ||
         Keyboard.GetKeyState(KeyCode.Return).State == ComplexButtonState.Pressed)
     {
         if (Time.timeScale == 0)
         {
             Time.timeScale = 1;
             Camera.main.audio.Play();
             renderer.enabled = false;
             transform.GetChild(0).renderer.enabled = false;
             transform.GetChild(1).renderer.enabled = false;
         }
         else
         {
             Time.timeScale = 0;
             Camera.main.audio.Pause();
             renderer.enabled = true;
             transform.GetChild(0).renderer.enabled = true;
             transform.GetChild(1).renderer.enabled = true;
         }
     }
 }
예제 #3
0
 public KeyState GetKeyState(TKeyId keyId)
 {
     return(_sourceKeyboard.GetKeyState(ToSourceKeyId(keyId)));
 }
예제 #4
0
    void Update()
    {
        var anyGamepad = Gamepads.Any;

        // Beat match
        SinceBeatMatch += Time.deltaTime;
        if (anyGamepad.X.State == ComplexButtonState.Pressed || Keyboard.GetKeyState(KeyCode.Space) == ComplexButtonState.Pressed)
        {
            if (SinceBeatMatch < 2)
            {
                Pico.HeartbeatDuration   = SinceBeatMatch;
                Pico.TimeLeftToHeartbeat = SinceBeatMatch;
            }
            SinceBeatMatch = 0;
        }

        Ray   mouseRay  = Camera.main.ScreenPointToRay(Input.mousePosition);
        var   basePlane = new Plane(Vector3.up, new Vector3(0, ActualHeight - 0.5f, 0));
        float distance;

        switch (Phase)
        {
        case PlacingPhase.ChoosingPosition:
            if (!anyGamepad.Connected)
            {
                if (Mouse.RightButton.State == MouseButtonState.Idle &&
                    Keyboard.GetKeyState(KeyCode.LeftControl) == ComplexButtonState.Up &&
                    basePlane.Raycast(mouseRay, out distance))
                {
                    Vector3 p  = (Camera.main.transform.position + mouseRay.direction * distance).Round();
                    var     hs = Pico.Level.Size / 2;

                    var clampedPosition = p.Clamp(-Pico.Level.Size / 2, Pico.Level.Size / 2 - 1);
                    if (Camera.main.transform.position.y < ActualHeight - 0.5f)
                    {
                        clampedPosition.y++;
                    }

                    if (Pico.Level.GetAccumulatorAt(clampedPosition) == null &&
                        Pico.Level.GetEmitterAt(clampedPosition) == null &&
                        Pico.Level.GetProjectorAt(clampedPosition) == null &&
                        Pico.Level.GetReceiverAt(clampedPosition) == null)
                    {
                        Anchor.transform.position = clampedPosition;

                        if (p.x < -hs || p.x >= hs || p.y < -hs || p.y >= hs || p.z < -hs || p.z >= hs)
                        {
                            ;     // Do nothing
                        }
                        else if (Mouse.LeftButton.State == MouseButtonState.Clicked && !Pico.IsChangingLevel)
                        {
                            Phase = PlacingPhase.ChoosingDirection;
                        }
                    }
                }
            }
            else
            {
                var mat = Camera.main.camera.worldToCameraMatrix;

                var     right = mat.GetRow(0).ToVector3().MaxClampXZ();
                Vector3 up;
                var     camUp      = mat.GetRow(1).ToVector3();
                var     camForward = mat.GetRow(2).ToVector3();

                if (Math.Abs(camUp.x) > Math.Abs(camUp.z))
                {
                    camUp = new Vector3(camUp.x, 0, 0);
                }
                else
                {
                    camUp = new Vector3(0, 0, camUp.z);
                }
                if (Math.Abs(camForward.x) > Math.Abs(camForward.z))
                {
                    camForward = new Vector3(camForward.x, 0, 0);
                }
                else
                {
                    camForward = new Vector3(0, 0, camForward.z);
                }
                if (Math.Abs(camUp.x + camUp.z) > Math.Abs(camForward.x + camForward.z))
                {
                    up = camUp.Sign();
                }
                else
                {
                    up = -camForward.Sign();
                }

                if (anyGamepad.LeftStick.Right.State == ComplexButtonState.Pressed || anyGamepad.DPad.Right.State == ComplexButtonState.Pressed)
                {
                    Anchor.transform.position += right;
                }
                if (anyGamepad.LeftStick.Left.State == ComplexButtonState.Pressed || anyGamepad.DPad.Left.State == ComplexButtonState.Pressed)
                {
                    Anchor.transform.position -= right;
                }
                if (anyGamepad.LeftStick.Up.State == ComplexButtonState.Pressed || anyGamepad.DPad.Up.State == ComplexButtonState.Pressed)
                {
                    Anchor.transform.position += up;
                }
                if (anyGamepad.LeftStick.Down.State == ComplexButtonState.Pressed || anyGamepad.DPad.Down.State == ComplexButtonState.Pressed)
                {
                    Anchor.transform.position -= up;
                }

                if (anyGamepad.LeftStick.Right.TimePressed > 0.3 || anyGamepad.DPad.Right.TimePressed > 0.3)
                {
                    SinceLongPress += Time.deltaTime; if (SinceLongPress > 0.05)
                    {
                        Anchor.transform.position += right; SinceLongPress = 0;
                    }
                }
                if (anyGamepad.LeftStick.Left.TimePressed > 0.3 || anyGamepad.DPad.Left.TimePressed > 0.3)
                {
                    SinceLongPress += Time.deltaTime; if (SinceLongPress > 0.05)
                    {
                        Anchor.transform.position -= right; SinceLongPress = 0;
                    }
                }
                if (anyGamepad.LeftStick.Up.TimePressed > 0.3 || anyGamepad.DPad.Up.TimePressed > 0.3)
                {
                    SinceLongPress += Time.deltaTime; if (SinceLongPress > 0.05)
                    {
                        Anchor.transform.position += up; SinceLongPress = 0;
                    }
                }
                if (anyGamepad.LeftStick.Down.TimePressed > 0.3 || anyGamepad.DPad.Down.TimePressed > 0.3)
                {
                    SinceLongPress += Time.deltaTime; if (SinceLongPress > 0.05)
                    {
                        Anchor.transform.position -= up; SinceLongPress = 0;
                    }
                }

                Anchor.transform.position = Anchor.transform.position.Clamp(-Pico.Level.Size / 2, Pico.Level.Size / 2 - 1);

                var worldPos = Anchor.transform.position;
                if (Pico.Level.GetAccumulatorAt(worldPos) == null &&
                    Pico.Level.GetEmitterAt(worldPos) == null &&
                    Pico.Level.GetProjectorAt(worldPos) == null &&
                    Pico.Level.GetReceiverAt(worldPos) == null &&
                    anyGamepad.A.State == ComplexButtonState.Pressed && !Pico.IsChangingLevel)
                {
                    FaceNormal = -mat.GetRow(2).ToVector3().MaxClamp();
                    Phase      = PlacingPhase.ChoosingDirection;
                }
            }

            // Move up/down one layer
            if ((anyGamepad.RightShoulder.State == ComplexButtonState.Pressed || Keyboard.GetKeyState(KeyCode.W) == ComplexButtonState.Pressed) && DestinationHeight < Pico.Level.Size / 2 - 1)
            {
                LastHeight = DestinationHeight;
                DestinationHeight++;
                EasingTimeLeft = 0;
            }
            if ((anyGamepad.LeftShoulder.State == ComplexButtonState.Pressed || Keyboard.GetKeyState(KeyCode.S) == ComplexButtonState.Pressed) && DestinationHeight > -Pico.Level.Size / 2)
            {
                LastHeight = DestinationHeight;
                DestinationHeight--;
                EasingTimeLeft = 0;
            }

            if (!Pico.IsChangingLevel)
            {
                // Undo last placement
                if (AllPlacedProjectors.Count > 0 && (anyGamepad.B.State == ComplexButtonState.Pressed || Keyboard.GetKeyState(KeyCode.Z) == ComplexButtonState.Pressed))
                {
                    var anchorAt = Pico.Level.GetProjectorAt(Anchor.transform.position);
                    if (anchorAt != null)
                    {
                        Destroy(anchorAt);
                        AllPlacedProjectors.Remove(anchorAt);
                    }
                    else
                    {
                        Destroy(AllPlacedProjectors[AllPlacedProjectors.Count - 1]);
                        AllPlacedProjectors.RemoveAt(AllPlacedProjectors.Count - 1);
                    }

                    Pico.Level.PlacedCount--;
                }

                // Undo ALL placements
                if (anyGamepad.Back == ComplexButtonState.Pressed || Keyboard.GetKeyState(KeyCode.R) == ComplexButtonState.Pressed)
                {
                    Pico.Level.PlacedCount = 0;
                    Pico.RebootLevel();
                }
            }
            break;

        case PlacingPhase.ChoosingDirection:
            if (!Pico.IsChangingLevel)
            {
                // Undo last placement
                if (anyGamepad.B.State == ComplexButtonState.Pressed || Keyboard.GetKeyState(KeyCode.Z) == ComplexButtonState.Pressed)
                {
                    HighlightFace.GetComponentInChildren <Renderer>().enabled = false;
                    Phase = PlacingPhase.ChoosingPosition;
                    break;
                }
            }

            if (!anyGamepad.Connected)
            {
                RaycastHit hitInfo;
                if (Anchor.collider.Raycast(mouseRay, out hitInfo, float.MaxValue))
                {
                    HighlightFace.GetComponentInChildren <Transform>().LookAt(HighlightFace.transform.position +
                                                                              hitInfo.normal);
                    HighlightFace.transform.position = Anchor.transform.position + hitInfo.normal * 0.5f;
                    HighlightFace.GetComponentInChildren <Renderer>().enabled = true;

                    if (Mouse.LeftButton.State == MouseButtonState.Clicked && !Pico.IsChangingLevel)
                    {
                        Phase = PlacingPhase.ChoosingPosition;
                        HighlightFace.GetComponentInChildren <Renderer>().enabled = false;

                        var cellPosition = (Anchor.transform.position + VectorEx.New(Pico.Level.Size / 2)).Round();
                        //Debug.Log("Adding projector @ " + cellPosition);

                        AllPlacedProjectors.Add(Pico.Level.AddProjectorAt(
                                                    (int)cellPosition.x, (int)cellPosition.y, (int)cellPosition.z,
                                                    DirectionEx.FromVector(hitInfo.normal)));
                        Pico.Level.PlacedCount++;
                    }
                }
                else
                {
                    HighlightFace.GetComponentInChildren <Renderer>().enabled = false;

                    if (Mouse.LeftButton.State == MouseButtonState.Clicked && !Pico.IsChangingLevel)
                    {
                        if (basePlane.Raycast(mouseRay, out distance))
                        {
                            Vector3 p  = (Camera.main.transform.position + mouseRay.direction * distance).Round();
                            var     hs = Pico.Level.Size / 2;
                            if (p.x < -hs || p.x >= hs || p.y < -hs || p.y >= hs || p.z < -hs || p.z >= hs)
                            {
                                Phase = PlacingPhase.ChoosingPosition;
                            }
                        }
                        else
                        {
                            Phase = PlacingPhase.ChoosingPosition;
                        }
                    }
                }
            }
            else
            {
                var mat   = Camera.main.camera.worldToCameraMatrix;
                var right = mat.GetRow(0).ToVector3().MaxClamp();
                var up    = -mat.GetRow(2).ToVector3().MaxClamp();

                if (anyGamepad.LeftStick.Position.sqrMagnitude > 0.5)
                {
                    FaceNormal = (right * anyGamepad.LeftStick.Position.x + up * anyGamepad.LeftStick.Position.y).MaxClamp();
                }

                if (anyGamepad.DPad.Direction.sqrMagnitude > 0.5)
                {
                    FaceNormal = (right * anyGamepad.DPad.Direction.x + up * anyGamepad.DPad.Direction.y).MaxClamp();
                }

                HighlightFace.GetComponentInChildren <Transform>().LookAt(HighlightFace.transform.position + FaceNormal);
                HighlightFace.transform.position = Anchor.transform.position + FaceNormal * 0.479035f;
                HighlightFace.GetComponentInChildren <Renderer>().enabled = true;

                if (anyGamepad.A.State == ComplexButtonState.Pressed && !Pico.IsChangingLevel)
                {
                    Phase = PlacingPhase.ChoosingPosition;
                    HighlightFace.GetComponentInChildren <Renderer>().enabled = false;

                    var cellPosition = (Anchor.transform.position + VectorEx.New(Pico.Level.Size / 2)).Round();
                    Debug.Log("Adding projector for " + FaceNormal);

                    AllPlacedProjectors.Add(Pico.Level.AddProjectorAt(
                                                (int)cellPosition.x, (int)cellPosition.y, (int)cellPosition.z,
                                                DirectionEx.FromVector(FaceNormal)));
                    Pico.Level.PlacedCount++;
                }
            }
            break;
        }

        EasingTimeLeft += Time.deltaTime;
        float step = Mathf.Clamp01(EasingTimeLeft / EasingTime);

        Pico.GridHeight           = ActualHeight = Mathf.Lerp(LastHeight, DestinationHeight, Easing.EaseIn(step, EasingType.Quartic));
        Anchor.transform.position = new Vector3(Anchor.transform.position.x, DestinationHeight, Anchor.transform.position.z);

        for (int i = 0; i <= Pico.Level.Size; i++)
        {
            Lines[i].transform.position = new Vector3(i - Pico.Level.Size / 2 - 0.5f, ActualHeight - 0.5f, -0.5f);
        }
        for (int i = 0; i <= Pico.Level.Size; i++)
        {
            Lines[i + (Pico.Level.Size + 1)].transform.position = new Vector3(-0.5f, ActualHeight - 0.5f, i - Pico.Level.Size / 2 - 0.5f);
            Lines[i + (Pico.Level.Size + 1)].transform.rotation = Quaternion.AngleAxis(90, Vector3.up);
        }
    }
예제 #5
0
    void FixedUpdate()
    {
        if (Controller.Dead)
        {
            //CharginLazor.SetActiveRecursively(false);
            foreach (var r in CharginLazor.GetComponentsInChildren <Renderer>())
            {
                r.enabled = false;
            }
            return;
        }
        foreach (var r in CharginLazor.GetComponentsInChildren <Renderer>())
        {
            r.enabled = true;
        }

        CharginLazor.transform.localScale = new Vector3(0.2132132f, 0.2132132f, 0.2132132f) * ((BowLevel - 1) * 0.5f + 1);
        CharginLazor.GetComponent <FlickerSize>().RefreshSize();

        if (BowLevel == 3)
        {
            CharginLazor.FindChild("Sphere.2").renderer.material = ColorShifting.Materials["clr_Shift"];
        }
        else
        {
            CharginLazor.FindChild("Sphere.2").renderer.material = ColorShifting.Materials["clr_GreyPale"];
        }

        var gamepadInput = GamepadsManager.Instance.Any;

        // Attacks
        bool rainShot  = gamepadInput.RightTrigger.Value > 0.1 || gamepadInput.RightShoulder.State.IsDown() || Keyboard.GetKeyState(KeyCode.A).State.IsDown();
        bool crossShot = gamepadInput.LeftTrigger.Value > 0.1 || gamepadInput.LeftShoulder.State.IsDown() || Keyboard.GetKeyState(KeyCode.S).State.IsDown();
        bool bowShot   = gamepadInput.A.State.IsDown() || gamepadInput.X.State.IsDown() || gamepadInput.B.State.IsDown() || gamepadInput.Y.State.IsDown() || Keyboard.GetKeyState(KeyCode.D).State.IsDown();

        if (!rainShot)
        {
            RainSine = 0;
        }

        float energySpent = rainShot.AsNumeric() + bowShot.AsNumeric() + crossShot.AsNumeric();

        if (energySpent > 0)
        {
            RainHead.SetActiveRecursively(rainShot || energySpent > 1);
            BowHead.SetActiveRecursively(bowShot && energySpent == 1);
            CrossHead.SetActiveRecursively(crossShot && energySpent == 1);

            Headz.transform.rotation = Quaternion.Slerp(Headz.transform.rotation, Quaternion.AngleAxis(-30, Vector3.right), 0.2f);
        }
        else
        {
            Headz.transform.rotation = Quaternion.Slerp(Headz.transform.rotation, Quaternion.AngleAxis(45, Vector3.right), 0.2f);
        }

        CharginLazor.SetActiveRecursively(bowShot && SinceBow > 0.25f);
        SinceBow += Time.deltaTime;

        bowShot &= !ShootingBow;

        if (energySpent == 0)
        {
            energySpent = 1;
        }
        //energySpent = (float) Math.Pow(energySpent, 1.25f); // TODO : Good idea?

        EnergyLeft[0] -= 1f / energySpent;
        if (bowShot)
        {
            EnergyLeft[1] -= (1f / energySpent) * Mathf.Lerp(1, 2, Mathf.Pow((BowLevel - 1) / 2.0f, 2.0f));
        }
        EnergyLeft[2] -= 1f / energySpent;

        if (rainShot && EnergyLeft[0] <= 0)
        {
            switch (RainLevel)
            {
            case 1:
            {
                Instantiate(RainBullet, transform.position, Quaternion.identity);
                break;
            }

            case 2:
            {
                Instantiate(RainBullet, transform.position - Vector3.right * 0.25f, Quaternion.identity);
                Instantiate(RainBullet, transform.position + Vector3.right * 0.25f, Quaternion.identity);
                break;
            }

            case 3:
            {
                RainSine += Time.deltaTime * 25;

                Instantiate(RainBullet, transform.position - Vector3.right * 0.25f, Quaternion.identity);
                Instantiate(RainBullet, transform.position + Vector3.right * 0.25f, Quaternion.identity);

                // Spread shot
                var v  = Vector3.Normalize(new Vector3((float)Math.Sin(RainSine) * 0.3f + 0.4f, 1, 0));
                var go = (GameObject)Instantiate(RainBullet, transform.position, Quaternion.LookRotation(v) * Quaternion.AngleAxis(90, Vector3.right));
                go.GetComponent <RainBulletBehaviour>().Direction = v;

                v  = Vector3.Normalize(new Vector3(-((float)Math.Sin(RainSine) * 0.3f + 0.4f), 1, 0));
                go = (GameObject)Instantiate(RainBullet, transform.position, Quaternion.LookRotation(v) * Quaternion.AngleAxis(90, Vector3.right));
                go.GetComponent <RainBulletBehaviour>().Direction = v;
                break;
            }
            }
            EnergyLeft[0] = EnergyRequirements[0];
        }
        if (bowShot && EnergyLeft[1] <= 0)
        {
            var go = (GameObject)Instantiate(BowBullet, transform.position, Quaternion.AngleAxis(90, Vector3.forward));
            go.GetComponent <BowBulletBehaviour>().PlayerShot = true;
            EnergyLeft[1] = EnergyRequirements[1];
            ShootingBow   = true;
            Wait.Until(t => t >= 0.49f * ((BowLevel - 1) / 3f + 1), () => { SinceBow = 0; ShootingBow = false; });
        }
        if (crossShot && EnergyLeft[2] <= 0)
        {
            switch (CrossLevel)
            {
            case 1:
            {
                for (int i = 0; i < 4; i++)
                {
                    var angle = ((i + 0.5f) - 2) / 1.5f * 40;
                    var q     = Quaternion.AngleAxis(angle, Vector3.forward) * Quaternion.AngleAxis(45, Vector3.right);
                    var go    = (GameObject)Instantiate(CrossBullet, transform.position, q);
                    go.GetComponent <CrossBulletBehaviour>().Direction = q * Vector3.Normalize(Vector3.up);
                }
                break;
            }

            case 2:
            {
                for (int i = 0; i < 6; i++)
                {
                    var angle = ((i + 0.5f) - 3) / 2.5f * 60;
                    var q     = Quaternion.AngleAxis(angle, Vector3.forward) * Quaternion.AngleAxis(45, Vector3.right);
                    var go    = (GameObject)Instantiate(CrossBullet, transform.position, q);
                    go.GetComponent <CrossBulletBehaviour>().Direction = q * Vector3.Normalize(Vector3.up);
                }
                break;
            }

            case 3:
            {
                for (int i = 0; i < 8; i++)
                {
                    var angle = ((i + 0.5f) - 4) / 3.5f * 80;
                    var q     = Quaternion.AngleAxis(angle, Vector3.forward) * Quaternion.AngleAxis(45, Vector3.right);
                    var go    = (GameObject)Instantiate(CrossBullet, transform.position, q);
                    go.GetComponent <CrossBulletBehaviour>().Direction = q * Vector3.Normalize(Vector3.up);
                    // TODO : Splash damage
                }
                break;
            }
            }
            EnergyLeft[2] = EnergyRequirements[2];
        }
    }
예제 #6
0
        void ProcessPlayerInput()
        {
            // no avatar... no nothing
            if (Game.CurrentWorld.CurrentAvatar == null)
            {
                return;
            }

            if (keyboard.GetKeyState(Key.key_F5))
            {
                Game.CurrentMainWindow.SetGameControlMode();
            }
            else if (keyboard.GetKeyState(Key.key_F6))
            {
                Game.CurrentMainWindow.ReleaseGameControlMode();
            }
            if (Game.GameControlMode)
            {
                if (keyboard.GetKeyState(Key.key_ESCAPE))
                {
                    Game.CurrentMainWindow.ReleaseGameControlMode();
                }
                else if (keyboard.GetKeyState(Key.key_1))
                {
                    Game.CurrentGameCommand = EnumSkill.Kill;
                }
                else if (keyboard.GetKeyState(Key.key_2))
                {
                    Game.CurrentGameCommand = EnumSkill.AcidBlast;
                }
                else if (keyboard.GetKeyState(Key.key_3))
                {
                    Game.CurrentGameCommand = EnumSkill.Kick;
                }
                else if (keyboard.GetKeyState(Key.key_4))
                {
                    Game.CurrentGameCommand = EnumSkill.Levitate;
                }
                else if (keyboard.GetKeyState(Key.key_0))
                {
                    Game.CurrentGameCommand = EnumSkill.None;
                }
            }

            // if not in game control mode, don't respond to game controls
            if (!Game.GameControlMode)
            {
                return;
            }

            float moveunit = 1.39F * (float)movementTimer.ElapsedSeconds();

            if (keyboard.GetKeyState(Key.key_LEFTSHIFT))
            {
                moveunit *= 2.5F;
            }

            #region ProcessRotationInput

            Vector3D avatarPosition = Game.CurrentWorld.CurrentAvatar.model.Position.Clone();
            Vector3D newRotation    = Game.CurrentWorld.CurrentAvatar.model.Rotation.Clone();
            mouse.GetState();
            if (mouse.X != 0)
            {
                newRotation.Y += mouse.X * 0.2f;
                newRotation.X  = pitch;
            }
            if (mouse.Y != 0)
            {
                pitch += mouse.Y * 0.2f;
                if (pitch > 60)
                {
                    pitch = 60;
                }
                if (pitch < -60)
                {
                    pitch = -60;
                }
                newRotation.X = pitch;
            }

            if (keyboard.GetKeyState(Key.key_Q))
            {
                newRotation.Y -= moveunit * 2F;
            }
            if (keyboard.GetKeyState(Key.key_E))
            {
                newRotation.Y += moveunit * 2F;
            }

            #endregion
            #region 2.0 Process Movement Input


            Vector3D changeOfPosition = new Vector3D(0, 0, 0);
            if (keyboard.GetKeyState(Key.key_W))
            {
                changeOfPosition.X += (float)Math.Sin(newRotation.Y * Math.PI / 180.0) * moveunit;
                changeOfPosition.Z += (float)Math.Cos(newRotation.Y * Math.PI / 180.0) * moveunit;
            }
            if (keyboard.GetKeyState(Key.key_S))
            {
                changeOfPosition.X -= (float)Math.Sin(newRotation.Y * Math.PI / 180.0) * moveunit / 2F;
                changeOfPosition.Z -= (float)Math.Cos(newRotation.Y * Math.PI / 180.0) * moveunit / 2F;
            }
            if (keyboard.GetKeyState(Key.key_D))
            {
                changeOfPosition.X += (float)Math.Cos(newRotation.Y * Math.PI / 180.0) * moveunit / 2F;
                changeOfPosition.Z -= (float)Math.Sin(newRotation.Y * Math.PI / 180.0) * moveunit / 2F;
            }
            if (keyboard.GetKeyState(Key.key_A))
            {
                changeOfPosition.X -= (float)Math.Cos(newRotation.Y * Math.PI / 180.0) * moveunit / 2F;
                changeOfPosition.Z += (float)Math.Sin(newRotation.Y * Math.PI / 180.0) * moveunit / 2F;
            }

            if (changeOfPosition.GetMagnitudeSquared() != 0)
            {
                // stay on the ground
                // TODO: What about when walking on objects?
                Vector3D newPosition = avatarPosition + changeOfPosition;
                try
                {
                    newPosition.Y =
                        Game.CurrentWorld.TerrainPieces.AltitudeAt(newPosition.X, newPosition.Z) + Game.CurrentWorld.CurrentAvatar.physicalObject.Height / 2;
                    //Game.CurrentWorld.WorldTerrain.HeightLookup( newPosition.X, newPosition.Z ) + Game.CurrentWorld.CurrentAvatar.physicalObject.Height/2;
                    changeOfPosition.Y = newPosition.Y - avatarPosition.Y;

                    // check that we can go there
                    foreach (PhysicalObjectInstance poi in Game.CurrentWorld.physicalObjectInstances.Values)
                    {
                        if (poi.physicalObject is Terrain)
                        {
                            continue;
                        }
                        if (poi == Game.CurrentWorld.CurrentAvatar)
                        {
                            //ignore ourselves
                            continue;
                        }

                        // do a bounding sphere test to see if the movement will go near poi
                        // test from the middle of the line drawn between current position
                        // and future position, distance is the radius of both objects
                        // plus half the distance of the movement.
                        float dx = avatarPosition.X + changeOfPosition.X / 2F - poi.model.Position.X;
                        float dy = avatarPosition.Y + changeOfPosition.Y / 2F - poi.model.Position.Y;
                        float dz = avatarPosition.Z + changeOfPosition.Z / 2F - poi.model.Position.Z;
                        float distance_squared = dx * dx + dy * dy + dz * dz;
                        float distance_moved   = changeOfPosition.X * changeOfPosition.X + changeOfPosition.Y * changeOfPosition.Y + changeOfPosition.Z * changeOfPosition.Z;
                        // TODO: optimize, no sqrts
                        if (Math.Sqrt(distance_squared) < Math.Sqrt(poi.model.RadiusSquared) + Math.Sqrt(Game.CurrentWorld.CurrentAvatar.model.RadiusSquared) + Math.Sqrt(distance_moved) / 2F)
                        {
                            // ok, these objects are close enough to collide,
                            // but did a collision really happen?
                            // now we do a more acurate test to find out.

                            Vector3D boxmin1 = new Vector3D();
                            Vector3D boxmax1 = new Vector3D();
                            Vector3D boxmin2 = new Vector3D();
                            Vector3D boxmax2 = new Vector3D();
                            poi.model.GetBoundingBox(boxmin1, boxmax1);
                            Game.CurrentWorld.CurrentAvatar.model.GetBoundingBox(boxmin2, boxmax2);
                            Vector3D halfbox1size = (boxmax1 - boxmin1) / 2;
                            boxmin2 -= halfbox1size;
                            boxmax2 += halfbox1size;
                            boxmin2 += poi.model.Position;
                            boxmax2 += poi.model.Position;

                            if (
                                avatarPosition.X > boxmin2.X &&
                                avatarPosition.Y > boxmin2.Y &&
                                avatarPosition.Z > boxmin2.Z &&
                                avatarPosition.X < boxmax2.X &&
                                avatarPosition.Y < boxmax2.Y &&
                                avatarPosition.Z < boxmax2.Z
                                )
                            {
                                // already in a collision, ignore collision detection
                                break;
                            }

                            if (
                                newPosition.X > boxmin2.X &&
                                newPosition.Y > boxmin2.Y &&
                                newPosition.Z > boxmin2.Z &&
                                newPosition.X < boxmax2.X &&
                                newPosition.Y < boxmax2.Y &&
                                newPosition.Z < boxmax2.Z
                                )
                            {
                                // would be a collision
                                changeOfPosition.Set(0, 0, 0);
                                break;
                                // TODO: should actually figure out the collision point
                            }
                        }
                    }
                }
                catch (InvalidLocationException)
                {
                    changeOfPosition.Set(0, 0, 0);
                }
                // NB: PlayerMovement is called regardless,
                // as we need to update values for message throtling
            }

            #endregion
            PlayerMovement(avatarPosition, changeOfPosition, newRotation);
            Game.CurrentWorld.RepositionCamera();
        }