Created
April 24, 2022 15:58
-
-
Save yashlamba/8b5aa009b69df40291ef5df88316c9f2 to your computer and use it in GitHub Desktop.
Snake Game Partial
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'dart:math'; | |
import 'package:flutter/material.dart'; | |
void main() { | |
runApp(const SnakeGame()); | |
} | |
class SnakeGame extends StatelessWidget { | |
const SnakeGame({Key? key}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return const MaterialApp( | |
title: "Snake Game", | |
home: Center( | |
child: Game(), | |
), | |
); | |
} | |
} | |
class Snake { | |
List<Point<int>> snake = [const Point(0, 0)]; | |
Point<int> direction = Constants.right; | |
Point<int> get head { | |
return snake[0]; | |
} | |
bool didBiteItself() { | |
for (int i = 1; i < snake.length; i++) { | |
if (snake[i] == head) { | |
return true; | |
} | |
} | |
return false; | |
} | |
bool pointOnSnake(Point<int> point) { | |
for (Point body in snake) { | |
if (body == point) { | |
return true; | |
} | |
} | |
return false; | |
} | |
void update() { | |
// For moving in a direction, move all body parts to the location of the | |
// part before them | |
for (int i = snake.length - 1; i > 0; --i) { | |
snake[i] = snake[i - 1]; | |
} | |
// Then update in the direction snake is moving | |
snake[0] = Point((head.x + direction.x) % 50, (head.y + direction.y) % 50); | |
} | |
void eatFood() { | |
// Since food is added to the end and snake would ultimately | |
// Update one position, save the last location and append it again. | |
var foodLoc = snake.last; | |
update(); | |
snake.add(foodLoc); | |
} | |
} | |
class Constants { | |
// Canvas | |
static const double canvasSize = 500; | |
static const double blockSize = 10; | |
// Directions | |
static const up = Point(0, -1); | |
static const down = Point(0, 1); | |
static const right = Point(1, 0); | |
static const left = Point(-1, 0); | |
} | |
class Game extends StatefulWidget { | |
const Game({Key? key}) : super(key: key); | |
@override | |
State<Game> createState() => _GameState(); | |
} | |
class _GameState extends State<Game> { | |
late Snake snake; | |
late Point<int> food; | |
Random random = Random(); | |
@override | |
void initState() { | |
initGame(); | |
Timer.periodic(const Duration(milliseconds: 50), (t) { | |
gameUpdate(); | |
}); | |
super.initState(); | |
} | |
initGame() { | |
snake = Snake(); | |
foodUpdate(); | |
} | |
void gameUpdate() { | |
// update this | |
if (food == snake.head) { | |
snake.eatFood(); | |
foodUpdate(); | |
} else { | |
snake.update(); | |
} | |
if (snake.didBiteItself()) { | |
initGame(); | |
} | |
setState(() {}); | |
} | |
void foodUpdate() { | |
do { | |
food = Point(random.nextInt(Constants.canvasSize ~/ Constants.blockSize), | |
random.nextInt(Constants.canvasSize ~/ Constants.blockSize)); | |
} while (snake.pointOnSnake(food)); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Container( | |
width: Constants.canvasSize, | |
height: Constants.canvasSize, | |
color: Colors.black, | |
child: Stack( | |
children: snake.snake | |
.map((e) => Positioned( | |
top: Constants.blockSize * e.y, | |
left: Constants.blockSize * e.x, | |
child: Container( | |
height: Constants.blockSize, | |
width: Constants.blockSize, | |
color: Colors.green, | |
), | |
)) | |
.toList() + | |
[ | |
Positioned( | |
top: Constants.blockSize * food.y, | |
left: Constants.blockSize * food.x, | |
child: Container( | |
height: Constants.blockSize, | |
width: Constants.blockSize, | |
color: Colors.red, | |
), | |
) | |
], | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment