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(); }
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); }