Closed MikaReesu closed 1 year ago
Hi @MikaReesu !
Using the version 3.0.2
I got it like this:
import 'package:bonfire/bonfire.dart';
import 'package:example/shared/util/person_sprite_sheet.dart';
enum EnemyState {
guarding,
backing,
}
class MeleeEnemy extends SimpleEnemy {
late Vector2 initialPOsition;
EnemyState state = EnemyState.guarding;
double distanceTolerance = 0;
MeleeEnemy({required Vector2 position})
: super(
position: position,
animation: PersonSpritesheet(path: 'orc2.png').simpleAnimation(),
size: Vector2.all(24),
speed: 25,
initDirection: Direction.down,
) {
initialPOsition = center.clone();
distanceTolerance = width;
}
@override
void update(double dt) {
switch (state) {
case EnemyState.guarding:
if (position.distanceTo(initialPOsition) > distanceTolerance) {
state = EnemyState.backing;
} else {
seeAndMoveToPlayer(closePlayer: (p) {
if (checkInterval('attack', 600, dt)) {
_playAttackAnimation();
}
});
}
break;
case EnemyState.backing:
if (center.distanceTo(initialPOsition) < 2) {
state = EnemyState.guarding;
lastDirection = Direction.down;
stopMove();
} else {
moveToPosition(initialPOsition);
}
break;
}
super.update(dt);
}
@override
Future<void> onLoad() {
/// Adds rectangle collision
add(RectangleHitbox(size: size / 2, position: size / 4));
return super.onLoad();
}
void _playAttackAnimation() {
switch (lastDirection) {
case Direction.left:
animation?.playOnceOther(PersonAttackEnum.meeleLeft);
break;
case Direction.right:
animation?.playOnceOther(PersonAttackEnum.meeleRight);
break;
case Direction.up:
animation?.playOnceOther(PersonAttackEnum.meeleUp);
break;
case Direction.down:
animation?.playOnceOther(PersonAttackEnum.meeleDown);
break;
case Direction.upLeft:
animation?.playOnceOther(PersonAttackEnum.meeleUpLeft);
break;
case Direction.upRight:
animation?.playOnceOther(PersonAttackEnum.meeleUpRight);
break;
case Direction.downLeft:
animation?.playOnceOther(PersonAttackEnum.meeleDownLeft);
break;
case Direction.downRight:
animation?.playOnceOther(PersonAttackEnum.meeleDownRight);
break;
}
}
}
Why is notObserved now a boolean? I am in the Ally, and I want it as a guard to attack enemies.
Could you please show me how to use it?
The idea was to have the ally here my guard, defending against enemies. Once enemy bitten, the guards would come back to their initial positions.
If you return true it's stop movement of your component. If return false not. So, when you need do some custom movement when not observe it's necessary return false to not have strange behavior.
Humm. I understood. You can recycle this implementation. When I got a time I will try do a example about this type of guardian.
It is much better now, I tried to implement your code and it's working well. Only thing is to master a bit more the distanceTolerance
, the concept is interesting, but, tricky at the same time.
I would like the guard to be able to go a bit further, it's just that, I want to avoid the back and forth, back and forth movement, that I see at the moment.
When I increase distanceTolerance
and if (center.distanceTo(initialPosition) < 2) {
, what is triggered is the stopMove(), and instead of going back to their initial position they stay static and waiting for the next enemy to appear.
I don't know if you see what I mean, but normally if put let's distanceTolerance = width * 2
and if (center.distanceTo(initialPosition) < 4) {
, it's gonna be visible directly.
Hope I was clear, and thank you very much for your help :)
I also noticed that you were using a playOnceOther
, what is the difference between the playOnceOther
and the playOnce
?
The playOnceOther is used to play once time the registered animation in the SimpleDirectionAnimation in him there is a param named others to register other animation beyond the animation of directions.
So is it something that allows you to play one animation after another? Not sure that I understand the difference honestly.
So both do the something but playOnce
expected a SpriteAnimation
and playOnceOther
expected only key to play a animation registered previously in param others
of SimpleDirectionAnimation
like this:
var animation = SimpleDirectionAnimation(
idleRight: SpriteAnimation(),
runRight: SpriteAnimation(),
others:{
'attackLeft': SpriteAnimation(),
}
);
animation.playOnceOther('attackLeft'');
I see, thank you for your help!
What happened?
Hello I have a simple ally that is a guard with AutomaticRandomMovement.
'seeAndMoveToEnemy( closeEnemy: (p0) => meleeAttack(), radiusVision: GlobalConstants.TILE_SIZE * 8, runOnlyVisibleInScreen: true, margin: GlobalConstants.TILE_SIZE / 3, visionAngle: 180, notObserved: () { if (position.distanceTo(initialPosition) > tolerance) { moveToPosition(initialPosition); } else { stopMove(); } });'
I added a code to see and move to the enemy and I added a not observed with a stopMove or a move to initial position. So the position in which the guard was loaded first. moveToPosition(initialPosition);
What is happening is that, the guard detect the enemy, goes to it. Once the enemy is killed, he goes back to his initial position but that's where the bug starts.
The guard starts to run on the spot, so he is not moving from his position and the animation left and right are played non stop and very fast, he could almost fly away.
I tried so many things, to put him back in idle, to stop the move, but it doesn't matter and there is still the same issue at the end. Thank you very much.
Do you have any idea? @Rafael Almeida
Steps to reproduce?
What did you expect to happen?
I expected the Ally to reach his position and stay idle, before he could see another enemy to chase.
Bonfire version
3.0.0
Relevant log output
No response