예제 #1
0
        public void CheckInvalidations(World world)
        {
            var chunks = _worldManager.GetLoadedChunks(world);

            foreach (var chunk in chunks)
            {
                CheckInvalidations(world, chunk.Item2, chunk.Item1);
            }
        }
예제 #2
0
        public GameStatePlay(IGameStateManager gameStateManager, IWorldManager worldManager, IChunkManager chunkManager, IChunkPartManager chunkPartManager, IBlockSelector blockSelector, IBlocksProvider blocksProvider, World world)
        {
            Debug = new DebugObjects();

            _world                 = world;
            _gameStateManager      = gameStateManager;
            _worldManager          = worldManager;
            _chunkManager          = chunkManager;
            _chunkPartManager      = chunkPartManager;
            _blockSelector         = blockSelector;
            _blocksProvider        = blocksProvider;
            _selectedBlockId       = _blockSelector.GetNextBlock(0);
            _selectedBlockMetadata = 0;

            _aabbShader   = ShaderManager.GetWithGeometry("AabbShader");
            _baseShader   = ShaderManager.GetWithGeometry("BaseShader");
            _debugShader  = ShaderManager.GetWithGeometry("Debug");
            _guiShader    = ShaderManager.Get("GuiShader");
            _skyboxShader = ShaderManager.Get("SkyboxShader");
            _player       = new Player()
            {
                Position = new Vector3(0, 90, 0)
            };
            _camera  = new Camera(new Vector3(0), new Vector3(0), (float)(80f * (Math.PI / 180f)));
            _frustum = new Plane[6];
            for (int i = 0; i < _frustum.Length; i++)
            {
                _frustum[i] = new Plane();
            }
            _terrainTexture = TextureManager.Get("terrain.png", TextureMinFilter.Nearest, TextureMagFilter.Nearest);
            _iconsTexture   = TextureManager.Get("icons.png", TextureMinFilter.Nearest, TextureMagFilter.Nearest);
            _skyTexture     = TextureManager.Get("skybox.png", TextureMinFilter.Nearest, TextureMagFilter.Nearest);
            _text           = new Text(new Vector2(5, 0), FontManager.Get("glyphs"), _guiShader, "");
            _renderDistance = 16;

            _crosshair = new Sprite(new Vector2(36, 36), new Vector2(0), new Vector2(16 / 256f), _guiShader);
            _crosshair.UploadInGl();

            _selectedBlocks = new AABBObjects();

            _skybox = new Mesh()
            {
                Vertices = new List <Vertex>()
                {
                    // FRONT
                    new Vertex(new Vector3(-10, -10, -10), Vector3.One, new Vector2(1 / 4f, 2 / 3f)),
                    new Vertex(new Vector3(10, -10, -10), Vector3.One, new Vector2(2 / 4f, 2 / 3f)),
                    new Vertex(new Vector3(-10, 10, -10), Vector3.One, new Vector2(1 / 4f, 1 / 3f)),

                    new Vertex(new Vector3(-10, 10, -10), Vector3.One, new Vector2(1 / 4f, 1 / 3f)),
                    new Vertex(new Vector3(10, -10, -10), Vector3.One, new Vector2(2 / 4f, 2 / 3f)),
                    new Vertex(new Vector3(10, 10, -10), Vector3.One, new Vector2(2 / 4f, 1 / 3f)),

                    // RIGHT
                    new Vertex(new Vector3(10, -10, -10), Vector3.One, new Vector2(2 / 4f, 2 / 3f)),
                    new Vertex(new Vector3(10, -10, 10), Vector3.One, new Vector2(3 / 4f, 2 / 3f)),
                    new Vertex(new Vector3(10, 10, -10), Vector3.One, new Vector2(2 / 4f, 1 / 3f)),

                    new Vertex(new Vector3(10, 10, -10), Vector3.One, new Vector2(2 / 4f, 1 / 3f)),
                    new Vertex(new Vector3(10, -10, 10), Vector3.One, new Vector2(3 / 4f, 2 / 3f)),
                    new Vertex(new Vector3(10, 10, 10), Vector3.One, new Vector2(3 / 4f, 1 / 3f)),

                    // LEFT
                    new Vertex(new Vector3(-10, -10, 10), Vector3.One, new Vector2(0 / 4f, 2 / 3f)),
                    new Vertex(new Vector3(-10, -10, -10), Vector3.One, new Vector2(1 / 4f, 2 / 3f)),
                    new Vertex(new Vector3(-10, 10, 10), Vector3.One, new Vector2(0 / 4f, 1 / 3f)),

                    new Vertex(new Vector3(-10, 10, 10), Vector3.One, new Vector2(0 / 4f, 1 / 3f)),
                    new Vertex(new Vector3(-10, -10, -10), Vector3.One, new Vector2(1 / 4f, 2 / 3f)),
                    new Vertex(new Vector3(-10, 10, -10), Vector3.One, new Vector2(1 / 4f, 1 / 3f)),

                    // TOP
                    new Vertex(new Vector3(-10, 10, -10), Vector3.One, new Vector2(1 / 4f, 1 / 3f)),
                    new Vertex(new Vector3(10, 10, -10), Vector3.One, new Vector2(2 / 4f, 1 / 3f)),
                    new Vertex(new Vector3(-10, 10, 10), Vector3.One, new Vector2(1 / 4f, 0 / 3f)),

                    new Vertex(new Vector3(-10, 10, 10), Vector3.One, new Vector2(1 / 4f, 0 / 3f)),
                    new Vertex(new Vector3(10, 10, -10), Vector3.One, new Vector2(2 / 4f, 1 / 3f)),
                    new Vertex(new Vector3(10, 10, 10), Vector3.One, new Vector2(2 / 4f, 0 / 3f)),

                    // BOTTOM
                    new Vertex(new Vector3(-10, -10, 10), Vector3.One, new Vector2(1 / 4f, 3 / 3f)),
                    new Vertex(new Vector3(10, -10, 10), Vector3.One, new Vector2(2 / 4f, 3 / 3f)),
                    new Vertex(new Vector3(-10, -10, -10), Vector3.One, new Vector2(1 / 4f, 2 / 3f)),

                    new Vertex(new Vector3(-10, -10, -10), Vector3.One, new Vector2(1 / 4f, 2 / 3f)),
                    new Vertex(new Vector3(10, -10, 10), Vector3.One, new Vector2(2 / 4f, 3 / 3f)),
                    new Vertex(new Vector3(10, -10, -10), Vector3.One, new Vector2(2 / 4f, 2 / 3f)),

                    // BACK
                    new Vertex(new Vector3(10, -10, 10), Vector3.One, new Vector2(3 / 4f, 2 / 3f)),
                    new Vertex(new Vector3(-10, -10, 10), Vector3.One, new Vector2(4 / 4f, 2 / 3f)),
                    new Vertex(new Vector3(10, 10, 10), Vector3.One, new Vector2(3 / 4f, 1 / 3f)),

                    new Vertex(new Vector3(10, 10, 10), Vector3.One, new Vector2(3 / 4f, 1 / 3f)),
                    new Vertex(new Vector3(-10, -10, 10), Vector3.One, new Vector2(4 / 4f, 2 / 3f)),
                    new Vertex(new Vector3(-10, 10, 10), Vector3.One, new Vector2(4 / 4f, 1 / 3f)),
                }
            };
            _skybox.LoadInGl();

            _loadingThread =
                new Thread(new ThreadStart(() =>
            {
                Func <int, Tuple <int, int> > spiral = (n) =>
                {
                    var k  = (int)Math.Ceiling((Math.Sqrt(n) - 1) / 2);
                    var t  = 2 * k + 1;
                    var m  = t * t;
                    t      = t - 1;
                    var mt = m - t;
                    if (n > mt)
                    {
                        return(new Tuple <int, int>(k - (m - n), -k));
                    }
                    m  = mt;
                    mt = m - t;
                    if (n > mt)
                    {
                        return(new Tuple <int, int>(-k, -k + (m - n)));
                    }
                    m  = mt;
                    mt = m - t;
                    if (n > mt)
                    {
                        return(new Tuple <int, int>(-k + (m - n), k));
                    }
                    return(new Tuple <int, int>(k, k - (m - n - t)));
                };
                while (!_stopLoading)
                {
                    var chunks         = _worldManager.GetLoadedChunks(_world);
                    var playerPosition = _player.Position;
                    var playerPos2D    = playerPosition.Xz;

                    ChunkPosition?chunkToLoad = null;

                    var renderDistanceTime2Square = _renderDistance * 2;
                    renderDistanceTime2Square     = renderDistanceTime2Square * renderDistanceTime2Square;
                    for (var i = 0; i < renderDistanceTime2Square; i++)
                    {
                        var pos = spiral(i);
                        var chunkPositionInLocalCoordinates = new Vector2(pos.Item1, pos.Item2);
                        if (chunkPositionInLocalCoordinates.LengthFast < _renderDistance)
                        {
                            var chunkPosition = new ChunkPosition((int)((chunkPositionInLocalCoordinates.X + Math.Floor(playerPos2D.X / 16f))), (int)((chunkPositionInLocalCoordinates.Y + Math.Floor(playerPos2D.Y / 16f))));
                            if (!chunks.Any(chunk => chunk.Item1.Equals(chunkPosition)))
                            {
                                chunkToLoad = chunkPosition;
                                break;
                            }
                        }
                    }

                    if (chunkToLoad != null)
                    {
                        _worldManager.GetChunkAt(_world, chunkToLoad.Value.X, chunkToLoad.Value.Z);
                    }
                    else
                    {
                        Thread.Sleep(1000);
                    }
                }
            }))
            {
                IsBackground = true
            };
            _loadingThread.Start();
        }
