Collisions use to work what did I do

Welcome to our brand new Clickteam Community Hub! We hope you will enjoy using the new features, which we will be further expanding in the coming months.

A few features including Passport are unavailable initially whilst we monitor stability of the new platform, we hope to bring these online very soon. Small issues will crop up following the import from our old system, including some message formatting, translation accuracy and other things.

Thank you for your patience whilst we've worked on this and we look forward to more exciting community developments soon!

Clickteam.
  • Hey CT Community,

    So I was working on my missile command type game to learn CT Fusion, and I took a week off. I come back, start adding some stuff, try it, and now I'm chasing bugs that didn't exist. So it must've been the code I added right? Well, I restored a backup from last week to make sure, and it was there too. So now I'm thinking some windows update did this, lol... But seriously even my buddy who played the version from last week was shocked and asked what happened...
    Anyway, I uploaded the mfa below. But the 2 new bugs that didn't exist before on the Level 1 frame are:

    1- On line 10 of the Event editor, the missile_counter now subtracts 2 every time you fire a missile instead of 1.... why?
    2- On line 21 of the Event Editor, the destroy call for the missile upon collision of the aim point no longer occurs....again, why?

    Also, let me know if there is a better way to troubleshoot these kinds of issues. I basically deleted the 2 conditions listed above, then re-added it to see if that would fix the problem, but it didn't. So since I don't know how to debug the problem, here I am :(

    Please help me know how to troubleshoot this!

    wiggy

    Please login to see this link.

  • Hi there wiggy,

    check out this example
    Please login to see this picture.
    Please login to see this link.

    X)

    Please login to see this link.Please login to see this link.
    Take a course in Clickteam Fusion Please login to see this link.
    Youtube Please login to see this link.
    Please login to see this link.

  • #10 is only subtracting 1 from the counter. #29 is subtracting the other amount.

    The reason your target points aren't getting hit is because the Clickteam Movement Controller only uses integer values instead of floats, so it isn't accurate enough to calculate the trajectory correctly between the turret and the target.

  • Thanks all for the replies!

    Klownzilla Yes, but even if I take it out, the behavior is a bit worse, 5-6 missiles fire at a time.

    Sparckman - Haha, yeah, I found your posting of that when I was doing a search for something else. I'm trying to learn how to do it without "cheating" by looking at your answers. But thanks, I think I'll have to look anyway if I get stuck on this for a while.

    Snail - Omg... It looks like I somehow copy / pasted lines 10-12 again at the bottom... typing too fast perhaps? So embarrassing, lol. :D As far as your other suggestion, I'll have to remove the ClickTeam controller and try something else I suppose. What is the best method if the CT controller is not?

    Thanks again!

    Wiggy

  • If you want the precision of using floats, this is the method to do that:

    I'm going to refer to "Alterable Value X" as "xPos" and "Alterable Value Y" as "yPos" in this, but you should always (and only!) use Alterable Values X and Y as xPos and yPos--it's just easier when writing to use xPos and yPos. The Advanced Direction Object simplifies one of the expressions you'll need (you can replace it with an angle formula if you feel like it). baseSpeed is the movement speed and targetAngle is the trajectory.

    If you don't want to use the extra math there (I imagine it's marginally slower in Fusion to process the vector movement events rather than running them through the Clickteam Movement Controller), you can increase the size of the target boxes, auto-correct the trajectory of the missiles, or use your current movement events while removing the hit boxes entirely (my preference regardless), but to do this with integers, you'll need to to use Range(), which will basically accomplish the same goal as enlarging the target boxes.

    I didn't care much about using the Clickteam Movement Controller method so I know there's something up with the Range() function I put in there on #4 but I honestly don't care about why the objects aren't always getting destroyed. As a comparison, though, watch the difference between Active and Active 3 as they travel along the line. Active 3 follows it 100%, whereas Active will continue deviating from it the further out it gets unless it's following sharp angles.

  • Using objDistance, you could do this with the Clickteam Movement Controller:

    Code
    -Missile.objDistance < 99999
    +Set Missile.objDistance to AdvDistance( "Advanced Direction Object", X( "Missile" ), Y( "Missile" ), targetX( "Missile" ), targetY( "Missile" ) )
    
    
    -Missile.objDistance < movementSpeed (this would probably be 10 unless your missile's moving particularly fast)
    +Create missile explosion
    +Set Missile.objDistance to 99999

    All you'd have to do there is store targetX and targetY, which are going to be XMouse and YMouse, when you create the missile. (You'd have to use a method like this even with the vector movement I posted unless you're going to either use target hit boxes, the Move Safely object, or loops to move the object; otherwise, it's possible for the object to go past its target before Fusion catches it.)

  • Thanks Snail,

    First, thanks for the example, that REALLY helps me understand. Several red flags come up when I look at your example and your thoughts:

    1.) I'm a bit amazed at the amount of code differences. It takes ALOT more of the math / code to get the Active3 to follow the correct path than Active (which was similar to how I did it). This makes me a bit uneasy, worrying that this is my Achilles heal. That unless I can become a trigonometry professor, I may not have a 100% solution and be stuck with a 60% solution like I have now... I'm not sure how to fix that other than just posting questions and hoping someone can answer when this happens in the future to other games I make. :(

    2.) I only used the Click Team Controller because I found highly recommended in another post. But your solution is using another / different extension manager. There seems to be thousands of them, so two questions. One, how do I know if one is gonna work for me, just try each until one works? Second, looking at your code, you have several methods such as VEC_DIR(), AdvDirection(), etc.. Without loading the extension and then right clicking on it to see every available method, is there a help file or some other document that tells you what methods come with the extension so I can know whether or not a method (such as AdvDirection()) exists and will even be worth trying? Hope that makes sense.

    Other than that, I'm gonna try some of your solutions tonight and see which one is the easiest that I can still understand. I want to be able to change stuff if needed, and I can't do that if I don't know whats going on, lol.

    Thanks!

    wiggy

  • Almost done reading all your code, and I'm understanding it pretty good. It makes sense, just a few questions.

    How did you create baseSpeed, targetAngle, and other new alterable values in your list? I did a quick search, no titles for "How to create new alterable values".
    Second, I noticed you have 3 lines with always. Would it not be cleaner / easier to have 3 events listed on one "always" condition, rather than three always conditions for each event separately?

    Just trying to learn and understand, thanks!

    Wiggy

  • Hi Wiggy,

    I'm glad that at least helped you consider more options. :)

    The Clickteam Movement Controller's definitely the easiest way to do this but you won't get the precision from it over longer distances because it doesn't use decimal points for its angles. There's certainly nothing wrong with going this route but you'll have to a find a way to compensate for that lack of precision (either making the target boxes larger or by adjusting each missile's trajectory). Yves could probably comment on the reason why the Clickteam extensions and internal functions use only integers instead of floats (decimal points), but I don't know the reason myself. It isn't a technical limitation since other extensions are perfectly happy using floats...

    Next, doing it yourself: That example I posted (you can find other 360-degree movement/shooting examples through the Search box here or in Google) is all you need for your missiles, so no editing is necessary. I believe I uploaded a video on YouTube for creating new variables, but I'll run through it here:

    Click your object
    In the Properties pane, click the "A-Z" icon (variables)
    Under Alterable Values, click "New"
    Double-click "Alterable Value A" and then rename it to whatever you like

    Variables are completely arbitrary, so you can name them whatever you like. That is, they don't do anything more or less than what exactly you tell them to do. baseSpeed I created because that's what I'm using for the speed parameter in those two expressions. targetAngle is what I'm using for the angle parameter, too. The reason I can't call them "speed" and "angle" is that those two names are reserved in Fusion because it uses them for some internal functions ("speed" for the movement functions and "angle" for the Scale/Angle functions).

    It's up to you if you want to consolidate your events like Always. For processor-intensive operations, you should always consolidate the conditions. For "Always" or "On loop," it makes a negligible amount of overhead to the runtime, so I always lean toward legibility in those cases. If I have two Always event for entirely unrelated methods, I'm never going to consolidate them because it'd make changing those methods much more difficult with no added benefit.

    In the case of the example,
    the first Always sets the angle of the line so you can see what the actual angle is that objects should follow;
    The second Always sets the counter to the current angle of the Clickteam Movement Controller to show that it's an integer (no decimal point);
    (if I thought about it, I would've added a second counter that shows the exact angle.)
    The third Always moves the missile and updates its distance from the target point.

    My lack of creativity is why I'm using the distance variable; if I had to do this myself, I wouldn't be using that because that's a fairly processor-heavy operation but it simplifies the event for whether the missile's hit the target or not. The Move Safely extension will remove the need for that and give you pixel-perfect collisions with considerably less overhead than you'd have with loops or the the variable I'm using there.

    Comparing the Clickteam Movement Controller method and this one, I'm not sure that this really does much more than the controller one does. The only extra event is the Always event that positions the object. Yes, you have to set some default variables when the object gets created, but you have to do that with the Clickteam Movement Controller, too.

    What's great about Fusion (as well as other engines like this) is that it allows you to take all sorts of different approaches to situations like this. So if you like taking more programming-like solutions, my methods are much more geared in that direction, but if you prefer more of the "click this button and then DONE!" approach, there are lots of ways of doing things like that but I generally avoid those.

  • Hey Snail,

    Considering more options for sure, thanks for that! :)

    I think the problem is you don't know what you don't know, haha. I had no idea that Clickteam Movement Controller was using integers. I just assumed since this was my first small game, that the problem was my knowledge and I needed to figure it out. I'm not sure I would have ever put together the "why the missile sometimes misses" with "I'll test the angles to see if they are down to the decimal for improved accuracy". The Clickteam Movement Controller did have a help file that I read through, and for the Vector section it stated:

    Quote

    Direction: The direction (or angle) the object will initially move in, value is in degrees.

    It should probably state "...value is in whole integer degrees". Oh well, lessons learned.

    Alterable Variables...

    Quote

    Click your object
    In the Properties pane, click the "A-Z" icon (variables)
    Under Alterable Values, click "New"
    Double-click "Alterable Value A" and then rename it to whatever you like

    Yeah, I basically right clicked to add an event (under the missile object), went down to Alterable Values, saw "Set", "Add to", "Subtract From", "Spread Value"... and started thinking, umm...how did he create new ones in his list? It never occurred to me they could be added / set on the properties of the item, otherwise, why have A-Z available right? lol. Oh well, another lesson learned.

    Thanks for sharing the reasoning on the distance variable. I thought to myself...why do that, isn't that intensive mathematically / cpu wise? I'll have to search around for the Move Safely extension examples to see how to implement that one. I did try your example and changed mine up a bit. It works pretty good, it still misses a couple times (not nearly as often as before), but I think its because the missile comes out always pointing at 3 oclock, not like before where it was in direction of turret. I'll have to see what I'm missing because I assumed (incorrectly obviously) that the targetAngle variable was being used to store the angle at which the missile needed to leave the turret at. Apparently its not, or it is and I just implemented it wrong. Its not visible in your example because both Active and Active3 are just small squares.

    As far as methods, I'm in to what is "accurate". So if it takes 10 lines of code / events / conditions to make it hit the X, I'm gonna do it. If its a simple solution, I won't make it harder either though, lol :D

    Thanks again for your thoughts! I'm gonna take a look at the Move Safely and also tinker around and see why the missile's angle is still stuck.

  • It's because I didn't change the actual angle of the object. That's done through the action box when you right-click it and then go to Scale/Angle > Set Angle. I can put a more finished example together for you in a little bit. :) Obviously the easiest way for you to do this now is to just enlarge the target boxes or use an invisible sensor on top of the current target boxes. That way you won't have to worry about changing your movement events and things.

  • If I were to make a Missile Command game, this is close to how I'd do it. This should get you back to the same place you were at with the Clickteam Movement Controller. All of your other events should integrate nicely into this. :)

    I didn't write this out in the example because it's usually implicit: The reason I'm running the for loop on #23 is because of a situation where multiple missiles could reach their targets at the exact same time. Without this loop, only one target would get destroyed. There's no performance impact of running this loop, first, because it's necessary, and second, because it's scoped to only the missiles that are actually reaching their targets at the same time (almost always a single missile), meaning it's the equivalent of running a fast loop to destroy one missile. Everything else is scoped so that you don't need (nor want!) any additional for loops.

    #20: I don't know if it's faster to use two conditions (objRange => 0 AND objRange <= 3) than it is to use one Range() condition (objDistance = Range(objDistance("Missile"), 0, 3)), but for this, I'm assuming objRange => 0 is going to return false more often than it's going to return true, so the runtime wouldn't need to check the second condition in those cases.

  • Thanks Snail,

    I went as far as I could without looking at yours haha. I increased my aim point and set the angle, still misses sometimes. So I'm putting in the objDistance as well.

    Thanks again. I think yours is interesting, I had never known how to use loops, but its fairly simple. Looks like a GOTO type of function to keep redundancy down. I like the checking off screen by using negative pixels, never thought of that either. I'm tweaking mine to be a bit more efficient based on some of the things I'm learning, so many thanks.

    As far as the speed of the conditions, I would assume they are about the same. If I remember correctly, I think it evaluates all conditions from outside parenthesis towards the center, testing the AND last. However, since the objDistance is a value, it would return faster to simply compare numerically rather than using the Range() condition which it would have to look that function up and read / execute it. In my game, probably a few milliseconds difference, but over time and bigger the game, the more it would differ for sure.

    I am a bit confused though on your usage of the ParentId / fixed call... I see what you're doing, but I don't know how those functions / values are being tracked / called / executed. The other value that seems difficult to understand is the alterable one "xPoint" / "yPoint". I kinda get what they are for, but they are being used in the AdvDistance functions where I wasn't expecting them... so seeing how they are initialized and used doesn't exactly follow.

    Any help there is appreciated as this all helps me make the collisions more accurate!!

  • Lol... figures...

    After pretty much rewriting a lot of the conditions to implement some of the things I learned I have a bug I can't figure out...
    Its because of the parentID / fixed relationship I'm pretty sure. So when the collision, or better yet, when the missile is less than 4 pixels (I rewrote it to detect if its close, then to go to the remove target loop instead of doing the collision detection like it was), now all the missiles go to the destroy instead of just the one that is close to its aimpoint.

    This is where my lack of understanding of that parentID / fixed values hurts because I'm not able to troubleshoot it since I don't know how it works :(

    I'm assuming the math is working since the explosion animation starts at the right spot and the missile and aimpoint are destroyed. However, fusion must've assigned all the missiles the same parentID, or why else destroy all the missiles and aim points on the screen instead of just the current missile that is close to its aimpoint.

    Just not sure how to fix, lol...help :)

    Please login to see this link.

    Edited once, last by wiggy: Forgot link (August 21, 2015 at 10:22 AM).

  • objDistance has no effect on accuracy here, so I suspect that isn't the reason the missile's missing its target. objDistance is just the calculated distance from each missile to its target; when that distance is lower than or equal to its baseSpeed, it's reached its target. The reason it has to be at least its baseSpeed is that if it's moving 10 pixels per frame and you're only only checking within 5 pixels, the missile could be 6 pixels from it on one side, move 10 pixels the next frame, and then it'd be 6 pixels from it on the other side.

    parentID was originally missileID but I renamed it because it's more general than that. The idea is that the missile is the owner of all of these related objects (the target, smoke effects, explosion effects, etc.), so you want to store its fixed value in each object it creates if that object is going to need to know its ID. In this case, the target needs to know who created it so that only its owner can destroy it; using collisions instead, you could end up in a situation where one missile destroys two targets at the same time, which you'd have to account for and solve. This removes that situation entirely by saying that the missile knows exactly what its target is and will only ever affect objects that are directly linked to it.

    The target itself never does anything; rather, it's there for visual feedback to the player so he or she can see where the missile's target is. When the missile reaches its target (xPoint, yPoint), it creates the explosion and notifies all the target objects that the missile's reached its target. Whichever target object matches that missile's fixed value (each target object's parentID will always equal exactly one missile's fixed value), remove it.

    The only math involved is the 360-degree movement for the missiles, which is already set up. The parentID is assigned to each target when you fire a missile. When a missile reaches its target (xPoint, yPoint), you have to loop through all missiles in order to find each one's corresponding target object (on each Missile AND parentID("Target") == fixed("Missile") >> destroy Target).

    I don't think you uploaded the newest version of your game. :) Can you reupload it and then I'll take a look at it to see what might be causing that?

  • Oops, it was an older version, haha. Apologies. Here it is. Been looking at it for a while, still cant figure it out, pretty strange.

    Please login to see this link.

    Thanks for the explanations, especially on the parentID. Still a little confusing only because I haven't used it enough, so it may take some time. Its like describing to someone an automobile who lives in the 1500's... they would eventually understand what your saying but not really get it until they see it more and drive it many times.

    This comment was interesting:

    Quote

    When a missile reaches its target (xPoint, yPoint), you have to loop through all missiles in order to find each one's corresponding target object (on each Missile AND parentID("Target") == fixed("Missile") >> destroy Target).

    It seems to me that is more difficult / cpu intensive if I have 20-30 missiles, rather than just detecting if a missile collides with a target... I guess what I'm getting at is that I see it more of a unnecessary complexity, and probably will for a while until I use it more. I'll continue to use it so I can understand it more, but for now that's my view :D

  • No. The unnecessary complexity is using hitboxes and collisions, both of which will reduce performance significantly more than a single loop will. :D Remember, if you have 100 missiles on the screen and only one reaches its target, the loop will run only one time. If five of those missiles reach their targets at the same time, the loop'll run 5 times.

    The reason Fusion's removing all of the target points is because you have "Destroy" still on #30. Deleting that action fixes the remaining issues you're having here.

  • Ahhh... I see. I already had the destroy on the loop "remove target", and the condition for going to that loop was met when one of the missiles was within 3 pixels of the aim point... So in essence, I was destroying the aim point on line 30, then it went to remove target function (line 32), where it was removing the aimpoint and missile, causing the unwanted behavior. Sweet, I think I'm understanding the loops better, I'll keep implementing them whenever I see repetitive calls, thanks for the tip.

    I see what you are saying on the cpu usage and complexity, so thanks for that additional explanation. Here is why I thought it was about the same, food for thought. So see what you think (for collisions)

    --Collision Detection method (my original way)
    Frame 1
    ...
    CPU tests for all missile / aim point collisions (i.e. 10 missiles 10 aim points)
    ...

    Frame 2
    ...
    CPU tests for all missile / aim point collisions (i.e. 20 missiles 20 aim points)
    ...


    ---Missile Range Detection method (your cooler / cpu saving way)
    Frame 1
    ...
    CPU creates objDistance variable, stores initial distance from aim point in variable
    CPU re-calculates missile range variable objDistance in pixels as it moves
    CPU test all missiles where objDistance <= 3 (i.e. 4 missiles 4 aim points)
    ...

    Frame 2
    ...
    CPU creates objDistance variable, stores initial distance from aim point in variable
    CPU re-calculates missile range variable objDistance in pixels as it moves
    CPU test all missiles where objDistance <= 3 (i.e. 8 missiles 8 aim points)
    ...


    That's what I thought about in my head when I say its more complex lol. To me the second way IS using less CPU, but more complex in coding / debugging... at least it was to me at first :) I mean, I get it now, and it makes sense, I just never thought of it like that. It seemed simpler to just say "hey if any collisions occur", rather than "create a variable to track distance between the objects", "recalculate that distance every frame", "destroy objects when distance <=3". I like cool stuff like that though, where you basically make your own "collision detection" method and are able to squeeze out more CPU power!! :D

    So thanks a bunch bro for the explanations! You've definitely given me ALOT more tools / methods to code my games more efficiently!

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!