rajath_pai

Flutter Snake Game

Aug 2nd, 2021
836
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // https://github.com/rajathpi/Snake
  2. // Star the project if you like it :)
  3.  
  4. import 'dart:async';
  5. import 'dart:math';
  6.  
  7. import 'package:flutter/material.dart';
  8.  
  9. void main() {
  10.   runApp(SnakeGame());
  11. }
  12.  
  13. class SnakeGame extends StatelessWidget {
  14.   const SnakeGame({Key? key}) : super(key: key);
  15.  
  16.   @override
  17.   Widget build(BuildContext context) {
  18.     return MaterialApp(
  19.       debugShowCheckedModeBanner: false,
  20.       home: GameField(),
  21.     );
  22.   }
  23. }
  24.  
  25. class GameField extends StatefulWidget {
  26.   const GameField({Key? key}) : super(key: key);
  27.  
  28.   @override
  29.   _GameFieldState createState() => _GameFieldState();
  30. }
  31.  
  32. enum Direction { up, down, left, right }
  33.  
  34. class _GameFieldState extends State<GameField> {
  35. //TODO 3: initialization of variable
  36.   bool _isAlive = true;
  37.   int length = 1;
  38.   Direction _direction = Direction.up;
  39.   List<Offset> _positions = [];
  40.   double? height;
  41.   double? width;
  42.   Timer? timer;
  43.   double speed = 4;
  44.   int _score = 0;
  45.   Offset? foodPosition;
  46.   Widget food = Container();
  47. //TODO: 1 build method
  48.   @override
  49.   Widget build(BuildContext context) {
  50.     changeSpeed();
  51.  
  52.     height = MediaQuery.of(context).size.height;
  53.     width = MediaQuery.of(context).size.width;
  54.     return Scaffold(
  55.         backgroundColor: Colors.black,
  56.         body: _isAlive
  57.             ? Stack(
  58.           children: [
  59.             Stack(
  60.               children: snakePieces(),
  61.             ),
  62.             score(),
  63.             food,
  64.             gamePad(),
  65.           ],
  66.         )
  67.             : onEnd());
  68.   }
  69.  
  70. //TODO on End
  71.   Widget onEnd() {
  72.     return SizedBox(
  73.       width: width,
  74.       child: Column(
  75.         mainAxisSize: MainAxisSize.max,
  76.         children: [
  77.           Spacer(
  78.             flex: 4,
  79.           ),
  80.           Text(
  81.             "Game Over",
  82.             style: TextStyle(
  83.                 color: Colors.red,
  84.                 fontSize: 30,
  85.                 fontWeight: FontWeight.bold),
  86.           ),
  87.           Spacer(
  88.             flex: 1,
  89.           ),
  90.           Text("Your Score is $_score",
  91.               style: TextStyle(
  92.                   color: Colors.white,
  93.                   fontSize: 20,
  94.                   fontWeight: FontWeight.bold)),
  95.           Spacer(
  96.             flex: 2,
  97.           ),
  98.           TextButton(
  99.             child: Text("Restart Game",
  100.                 style: TextStyle(
  101.                     color: Colors.white,
  102.                     fontSize: 22,
  103.                     fontWeight: FontWeight.bold)),
  104.             onPressed: () {
  105.               setState(() {
  106.                 _score = 0;
  107.                 speed = 4;
  108.                 length = 1;
  109.                 _positions = [];
  110.                 _isAlive = true;
  111.               });
  112.             },
  113.           ),
  114.           Spacer(
  115.             flex: 4,
  116.           ),
  117.         ],
  118.       ),
  119.     );
  120.   }
  121.  
  122. //check Alive
  123.   checkAlive() {
  124.     for (int i = 1; i < _positions.length; i++) {
  125.       if (_positions[i] == _positions[0]) {
  126.         _isAlive = false;
  127.       }
  128.     }
  129.   }
  130.  
  131. //TODO gamePAd
  132.   Widget gamePad() {
  133.     return Align(
  134.       alignment: Alignment.bottomCenter,
  135.       child: SizedBox(
  136.         height: width! / 2,
  137.         width: width! / 2,
  138.         child: Stack(
  139.           children: [
  140.             Align(
  141.               alignment: Alignment.bottomCenter,
  142.               child: IconButton(
  143.                   padding: EdgeInsets.zero,
  144.                   onPressed: () {
  145.                     if (_direction != Direction.up) _direction = Direction.down;
  146.                   },
  147.                   icon: Icon(
  148.                     Icons.keyboard_arrow_down,
  149.                     color : Colors.grey[800],
  150.                     size: 50,
  151.                   )),
  152.             ),
  153.             Align(
  154.               alignment: Alignment.topCenter,
  155.               child: IconButton(
  156.                   padding: EdgeInsets.zero,
  157.                   onPressed: () {
  158.                     if (_direction != Direction.down) _direction = Direction.up;
  159.                   },
  160.                   icon: Icon(
  161.                     Icons.keyboard_arrow_up,
  162.                     color : Colors.grey[800],
  163.                     size: 50,
  164.                   )),
  165.             ),
  166.             Align(
  167.               alignment: Alignment.centerRight,
  168.               child: IconButton(
  169.                   padding: EdgeInsets.zero,
  170.                   onPressed: () {
  171.                     if (_direction != Direction.left)
  172.                       _direction = Direction.right;
  173.                   },
  174.                   icon: Icon(
  175.                     Icons.keyboard_arrow_right,
  176.                     color : Colors.grey[800],
  177.                     size: 50,
  178.                   )),
  179.             ),
  180.             Align(
  181.               alignment: Alignment.centerLeft,
  182.               child: IconButton(
  183.                   padding: EdgeInsets.zero,
  184.                   onPressed: () {
  185.                     if (_direction != Direction.right)
  186.                       _direction = Direction.left;
  187.                   },
  188.                   icon: Icon(
  189.                     Icons.keyboard_arrow_left,
  190.                     color : Colors.grey[800],
  191.                     size: 50,
  192.                   )),
  193.             ),
  194.           ],
  195.         ),
  196.       ),
  197.     );
  198.   }
  199.  
  200. //TODO score
  201.   Positioned score() => Positioned(
  202.       top: 50,
  203.       right: 50,
  204.       child:
  205.       Text("$_score", style: TextStyle(color: Colors.white, fontSize: 22)));
  206.  
  207. //TODO speed
  208.   changeSpeed() {
  209.     if (timer != null) if (timer!.isActive) timer!.cancel();
  210.     timer = Timer.periodic(Duration(milliseconds: 500 ~/ speed), (timer) {
  211.       setState(() {});
  212.     });
  213.   }
  214.  
  215. //TODO snakePieces
  216.   List<Piece> snakePieces() {
  217.     List<Piece> pieces = [];
  218.     if (_isAlive) {
  219.       setState(() {
  220.         draw();
  221.         foodDraw();
  222.       });
  223.     }
  224.     for (int i = 0; i < _positions.length; i++) {
  225.       pieces.add(Piece(
  226.           size: 15,
  227.           posX: _positions[i].dx,
  228.           posY: _positions[i].dy,
  229.           color: Colors.white));
  230.     }
  231.     checkAlive();
  232.     return pieces;
  233.   }
  234.  
  235. // TODO foodDraw
  236.   foodDraw() {
  237.     if (foodPosition == null) foodPosition = getRandomPositionWithinScreen();
  238.     food = Piece(
  239.         color: Colors.green,
  240.         posX: foodPosition!.dx,
  241.         posY: foodPosition!.dy,
  242.         size: 18);
  243.     if (foodPosition! <= (_positions[0] + Offset(15, 15)) &&
  244.         foodPosition! >= (_positions[0] - Offset(15, 15))) {
  245.       _score += 5;
  246.       length += 1;
  247.       foodPosition = getRandomPositionWithinScreen();
  248.       speed += 0.15;
  249.     }
  250.   }
  251.  
  252. // TODO draw()
  253.   draw() {
  254.     if (_positions.length == 0) {
  255.       _positions.add(getRandomPositionWithinScreen());
  256.     }
  257.     while (length > _positions.length) {
  258.       _positions.add(_positions[_positions.length - 1]);
  259.     }
  260.     for (int i = _positions.length - 1; i > 0; i--) {
  261.       _positions[i] = _positions[i - 1];
  262.     }
  263.     _positions[0] = checkBorder(_positions[0]);
  264.     _positions[0] = getNextPosition(_positions[0]);
  265.   }
  266.  
  267. //TODO getNextPosition
  268.   Offset getNextPosition(Offset position) {
  269.     Offset nextPosition = Offset(5, 6);
  270.     if (_direction == Direction.up) nextPosition = position - Offset(0, 15);
  271.     if (_direction == Direction.down) nextPosition = position + Offset(0, 15);
  272.     if (_direction == Direction.right) nextPosition = position + Offset(15, 0);
  273.     if (_direction == Direction.left) nextPosition = position - Offset(15, 0);
  274.  
  275.     return nextPosition;
  276.   }
  277.  
  278. //TODO chck border
  279.   checkBorder(Offset position) {
  280.     if (position.dy > height!) position = Offset(position.dx, 0);
  281.     if (position.dy < 0) position = Offset(position.dx, height!);
  282.     if (position.dx > width!) position = Offset(0, position.dy);
  283.     if (position.dx < 0) position = Offset(width!, position.dy);
  284.     return position;
  285.   }
  286.  
  287. //TODO getRandomPosition
  288.   Offset getRandomPositionWithinScreen() {
  289.     Random rand = Random();
  290.     double x = rand.nextInt(width!.toInt()).toDouble();
  291.     double y = rand.nextInt(height!.toInt()).toDouble();
  292.     return Offset(x, y) - Offset(10, 10);
  293.   }
  294. }
  295.  
  296. // TODO 2 Piece
  297. class Piece extends StatelessWidget {
  298.   double size;
  299.   double posX;
  300.   double posY;
  301.   Color color;
  302.   Piece(
  303.       {Key? key,
  304.         required this.size,
  305.         required this.posX,
  306.         required this.posY,
  307.         required this.color})
  308.       : super(key: key);
  309.  
  310.   @override
  311.   Widget build(BuildContext context) {
  312.     return Positioned(
  313.       top: posY,
  314.       left: posX,
  315.       child: Container(
  316.         height: size,
  317.         width: size,
  318.         decoration: BoxDecoration(color: color, shape: BoxShape.circle),
  319.       ),
  320.     );
  321.   }
  322. }
  323.  
RAW Paste Data