private void generateTreeTrunk(ChunkDecorator decorator, out TileType treeTrunk, out TileType treeTop)
        {
            //we want to generate an appropriate variety of trunk images.
            int numGeneratedTrunks = 9;

            //set up the texture array and spritebatch
            RenderTarget2D[] trunks   = new RenderTarget2D[numGeneratedTrunks];
            RenderTarget2D[] treeTops = new RenderTarget2D[numGeneratedTrunks];
            SpriteBatch      batch    = new SpriteBatch(Game1.instance.GraphicsDevice);

            //numPrimitives represents the number of different "basic shapes" used to generate the tree trunk.
            int numPrimitives = 1 + decorator.rand.Next(2);

            //each primitive gets N different "strings" of drawings.
            int[] branches = new int[numPrimitives];
            //each primitive gets to move N distance each pass along its "string".
            float[] jumpHeight = new float[numPrimitives];
            //each primitive can change direction N amount each pass along its string.
            float[] rotationRange = new float[numPrimitives];
            //each primitive can start rotated an arbitrary amount.
            float[] startDisplayRotation = new float[numPrimitives];
            float[] displayRotationRange = new float[numPrimitives];

            Texture2D[] primitives = new Texture2D[numPrimitives];

            for (int i = 0; i < numPrimitives; i++)
            {
                //select a random primitive texture
                primitives[i] = Game1.instance.primitives[decorator.rand.Next(Game1.instance.primitives.Count)];
                //select a random number of times for the primitive to draw a string on the texture.
                branches[i] = 2 + decorator.rand.Next(3);
                //select a random distance for the primitive to jump through each pass.
                jumpHeight[i] = 7 + decorator.rand.Next(5);
                //select a random rotation for each primitive to use on each pass.
                rotationRange[i] = (float)(decorator.rand.NextDouble() / 2);
                //select a random display rotation for each primitive to use
                startDisplayRotation[i] = (float)(decorator.rand.NextDouble() * Math.PI * 2);
                displayRotationRange[i] = (float)(decorator.rand.NextDouble() * Math.PI * 2);
            }

            //make the texture size a bit bigger than the normal block, so that
            //the generation has room to work without ugly cut-offs on the final texture.
            int texSizeTrunk = (int)(Chunk.tileDrawWidth * 1.5);

            for (int i = 0; i < numGeneratedTrunks; i++)
            {
                RenderTarget2D trunkImages = new RenderTarget2D(
                    Game1.instance.GraphicsDevice,
                    texSizeTrunk,
                    texSizeTrunk,
                    false,
                    Game1.instance.GraphicsDevice.PresentationParameters.BackBufferFormat,
                    DepthFormat.Depth24);


                Game1.instance.GraphicsDevice.SetRenderTarget(trunkImages);
                Game1.instance.GraphicsDevice.Clear(Color.Transparent);
                batch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, null);

                for (int k = 0; k < numPrimitives; k++)
                {
                    for (int j = 0; j < branches[k]; j++)
                    {
                        //set up the start position and rotations.
                        Vector2 lastLocation = new Vector2((texSizeTrunk * .66f) - decorator.rand.Next((int)(texSizeTrunk * .33f)), 10);
                        float   lastRotation = (float)((Math.PI * -1.5) + decorator.rand.NextDouble() * rotationRange[k] - rotationRange[k] / 2); //turns out that this number is more-or-less vertically aligned for some reason.

                        //stop drawing when we've reached the other side of the texture
                        while (lastLocation.Y < texSizeTrunk - 15)
                        {
                            //find the rotation location and rotation after a jump
                            float   nextRotation = lastRotation + (float)(decorator.rand.NextDouble() * rotationRange[k] - rotationRange[k] / 2);
                            Vector2 nextLocation = lastLocation + vectorFromAngle(nextRotation) * jumpHeight[k];

                            //50% chance to flip the sprite
                            SpriteEffects effect = SpriteEffects.None;
                            if (decorator.rand.NextDouble() < .5f)
                            {
                                effect = SpriteEffects.FlipHorizontally;
                            }

                            //calculate the overall location of the primitive given the parameters
                            Rectangle rect = new Rectangle((int)(nextLocation.X), (int)(nextLocation.Y), 20, 20);

                            //draw onto the trunk texture
                            batch.Draw(primitives[k], rect, null, Color.White, nextRotation + startDisplayRotation[k] + (float)decorator.rand.NextDouble() * displayRotationRange[k], Vector2.Zero, effect, 0);

                            lastLocation = nextLocation;
                            lastRotation = nextRotation;
                        }
                    }
                }


                batch.End();
                Game1.instance.GraphicsDevice.SetRenderTarget(null);

                trunks[i] = trunkImages;
            }

            //lastly, generate a texture for the branches.
            //make the texture size a bit bigger than the normal block, so that
            //the generation has room to work without ugly cut-offs on the final texture.
            int texSizeTop = (int)(Chunk.tileDrawWidth * 3);

            for (int i = 0; i < numGeneratedTrunks; i++)
            {
                RenderTarget2D treeTopImages = new RenderTarget2D(
                    Game1.instance.GraphicsDevice,
                    texSizeTop,
                    texSizeTop,
                    false,
                    Game1.instance.GraphicsDevice.PresentationParameters.BackBufferFormat,
                    DepthFormat.Depth24);

                //blah blah blah
                Game1.instance.GraphicsDevice.SetRenderTarget(treeTopImages);
                Game1.instance.GraphicsDevice.Clear(Color.Transparent);
                batch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, null);

                for (int k = 0; k < numPrimitives; k++)
                {
                    for (int j = 0; j < branches[k]; j++)
                    {
                        //set up the start position and rotations.
                        //Vector2 lastLocation = new Vector2((texSize / 2) + rand.Next(texSize / 4) - texSize / 8, 10);
                        Vector2 lastLocation = new Vector2((texSizeTop * .66f) - decorator.rand.Next((int)(texSizeTop * .33f)), texSizeTop - 15);
                        float   lastRotation = (float)((Math.PI * -1.5) + decorator.rand.NextDouble() * rotationRange[k] - rotationRange[k] / 2); //turns out that this number is more-or-less vertically aligned for some reason.

                        //stop drawing when we've reached the other side of the texture
                        while (lastLocation.Y > 15 && lastLocation.X > 15 && lastLocation.X < texSizeTop - 15)
                        {
                            //find the rotation location and rotation after a jump
                            float   nextRotation = lastRotation + (float)(decorator.rand.NextDouble() * rotationRange[k] - rotationRange[k] / 2);
                            Vector2 nextLocation = lastLocation - vectorFromAngle(nextRotation) * jumpHeight[k];

                            //50% chance to flip the sprite
                            SpriteEffects effect = SpriteEffects.None;
                            if (decorator.rand.NextDouble() < .5f)
                            {
                                effect = SpriteEffects.FlipHorizontally;
                            }

                            //calculate the overall location of the primitive given the parameters
                            Rectangle rect = new Rectangle((int)(nextLocation.X), (int)(nextLocation.Y), 20, 20);

                            //draw onto the trunk texture
                            batch.Draw(primitives[k], rect, null, Color.White, nextRotation + startDisplayRotation[k] + (float)decorator.rand.NextDouble() * displayRotationRange[k], Vector2.Zero, effect, 0);

                            lastLocation = nextLocation;
                            lastRotation = nextRotation;
                        }
                    }
                }


                batch.End();
                Game1.instance.GraphicsDevice.SetRenderTarget(null);

                treeTops[i] = treeTopImages;
            }

            //TODO: randomize parameters
            //treeTrunk = new RandomImageTile(new TileTag[] { TagReferencer.AIR, TagReferencer.Climbeable, TagReferencer.DRAWOUTSIDEOFBOUNDS }, trunks, false);
            //trunk.friction += .03f;

            //TODO: randomize parameters
            //treeTop = new RandomImageTile(new TileTag[] { TagReferencer.AIR, TagReferencer.Climbeable, TagReferencer.DRAWOUTSIDEOFBOUNDS }, treeTops, false);
            //treeTop.friction += .03f;

            treeTrunk = new RandomImageTileFromSpritesheet(new TileTag[] { TagReferencer.AIR, TagReferencer.Climbeable, TagReferencer.Harvest, TagReferencer.DRAWOUTSIDEOFBOUNDS }, trunks, texSizeTrunk, batch, false);
            treeTrunk.harvestTicks = 5 + getRandValuePlusOrMinus(decorator.rand, Math.Max(decorator.metaDifficulty, 1));
            treeTop = new RandomImageTileFromSpritesheet(new TileTag[] { TagReferencer.AIR, TagReferencer.Climbeable, TagReferencer.DRAWOUTSIDEOFBOUNDS }, treeTops, texSizeTop, batch, false);

            batch.Dispose();
        }
