예제 #1
0
파일: Program.cs 프로젝트: VVatashi/Cubach
        private static Vector3 HandlePlayerInput(bool isOnGround)
        {
            Vector3 acceleration     = Vector3.Zero;
            Vector2 mousePosition    = Window.MousePosition;
            float   moveAcceleration = isOnGround ? 50f : 2.5f;

            if (isOnGround && Window.KeyboardState.IsKeyDown(Keys.LeftShift))
            {
                moveAcceleration *= 2;
            }

            var playerMoveDirection = Vector3.Zero;

            if (Window.KeyboardState.IsKeyDown(Keys.A))
            {
                playerMoveDirection -= new Vector3(Camera.Right.X, 0, Camera.Right.Z).Normalized();
            }
            else if (Window.KeyboardState.IsKeyDown(Keys.D))
            {
                playerMoveDirection += new Vector3(Camera.Right.X, 0, Camera.Right.Z).Normalized();
            }

            if (Window.KeyboardState.IsKeyDown(Keys.W))
            {
                playerMoveDirection += new Vector3(Camera.Front.X, 0, Camera.Front.Z).Normalized();
            }
            else if (Window.KeyboardState.IsKeyDown(Keys.S))
            {
                playerMoveDirection -= new Vector3(Camera.Front.X, 0, Camera.Front.Z).Normalized();
            }

            if (playerMoveDirection.LengthSquared > 10e-3f)
            {
                acceleration += playerMoveDirection.Normalized() * moveAcceleration;
            }

            if (isOnGround && Window.KeyboardState.IsKeyDown(Keys.Space) && LastJumpTime < CurrentTime - 0.5f)
            {
                const float jumpAcceleration = 400f;

                acceleration += Vector3.UnitY * jumpAcceleration;
                LastJumpTime  = CurrentTime;
            }

            if (Window.MouseState.IsAnyButtonDown && !LockCursor)
            {
                LockCursor           = true;
                Window.CursorGrabbed = true;
                Window.CursorVisible = false;
                mousePosition        = Window.MousePosition = new Vector2(Window.ClientSize.X / 2, Window.ClientSize.Y / 2);
            }

            if (Window.KeyboardState.IsKeyDown(Keys.Escape))
            {
                LockCursor           = false;
                Window.CursorGrabbed = false;
                Window.CursorVisible = true;
            }

            if (LockCursor)
            {
                float mouseSensitivity = MathHelper.DegreesToRadians(0.1f);
                var   mouseDelta       = mousePosition - new Vector2(Window.ClientSize.X / 2, Window.ClientSize.Y / 2);

                if (mouseDelta.X != 0)
                {
                    Camera.Rotation = Quaternion.FromAxisAngle(Vector3.UnitY, mouseSensitivity * -mouseDelta.X) * Camera.Rotation;
                }

                if (mouseDelta.Y != 0)
                {
                    var newRotation = Quaternion.FromAxisAngle(Camera.Right, mouseSensitivity * -mouseDelta.Y) * Camera.Rotation;
                    var newFront    = newRotation * -Vector3.UnitZ;
                    if (MathF.Sign(newFront.X) == MathF.Sign(Camera.Front.X) && MathF.Sign(newFront.Z) == MathF.Sign(Camera.Front.Z))
                    {
                        Camera.Rotation = newRotation;
                    }
                }

                Camera.Rotation.Normalize();

                if (Window.MouseState.IsButtonDown(MouseButton.Left) && LastBlockDeleteTime < CurrentTime - 0.25f)
                {
                    var ray = new Ray(Camera.Position, Camera.Front);
                    if (World.RaycastBlock(ray, 0, 128f, out _, out Vector3i blockPosition).HasValue)
                    {
                        World.SetBlockAt(blockPosition, new Block((byte)BlockType.GetIdByName("air")));

                        var gridPosition = new Vector3i((int)MathF.Floor(blockPosition.X / 16f), (int)MathF.Floor(blockPosition.Y / 16f), (int)MathF.Floor(blockPosition.Z / 16f));
                        GridMeshesToUpdate.Enqueue(gridPosition);

                        var blockLocalPosition = blockPosition - WorldGen.GRID_SIZE * gridPosition;

                        if (blockLocalPosition.X == 0)
                        {
                            GridMeshesToUpdate.Enqueue(gridPosition + new Vector3i(-1, 0, 0));
                        }

                        if (blockLocalPosition.Y == 0)
                        {
                            GridMeshesToUpdate.Enqueue(gridPosition + new Vector3i(0, -1, 0));
                        }

                        if (blockLocalPosition.Z == 0)
                        {
                            GridMeshesToUpdate.Enqueue(gridPosition + new Vector3i(0, 0, -1));
                        }

                        if (blockLocalPosition.X == WorldGen.GRID_SIZE - 1)
                        {
                            GridMeshesToUpdate.Enqueue(gridPosition + new Vector3i(1, 0, 0));
                        }

                        if (blockLocalPosition.Y == WorldGen.GRID_SIZE - 1)
                        {
                            GridMeshesToUpdate.Enqueue(gridPosition + new Vector3i(0, 1, 0));
                        }

                        if (blockLocalPosition.Z == WorldGen.GRID_SIZE - 1)
                        {
                            GridMeshesToUpdate.Enqueue(gridPosition + new Vector3i(0, 0, 1));
                        }

                        WorldMeshGenBarrier.Set();

                        LastBlockDeleteTime = CurrentTime;
                    }
                }

                if (Window.MouseState.IsButtonDown(MouseButton.Right) && LastBlockPlaceTime < CurrentTime - 0.25f)
                {
                    var ray = new Ray(Camera.Position, Camera.Front);
                    if (World.RaycastBlock(ray, 0, 128f, out Vector3 intersection, out _).HasValue)
                    {
                        intersection -= ray.Direction * 10e-3f;

                        var blockPosition = new Vector3i((int)MathF.Floor(intersection.X), (int)MathF.Floor(intersection.Y), (int)MathF.Floor(intersection.Z));
                        var blockAABB     = new AABB(blockPosition, blockPosition + new Vector3i(1, 1, 1));
                        if (!CollisionDetection.AABBIntersection(blockAABB, Player.AABB))
                        {
                            World.SetBlockAt(blockPosition, new Block((byte)BlockType.GetIdByName("glass")));

                            var gridPosition = new Vector3i((int)MathF.Floor(blockPosition.X / 16f), (int)MathF.Floor(blockPosition.Y / 16f), (int)MathF.Floor(blockPosition.Z / 16f));
                            GridMeshesToUpdate.Enqueue(gridPosition);

                            var blockLocalPosition = blockPosition - WorldGen.GRID_SIZE * gridPosition;

                            if (blockLocalPosition.X == 0)
                            {
                                GridMeshesToUpdate.Enqueue(gridPosition + new Vector3i(-1, 0, 0));
                            }

                            if (blockLocalPosition.Y == 0)
                            {
                                GridMeshesToUpdate.Enqueue(gridPosition + new Vector3i(0, -1, 0));
                            }

                            if (blockLocalPosition.Z == 0)
                            {
                                GridMeshesToUpdate.Enqueue(gridPosition + new Vector3i(0, 0, -1));
                            }

                            if (blockLocalPosition.X == WorldGen.GRID_SIZE - 1)
                            {
                                GridMeshesToUpdate.Enqueue(gridPosition + new Vector3i(1, 0, 0));
                            }

                            if (blockLocalPosition.Y == WorldGen.GRID_SIZE - 1)
                            {
                                GridMeshesToUpdate.Enqueue(gridPosition + new Vector3i(0, 1, 0));
                            }

                            if (blockLocalPosition.Z == WorldGen.GRID_SIZE - 1)
                            {
                                GridMeshesToUpdate.Enqueue(gridPosition + new Vector3i(0, 0, 1));
                            }

                            WorldMeshGenBarrier.Set();

                            LastBlockPlaceTime = CurrentTime;
                        }
                    }
                }

                Window.MousePosition = new Vector2(Window.ClientSize.X / 2, Window.ClientSize.Y / 2);
            }

            return(acceleration);
        }