Escape from blog park, carrying an old article from the period of mobile games in 2015.

Write less code

Why do you need a flash screen

  1. Mobile apps should not have flash screens, and Google’s Own Android apps are said to have completely disabled them.

Splash Screens Are Evil, Don’t Use Them!

  1. A large number of Mobile apps in China, or those who work in them, still insist on a flash-screen aesthetic.

Why a native implementation

  1. When UnrealEngine3 needs UE3 initialization and scene switching, the rendering thread pauses, so it needs to use the native solution to display images or videos to transition the wait.
  2. Cocos2d-x requires cocos2D-x forum discussion posts
  3. Unity3D is similar to Unity3D.

Why shouldn’t Splash Activity be used

“What you’re getting is wrong.” A web search for Android splash screen implementations shows 99% of the results showing how to use a simple Activity implementation and then switch to the actual GameActivity. This scheme is only for teaching and has many disadvantages in practical application.

  1. This scheme requires thatAndroidManifest.xmlConfigured inLaunchActivityIt must beSplashActivity.

    When required to implement with parametersIntentAt the start,SplashActivityParameters need to be passed correctly (Intent) toGameActivity. Cumbersome.
  2. Games that useNDKThe development,OpenGL.UI View.threadNeed to talk toGameActivity's SurfaceViewBinding.

    SplashActivityDuring display,GameActivityCannot be loaded, and therefore cannot load the game engine related instances in parallel. After causing the flash screen,GameActivityA load screen is still required for transition waitingGameEngineIs the startup time.
  3. Games need access to various SDKS. A lot of SDKS require inGameActivityThe life cycle inserts a lot of hook event code.

    For example,onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy()Wait, these are commonhookPosition.

    SplashActivityScenarios complicate the implementation of related logic.

A simple flash screen for the game implementation scheme

  1. Use a full screenDialog

    Android DialogBe independent ofWindow, andGameViewThere is no coupling.
  2. shieldingUser Input Event

    DialogAccept all by defaultUser Input Event, you don’t need to pass toGameView, thus decoupled from the game logic.
  3. Realization of animation

    You can easily use a variety of nativeAndroid AnimationTo achieve the transition animation rendering available.
  4. The animation disappears automatically

    DialogCan self-manage the life cycle, again decoupled from the game.
  5. Load the game instance in parallel

    GameSurfaceView and GameEngineCan be found inDialogDuring the display, the background is loaded in parallel, without coupling, and truly achieves asynchronous and time-saving goals.

Code sample

  1. Create a full-screen Dialog
public class NSSplashDialog extends Dialog {
    private PercentFrameLayout mLayout = null;
    private ImageView mImageView = null;
    public NSSplashDialog(Context context) {
        super(context, android.R.style.Theme_NoTitleBar_Fullscreen);
        setContentView(R.layout.splash);
        mLayout = (PercentFrameLayout)findViewById(R.id.layout_splash);
        mImageView = (ImageView)this.findViewById(R.id.iv_splash); }}Copy the code

2. Mask the User Input Event

setCanceledOnTouchOutside(false);
setCancelable(false);
Copy the code

3. Animate

private AlphaAnimation mAnimation = null;
private int mBitmapIndex = 0;

mAnimation = new AlphaAnimation(0.0 f.1.0 f); //fade in, fade out
mAnimation.setDuration(2000);//2 seconds
mAnimation.setRepeatCount(3); //show 4 images
mAnimation.setAnimationListener(new Animation.AnimationListener(){

    @Override
    public void onAnimationStart(Animation animation) {
        mBitmapIndex = 0;
        mLayout.setBackgroundColor(Color.WHITE);
        mImageView.setImageDrawable(BitmapUtil.loadDrawable(getContext(), R.drawable.splash0));
    }

    @Override
    public void onAnimationEnd(Animation animation) {
        mBitmapIndex = 0;
        kick(false);
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
        mBitmapIndex++;
        switch(mBitmapIndex) {
        case 1:
            mLayout.setBackgroundColor(Color.WHITE);
            mImageView.setImageDrawable(BitmapUtil.loadDrawable(getContext(), R.drawable.splash1));
            break;
        case 2:
            mLayout.setBackgroundColor(Color.BLACK);
            mImageView.setImageDrawable(BitmapUtil.loadDrawable(getContext(), R.drawable.splash2));
            break;
        case 3:
            mLayout.setBackgroundColor(Color.BLACK);
            mImageView.setImageDrawable(BitmapUtil.loadDrawable(getContext(), R.drawable.splash3));
            break;
        default:
            break; }}}); mImageView.setAnimation(mAnimation);Copy the code

4. Automatically disappears after the animation ends

Call kick(false) in onAnimationEnd() to close itself.

Some systems have a bug: onAnimationEnd() and cancel() may loop indefinitely, so add protection logic to judge hasEnded().

public void kick(boolean show) {
    if(show) {
        show();
        mAnimation.start();
    } else {
        if(!mAnimation.hasEnded()) {
            mAnimation.cancel();
        }
        dismiss();
    }
}
Copy the code

5. Flash screen loads in parallel with the game

During the GameActivity life cycle, create the SplashDialog instance on onCreate() and destroy it on onDestroy().

    //Create
    mSplashDialog = new NSSplashDialog(this);
	mSplashDialog.kick(true);

    //Destroy
    if(mSplashDialog ! =null && mSplashDialog.isShowing()) {
        mSplashDialog.kick(false);
    }
Copy the code

Loading View

Finally, Loading View.

As mentioned above, UE3 needs to use the platform’s native interface for transition display when switching scenes. Depending on your business needs, it may be difficult to reuse splashDialogs. Instead, use a separate Layout View.