Skip to content
This repository has been archived by the owner on Apr 25, 2024. It is now read-only.

Commit

Permalink
Add path finder for player move
Browse files Browse the repository at this point in the history
  • Loading branch information
warioddly committed Feb 11, 2024
1 parent af4c279 commit 329ae63
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import 'package:flame/components.dart';
import 'package:flame/geometry.dart';
import 'package:flutter/material.dart';
import 'package:pacman/core/extensions/extensions.dart';
import 'package:pacman/core/mixins/internal_checker.dart';
import 'package:pacman/core/mixins/sensor.dart';
import 'package:pacman/game.dart';

abstract class MyComponent extends PositionComponent with HasGameRef<PacmanGame>, HasPaint, CollisionCallbacks {
abstract class MyComponent extends PositionComponent with HasGameRef<PacmanGame>, HasPaint, CollisionCallbacks, InternalChecker {
final String _keyIntervalCheckIsVisible = "CHECK_VISIBLE";
final int _intervalCheckIsVisible = 100;
Map<String, dynamic>? properties;
Expand Down Expand Up @@ -127,15 +129,15 @@ abstract class MyComponent extends PositionComponent with HasGameRef<PacmanGame>

void _confHitBoxRender(Component component) {
if (component is ShapeHitbox) {
if (gameRef.showCollisionArea) {
// if (gameRef.showCollisionArea) {
var paintCollition = Paint()
..color = gameRef.collisionAreaColor ?? const Color(0xffffffff);
..color = const Color(0xffffffff);
if (component is Sensor) {
paintCollition.color = sensorColor;
}
component.paint = paintCollition;
component.renderShape = true;
}
// }
}
}

Expand Down Expand Up @@ -244,19 +246,19 @@ abstract class MyComponent extends PositionComponent with HasGameRef<PacmanGame>

List<ShapeHitbox> _getSensorsHitbox() {
var sensorHitBox = <ShapeHitbox>[];
// query<Sensor>(onlyVisible: true).forEach((e) {
// sensorHitBox.addAll(e.children.query<ShapeHitbox>());
// });
query<Sensor>(onlyVisible: true).forEach((e) {
sensorHitBox.addAll(e.children.query<ShapeHitbox>());
});
return sensorHitBox;
}


// Iterable<T> query<T extends Component>({bool onlyVisible = false}) {
// if (onlyVisible) {
// return _visibleComponents.whereType<T>();
// }
// return world.children.query<T>();
// }
Iterable<T> query<T extends Component>({bool onlyVisible = false}) {
if (onlyVisible) {
return _visibleComponents.whereType<T>();
}
return gameRef.world.children.query<T>();
}


@override
Expand Down
88 changes: 88 additions & 0 deletions lib/core/mixins/internal_checker.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@

import 'package:flutter/cupertino.dart';

mixin InternalChecker {
/// Map available to store times that can be used to control the frequency of any action.
Map<String, IntervalTick>? _timers;

/// Returns true if for each time the defined millisecond interval passes.
/// Like a `Timer.periodic`
/// Used in flows involved in the [update]
bool checkInterval(
String key,
int intervalInMilli,
double dt, {
bool firstCheckIsTrue = true,
}) {
_timers ??= {};
if (_timers![key]?.interval != intervalInMilli) {
_timers![key] = IntervalTick(intervalInMilli);
return firstCheckIsTrue;
} else {
return _timers![key]?.update(dt) ?? false;
}
}

void resetInterval(String key) {
_timers?[key]?.reset();
}

void tickInterval(String key) {
_timers?[key]?.tick();
}

void pauseEffectController(String key) {
_timers?[key]?.pause();
}

void playInterval(String key) {
_timers?[key]?.play();
}

bool invervalIsRunning(String key) {
return _timers?[key]?.running ?? false;
}
}


class IntervalTick {
late int interval; // in Milliseconds
final VoidCallback? onTick;
double _currentTime = 0;
bool _running = true;
late double _intervalSeconds;
IntervalTick(this.interval, {this.onTick}) {
_intervalSeconds = interval / 1000;
}

bool update(double dt) {
if (_running) {
_currentTime += dt;
if (_currentTime >= _intervalSeconds) {
onTick?.call();
reset();
return true;
}
}

return false;
}

void reset() {
_currentTime = 0;
}

void pause() {
_running = false;
}

void play() {
_running = true;
}

void tick() {
_currentTime = _intervalSeconds;
}

bool get running => _running;
}
65 changes: 65 additions & 0 deletions lib/core/mixins/sensor.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@


import 'dart:ui';

import 'package:flame/collisions.dart';
import 'package:flame/components.dart';
import 'package:pacman/components/my_component.dart';

final Color sensorColor = const Color(0xFFF44336).withOpacity(0.5);

/// Mixin responsible for adding trigger to detect other objects above
/// T is a type that Sensor will be find contact.
mixin Sensor<T extends MyComponent> on MyComponent {
static const _sensorIntervalKey = 'SensorContact';
int _intervalCallback = 100;
MyComponent? componentIncontact;
bool sensorEnabled = true;

void onContact(T component) {}
void onContactExit(T component) {}

void setSensorInterval(int intervalCallback) {
_intervalCallback = intervalCallback;
}

@override
void update(double dt) {
super.update(dt);
if (componentIncontact != null && sensorEnabled) {
if (checkInterval(_sensorIntervalKey, _intervalCallback, dt)) {
onContact(componentIncontact! as T);
}
}
}

@override
Future<void> onLoad() async {
await super.onLoad();
bool containsShape = children.query<ShapeHitbox>().isNotEmpty;
if (!containsShape) {
add(RectangleHitbox(size: size, isSolid: true));
}
}

@override
void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {
if (other is T) {
componentIncontact = other;
}
super.onCollision(intersectionPoints, other);
}

@override
void onCollisionEnd(PositionComponent other) {
if (componentIncontact == other) {
componentIncontact = null;
onContactExit(other as T);
resetInterval(_sensorIntervalKey);
}
super.onCollisionEnd(other);
}

@override
int get priority => 1;
}

0 comments on commit 329ae63

Please sign in to comment.