Skip to content

Latest commit

 

History

History
299 lines (243 loc) · 6.91 KB

ex17-8.md

File metadata and controls

299 lines (243 loc) · 6.91 KB

17.8 Adding Collision Detection

Example: Collision detection

import 'dart:async';
import 'package:flame/collisions.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/components.dart';
import 'package:flutter/material.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Flame.device.setPortrait();
  final shapeGame = ShapesExample();

  runApp(GameWidget(game: shapeGame));
}

class ShapesExample extends FlameGame with HasCollisionDetection {
  @override
  Future<void> onLoad() async {
    super.onLoad();

    add(RectComponent(size[0], size[1]));
  }

  // @override
  // void update(double dt) {
  //   super.update(dt);
  // }

  // @override
  // void render(Canvas canvas) {
  //   super.render(canvas);
  // }
}

// Add a [Color] Rect on screen
class RectComponent extends PositionComponent with CollisionCallbacks {
  double screenWidthMax = 0;
  double screenHeightMax = 0;

  double xStartPosition = 0;
  double yStartPosition = 0;
  static double xRectWidth = 50;
  static double yRectHeight = 50;
  int rectDirection = 1;

  final paint = Paint()
    ..color = Colors.white
    ..strokeWidth = 4;

  RectComponent(this.screenWidthMax, this.screenHeightMax);

  @override
  Future<void> onLoad() async {
    super.onLoad();
    // Set the start position of the Rect - center of the screen
    xStartPosition = (screenWidthMax) / 2;
    yStartPosition = (screenHeightMax) / 2;

    add(RectangleHitbox());
  }

  @override
  void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {
    super.onCollision(intersectionPoints, other);

    if (other is ScreenHitbox) {
      switch (rectDirection) {
        case 0:
          rectDirection = 1;
          break;
        case 1:
          rectDirection = 0;
          break;
        default:
          break;
      }
    }
  }

  @override
  void update(double dt) {
    super.update(dt);
    if (rectDirection == 1) {
      xStartPosition += 5;
      if (xStartPosition >= (screenWidthMax - xRectWidth)) {
        rectDirection = 0;
      }
    }

    if (rectDirection == 0) {
      xStartPosition -= 5;
      if (xStartPosition <= (0)) {
        rectDirection = 1;
      }
    }
  }

  @override
  void render(Canvas canvas) {
    super.render(canvas);

    // xStartPos, yStartPos, xRectWidth, yRectHeight
    canvas.drawRect(
        Rect.fromLTWH(xStartPosition, yStartPosition, xRectWidth, yRectHeight),
        paint);
  }
}
```i

# Example: Test

```dart
import 'dart:async';
import 'package:flame/collisions.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/components.dart';
import 'package:flutter/material.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Flame.device.setPortrait();
  final shapeGame = ShapesExample();

  runApp(GameWidget(game: shapeGame));
}

class ShapesExample extends FlameGame with HasCollisionDetection {
  @override
  Future<void> onLoad() async {
    add(GridComponent(size[0], size[1]));
    add(RectComponent(size[0], size[1]));
    super.onLoad();
  }

  // @override
  // void update(double dt) {
  //   super.update(dt);
  // }

  // @override
  // void render(Canvas canvas) {
  //   super.render(canvas);
  // }
}

class GridComponent extends PositionComponent with CollisionCallbacks {
  double screenWidthMax = 0;
  double screenHeightMax = 0;
  double xPos = 0;
  double yPos = 0;

  final paint = Paint()
    ..color = Colors.grey
    ..strokeWidth = 1;

  GridComponent(this.screenWidthMax, this.screenHeightMax);

  @override
  Future<void> onLoad() async {
    super.onLoad();
    xPos = (screenWidthMax / 2) - 100;
    yPos = (screenHeightMax / 2);

    // add(RectangleHitbox());
    add(RectangleHitbox.relative(Vector2(xPos, yPos),
        parentSize: Vector2(50, 50)));
    add(ScreenHitbox());
  }

  @override
  void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {
    // print('Grid Edge detected - onCollision');

    if (other is ScreenHitbox) {
      print('ScreenHitbox: other onCollision');
    } else if (other is RectComponent) {
      print('RectangleHitbox: other onCollision');
    } else {
      print('Other onCollision: $other');
    }
    super.onCollision(intersectionPoints, other);
  }

  // @override
  // void onCollisionStart(
  //     Set<Vector2> intersectionPoints, PositionComponent other) {
  //   // ignore: avoid_print
  //   print('Grid Edge detected - onCollisionStart');
  //   super.onCollisionStart(intersectionPoints, other);
  // }

  @override
  void render(Canvas canvas) {
    super.render(canvas);
    canvas.drawRect(Rect.fromLTWH(xPos, yPos, 50, 50), paint);
  }
}

// Add a [Color] Rect on screen
class RectComponent extends PositionComponent with CollisionCallbacks {
  double screenWidthMax = 0;
  double screenHeightMax = 0;

  double xStartPosition = 0;
  double yStartPosition = 0;
  static double xRectWidth = 50;
  static double yRectHeight = 50;
  int rectDirection = 0;
  double elapsedTime = 0.0;

  final paint = Paint()
    ..color = Colors.white
    ..strokeWidth = 4;

  RectComponent(this.screenWidthMax, this.screenHeightMax);

  @override
  Future<void> onLoad() async {
    super.onLoad();
    // Set the start position of the Rect - center of the screen
    xStartPosition = (screenWidthMax) / 2;
    yStartPosition = (screenHeightMax) / 2;

    // add(RectangleHitbox());
    add(RectangleHitbox.relative(Vector2(xStartPosition, yStartPosition),
        parentSize: Vector2(50, 50)));
    add(ScreenHitbox());
  }

  @override
  void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {
    // print('Rect Edge detected - onCollision');

    if (other is ScreenHitbox) {
      // ignore: avoid_print
      print('detected collision');
    } else if (other is GridComponent) {
      // ignore: avoid_print
      print('Rectangle: onCollision');
    } else {
      print('Other onCollision: $other');
    }

    super.onCollision(intersectionPoints, other);
  }

  // @override
  // void onCollisionStart(
  //     Set<Vector2> intersectionPoints, PositionComponent other) {
  //   // ignore: avoid_print
  //   print('Rect Edge detected - onCollisionStart');
  //   super.onCollisionStart(intersectionPoints, other);
  // }

  @override
  void update(double dt) {
    super.update(dt);

    elapsedTime += dt;

    if (elapsedTime > 1.0) {
      if (rectDirection == 1) {
        xStartPosition += 5;
        // if (xStartPosition >= (screenWidthMax - xRectWidth)) {
        //   rectDirection = 0;
        // }
      }

      if (rectDirection == 0) {
        xStartPosition -= 5;
        // if (xStartPosition <= (0)) {
        //   rectDirection = 1;
        // }
      }

      elapsedTime = 0.0;
    }
  }

  @override
  void render(Canvas canvas) {
    super.render(canvas);

     // xStartPos, yStartPos, xRectWidth, yRectHeight
    canvas.drawRect(
        Rect.fromLTWH(xStartPosition, yStartPosition, xRectWidth, yRectHeight),
        paint);
  }
}