예제 #3
0
        public void Update(double deltaTime)
        {
            var chunks = _worldManager.GetLoadedChunks(_world);

            foreach (var chunk in chunks)
            {
                var chunkPos = chunk.Item1;
                var chunkPositionInWorldCoordinates = new Vector2(chunkPos.X * 16 + 8, chunkPos.Z * 16 + 8);
                if ((_player.Position.Xz - chunkPositionInWorldCoordinates).LengthFast > _renderDistance * 16 + 16)
                {
                    _worldManager.SetChunkToUnload(_world, chunkPos.X, chunkPos.Z);
                }
            }

            _worldManager.UnloadChunks(_world);
            CleanMeshes();
            _player.Update(deltaTime);

            if (KeyboardHelper.IsKeyPressed(Key.P))
            {
                StaticReferences.ParallelMode = !StaticReferences.ParallelMode;
            }
            if (KeyboardHelper.IsKeyPressed(Key.Plus))
            {
                _renderDistance += 1;
            }
            if (KeyboardHelper.IsKeyPressed(Key.Minus))
            {
                _renderDistance = _renderDistance > 1 ? _renderDistance - 1 : _renderDistance;
            }
            if (KeyboardHelper.IsKeyPressed(Key.Escape))
            {
                OnUnload();
                _gameStateManager.SetGameState(null);
            }
            if (MouseHelper.IsKeyPressed(MouseButton.Left))
            {
                HitInfo hitInfo;
                if (_worldManager.CastRay(_world, _player.Position + new Vector3(0, 1.7f, 0f), _player.EyeForward, 20f, out hitInfo))
                {
                    _worldManager.SetBlockIdAt(_world, hitInfo.X, hitInfo.Y, hitInfo.Z, 0);
                }
            }
            if (MouseHelper.IsKeyPressed(MouseButton.Right))
            {
                HitInfo hitInfo;
                if (_worldManager.CastRay(_world, _player.Position + new Vector3(0, 1.7f, 0f), _player.EyeForward, 20f, out hitInfo))
                {
                    var x = hitInfo.X;
                    var y = hitInfo.Y;
                    var z = hitInfo.Z;
                    if (hitInfo.Face == HitInfo.FaceEnum.Left)
                    {
                        x--;
                    }
                    else if (hitInfo.Face == HitInfo.FaceEnum.Right)
                    {
                        x++;
                    }
                    else if (hitInfo.Face == HitInfo.FaceEnum.Top)
                    {
                        y++;
                    }
                    else if (hitInfo.Face == HitInfo.FaceEnum.Bottom)
                    {
                        y--;
                    }
                    else if (hitInfo.Face == HitInfo.FaceEnum.Front)
                    {
                        z++;
                    }
                    else if (hitInfo.Face == HitInfo.FaceEnum.Back)
                    {
                        z--;
                    }
                    _worldManager.SetBlockIdAndMetadataAt(_world, x, y, z, (byte)_selectedBlockId, (byte)_selectedBlockMetadata);
                }
            }
            if (KeyboardHelper.IsKeyPressed(Key.Q))
            {
                _selectedBlockId       = _blockSelector.GetPreviousBlock(_selectedBlockId);
                _selectedBlockMetadata = 0;
            }
            if (KeyboardHelper.IsKeyPressed(Key.E))
            {
                _selectedBlockId       = _blockSelector.GetNextBlock(_selectedBlockId);
                _selectedBlockMetadata = 0;
            }
            if (KeyboardHelper.IsKeyPressed(Key.R))
            {
                _selectedBlockMetadata = _selectedBlockMetadata >= 255 ? 0 : _selectedBlockMetadata + 1;
            }
            if (KeyboardHelper.IsKeyPressed(Key.F))
            {
                _selectedBlockMetadata = _selectedBlockMetadata <= 0 ? 255 : _selectedBlockMetadata - 1;
            }
            if (KeyboardHelper.IsKeyPressed(Key.BracketRight))
            {
                _destroySphereRadius = _destroySphereRadius < 30 ? _destroySphereRadius + 1 : _destroySphereRadius;
            }
            if (KeyboardHelper.IsKeyPressed(Key.BracketLeft))
            {
                _destroySphereRadius = _destroySphereRadius > 1 ? _destroySphereRadius - 1 : _destroySphereRadius;
            }
            if (KeyboardHelper.IsKeyPressed(Key.X))
            {
                HitInfo hitInfo;
                if (_worldManager.CastRay(_world, _player.Position + new Vector3(0, 1.7f, 0f), _player.EyeForward, 800f, out hitInfo))
                {
                    var impactPoint = new Vector3(hitInfo.X, hitInfo.Y, hitInfo.Z);
                    for (int x = hitInfo.X - _destroySphereRadius + 1; x <= hitInfo.X + _destroySphereRadius - 1; x++)
                    {
                        for (int y = hitInfo.Y - _destroySphereRadius + 1; y <= hitInfo.Y + _destroySphereRadius - 1; y++)
                        {
                            for (int z = hitInfo.Z - _destroySphereRadius + 1; z <= hitInfo.Z + _destroySphereRadius - 1; z++)
                            {
                                if ((new Vector3(x, y, z) - impactPoint).LengthFast <= _destroySphereRadius)
                                {
                                    _worldManager.SetBlockIdAt(_world, x, y, z, 0);
                                }
                            }
                        }
                    }
                }
            }
            if (KeyboardHelper.IsKeyPressed(Key.C))
            {
                HitInfo hitInfo;
                if (_worldManager.CastRay(_world, _player.Position + new Vector3(0, 1.7f, 0f), _player.EyeForward, 800f, out hitInfo))
                {
                    var impactPoint = new Vector3(hitInfo.X, hitInfo.Y, hitInfo.Z);
                    for (int x = hitInfo.X - _destroySphereRadius + 1; x <= hitInfo.X + _destroySphereRadius - 1; x++)
                    {
                        for (int y = hitInfo.Y - _destroySphereRadius + 1; y <= hitInfo.Y + _destroySphereRadius - 1; y++)
                        {
                            for (int z = hitInfo.Z - _destroySphereRadius + 1; z <= hitInfo.Z + _destroySphereRadius - 1; z++)
                            {
                                if ((new Vector3(x, y, z) - impactPoint).LengthFast <= _destroySphereRadius)
                                {
                                    _worldManager.SetBlockIdAndMetadataAt(_world, x, y, z, (byte)_selectedBlockId, (byte)_selectedBlockMetadata);
                                }
                            }
                        }
                    }
                }
            }
            if (KeyboardHelper.IsKeyPressed(Key.V))
            {
                HitInfo hitInfo;
                if (_worldManager.CastRay(_world, _player.Position + new Vector3(0, 1.7f, 0f), _player.EyeForward, 800f, out hitInfo))
                {
                    int[,] cupil = new[, ]
                    {
                        { -1, -1, -1, -1, -1, 07, 07, 07, 07, -1, -1, -1, -1 },
                        { -1, -1, -1, 07, 07, 08, 08, 08, 08, 07, -1, -1, -1 },
                        { -1, -1, 07, 00, 00, 00, 00, 00, 08, 08, 07, -1, -1 },
                        { -1, 07, 08, 00, 00, 08, 08, 08, 08, 08, 08, 07, -1 },
                        { 07, 07, 08, 00, 08, 08, 08, 08, 08, 08, 08, 07, -1 },
                        { 07, 08, 00, 08, 08, 08, 08, 15, 08, 08, 15, 07, -1 },
                        { -1, 07, 08, 08, 08, 07, 06, 08, 08, 08, 08, 06, 07 },
                        { 07, 08, 08, 08, 08, 08, 07, 07, 07, 07, 07, 07, -1 },
                        { 07, 00, 08, 07, 08, 08, 08, 08, 08, 08, 07, -1, -1 },
                        { 07, 00, 07, 08, 07, 07, 08, 07, 07, 07, 08, 07, -1 },
                        { -1, 07, 08, 08, 07, -1, 07, -1, -1, -1, 07, -1, -1 },
                        { -1, -1, 07, 07, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
                    };
                    var impactPoint = new Vector3(hitInfo.X, hitInfo.Y, hitInfo.Z);
                    for (int x = 0; x < 13; x++)
                    {
                        for (int y = 11; y >= 0; y--)
                        {
                            if (cupil[y, x] != -1)
                            {
                                _worldManager.SetBlockIdAndMetadataAt(_world, hitInfo.X - 7 + x, hitInfo.Y + 12 - y, hitInfo.Z, (byte)35, (byte)cupil[y, x]);
                            }
                        }
                    }
                }
            }

            var txt = $"Framerate: {_framerate:0.0}\nDirection : {_player.EyeForward.X:0.00} ; {_player.EyeForward.Y:0.00} ; {_player.EyeForward.Z:0.00}\nPosition: {_player.Position.X:0.00} ; {_player.Position.Y:0.00} ; {_player.Position.Z:0.00}\nParallel Mode: {StaticReferences.ParallelMode}\nRender distance: {_renderDistance} chunks\nDestroy sphere radius: {_destroySphereRadius}\nHand: {_blocksProvider.GetBlockForId((byte)_selectedBlockId).Name}:{_selectedBlockMetadata}";

            txt           += $"\nVisible chunks: {_visibleChunks}";
            txt           += $"\nVisible blocks: {_gpuBlocks}";
            _text.Str      = txt;
            _text.Position = new Vector2(5, _height - 5);
        }