Skip to content

Instantly share code, notes, and snippets.

@subramanian42
Created September 20, 2023 06:10
Show Gist options
  • Save subramanian42/8cb0782f2512471e30279cd892e6afc7 to your computer and use it in GitHub Desktop.
Save subramanian42/8cb0782f2512471e30279cd892e6afc7 to your computer and use it in GitHub Desktop.
asteroid game
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(AsteroidGame());
}
class AsteroidGame extends StatefulWidget {
@override
_AsteroidGameState createState() => _AsteroidGameState();
}
class _AsteroidGameState extends State<AsteroidGame> {
final List<Asteroid> asteroids = [];
final List<Bullet> bullets = [];
late Spaceship spaceship;
late Timer timer;
int score = 0;
bool gameOver = false;
@override
void initState() {
super.initState();
spaceship = Spaceship();
timer = Timer.periodic(Duration(milliseconds: 16), (timer) {
setState(() {
updateGame();
});
});
}
@override
void dispose() {
timer.cancel();
super.dispose();
}
void updateGame() {
if (gameOver) {
return;
}
// Update spaceship position
spaceship.updatePosition();
// Update asteroid positions
for (var asteroid in asteroids) {
asteroid.updatePosition();
}
// Update bullet positions and check for collisions
for (var bullet in bullets) {
bullet.updatePosition();
for (var asteroid in asteroids) {
if (bullet.collidesWith(asteroid)) {
setState(() {
score += 10;
asteroids.remove(asteroid);
bullets.remove(bullet);
});
break;
}
}
}
// Check for spaceship collisions
for (var asteroid in asteroids) {
if (spaceship.collidesWith(asteroid)) {
setState(() {
gameOver = true;
});
break;
}
}
// Add new asteroids
if (asteroids.length < 5) {
asteroids.add(Asteroid());
}
}
void startNewGame() {
setState(() {
asteroids.clear();
bullets.clear();
spaceship = Spaceship();
score = 0;
gameOver = false;
});
}
void shootBullet() {
setState(() {
bullets.add(Bullet(spaceship.x, spaceship.y, spaceship.angle));
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: GestureDetector(
onTap: shootBullet,
child: Stack(
children: [
CustomPaint(
painter: GameBoardPainter(),
size: Size.infinite,
),
CustomPaint(
painter: SpaceshipPainter(spaceship),
size: Size.infinite,
),
for (var asteroid in asteroids)
CustomPaint(
painter: AsteroidPainter(asteroid),
size: Size.infinite,
),
for (var bullet in bullets)
CustomPaint(
painter: BulletPainter(bullet),
size: Size.infinite,
),
if (gameOver)
Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Game Over',
style: TextStyle(fontSize: 32),
),
Text(
'Score: $score',
style: TextStyle(fontSize: 24),
),
ElevatedButton(
onPressed: startNewGame,
child: Text('New Game'),
),
],
),
),
],
),
),
),
);
}
}
class GameBoardPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// Draw the game board on the canvas
canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height),
Paint()..color = Colors.black);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
class Asteroid {
double x;
double y;
double angle;
double speed;
Asteroid()
: x = Random().nextDouble() * 400 + 100,
y = Random().nextDouble() * 400 + 100,
angle = Random().nextDouble() * pi * 2,
speed = Random().nextDouble() * 2 + 1;
void updatePosition() {
x += cos(angle) * speed;
y += sin(angle) * speed;
if (x < -50) {
x = 550;
} else if (x > 550) {
x = -50;
}
if (y < -50) {
y = 550;
} else if (y > 550) {
y = -50;
}
}
}
class AsteroidPainter extends CustomPainter {
final Asteroid asteroid;
AsteroidPainter(this.asteroid);
@override
void paint(Canvas canvas, Size size) {
// Draw asteroid on the canvas
canvas.drawCircle(
Offset(asteroid.x, asteroid.y), 25, Paint()..color = Colors.white);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
class Spaceship {
double x;
double y;
double angle;
double speed;
bool turningLeft = false;
bool turningRight = false;
Spaceship()
: x = 300,
y = 300,
angle = -pi / 2,
speed = 0;
void updatePosition() {
if (turningLeft) {
angle -= 0.1;
}
if (turningRight) {
angle += 0.1;
}
x += cos(angle) * speed;
y += sin(angle) * speed;
if (x < -50) {
x = 550;
} else if (x > 550) {
x = -50;
}
if (y < -50) {
y = 550;
} else if (y > 550) {
y = -50;
}
speed *= 0.99;
}
bool collidesWith(Asteroid asteroid) {
return sqrt(pow(x - asteroid.x, 2) + pow(y - asteroid.y, 2)) < 50;
}
}
class SpaceshipPainter extends CustomPainter {
final Spaceship spaceship;
SpaceshipPainter(this.spaceship);
@override
void paint(Canvas canvas, Size size) {
// Draw spaceship on the canvas
canvas.save();
canvas.translate(spaceship.x, spaceship.y);
canvas.rotate(spaceship.angle);
Path path = Path();
path.moveTo(0, -20);
path.lineTo(-10, 10);
path.lineTo(10, 10);
path.close();
canvas.drawPath(path, Paint()..color = Colors.white);
canvas.restore();
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
class BulletPainter extends CustomPainter {
final Bullet bullet;
BulletPainter(this.bullet);
@override
void paint(Canvas canvas, Size size) {
// Draw bullet on the canvas
canvas.drawCircle(
Offset(bullet.x, bullet.y), 5, Paint()..color = Colors.white);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
class Bullet {
double x;
double y;
double angle;
double speed;
Bullet(this.x, this.y, this.angle)
: speed = 10;
void updatePosition() {
x += cos(angle) * speed;
y += sin(angle) * speed;
}
bool collidesWith(Asteroid asteroid) {
return sqrt(pow(x - asteroid.x, 2) + pow(y - asteroid.y, 2)) < 25;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment