Skip to content

h65wang/slide-puzzle-challenge

Repository files navigation

Slide Puzzle: Escape of Cao Cao

This is a puzzle game made on live-stream, demonstrating various animation techniques in Flutter with just Dart code - no dependencies or asset files. It can target mobile, desktop, and the web from a single code base.

The goal of the game is to move "the biggest puzzle piece (Cao Cao)" to "the exit" at the bottom, in as few steps as possible.

A playable web version is available. For the best experience, you can also try out native desktop or mobile apps.

Releases

v1.2.1 (2022-03-14)

  • Added an animation when the game launches.

an intro animation when the game starts

v1.2.0 (2022-03-12)

  • Added a hint button.
  • Minor changes to the reset button.

The new hint feature spawns an isolate to find an optimal solution for the current state using Breadth-First Search. Once the result comes back, an OverlayEntry is created precisely on top of the hinted piece, with the help of a CompositedTransformFollower widget and LayerLinks embedded in the pieces.

the new hint button in action

v1.1.0 (2022-03-06)

  • Added more levels.
  • Added a new 3D animation during level transitions.
  • Added an option to hide decorative texts on puzzle pieces.
  • Various minor UI enhancements and performance improvements.

This is my first time trying to simulate 3D objects without 3rd party tools or plugins in Flutter. It's made using Transform widgets to translate and rotate 6 rectangles to correct places to form a cuboid.

a 3d cube made with transform widget

Further optimizations were made so only up to 3 faces (visible to the viewers) are rendered at a time, and a glare effect was added by changing stops on a LinearGradient. This formed the basis for a new transition animation when a level is completed.

a 3d puzzle piece with glare effect

I've published a video tutorial on this topic, watch it in English | Chinese.

v1.0.1 (2022-02-26)

  • Added a simple tutorial screen.
  • Fixed a bug where the web version was not rendering correctly on mobile browsers.

The tutorial screen is a responsive dialog made with LayoutBuilder and ConstrainedBox, and decorated by CupertinoPopupSurface. It also includes a WillPopScope to allow Android users to dismiss it with the back button.

new tutorial dialog with an option to hide decorative texts

It provides an option to hide decorative texts (v1.1.0) in case they don't render properly, e.g. when there are no international fonts installed.

When building for web, make sure to use canvaskit renderer for better experience across devices. You can do so with flutter build web --web-renderer canvaskit command. Otherwise, the puzzle might not render correctly on mobile browsers. I've created an issue for this and looks like the Flutter team is already on it.

v1.0.0 (2022-02-22)

  • Initial release for all platforms.

The initial version of the app was created as "live coding" stream sessions. With discussions and voting polls on design choices such as the color palette, together we built the game in 12 live-stream sessions.

the project was created on live stream

The support for more platforms were added after the live stream ended.

multi-platform: a photo of the app running on multiple devices

The video overview (see below) was released at the same time as the initial version, so new features mentioned above are not included in the video.

Video Overview

A short video (less than 3 min) is available, providing a brief overview of version 1.0.0.

video

You can choose to watch the video in English | Chinese.

At a high level, the app can be divided into 3 parts: the background layer, the game board, and the puzzle pieces. Each puzzle piece also comes with a pair of interlocking attachments and a shadow for some added depth. These components are stacked as 3 different layers, to make sure they always appear in the correct order when being moved.

each puzzle piece is layered 3 times

The color palette is configured as an InheritedWidget so its values can be modified in one place, and easily accessed elsewhere in the widget tree.

The puzzle pieces are made from AnimatedPositioned. For the duration, I pass in zero if the window size is different from before. This is to skip the unwanted animation when the app is being resized. And for the curve, I use EaseOut to slow them down naturally.

To handle user input, I added GestureDetector. I used the onPanUpdate event instead of the onPanEnd event, to reduce input lag.

use onPanUpdate for a faster response

From the picture above you can see that the user has not finished the action (finger is still touching the screen), but with onPanUpdate event, the game has already responded.

For the reset button, I added a MouseRegion widget to make it glow when being hovered.

use MouseRegion to make the reset button glow

The step counter on the side is another example of utilizing implicit animations in Flutter. It’s also wrapped in a ValueListenableBuilder, so it can always keep up with the steps.

an animated flip counter used to track steps

I’ve published the counter as a package on pub and made a video explaining how it was made. If you like this animation, you can import it to your own project.

The game board is mostly a Container with some decorations and clipping. I also used a BackdropFilter here to blur everything behind it, and a ShaderMask to create a beam effect.

BackdropFilter and ShaderMask

The beam created by ShaderMask is an explicit animation with its controller set to repeat, so it can keep dancing around in the game.

glare effect on texts

Similarly, the decorative texts puzzle pieces are also animated to have a subtle glare effect.

Lastly, I used a CustomPaint for the app background. It efficiently draws colorful rectangles every frame and runs well even on low-end devices.

What's Next

  • Resolve web rendering issue for mobile browsers
  • Add a tutorial screen to explain the game
  • Add more levels to the game
  • Add an automatic solver or a hint system
  • Allow users to select levels
  • Add keyboard support
  • Further improve swiping gestures

Extra Resources

I've been making lots of video tutorials (mostly in Chinese) on Flutter, covering a wide range of topics and popular questions from viewers. If you are interested, please follow me on "bilibili" so you won't miss the next live stream or video from me.

Animations

I've made a total of 19 video tutorials on Flutter Animations, divided into 3 sections: implicit, explicit and others.

Implicit Animations

Explicit Animations

Other types of Animations

Keys

I've made 7 video tutorials on keys, covering basic concepts such as widgets and elements, 3 types of local keys, 2 different uses of global keys, and more.

Scrollable

Asynchronous

Layout

Slivers

Coding challenge and follow-ups

(Sometimes I post questions for my viewers and then do follow-up videos to discuss all the creative solutions I receive, so we can learn from each other.)

Other popular topics