MattDower's Forum Posts

  • 12 posts
  • I’m working on a simplified RTS. I animate unit states (idle, move, attack) using Timeline, and as long as animation/property names match across sprites, everything works fine.

    The problem: when switching states, the previous timeline doesn’t stop — it keeps playing on top of the new one. So an idle squash & stretch + a walk angle change end up stacking together.

    Stopping the animation or unsetting instances before playing a new timeline doesn’t seem to work.

    Has anyone run into this? Is there a proper way to stop or clear the previous timeline before playing the next one?

    + UnitsA: State = "chase"

    + Sprites_Units: Pick instance with UID UnitsA.SpriteUID

    -----> TimelineController: Set Sprites_Units to track "" of the next timeline

    -----> TimelineController: Play Anim_Walk with tags str(Sprites_Units.UID)

    + UnitsA: State = "idle"

    + Sprites_Units: Pick instance with UID UnitsA.SpriteUID

    -----> TimelineController: Set Sprites_Units to track "" of the next timeline

    -----> TimelineController: Play Anim_Idle with tags str(Sprites_Units.UID)

  • Hi! You are right! the every tick was the trouble-maker. Thanks for the reply!

    I added a boolean that Pathfinding needs to check that it´s set before it acts, and turns it off right after. then it turns on every x seconds.

    I get what you are saying about "state = chase and unit is not moving along path, then find path." but I fear that this wont refresh the pathfinding if the target moves right?

    The unitA/unitB is a hack solution to make sure all units share stats, vairables and behaviours, all info is in UnitsA, and Units be is for reference, I saw it in a tutorial as an easy way to reference something in the same group and not risking construct3 mixing target and origin, it was a bit messy at first, but I used it a lot in a previous project and i worked like a charm once i got the hang of it! Thanks for the warning any way, you never now when you might be going down a rabbit hole haha

  • I'm working on a simple, mostly automated RTS.

    I'm using a state machine to handle the units, and even though on debug I see that the states are changing correctly in real time, I can't get the units to act accordingly. The game seems to pick one, complete its pathfinding task, and only then moves to another.

    If I don't use pathfinding, I use "move to" instead, it works as intended, without the pathfinding of course (MoveTo: Move along Pathfinding path yields the same results as moving with pathfinding)

    I didn´t find any solutions on the manual, maybe I´m overlooking something obvious, any help would be appreciated.

    the project:

    https://drive.google.com/file/d/1K8_Ay0JzGBEGJAj9iMziTP0gxKK5im9V/view?usp=sharing

    //DEACTIVATING "FOR EACH" MAKES THEM WORK SIMULTANEOUSLY, BUT THEY APPEAR TO GRAB THE UnitsA.TargetUID VARIABLE FROM ANY UNIT A, NOT THEMSELVES//

    + System: For each UnitsA ===>

    ----+ UnitsA: State = "idle"

    --------+ Sprites_Units: Pick instance with UID UnitsA.SpriteUID

    ---------> UnitsA: Pathfinding: Stop

    ---------> Sprites_Units: Set animation to "idle" (play from current frame)

    ----+ UnitsA: State = "attack"

    --------+ Sprites_Units: Pick instance with UID UnitsA.SpriteUID

    ---------> UnitsA: Pathfinding: Stop

    ---------> Sprites_Units: Set animation to "attack" (play from current frame)

    ----+ UnitsA: State = "chase"

    --------+ Sprites_Units: Pick instance with UID UnitsA.SpriteUID

    ---------> Sprites_Units: Set animation to "move" (play from current frame)

    --------+ System: Every 0.2 seconds

    --------+ UnitsB: Pick instance with UID UnitsA.TargetUID

    ------------+ (no conditions)

    -------------> UnitsA: Pathfinding: Find path to (UnitsB.X, UnitsB.Y)

    + UnitsA: On Pathfinding path found

    -> UnitsA: Pathfinding: Move along path

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • alextro I had to stop to keep for work, but I´m about to re-engage this project, I´ll keep you posted if I find a solution!

  • alextro Hi! I´ve been working on other systems, but I just tried delating line 55 in "Enemies" but I still get the same mistake :/ tried in two different PCs in case it was some weird mistake, but it still doesn't work.

    thank you nonetheless

  • thanks alextro

    I´m still kind of new to participating in forums and don't have all the proper "etiquette" ,next time I´ll just post the project :)

    I removed a lot of functions and behaviours trying to detect the problem, enemies have two states, "ready to move/attack" and "idle", they switch between them every turn.

    The function that's giving me trouble is "GetAngleOfSigth", in the event sheet Enemies, under the group ranged, as I said, it works great EXCEPT when the player is straight up at 90°, it try feeding that variable directly to check if it´s that the function isn't working properly, but that´s not the case. It just acts as if it cant the the player.

    Any insight is welcomed

    https://drive.google.com/drive/folders/1DYgKzNhHXuw-rgVvdAwvKYAmzzU-kd8s?usp=sharing

  • I´m working on a checkered grid dungeon crawler, and while working with a Ranged unit, that should only attack while aligned with the player (think of it as a Ranged Rook) when I check LineOfSigth in the 90° it doesn´t detect it, it does work with every other angle thought, I tried trouble-shooting it by removing everything else but it still gives trouble with that angle, any ideas what I might be doing wrong?

    I´ll leave some caps:

    Subscribe to Construct videos now

    as you can see, all enemies attack expect the one straight down

    (angle of sigth is only used for LOS, and angle of movement marks the moving direction

    * On function 'EnemyRanged_PathFinding'

    * Parameter 'UID' (Number)

    + Enemy: Pick instance with UID UID

    // Check if the Enemy is closer to the Player in Y Axis

    ----+ System: abs(Enemy.X - Samurai.X) ≥ abs(Enemy.Y- Samurai.Y)

    --------+ System: Enemy.X < Samurai.X

    --------// Right

    ---------> Enemy: Set AngleOfSight to 0

    --------+ System: Enemy.X > Samurai.X

    --------// Left

    ---------> Enemy: Set AngleOfSight to 180

    --------+ System: Enemy.Y < Samurai.Y

    --------// Up

    ---------> Enemy: Set AngleOfMovement to 90

    --------+ System: Enemy.Y > Samurai.Y

    --------// Down

    ---------> Enemy: Set AngleOfMovement to 270

    // Check if the Enemy is closer to the Player in X Axis

    ----+ System: abs(Enemy.X - Samurai.X) < abs(Enemy.Y- Samurai.Y)

    --------+ System: Enemy.Y < Samurai.Y

    --------// Up

    ---------> Enemy: Set AngleOfSight to 90

    --------+ System: Enemy.Y > Samurai.Y

    --------// Down

    ---------> Enemy: Set AngleOfSight to 270

    --------+ System: Enemy.X < Samurai.X

    --------// Right

    ---------> Enemy: Set AngleOfMovement to 0

    --------+ System: Enemy.X > Samurai.X

    --------// Left

    ---------> Enemy: Set AngleOfMovement to 180

    ----+ (no conditions)

    -----> Functions: Call EnemyRanged_MoveOrAttack (UID: UID)

    --------

    * On function 'EnemyRanged_MoveOrAttack'

    * Parameter 'UID' (Number)

    + Enemy: Pick instance with UID UID

    // if the player is in range, attack

    ----+ Enemy: Has LineOfSight from (Self.X, Self.Y) angle Self.AngleOfSight to (Samurai.X, Samurai.Y)

    -----> Functions: Call Move_Attack (UID: UID, AngleOfMotion: Enemy.AngleOfSight)

    -----> Functions: Call PlayerGetsAttacked

    --------+ [DISABLED] Enemy: Is overlapping Samurai at offset (round(cos(Enemy.AngleOfMovement) × TileSize), round(sin(Enemy.AngleOfMovement) × TileSize))

    ---------> (no actions)

    // for some reason, it gives priority to MOVE>Attack, this "if" is to force it´s hand

    ----+ Enemy: [X] Has LineOfSight from (Self.X, Self.Y) angle Self.AngleOfSight to (Samurai.X, Samurai.Y)

    // if you can move to, do so

    --------+ Enemy: TileMovement can move to (Enemy.TileMovement.GridX + round(cos(Enemy.AngleOfMovement)),Enemy.TileMovement.GridY + round(sin(Enemy.AngleOfMovement)))

    ---------> Functions: Call Move_Forward (UID: Enemy.UID, AngleOfMotion: Enemy.AngleOfMovement)

    // if there´s an obstacle, try to go around

    --------+ Enemy: [X] TileMovement can move to (Enemy.TileMovement.GridX + round(cos(Enemy.AngleOfMovement)),Enemy.TileMovement.GridY + round(sin(Enemy.AngleOfMovement)))

    --------+ Enemy: [X] Is TriedToMoveThisTurn

    ---------> Enemy: Set TriedToMoveThisTurn to True

    // if its Left or Right

    ------------+ Enemy: AngleOfMovement = 0

    ------------+ OR Enemy: AngleOfMovement = 180

    ----------------+ System: Enemy.Y < Samurai.Y

    ----------------// Up

    -----------------> Enemy: Set AngleOfMovement to 90

    -----------------> Functions: Call EnemyMelee_MoveOrAttack (UID: UID)

    ----------------+ System: Enemy.Y ≥ Samurai.Y

    ----------------// Down

    -----------------> Enemy: Set AngleOfMovement to 270

    -----------------> Functions: Call EnemyMelee_MoveOrAttack (UID: UID)

    // if its Up or Down

    ------------+ Enemy: AngleOfMovement = 90

    ------------+ OR Enemy: AngleOfMovement = 270

    ----------------+ System: Enemy.X < Samurai.X

    ----------------// Right

    -----------------> Enemy: Set AngleOfMovement to 0

    -----------------> Functions: Call EnemyMelee_MoveOrAttack (UID: UID)

    ----------------+ System: Enemy.X ≥ Samurai.X

    ----------------// Left

    -----------------> Enemy: Set AngleOfMovement to 180

    -----------------> Functions: Call EnemyMelee_MoveOrAttack (UID: UID)

    // //if everything fails, just stand still

    ----+ System: Else

    -----> (no actions)

  • Okay, that´s brilliant, thanks a lot!

  • Hi! I´m working with a tile based game,

    and although I{m making good progress, I hit a brick walk:

    I´m calculating movement using a variable AngleOfMovment for Each Unit(0,90,180,270)

    So if i want a unit to move left(the player samurai for example) I use a tween like this:

    AngleOfMovment: 180

    End X: Self.X + round(cos(Samurai.AngleOfMovement) * TileSize)

    End Y: Self.Y + round(sin(Samurai.AngleOfMovement) * TileSize)

    and for basic movement and collision detection it works great!

    But I´m implementing a lot of push and knockback mechanics, and that means that I sometimes need to get the opposite angle, and that is giving me a lot of trouble, because depending on the situation sometimes

    Self.X - round(cos(Samurai.AngleOfMovement) * TileSize)

    works, on others

    Self.X + round(cos(-Samurai.AngleOfMovement) * TileSize)

    this does, and I can figure out why, because both should add the opposite value right?

    If anyone has a more elegant solution, or a better way to get the opposite angle, I would be grateful.

  • dop2000 it worked wonders! Thank you very much, the only problem I had is that I still need to run "trigger once" or it wont work, I think its constantly checking and resetting the timer. I trust you that this might bring problems long term, so if you have a solution, it would be appreciated, either way, I consider this problem resolved!.

  • Okay, I get the logic! a circular function that checks a variable of "acted this turn", if there are none left it pass to the player, much more elegant than my solution ha!

    I´ll try it and post pack :)

  • Hi! I checked many post and couldn't get a complete answer, so I would appreciate some help.

    How to I make enemies act in order?

    I'm making a turn based limited dungeon crawler, inspired by games like Hoplite.

    After the player acts, I want for all enemies to act, but not at the same time, they should do it one after another, so they don't end up occupying the same tile or such.

    The best solution so far I managed was to create a timer that multiples a base value for each of their LoopIndex, but I fear that this might bring troubles long term (if I need a new one to take more time to do an attack, for example), I could add a variable of "neededTimeToAttack", bur it feels more like a patch than a solution.

    I'm experimenting with setting each LoopIndex to a variable TurnOrder for each instance, then checking it against a global variable, but all enemies started acting simultaneously again

    Can someone detect the problem in my logic? It goes over my head.

    Cheers!

    Tagged:

  • 12 posts