Ara farem que la pala sigui un sprite. Això ens permetrà fer servir un fitxer gràfic i així la pala no serà un simple rectangle sinó que li podrem donar l'aspecte que vulguem.
El primer que necessitem és el fitxer amb la imatge de la pala. Aquesta és la imatge que farem servir, amb el fons transparent. És important que l'objecte, en aquest cas la pala, ocupi quasi tot el rectamgle gràfic i escollir un detector de col·lisions apropiat; en cas contrari les col·lisions es veuran estranyes. En aquest cas, ens cal un detector rectangular.
Per baixar-la, pots picar sobre la imatge amb el botó dret i guardar-la a l'ordinador.
Ara hem de modificar el fitxer pala.dart per eliminar les coses específiques del RectangleComponent i substituir-les per les de l'sprite. Hi haurà importacions i mètodes que ja no necessitarem.
pala.dart
import 'package:flame/collisions.dart'; import 'package:flame/components.dart'; import 'package:flame/effects.dart'; import 'package:flame/events.dart'; //import 'package:flutter/material.dart'; import 'package:joc_breakout/breakout.dart'; //import 'package:joc_breakout/core/colors.dart';
//class Pala extends PositionComponent
class Pala extends SpriteComponent
with DragCallbacks, HasGameReference<Breakout> {
Pala({
// Les vores de la pala estan definides a la imatge
//required this.cornerRadius,
required super.position,
required super.size,
}) : super(
anchor: Anchor.center,
// Eliminem el detector de col·lisions, perquè ara va a un altre lloc
//children: [RectangleHitbox()]
);
//final Radius cornerRadius;
//final _paint = Paint()
//..color = ColorsApp.pala
//..style = PaintingStyle.fill;
// En carregar l'sprite, definim el fitxer i el detector de col·lisions
@override
Future<void> onLoad() async {
super.onLoad();
// Carrega la imatge de la pala des d'assets/images/pala.png
sprite = await game.loadSprite('pala.png');
// Afegim la caixa de col·lisions rectangular adaptada a la mida del component
add(RectangleHitbox());
}
// El mètode render no cal, ara la imatge es carrega
//@override
//void render(Canvas canvas) {
//super.render(canvas);
//canvas.drawRRect(
//RRect.fromRectAndRadius(Offset.zero & size.toSize(), cornerRadius),
//_paint,
//);
//}
@override
void onDragUpdate(DragUpdateEvent event) {
super.onDragUpdate(event);
position.x = (position.x + event.localDelta.x).clamp(size.x / 2, game.width - size.x / 2);
}
void moveBy(double dx) {
add(
MoveToEffect(
Vector2((position.x + dx).clamp(size.x / 2, game.width - size.x / 2), position.y),
EffectController(duration: 0.1),
),
);
}
}
Hem suprimit el paràmetre cornerRadius i, per tant, cal treure'l del mètode startGame de la classe Breakout.
breakout.dart
...
void startGame() {
if (playState == PlayState.jugant) return;
world.removeAll(world.children.query<Bola>());
world.removeAll(world.children.query<Pala>());
world.removeAll(world.children.query<Totxo>());
playState = PlayState.jugant;
punts.value = 0;
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
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],
),
]);
}
...
Ara en el fitxer colors.dart podem eliminar el color de la pala; encara que, si no ho fem, no afecta al funcionament del joc.
Quan executem aquest programa veurem que ara la pala té un aspecte diferent.

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