0
\$\begingroup\$

I'm working on a 2D game for WPF8 using XNA 4.0.

Everything goes great, but it's too fast. I was just wondering, what could I do between the end of the game and the score screen, and before the game starts? I'm looking for a sample of how to do that (black screen with "loading" write in windows phone style) or a way to implement it.

\$\endgroup\$
  • 5
    \$\begingroup\$ Why show a loading screen when it is completly unnecessary? Why don't you just make some smooth transition? \$\endgroup\$ – Lasse Dec 5 '13 at 10:16
  • \$\begingroup\$ Yeah, that also a solution, but i didn't find any way to do that. Like a library with transition animation. \$\endgroup\$ – Gabson Dec 5 '13 at 10:17
3
\$\begingroup\$

No code from me, since I'm not that experienced with XNA, but this is more a general "issue":

  • First of all - as mentioned in the comments - do not (never ever!) add fake loading screens! People will think it's really that ressource heavy which can show your app in a worse light than it actually should be. Especially on mobile you don't usually trust an app showing constant loading screens to safe battery for example.

  • Instead, add a transition. A very easy to do transition would be blending to/from black. You can do more interesting stuff when using shaders and render to texture, but this one should be more than sufficient to slow down pace a bit.

The basic steps are pretty much self-explanatory and there are multiple ways to approach this, also depending a bit on how you handle your game state, progress, etc.

  • Rather than switching game state immediately, e.g. from GAME_PLAYING to GAME_HIGHSCORE, you'd set some counter. Let's call it blending_time.
  • From there on, as long as blending_time isn't equal to zero, you'll just draw a black quad over the whole screen, using an alpha value based on the time left.
  • Once your counter reaches zero, you do'd the state switch.
  • To get a soft blending in, you could then reverse the whole thing.
  • Again set blending_time to the time you'd like to blend (you might want to use a different value or some toggle to identify whether blending to or from black).
  • As long as blending_time isn't 0, you'd draw once again a black quad over the whole scene with its alpha depending on the time left (this time starting with 100% opaque).
\$\endgroup\$
  • \$\begingroup\$ Agreed, but also think about whether you really have nothing to do in this time. Some games post high scores to a server, some show advertising, some show fancy animations. If it's the sort of game where you die and get catapulted back to the last checkpoint, time is merely needed for the player to mentally reset and get ready, so a simple countdown and some appropriate music/SFX to hype them up is enough. \$\endgroup\$ – David Cummins Dec 5 '13 at 10:51
1
\$\begingroup\$

If you are looking for a smooth image transition, there is a cool and extremely-easy-to-implement shader that was used in Incredipede. In this GDC 2013 talk the art team explain it in detail. I have also implemented it in Unity. If you want to see the code to get the idea and translate it to XNA, there it is:

Shader "Custom/InkPress"
{
    Properties
    {
            _MainTex ("Base (RGB)", 2D) = "white" {}
            _BlurTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader
    {
            Pass
            {
                    //Usual post processing setup
                    ZTest Always Cull Off ZWrite Off
                      Fog { Mode off }

                    CGPROGRAM
                    #pragma vertex vert
                    #pragma fragment frag
                    #pragma target 2.0

                    #include "UnityCG.cginc"

                    struct v2f {
                            float4 pos : POSITION;
                            float2 uv : TEXCOORD0;
                    };

                    v2f vert (appdata_img v)
                    {
                        v2f o;
                            o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                            o.uv = v.texcoord.xy;
                            return o;
                    }

                    sampler2D _MainTex;
                    sampler2D _BlurTex;
                    float _threshold;

                    float4 frag( v2f v ) : COLOR
                    {
                        // Step 1: Get the brightness of the blur texture
                        float2 vUv = v.uv;
                        float4 returnColour = float4(1.0 , 1.0 , 1.0 , 1.0);
                        float3 texColour = tex2D(_BlurTex , v.uv).xyz;
                        float bright = (texColour.r + texColour.g + texColour.b) / 3.0;

                        //Step 2: Return the main texture pixel colour if its brightness is bellow
                        //the threshold. Clear the pixel otherwise.
                        if(bright < _threshold)
                        {
                                returnColour = tex2D(_MainTex , v.uv);
                        }

                        return returnColour;
                    }
                    ENDCG
            }
    } 
    FallBack "Diffuse"
}

The shader above is just the transition. To achieve a better effect you should blur the image before as stated in the talk. I have omitted the blur part for the sake of simplicity.

If you want more detail and the full source, you can check my page.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.