preface

A version of this game has been developed using Flare, the game engine inside Flutter, originally at juejin.cn/post/693906… . In the article I said to do it again with widgets. Now make good on my promise and live broadcast the whole development process on Station B last Sunday

📺 Check out the live video

Display Sprite animations in Flutter

Please read the article “Write a Widget that Displays” Sprites in Flutter”

Movement of aircraft

Start by placing the aircraft in the middle of the image. Since the origin of the Widget is the top left corner, subtract half the width and height of the aircraft image.

// Get the width and height of the canvas
Size screenSize = window.physicalSize/window.devicePixelRatio;

// Set the plane's x and y coordinates as the center of the screen
playerLeft = screenSize.width/2- 66./2;
playerTop = screenSize.height/2- 82./2;

Copy the code

Aircraft we need to capture the user’s gesture events and use the GestureDetector Widget to drag the aircraft.

GestureDetector( 
  onPanUpdate: (DragUpdateDetails details) {
    setState(() {
      playerLeft += details.delta.dx;
      playerTop += details.delta.dy;
    });
  },
  child:// Airplane Widget
}
Copy the code

Set the FPS

Since there was no game engine, I had to do it myself through a timer. For example, if we want to achieve a refresh rate of 60FPS, we can set the timer to 17 ms, so that the refresh rate is approximately 59fps. It could be more precise, of course, but it’s not necessary.

Timer.periodic(Duration(milliseconds: 17), (timer) {
  gameloop();
});

gameloop(){
    setState(() {
        // Trigger the build method
    });
}
Copy the code

However, I recommend setting it to refresh every 20 milliseconds, for reasons I’ll discuss later.

Add a bullet

Let’s create a bullet management array and put all the bullet data in the array

List bulletsData = [];

addBullet(){
    double bulletX;
    double bulletY;

    if (Random().nextBool()) {
      bulletX = Random().nextDouble() * (screenSize.width + bulletSize.width) -
          bulletSize.width;
      bulletY = Random().nextBool() ? -bulletSize.height : screenSize.height;
    } else {
      bulletX = Random().nextBool() ? -bulletSize.width : screenSize.width;
      bulletY = Random().nextDouble() * (screenSize.height + bulletSize.height) -
          bulletSize.height;
    }

    bulletsData.add({
      "x":bulletX,
      "y":bulletY,
      "speed": (1+gameTime/10) + Random().nextDouble()*3."angle": atan2(((bulletY + bulletSize.height/2) - (playerTop + playerHeight / 2)),
          ((bulletX + bulletSize.width) - (playerLeft + playerWidth / 2)))}); }Copy the code

The bullet mobile

Move bullets through groups in Gameloop.

for (int i = bulletsData.length - 1; i >= 0; i--) {
      var bulletItem = bulletsData[i];

      double angle = bulletItem["angle"];
      double speed = bulletItem["speed"];

      bulletItem["x"] -= cos(angle) * speed;
      bulletItem["y"] -= sin(angle) * speed;

      if (isHitPlayer(bulletItem["x"], bulletItem["y"]) {print("gameOver");
        gameOver();
      }

      if (isNotInScreen(bulletItem["x"], bulletItem["y"]) {print("bullet removed");
        bulletsData.removeAt(i);
        continue; }}}Copy the code

The bullet show

Once the above code is complete, our bullet exists in the data. But you can’t see them because they’re not drawn into the picture. We need to display them using the Stack and the toy controls.

Stack(
  children: getBulletsWidget(),
)

getBulletsWidget(){
    List<Positioned> bullets = [];

    for(int i = 0; i<bulletsData.length; i++){var bulletItem = bulletsData[i];
      // print(bulletItem);
      var bulletWidget = Positioned(
        left: bulletItem["x"],
        top: bulletItem["y"],
        child: bulletImage
      );

      bullets.add(bulletWidget);
    }

    return bullets;
}
Copy the code

According to the second time

Since the title of the game is “100 seconds if you’re a man”, there must be a second timer in the game. Remember why I suggested setting the timer to refresh at 20 milliseconds? In that case, is every 50 refreshes a second?

Timer.periodic(Duration(milliseconds: 20), (timer) {
  if(timer.tick%50= =0){
    gameSeconds+=1;
    //seconds
  }

  loop();
});
Copy the code

In a Flutter, we can do this. The tick in a timer is the execution count of a timer, and it accumulates, so we only need to mod 50. Every time we divide 50, that’s 1 second

Across the

With the powerful cross-terminal capabilities of Flutter, this game allows us to…

Running on a Mac desktop

flutter run -d macOS
Copy the code

Running in a browser

flutter run -d Chrome
Copy the code

Running on the iOS

Flutter run -d Simulator IDCopy the code

Linux, Windows, Android and I’m not going to give you screenshots

The project is open source, please run it yourself!

Source warehouse

Github.com/ezshine/flu…

Keep an eye on the handsome

How about a wave of likes and attention?