Aplicacions amb Flutter, Dart i Flame

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

Afegim la bola

Ara afegirem la bola i farem que es mogui per la pantalla. Després hi afegirem la detecció de col·lisions.

És molt recomanable definir les dimensions principals dels components en valors relatius a les dimensions de l'àrea de joc; així, si canviem les dimensions d'aquesta, els elements s'hi adaptaran automàticament.

config.dart
const gameWidth = 820.0;
const gameHeight = 1600.0;
const ballRadius = gameWidth * 0.02;

També hem de definir el color de la bola.

colors.dart
import 'dart:ui';
class ColorsApp {
  static const Color fons = Color(0xFFFFEECC);
  static const Color bola = Color(0xFFFF6699);
}

A la carpeta components creem el fitxer bola.dart on posarem un CircleComponent on definirem l'aspecte de la bola, indicarem que les coordenades de posició corresponen al seu centre i establirem com canvia la posició a partir de la velocitat. La velocitat es defineix com un vector, perquè cal establir-ne la direcció.

bola.dart
import 'package:flame/components.dart';
import 'package:flutter/material.dart';
import 'package:joc_breakout/core/colors.dart';
class Bola extends CircleComponent {
  Bola({
    required this.velocity,
    required super.position,  // El paràmetre accedirà directament a l'original
    required double radius,
  }) : super(
        radius: radius,
        anchor: Anchor.center,
        paint: Paint()
          ..color = ColorsApp.bola
          ..style = PaintingStyle.fill,
      );

  final Vector2 velocity;

  @override
  void update(double dt) {
    super.update(dt);
    position += velocity * dt;
  }
}

Un cop definida la bola, l'haurem d'afegir en el fitxer de components.

components.dart
export 'bola.dart';
export 'play_area.dart';

Per tal que es vegi, l'haurem d'incorporar al joc. La posició inicial és al centre de l'àrea de joc, la velocitat vertical és un valor constant calculat a partir de l'alçada i la velocitat horitzontal és un valor amb signe calculat a partir de l'amplada i d'un nombre aleatori. El paràmetre (en aquest cas, 0.2) normalment es defineix a base de fer proves. Un cop tenim el vector, el normalitzem (el reduïm a un vector de mòdul unitari) i després l'escalem a un quart de l'alçada de l'àrea de lloc.

En aquest cas, a més, hem activat el mode de depuració, de manera que, al costat de la bola, hi veurem les seves coordenades.

breakout.dart
import 'dart:async';
import 'dart:math' as math;
import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'components/components.dart';
import 'config.dart';
class Breakout extends FlameGame {
  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),
    ));
    debugMode = true;  // Línia provisional
  }
}

Quan executem aquest programa veurem aparèixer la pilota al mig i es desplaçarà cap avall però amb una direcció diferent cada vegada.

 

 

 

 

 

 

 

 

 

 

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