Ejemplo n.º 2
0
        public TileType generateGrass(ChunkDecorator decorator)
        {
            //we want to generate an appropriate variety of trunk images.
            int numGeneratedGrasses = 16;

            //set up the texture array and spritebatch
            RenderTarget2D[] grasses = new RenderTarget2D[numGeneratedGrasses];
            SpriteBatch      batch   = new SpriteBatch(Game1.instance.GraphicsDevice);

            //numPrimitives represents the number of different "basic shapes" used to generate the tree trunk.
            //int numPrimitives = 1 + rand.Next(2);
            //each primitive gets N different "strings" of drawings.
            //int[] branches = new int[numPrimitives];
            //each primitive gets to move N distance each pass along its "string".
            float jumpHeight = 1 + decorator.rand.Next(1);
            float bumpiness  = 1 + decorator.rand.Next(7);
            //each primitive can change direction N amount each pass along its string.
            //each primitive can start rotated an arbitrary amount.
            float startDisplayRotation = (float)(decorator.rand.NextDouble() * Math.PI * 2);
            float displayRotationRange = (float)(decorator.rand.NextDouble() * Math.PI * 2);

            Texture2D primitives = Game1.instance.primitives[decorator.rand.Next(Game1.instance.primitives.Count)];

            //make the texture size a bit bigger than the normal block, so that
            //the generation has room to work without ugly cut-offs on the final texture.
            int texSize = (int)(Chunk.tileDrawWidth * 1.7);

            for (int i = 0; i < numGeneratedGrasses; i++)
            {
                RenderTarget2D grassImage = new RenderTarget2D(
                    Game1.instance.GraphicsDevice,
                    texSize,
                    texSize,
                    false,
                    Game1.instance.GraphicsDevice.PresentationParameters.BackBufferFormat,
                    DepthFormat.Depth24);

                //blah blah blah
                Game1.instance.GraphicsDevice.SetRenderTarget(grassImage);
                Game1.instance.GraphicsDevice.Clear(Color.Transparent);
                batch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, null);


                //set up the start position and rotations.
                //Vector2 lastLocation = new Vector2((texSize / 2) + rand.Next(texSize / 4) - texSize / 8, 10);
                Vector2 lastLocation = new Vector2(15, Chunk.tileDrawWidth + 19);

                //stop drawing when we've reached the other side of the texture
                for (int z = 0; z < 10; z++)
                {
                    while (lastLocation.X < texSize - 20)
                    {
                        //find the rotation location and rotation after a jump
                        Vector2 nextLocation = lastLocation + new Vector2(jumpHeight, 0);

                        //50% chance to flip the sprite
                        SpriteEffects effect = SpriteEffects.None;
                        if (decorator.rand.NextDouble() < .5f)
                        {
                            effect = SpriteEffects.FlipHorizontally;
                        }

                        //calculate the overall location of the primitive given the parameters
                        Rectangle rect = new Rectangle((int)(nextLocation.X), (int)(nextLocation.Y + decorator.rand.NextDouble() * bumpiness), 7, 7);

                        //draw onto the trunk texture
                        batch.Draw(primitives, rect, null, Color.White, startDisplayRotation + (float)decorator.rand.NextDouble() * displayRotationRange, Vector2.Zero, effect, 0);

                        lastLocation = nextLocation;
                    }
                }

                batch.End();
                Game1.instance.GraphicsDevice.SetRenderTarget(null);

                grasses[i] = grassImage;
            }

            //TODO: randomize parameters
            //return new RandomImageTile(new TileTag[] { TagReferencer.AIR, TagReferencer.DRAWOUTSIDEOFBOUNDS }, grasses, false);
            RandomImageTileFromSpritesheet tile = new RandomImageTileFromSpritesheet(new TileTag[] { TagReferencer.AIR, TagReferencer.DRAWOUTSIDEOFBOUNDS }, grasses, texSize, batch, false);

            batch.Dispose();
            return(tile);
        }