/// <summary> /// Stamp another sprite onto this sprite based on their scene positions /// </summary> /// <param name="otherSprite">The sprite to stamp onto this one</param> /// <param name="stampMethod">Stamp drawing method (Normal or Cutout)</param> /// <param name="stampMethod">Stamp cropping method (Crop or Grow)</param> public void Stamp(Sprite otherSprite, StampMethods stampMethod, StampCroppings stampCropping) { switch (stampCropping) { case StampCroppings.CropToSprite: break; case StampCroppings.GrowSprite: default: throw new Exception("Sprite.Stamp() does not yet support cropping mode " + stampCropping); } int width = Costume.Width; int height = Costume.Height; switch (stampMethod) { case StampMethods.Normal: { RenderTarget2D newTexture = new RenderTarget2D( this.Game.GraphicsDevice, width, height, /*mipMap:*/ false, /*preferredFormat:*/ SurfaceFormat.Color, /*preferredDepthFormat:*/ DepthFormat.Depth24Stencil8, /*preferredMultiSampleCount:*/ 1, /*usage:*/ RenderTargetUsage.DiscardContents); // Calculate a matrix which transforms from A's local space into // world space and then into B's local space Matrix TransformA = this.TransformAlt; Matrix TransformB = otherSprite.TransformAlt; Matrix transformAToB = TransformB * Matrix.Invert(TransformA); Vector2 position; float rotation; float scale; transformAToB.Decompose2D(out position, out rotation, out scale); // Set render target this.Game.GraphicsDevice.SetRenderTarget(newTexture); this.Game.GraphicsDevice.Clear(Color.Transparent); this.Game.spriteBatch.Begin(); // Copy the current costume this.Game.spriteBatch.Draw(Costume.Texture, Vector2.Zero, Color.White); // Draw the other sprite this.Game.spriteBatch.Draw(otherSprite.Costume.Texture, position, null, otherSprite.SpriteColor * otherSprite.Alpha, rotation, Vector2.Zero, // otherSprite.Costume.Center, otherSprite.Scale / Scale, SpriteEffects.None, 0f); this.Game.spriteBatch.End(); // Unset render target this.Game.GraphicsDevice.SetRenderTarget(null); Costume.Texture = newTexture; } break; case StampMethods.Cutout: { Color[] newPixels = StampAlpha( this.Transform, this.Costume.Texture.Width, this.Costume.Texture.Height, this.Costume.Pixels, otherSprite.Transform, otherSprite.Costume.Texture.Width, otherSprite.Costume.Texture.Height, otherSprite.Costume.Pixels, false); Costume.Pixels = newPixels; } break; case StampMethods.CutoutInverted: { Color[] newPixels = StampAlpha( this.Transform, this.Costume.Texture.Width, this.Costume.Texture.Height, this.Costume.Pixels, otherSprite.Transform, otherSprite.Costume.Texture.Width, otherSprite.Costume.Texture.Height, otherSprite.Costume.Pixels, true); Costume.Pixels = newPixels; } break; default: throw new Exception("Sprite.Stamp() does not yet support stampMethod " + stampMethod); } }
/// <summary> /// Stamp another sprite onto this sprite based on their scene positions. The other sprite will be cropped to the rectangle of the current sprite. /// </summary> /// <param name="otherSprite">The sprite to stamp onto this one</param> /// <param name="stampMethod">Stamp drawing method (Normal or Cutout)</param> public void Stamp(Sprite otherSprite, StampMethods stampMethod) { Stamp(otherSprite, stampMethod, StampCroppings.CropToSprite); }