Aplicacions amb Flutter, Dart i Flame

Tutorial Flutter Flame Projectes   Recursos CITCEA
Exemples Dart Dades pràctiques     Inici

Fem que la pala tingui les vores arrodonides

Fins ara, els nostres components (àrea de joc, bola i pala) eren figures bàsiques (RectangleComponent o CircleComponent); però ens pot interessar fer servir altres formes, en quin cas caldrà emprar el component genèric PositionComponent i definir específicament la forma. Com a aexemple, anem a fer que la pala sigui un rectangle amb les vores arrodonides.

Ara, doncs, la pala es basarà en un PositionComponent i li afegirem un paràmetre que serà el radi de curvatura de les cantonades. Ara les instruccions per pintar el rectangle estaran en una funció a banda (_paint) que s'haurà de cridar al mètode render, que caldrà sobrescriure per tal que el rectangle es representi.

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
    with DragCallbacks, HasGameReference<Breakout> {
  Pala({
    required this.cornerRadius,
    required super.position,
    required super.size,
  }) : super(
    anchor: Anchor.center, 
    children: [RectangleHitbox()]
  );

  final Radius cornerRadius;

  final _paint = Paint()
    ..color = ColorsApp.pala
    ..style = PaintingStyle.fill;

  @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(0, game.width);
  }

  void moveBy(double dx) {
    add(
      MoveToEffect(
        Vector2((position.x + dx).clamp(0, game.width), position.y),
        EffectController(duration: 0.1),
      ),
    );
  }
}

En la definició del joc, caldrà afegir el nou paràmetre.

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 '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(
      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),
      ),
    );
    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;
  }
}

A banda de la forma de la pala, el funcionament del joc es manté.

 

 

 

 

 

 

 

 

 

 

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