Ara farem que la dificultat vagi augmentant progressivament. En concret, cada cop que s'elimini un totxo la bola anirà una mica més ràpid.
El primer que farem serà definir un coeficient, més gran que la unitat, pel que multiplicarem la velocitat cada vegada que desaparegui un totxo. El valor d'aquest paràmetre s'obté fent proves.
config.dart
const gameWidth = 820.0; const gameHeight = 1600.0; const ballRadius = gameWidth * 0.02; const batWidth = gameWidth * 0.2; const batHeight = ballRadius * 2; const batStep = gameWidth * 0.05; const numTotxosFilera = 10; const juntaTotxos = gameWidth * 0.015; final brickWidth = (gameWidth - (juntaTotxos * (numTotxosFilera + 1))) / numTotxosFilera; const brickHeight = gameHeight * 0.03; const factorDif = 1.03;
A la bola, hem d'afegir el factor com a paràmetre i modificar la velocitat quan correspongui.
bola.dart
import 'package:flame/collisions.dart'; import 'package:flame/components.dart'; import 'package:flame/effects.dart'; import 'package:flutter/material.dart'; import 'package:joc_breakout/breakout.dart'; import 'package:joc_breakout/components/pala.dart'; import 'package:joc_breakout/components/totxo.dart'; import 'package:joc_breakout/components/play_area.dart'; import 'package:joc_breakout/core/colors.dart';
class Bola extends CircleComponent
with CollisionCallbacks, HasGameReference<Breakout> {
Bola({
required this.velocity,
required super.position,
required double radius,
required this.factorDificultat,
}) : super(
radius: radius,
anchor: Anchor.center,
paint: Paint()
..color = ColorsApp.bola
..style = PaintingStyle.fill,
children: [CircleHitbox()],
);
final Vector2 velocity;
final double factorDificultat;
@override
void update(double dt) {
super.update(dt);
position += velocity * dt;
}
@override
void onCollisionStart(
Set<Vector2> intersectionPoints,
PositionComponent other,
) {
super.onCollisionStart(intersectionPoints, other);
if (other is PlayArea) {
if (intersectionPoints.first.y <= 0) {
velocity.y = -velocity.y;
} else if (intersectionPoints.first.x <= 0) {
velocity.x = -velocity.x;
} else if (intersectionPoints.first.x >= game.width) {
velocity.x = -velocity.x;
} else if (intersectionPoints.first.y >= game.height) {
add(RemoveEffect(delay: 0.35));
}
} else if (other is Pala) {
velocity.y = -velocity.y;
velocity.x =
velocity.x +
(position.x - other.position.x) / other.size.x * game.width * 0.3;
} else if (other is Totxo) {
if (position.y < other.position.y - other.size.y / 2) {
velocity.y = -velocity.y;
} else if (position.y > other.position.y + other.size.y / 2) {
velocity.y = -velocity.y;
} else if (position.x < other.position.x) {
velocity.x = -velocity.x;
} else if (position.x > other.position.x) {
velocity.x = -velocity.x;
}
velocity.setFrom(velocity * factorDificultat);
}
}
}
I en el joc hem de passar el paràmetre a la bola.
breakout.dart
import 'dart:async'; import 'dart:math' as math; import 'package:flame/components.dart'; import 'package:flame/events.dart'; import 'package:flame/game.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:joc_breakout/core/colors.dart'; import 'components/components.dart'; import 'config.dart';
class Breakout extends FlameGame
with HasCollisionDetection, KeyboardEvents {
Breakout()
: super(
camera: CameraComponent.withFixedResolution(
width: gameWidth,
height: gameHeight,
),
);
final rand = math.Random(); // Generador de valors aleatoris
double get width => size.x;
double get height => size.y;
@override
FutureOr<void> onLoad() async {
super.onLoad();
camera.viewfinder.anchor = Anchor.topLeft;
world.add(PlayArea());
world.add(Bola(
factorDificultat: factorDif,
radius: ballRadius,
position: size / 2, // Centre de l'àrea de joc
velocity: Vector2(
(rand.nextDouble() - 0.5) * width,
height * 0.2,
).normalized()..scale(height / 4),
));
world.add(
Pala(
size: Vector2(batWidth, batHeight),
cornerRadius: const Radius.circular(ballRadius / 2),
position: Vector2(width / 2, height * 0.95),
),
);
// Afegim els totxos amb dos bucles
await world.addAll([
for (var i = 0; i < numTotxosFilera; i++)
for (var j = 0; j < ColorsApp.colorsTotxos.length; j++)
Totxo(
position: Vector2(
(i + 0.5) * brickWidth + (i + 1) * juntaTotxos,
(j + 1 + 2.0) * brickHeight + (j + 1) * juntaTotxos,
),
color: ColorsApp.colorsTotxos[j],
),
]);
debugMode = true; // Línia provisional
}
@override
KeyEventResult onKeyEvent(
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
super.onKeyEvent(event, keysPressed);
switch (event.logicalKey) {
case LogicalKeyboardKey.arrowLeft:
world.children.query<Pala>().first.moveBy(-batStep);
case LogicalKeyboardKey.arrowRight:
world.children.query<Pala>().first.moveBy(batStep);
}
return KeyEventResult.handled;
}
}

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.