Hiệu ứng Flash XNA Sprite


8

Tôi đang tìm cách để hiển thị mọi pixel không trong suốt ở dạng rắn màu trắng (để 'flash' màu trắng sprite khi người chơi chịu sát thương, v.v.). Đây là trên Windows Phone 7.

Tôi đã sử dụng một trình tạo bóng tùy chỉnh rất đơn giản để thực hiện điều này trong XNA 3.1, nhưng WP7 không hỗ trợ những điều này và việc tìm kiếm một giải pháp thay thế khó khăn.

Tôi đánh giá cao bất kỳ trợ giúp hoặc đề xuất. Tôi không muốn phải tự tạo một bản sao trắng của mỗi sprite trong trò chơi của mình.


1
Được rồi, tôi đã tìm ra một cách, nhưng nó không đẹp. Hãy để tôi dọn dẹp nó một chút và tôi sẽ cập nhật câu trả lời của mình.
David Gouveia

Câu trả lời:


9

Phương pháp 1

Bạn không phải tạo một phiên bản màu trắng của mỗi sprite trong trò chơi của mình một cách thủ công - bạn cũng có thể tự động hóa quá trình khi tải. Nói cách khác, bạn có thể sử dụng Texture2D.GetData()để truy cập các pixel của kết cấu của mình (và truy xuất chúng dưới dạng đơn giản Color[]), lặp lại chúng thay thế bất kỳ pixel không trong suốt nào bằng màu trắng, sau đó lưu nó vào một kết cấu mới bằng cách sử dụng và Texture2D.SetData().

Cách 2

Tôi đã thử chơi xung quanh BlendStatenhưng không thể tìm ra cách hiển thị toàn bộ màu trắng, ít nhất là không nằm trong giới hạn của hồ sơ Reach. Nhưng nếu ai đó biết một cách cho tôi biết. Tuy nhiên, những gì tôi đã tìm thấy là một cách để làm điều đó bằng cách sử dụng bộ đệm stpson và AlphaTestEffectlớp tích hợp. Ý tưởng như sau:

  1. Tạo một backbuffer có bộ đệm stpson.
  2. Xóa bộ đệm stprint về không.
  3. Vẽ các họa tiết bạn muốn tô màu trắng và bất cứ khi nào chúng vượt qua bài kiểm tra alpha, hãy đặt bộ đệm stpson tại vị trí đó thành 1.
  4. Vẽ một hình tứ giác màu trắng bao phủ toàn bộ màn hình, nhưng chỉ khi giá trị của bộ đệm stprint là 1.

Đây là mã tôi đã sử dụng:

(Bước 1) Trước tiên, hãy đảm bảo rằng backbuffer đang được tạo có chỗ cho bộ đệm stpson:

graphics = new GraphicsDeviceManager(this) { PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8 };

(Bước 2) Tạo kết cấu trắng 1x1 sẽ được thu nhỏ để lấp đầy toàn bộ màn hình:

private Texture2D pixel;
pixel = new Texture2D(GraphicsDevice, 1, 1);
pixel.SetData(new[] { Color.White });

(Bước 3) Và bây giờ là phần khó - kết xuất nó. Chà, không khó lắm, nhưng đòi hỏi hai DepthStencilStateđối tượng và một AlphaTestEffectđối tượng. Bạn chỉ nên tạo những thứ này một lần.

// Clear stencil buffer
GraphicsDevice.Clear(ClearOptions.Stencil, Color.Black, 0f, 0);

// Prepare the alpha test effect object (create it only once on initilization)
AlphaTestEffect alphaTestEffect = new AlphaTestEffect(GraphicsDevice)
{
    DiffuseColor = Color.White.ToVector3(), 
    AlphaFunction = CompareFunction.Greater, 
    ReferenceAlpha = 0, World = Matrix.Identity, 
    View = Matrix.Identity, 
    Projection = Matrix.CreateTranslation(-0.5f, -0.5f, 0) * 
    Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 0, 1)
};

// Prepare the first DepthStencilState (create only once, or put it in a static class)
DepthStencilState beforeDepthStencilState = new DepthStencilState
{
    StencilEnable = true, 
    StencilFunction = CompareFunction.Always,
    StencilPass = StencilOperation.Replace, 
    ReferenceStencil = 1
};

// Draw your sprites using the structures above
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, beforeDepthStencilState, null, alphaTestEffect);
spriteBatch.Draw(sprite, new Vector2(300, 150), Color.White);
spriteBatch.End();

// Prepare the second DepthStencilState (create only once, or put it in a static class)
DepthStencilState afterDepthStencilState = new DepthStencilState
{
    StencilEnable = true, 
    StencilFunction = CompareFunction.Equal, 
    ReferenceStencil = 1
};

// Draw a full screen white quad with the structure above
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, afterDepthStencilState, null);
spriteBatch.Draw(pixel, GraphicsDevice.Viewport.Bounds, Color.White);
spriteBatch.End();

Và kết quả:

nhập mô tả hình ảnh ở đây


Kinh ngạc! Cảm ơn rất nhiều vì đã nỗ lực rất nhiều vào việc này, David. Xấu hổ không phải là một giải pháp đơn giản hơn, nhưng điều này sẽ thực hiện thủ thuật độc đáo.
Ryan McD
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.