Beispiel #1
0
        public float[,] Generate()
        {
            // Start with the world in a bowl.
            float halfSize = Size / 2f;
            for (int z = 0; z < Size; z++)
            {
                for (int x = 0; x < Size; x++)
                {
                    float xH = (float)Math.Pow((x - halfSize) / halfSize, 2);
                    float zH = (float)Math.Pow((z - halfSize) / halfSize, 2);
                    Heights[x, z] = MathHelper.Lerp(xH, zH, .5f);
                }
            }

            AddPerlinNoise(6.0f);
            Perturb(35.0f);

            float[,] additional = new HeightMap(Size / 4).Generate(9, 20);

            int quadSize = Size / 4;
            for (int z = 0; z < Size; z++)
                for (int x = 0; x < Size; x++)
                    Heights[x, z] += .15f * additional[x % quadSize, z % quadSize];

            Smoothen();

            for (int z = 0; z < Size; z++)
            {
                for (int x = 0; x < Size; x++)
                {
                    Heights[x, z] = Math.Max(0, Heights[x, z]);
                }
            }

            return Heights;
        }
Beispiel #2
0
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // Overlay component, used to draw the pause menu and game over menu
            overlayComponent = new OverlayComponent(Game, spriteBatch);
            Game.Components.Add(overlayComponent);

            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
                GraphicsDevice.Viewport.AspectRatio, 0.1f, 50000);

            directionalLight = new DirectionalLight(
                new Vector3(-1.25f, -2f, 5.0f), // Direction
                new Vector3(.1f, .1f, .1f),//new Vector3(.15f, .14f, .29f), // Ambient
                new Vector3(.46f, .33f, .75f)); // Diffuse

            Game.AddService(typeof(DirectionalLight), directionalLight);

            #region Level terrain generation

            int heightMapSize = terrainSegmentsCount * terrainSegmentSize + 1;
            float halfHeightMapSize = heightMapSize / 2f;
            HeightMap heightmapGenerator = new HeightMap(heightMapSize);
            var heightMap = heightmapGenerator.Generate();

            var roadMap = new float[heightMapSize, heightMapSize];
            raceTrack = new RaceTrack(heightMapSize, terrainScale);

            navMesh = new NavMesh(GraphicsDevice, raceTrack.Curve, //1500, roadWidth, terrainScale);
                750, roadWidth, terrainScale);

            Vector3 lastPosition = raceTrack.Curve.GetPoint(.01f) / terrainScale;

            for (float t = 0; t < 1; t += .0002f)
            {
                var e = raceTrack.Curve.GetPoint(t) / terrainScale;

                for (float j = -roadFalloff; j <= roadFalloff; j++)
                {
                    var pos = e + j * Vector3.Normalize(Vector3.Cross(lastPosition - e, Vector3.Up));

                    // Indices
                    int x = (int)(pos.X + halfHeightMapSize),
                        z = (int)(pos.Z + halfHeightMapSize);

                    float height = e.Y;

                    if (Math.Abs(j) <= roadWidth)
                    {
                        heightMap[x, z] = height;
                        roadMap[x, z] = 1;
                    }
                    else
                    {
                        float amount = (Math.Abs(j) - roadWidth) / (roadFalloff - roadWidth);
                        heightMap[x, z] = MathHelper.Lerp(height,
                            heightMap[x, z], amount);
                        roadMap[x, z] = amount / 10f;
                    }
                }
                lastPosition = e;
            }

            heightmapGenerator.Smoothen();
            heightmapGenerator.Perturb(30f);

            for (int i = 0; i < 5; i++)
            {
                heightmapGenerator.Smoothen();
            }

            terrainEffect = content.Load<Effect>(@"Effects\TerrainShading");

            //terrainEffect.Parameters["TextureMap0"].SetValue(content.Load<Texture2D>(@"Terrain\sand"));
            #region TEXTURE RENDERING

            //var unprocessedGrassTexture = content.Load<Texture2D>(@"Terrain\grass");
            //var grassTexture = new RenderTarget2D(GraphicsDevice, unprocessedGrassTexture.Width, unprocessedGrassTexture.Height);

            //GraphicsDevice.SetRenderTarget(grassTexture);
            //spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
            //spriteBatch.Draw(unprocessedGrassTexture, new Rectangle(0, 0, unprocessedGrassTexture.Width, unprocessedGrassTexture.Height), Color.White);
            //spriteBatch.Draw(content.Load<Texture2D>(@"Particles\fire"), new Rectangle(0, 0, unprocessedGrassTexture.Width, unprocessedGrassTexture.Height), Color.White);
            //spriteBatch.End();
            //GraphicsDevice.SetRenderTarget(null);

            //terrainEffect.Parameters["TextureMap1"].SetValue(grassTexture);

            #endregion
            terrainEffect.Parameters["TextureMap0"].SetValue(content.Load<Texture2D>(@"Terrain\road"));
            terrainEffect.Parameters["TextureMap1"].SetValue(content.Load<Texture2D>(@"Terrain\grass"));
            terrainEffect.Parameters["TextureMap2"].SetValue(content.Load<Texture2D>(@"Terrain\rock"));
            terrainEffect.Parameters["TextureMap3"].SetValue(content.Load<Texture2D>(@"Terrain\snow"));
            terrainEffect.Parameters["RoadNormalMap"].SetValue(content.Load<Texture2D>(@"Terrain\road_n"));
            terrainEffect.Parameters["Projection"].SetValue(projectionMatrix);

            // Creates a terrainmodel around Vector3.Zero
            terrainSegments = new TerrainModel[terrainSegmentsCount, terrainSegmentsCount];

            float terrainStart = -.5f * heightMapSize;

            for (int z = 0; z < terrainSegmentsCount; z++)
            {
                for (int x = 0; x < terrainSegmentsCount; x++)
                {
                    terrainSegments[x, z] = new TerrainModel(GraphicsDevice,
                        terrainSegmentSize, terrainSegmentsCount, terrainStart,
                        x * terrainSegmentSize, z * terrainSegmentSize,
                        terrainScale, heightMap, roadMap, terrainEffect, directionalLight);
                }
            }

            #endregion

            #region Car

            Car = MakeCar();
            gameInstance.AddService(typeof(Car), Car);
            Player localPlayer = gameInstance.GetService<ServerClient>().LocalPlayer;
            gameInstance.GetService<CarControlComponent>().Cars[localPlayer] = Car;
            gameInstance.AddService(typeof(Player), localPlayer);

            #endregion

            #region Lights

            // Load model to represent our lightsources
            var pointLightModel = content.Load<Model>(@"Models\light");

            //spotLightModel = content.Load<Model>(@"Models\Cone");

            Vector3 pointLightOffset = new Vector3(0, 250, 0);

            var cr = new CurveRasterization(raceTrack.Curve, 50);

            float colorOffset = 0f;

            foreach (var point in cr.Points)
            {
                Random r = UniversalRandom.GetInstance();

                Vector3 color = new Vector3(0f,0f,0f);
                PointLight pl = new PointLight(point.Position + pointLightOffset +
                    Vector3.Transform(50 * Vector3.Up, Matrix.CreateRotationZ(MathHelper.TwoPi * (float)UniversalRandom.GetInstance().NextDouble())),
                    color, 450)
                {
                    Model = pointLightModel,
                    ColorTimeOffset = colorOffset
                };

                pointLights.Add(pl);
                GraphicalObjects.Add(pl);

                colorOffset += 100 / cr.Points.Count;
            }

            #endregion

            dustEmitter = new ParticleEmitter(dustSystem, 150, Car.Position);

            #region SkySphere

            skyBoxModel = content.Load<Model>(@"Models/skybox");
            skyBoxEffect = content.Load<Effect>(@"Effects/SkyBox");

            skyMap = new TextureCube(GraphicsDevice, 2048, false, SurfaceFormat.Color);
            string[] cubemapfaces = { @"SkyBoxes/PurpleSky/skybox_right1",
                @"SkyBoxes/PurpleSky/skybox_left2",
                @"SkyBoxes/PurpleSky/skybox_top3",
                @"SkyBoxes/PurpleSky/skybox_bottom4",
                @"SkyBoxes/PurpleSky/skybox_front5",
                @"SkyBoxes/PurpleSky/skybox_back6_2"
            };

            //cubeMap = new TextureCube(GraphicsDevice, 1024, false, SurfaceFormat.Color);
            //string[] cubemapfaces = {
            //    @"SkyBoxes/StormyDays/stormydays_ft",
            //    @"SkyBoxes/StormyDays/stormydays_bk",
            //    @"SkyBoxes/StormyDays/stormydays_up",
            //    @"SkyBoxes/StormyDays/stormydays_dn",
            //    @"SkyBoxes/StormyDays/stormydays_rt",
            //    @"SkyBoxes/StormyDays/stormydays_lf"
            //};

            //cubeMap = new TextureCube(GraphicsDevice, 1024, false, SurfaceFormat.Color);
            //string[] cubemapfaces = {
            //    @"SkyBoxes/Miramar/miramar_ft",
            //    @"SkyBoxes/Miramar/miramar_bk",
            //    @"SkyBoxes/Miramar/miramar_up",
            //    @"SkyBoxes/Miramar/miramar_dn",
            //    @"SkyBoxes/Miramar/miramar_rt",
            //    @"SkyBoxes/Miramar/miramar_lf"
            //};

            for (int i = 0; i < cubemapfaces.Length; i++)
                LoadCubemapFace(skyMap, cubemapfaces[i], (CubeMapFace)i);

            skyBoxEffect.Parameters["SkyboxTexture"].SetValue(skyMap);

            foreach (var mesh in skyBoxModel.Meshes)
                foreach (var part in mesh.MeshParts)
                    part.Effect = skyBoxEffect;

            #endregion

            #region Weather

            thunderBoltGenerator = new ThunderBoltGenerator(gameInstance, thunderParticleSystem);
            gameInstance.Components.Add(thunderBoltGenerator);

            #endregion

            #region GameObjects

            OakTree.LoadMaterial(content);
            BirchTree.LoadMaterial(content);
            Stone.LoadMaterial(content);

            int numObjects = 75;

            for (int i = 0; i < numObjects; i++)
            {

                var t = navMesh.triangles[UniversalRandom.GetInstance().Next(navMesh.triangles.Length)];
                float v = (float)UniversalRandom.GetInstance().NextDouble();

                //float u = (float) (UniversalRandom.GetInstance().NextDouble() - 1/2f);
                //if (u < 0)
                //    u -= .5f;
                //else
                //    u += 1.5f;

                float u = 0;
                if (UniversalRandom.GetInstance().NextDouble() <= .5)
                    u = -.5f - .3f * (float)(-UniversalRandom.GetInstance().NextDouble());
                else
                    u = (float)(1.5f + .3f * UniversalRandom.GetInstance().NextDouble());

                var pos = (t.vertices[0] + u * t.ab + v * t.ac) / terrainScale;
                //var treePos = new Vector3(-halfHeightMapSize + (float)UniversalRandom.GetInstance().NextDouble() * (heightMapSize-50), 0,
                //    -halfHeightMapSize + (float)UniversalRandom.GetInstance().NextDouble() * (heightMapSize-50));

                float X = pos.X + heightMapSize / 2f,
                    Z = pos.Z +heightMapSize / 2f;

                float Xlerp = X % 1f,
                    Zlerp = Z % 1f;

                int x0 = (int)X,
                    z0 = (int)Z,
                    x1 = x0 + 1,
                    z1 = z0 + 1;

                float height;
                float k;
                if (Xlerp + Zlerp > 1)
                {
                    float h1 = MathHelper.Lerp(heightMap[x0, z1], heightMap[x1, z1], Xlerp);
                    float h2 = MathHelper.Lerp(heightMap[x1, z0], heightMap[x1, z1], Zlerp);
                    k = h2 / h1;
                    height = MathHelper.Lerp(h1, h2, .5f);
                }
                else
                {
                    float h1 = MathHelper.Lerp(heightMap[x0, z0], heightMap[x1, z0], Xlerp),
                        h2 = MathHelper.Lerp(heightMap[x0, z0], heightMap[x0, z1], Zlerp);
                    k = h2 / h1;
                    height = MathHelper.Lerp(h1, h2, .5f);
                }
                pos.Y = height - 0.002f;

                if (k > 1.02 ) continue;

                GameObject obj;
                switch(UniversalRandom.GetInstance().Next(0, 3))
                {
                case 0:
                    obj = new OakTree(gameInstance);
                    obj.Scale = 3 + 3 * (float)UniversalRandom.GetInstance().NextDouble();
                    FireflyCandidates.Add(obj);
                    break;
                case 1:
                    obj = new BirchTree(gameInstance);
                    obj.Scale = 3 + 3 * (float)UniversalRandom.GetInstance().NextDouble();
                    FireflyCandidates.Add(obj);
                    break;
                default:
                    obj = new Stone(gameInstance);
                    obj.Scale = 0.5f + (float)(.25 * UniversalRandom.GetInstance().NextDouble());
                    break;
                }

                obj.Position = terrainScale * pos;
                obj.Rotation = new Vector3(0, MathHelper.Lerp(0, MathHelper.Pi * 2, (float)UniversalRandom.GetInstance().NextDouble()), 0);

                GraphicalObjects.Add(obj);
                ShadowCasterObjects.Add(obj);
            }

            for (int i = 0; i < FireflyCandidates.Count; i+=5)
            {
                ParticleEmitter emitter = new ParticleEmitter(fireflySystem, 80, FireflyCandidates[i].Position);
                emitter.Origin = FireflyCandidates[i].Position + Vector3.Up * 500;
                fireflyEmitter.Add(emitter);
            }

            #endregion

            //foreach (GameObject obj in GraphicalObjects)
            //{
            //    pointLights.Add(new PointLight(obj.Position + Vector3.Up * 500, new Vector3(0.7f, 0.7f, 0.7f), 450)
            //    {
            //        Model = pointLightModel
            //    });
            //}
            //GraphicalObjects.AddRange(pointLights);

            //List<FireObject> list = new List<FireObject>();
            //foreach (PointLight p in pointLights)
            //{
            //    FireObject obj = new FireObject(gameInstance, content, p.Position, p.Position + Vector3.Up * 10);
            //    list.Add(obj);

            //}
            //pointLights.AddRange(list);
            //GraphicalObjects.AddRange(list);

            #region Cameras

            var input = gameInstance.GetService<InputComponent>();

            gameInstance.GetService<CameraComponent>().AddCamera(new DebugCamera(new Vector3(-11800, 3000, -8200), input));
            Camera c;
            gameInstance.GetService<CameraComponent>().AddCamera(c = new ThirdPersonCamera(Car, input));
            gameInstance.GetService<CameraComponent>().CurrentCamera = c;

            #endregion

            #region DynamicEnvironment

            // TODO: CARMOVE
            environmentCubeMap = new RenderTargetCube(this.GraphicsDevice, 256, true, SurfaceFormat.Color, DepthFormat.Depth16);
            Car.EnvironmentMap = skyMap;

            #endregion

            #region PostProcess

            postProcessingComponent = new PostProcessingComponent(Game);
            Game.Components.Add(postProcessingComponent);

            postProcessTexture = new RenderTarget2D(GraphicsDevice,
                GraphicsDevice.Viewport.Width,
                GraphicsDevice.Viewport.Height,
                true, SurfaceFormat.Color, DepthFormat.Depth24);

            #endregion

            // Adding a prelighingrenderer as a service
            prelightingRenderer = new PrelightingRenderer(GraphicsDevice, content);
            Game.AddService(typeof(PrelightingRenderer), prelightingRenderer);

            #region ShadowMapEffect

            shadowMapEffect = content.Load<Effect>(@"Effects\ShadowMap");

            #endregion

            #region Gameplay Trigger Manager (with sample)

            /// <summary>
            /// Gets the triggermanager
            /// Add new PositionTrigger
            /// Hook up to listener => when hit, use the thunderBoltGenerator and spawn a flash
            /// Adds it to triggers.
            /// </summary>

            //var triggerManager = gameInstance.GetService<TriggerManager>();

            //int noOfCheckpoints = 10;
            //for (int i = 0; i < noOfCheckpoints; i++)
            //{
            //    var trigger = new PositionTrigger(raceTrack.CurveRasterization, (int)(((float)i / noOfCheckpoints) * raceTrack.CurveRasterization.Points.Count), true, true);
            //    string cp = "Checkpoint " + i;
            //    trigger.Triggered += (sender, e) =>
            //    {
            //        Console.WriteLine(cp);
            //    };
            //    triggerManager.Triggers.Add("checkpoint"+i, trigger);
            //}

            #endregion

            #region Game Mode
            if (gameInstance.GetService<ServerClient>().connected)
            {
                foreach (var player in gameInstance.GetService<ServerClient>().Players.Values)
                {
                    gameInstance.GetService<CarControlComponent>().AddCar(player, null, this);
                }
                var carList = gameInstance.GetService<CarControlComponent>().Cars.OrderBy(pc => pc.Key.ID).Select(pc => pc.Value).ToList();
                SetCarsAtStart(carList);
            }

            int cp = 6;
            if (gameModeChoice == GameModeChoice.SimpleRace)
                this.mode = new SimpleRaceMode(gameInstance, 3, cp, raceTrack, Car);
            else if (gameModeChoice == GameModeChoice.Multiplayer)
                this.mode = new MultiplayerRaceMode(gameInstance, 3, cp, raceTrack, Car);
            else
                throw new Exception("Stop choosing weird game modes");

            gameInstance.AddService(typeof(GameplayMode), mode);

            #endregion

            #region Checkpoint lights
            for (int i=0; i<cp; i++) {
                var point = raceTrack.GetCurveRasterization(cp).Points[i];

                var pl = new CheckpointLight(point.Position + 500 * Vector3.Up)
                {
                    Model = pointLightModel
                };
                pointLights.Add(pl);
                GraphicalObjects.Add(pl);

                #region Fire
                int halfnumberoffire = 5;

                for (int o = -halfnumberoffire + 1; o < halfnumberoffire; o++)
                {
                    Vector3 side = Vector3.Cross(Vector3.Normalize(raceTrack.Curve.GetPoint((i) / (float)cp + .001f) - point.Position), Vector3.Up);

                    var fire = new FireObject(content, fireSystem, fireSmokeSystem, point.Position + side * 100 * o -
                        Vector3.Up * 400 +
                        Vector3.Up * 650 * (float)Math.Cos(o/(float)halfnumberoffire), Vector3.Up * 10);
                    pointLights.Add(fire);
                    GraphicalObjects.Add(fire);
                }
                #endregion
            }
            #endregion

            #region BackgroundSound
            loopSoundManager.AddNewSound("forestambient");
            #endregion

            prelightingRenderer.GameObjects = GraphicalObjects;

            init = true;
        }