CPD/lib/main.dart

278 lines
6.4 KiB
Dart
Raw Normal View History

2024-01-10 14:36:14 +01:00
import 'dart:async';
import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:pong/pong_menu.dart';
void main() {
runApp(const PongGame());
}
class PongGame extends StatelessWidget {
const PongGame({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Pong Game',
theme:
ThemeData(scaffoldBackgroundColor: Color.fromARGB(255, 41, 38, 38)),
home: const StartScreen(),
);
}
}
class StartScreen extends StatelessWidget {
const StartScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) {
return const GameScreen();
},
));
},
child: const Center(
child: Text(
'Berühren um zu beginnen!',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
);
}
}
class GameScreen extends StatefulWidget {
const GameScreen({super.key});
@override
State<GameScreen> createState() => _GameScreenState();
}
@visibleForTesting
class _GameScreenState extends State<GameScreen> {
final ballSize = 20.0;
final racketWidth = 240.0;
final racketHeight = 25.0;
final racketBottomOffset = 100.0;
final initialBallSpeed = 2.0;
double ballX = 0;
double ballY = 0;
double ballSpeedX = 0;
double ballSpeedY = 0;
double racketX = 20;
int score = 0;
late Ticker ticker;
final double ballSpeedMultiplier = 2;
@override
void initState() {
super.initState();
startGame();
}
@override
void dispose() {
super.dispose();
stopGame();
}
void startGame() {
final random = Random();
ballX = 0;
ballY = 0;
ballSpeedX = initialBallSpeed;
ballSpeedY = initialBallSpeed;
racketX = 200;
score = 0;
if (random.nextBool()) ballSpeedX = -ballSpeedX;
if (random.nextBool()) ballSpeedY = -ballSpeedY;
Future.delayed(const Duration(seconds: 1), () {
ticker = Ticker((elapsed) {
setState(() {
moveBall(ballSpeedMultiplier);
});
});
ticker.start();
});
}
void stopGame() {
ticker.dispose();
}
void moveBall(double ballSPeedMultiplier) {
ballX += ballSpeedX * ballSpeedMultiplier;
ballY += ballSpeedY * ballSpeedMultiplier;
final Size size = MediaQuery.of(context).size;
if (ballX < 0 || ballX > size.width - ballSize) {
ballSpeedX = -ballSpeedX;
}
if (ballY < 0) {
ballSpeedY = -ballSpeedY;
}
// Was prüft diese if-Anweisung?
if (ballY > size.height - ballSize - racketHeight - racketBottomOffset &&
ballX >= racketX &&
ballX <= racketX + racketWidth) {
ballSpeedY = -ballSpeedY;
} else if (ballY > size.height - ballSize) {
debugPrint('Game over');
stopGame();
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return PongMenu(
title: 'Game over!',
subTitle: 'Deine Punkte: $score',
child: CupertinoButton(
child: const Text('Nochmal Spielen'),
onPressed: () {
Navigator.of(context).pop();
startGame();
},
),
);
},
);
}
}
moveRacket(double x) {
setState(() {
racketX = x - racketWidth / 2;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
GestureDetector(
onHorizontalDragUpdate: (details) {
moveRacket(details.globalPosition.dx);
},
child: CustomPaint(
painter: PongGamePainter(
racketHeight: racketHeight,
racketWidth: racketWidth,
racketX: racketX,
racketBottomOffset: racketBottomOffset,
ballSize: ballSize,
ballX: ballX,
ballY: ballY,
),
size: Size.infinite,
),
),
Center(
child: Text(
'Punkte: $score',
style: const TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
),
Positioned(
top: 20,
right: 20,
child: IconButton(
icon: const Icon(
CupertinoIcons.pause,
size: 30,
),
onPressed: () {
stopGame();
showDialog(
context: context,
builder: (context) {
return PongMenu(
title: 'Pause',
subTitle: 'Deine Punkte: $score',
child: CupertinoButton(
onPressed: () {},
child: const Text('Weiter'),
),
);
});
},
),
)
],
),
);
}
}
class PongGamePainter extends CustomPainter {
final double ballSize;
final double ballX;
final double ballY;
final double racketX;
final double racketWidth;
final double racketHeight;
final double racketBottomOffset;
PongGamePainter({
required this.ballSize,
required this.ballX,
required this.ballY,
required this.racketX,
required this.racketWidth,
required this.racketHeight,
required this.racketBottomOffset,
});
@override
void paint(Canvas canvas, Size size) {
final racketPaint = Paint()..color = Colors.white;
final ballPaint = Paint()..color = Colors.white;
canvas.drawOval(
Rect.fromLTWH(ballX, ballY, ballSize, ballSize),
ballPaint,
);
canvas.drawRect(
Rect.fromLTWH(
racketX,
size.height - racketHeight - racketBottomOffset,
racketWidth,
racketHeight,
),
racketPaint,
);
}
@override
bool shouldRepaint(covariant PongGamePainter oldDelegate) {
return ballX != oldDelegate.ballX ||
ballY != oldDelegate.ballY ||
racketX != oldDelegate.racketX;
}
}