Happy Mid-Autumn Festival!!

Foreword: during the holidays, small T plan to review the classic, want to do with Flutter the small game, what can do, from the plane and the tanks war finally do you want to be a snake, vaguely remember, when I was a child, for the first time playing a game is to play on the parents of the PHS snake ha ha, but rather a snake too drab, let’s add a gyroscope ~

Words do not say, first on the effect map, there is a map there is the truth!! Gyroscopes are hard to control!

Development steps:

It’s very simple, but it takes a little effort to play

Source code in the last oh, directly run

1. Define snakes and beans

2. Let the snake move

3. Use a gyroscope to control the snake

Let the snake eat the beans

5. Eat beans to generate a random bean

1. Define snakes and beans

/// const double size = 10; Offset ball = Offset.zero; // List<Offset> snakeList = [Offset(50, 0), Offset(60, 0)]; The length of the snakeCopy the code

Show beans and snakes:

Stack is used because beans overlap when eaten by snakes

Positioned

body: Stack( children: snakeList .map((snake) => Positioned.fromRect( rect: Rect.fromCenter( center: adjust(snake), width: size, height: size), child: Container(margin:const EdgeInsets.all(1),color: Color.black))// Add a margin to make each piece clearer. ToList ().. add(Positioned.fromRect( rect: Rect.fromCenter( center: adjust(ball), width: size, height: size), child: Container(color: Colors.orange))), )Copy the code
Offset adjust(Offset offset) { return Offset(offset.dx + size / 2, offset.dy + size / 2); // Make each piece better displayed}Copy the code

2. Let the snake move

Here we will first give the snake a state definition:

Enum Direction {Up, Down, Left, Right}Copy the code

Since the snake is always moving, a periodic function is given:

1. Define a movement for 200 milliseconds

2. Deal with updating the length of the snake

3. The advantage of remainder is to optimize the eating of beans, because when randomly generating beans, it may not be divisible.

Direction direction = Direction.Left; Localhost = localhost; localhost = localhost; localhost = localhost; localhost = localhost; localhost = localhost; localhost = localhost; localhost = localhost; localhost = localhost; Double maxWidth = mediaQuery.of (context).size. Width; double widthPad = maxWidth % size; maxWidth -= widthPad; double maxHeight = MediaQuery.of(context).size.height; double heigthPad = maxHeight % size; // maxHeight -= heigthPad; Periodic (period, (Timer) {final snakeHead = snakeList[0]; final snakeHead = snakeList[0]; List<Offset> newSnakeList = List.generate(snakeList.length, (index) { if (index > 0) { return snakeList[index - 1]; } else {switch (direction) {case direction.up: return Offset(snakeHead.dx, (snakeHead.dy - size + maxHeight) % maxHeight); Down: return Offset(snakehead. dx, (snakehead. dy + size + maxHeight) % maxHeight); case Direction.Left: return Offset( (snakeHead.dx - size + maxWidth) % maxWidth, snakeHead.dy); case Direction.Right: return Offset( (snakeHead.dx + size + maxWidth) % maxWidth, snakeHead.dy); }}}); setState(() { snakeList = newSnakeList; // Update the snake status}); }); super.didChangeDependencies(); }Copy the code

3. Use a gyroscope to control the snake

The Flutter uses a gyroscope that relies on a library: sensors or Sensors_Plus, which are not much different

This demo uses:

sensors: any
Copy the code

Official examples:

import 'package:sensors/sensors.dart'; accelerometerEvents.listen((AccelerometerEvent event) { print(event); }); // [AccelerometerEvent (x: 0.0, y: 9.8, z: 0.0)] acceleration userAccelerometerEvents. Listen ((UserAccelerometerEvent event) {print (event); }); // [UserAccelerometerEvent (x: 0.0, y: 0.0, z: 0.0)] gyroscopeEvents. Listen (GyroscopeEvent) {print(event); }); // [GyroscopeEvent (x: 0.0, y: 0.0, z: 0.0)Copy the code

We listen on the gyroscope in initState:

There are three parameters x,y,z, also can be optimized debugging, 5.0 is when the phone tilt >=45°

@override void initState() { super.initState(); accelerometerEvents.listen((AccelerometerEvent event) { setState(() { _accelerometerValues = <double>[event.x, event.y, event.z]; If (_accelerometerValues[0] >= 5.0){direction = direction. Left; }else if(_accelerometerValues[1] >= 5.0){direction = direction.down; }else if(_accelerometerValues[0] <= -5.0){direction = direction.right; }else if(_accelerometerValues[1] <= -5.0){direction = direction.up; }}); }); }Copy the code

Let the snake eat the beans

Again, add to the periodic function:

When the snake head touches the bean, add a space to the snake

if(newSnakeList[0] == ball){ newSnakeList.. add(snakeList[snakeList.length - 1]); setState(() { ball = randoowPositon(maxWidth, maxHeight); // Generate a random bean, randoowPositon method behind}); }Copy the code

5. Eat beans to generate a random bean

The generation of beans also needs to be optimized

Offset randoowPositon (double widthRange,double heigthRange){var RNG = Random(); double widthPad = widthRange % size; widthRange -= widthPad; double heigthPad = heigthRange % size; HeigthRange -= heigthPad; return Offset(rng.nextInt(widthRange.toInt()).toDouble(),rng.nextInt(heigthRange.toInt()).toDouble()); }Copy the code

Ok to finish here, need source code, give the article a thumbs up, in my home page exchange group, source code has been uploaded ~

This game is fun is fun, is a waste of hands, ha ha, to a god optimization bar