Created with <3 with dartpad.dev.
Created
September 20, 2023 06:10
-
-
Save subramanian42/8cb0782f2512471e30279cd892e6afc7 to your computer and use it in GitHub Desktop.
asteroid game
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(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