How to end game (race) when actor crosses finish line?

britto24britto24 Member Posts: 35
edited May 2012 in Working with GS (Mac)
Hey everyone!

I am creating a very simple racing game to get my feet wet in GS. I have 2 cars (one computer player and one real person player) and a timer that displays the time counting up as the race goes on.

So far everything is working. When the race starts, the timer counts up and the cars move towards the finish line.

I have a few problems though...

1. My display text shows the race time great, but when the car crosses the finish line the time keeps going. How do I stop the time and just display the final time when the car crosses the finish line?

2. When the car actor crosses the finish line, it's supposed to spawn the youWin actor. However, right now when the car crosses the finish line nothing happens. Here's the rule for the car:

Rule: when, Actor: overlaps or collides with finishLine
-spawn actor youWin

But if I wrap x for the scene, it will spawn the youWin actor once the car goes back to the start (when it wraps back around). But neither one of these is right. I must be missing a small detail...Do I need to mess with the physics or motion on the finish line or car? How do I get the game to end when the car crosses the finish line?

Here's what I created so far:

gameAttribute: raceTime

CAR ACTOR:

selfAttribute: startTime
selfAttribute: endTime

Attribute: game.raceTime To: 0

Rule: when race begins:
-changeAttribute: self.startTime To: self.Time

Rule: when
Event: overlaps or collides with finishLine
-changeAttribute: self.endTime To: self.Time
-changeAttribute: game.raceTime To: self.endTime-self.startTime

DISPLAY TIME ACTOR:

unlocked …

Rule: when
Attribute: scene.Background.car.startTime > 0
-displayText … Text: scene.Background.car.Time-scene.Background.car.startTime

Any suggestions on how to stop the time and end the race when the car crosses the finish line?

Sooo, that was long! Thanks for reading and thanks in advance for any help!

Best Answer

  • tatiangtatiang Posts: 11,949
    Accepted Answer
    You've done a great job of calculating the race duration and converting it to game.raceTime. But then on your display time actor, you're telling it to subtract the startTime from actor.time, which is a constantly changing value that can't be stopped. Since you've already done the leg work to determine game.raceTime, that's what you should be displaying.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

Answers

  • britto24britto24 Member Posts: 35
    @tatiang

    Thanks!! So the display time actor should say:

    Rule: when
    Attribute: scene.Background.car.startTime > 0
    -displayText … Text: game.raceTime ??

    Any ideas for why the car actor is not triggering the spawn attribute to display the youWin actor when it collides with the finishLine actor?

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    Yes, that's the correct rule.

    Sometimes I've had a problem with collision detection when one actor is moving very fast. I'm not sure how fast your car actors are moving, but it could be that the car is "crossing" the finish line but actually not ever touching it. So for example, if the finish line is at x=300 and the finish line actor is 10 wide, the car would have to be at x=290 to 310 to trigger it. But if the car is moving very quickly, it might jump from 285 to 315 and skip the finish actor altogether.

    Not sure if that's causing the problem, but it's what came to mind. To test for that, you can do a Timer set to every 0 seconds with Log Debugging Statement self.position.x (or y) and then watch the debugger window to see where the car actually is when it "crosses" the finish line.

    What happens if you change the rule from a collision rule to a When attribute self.position.x (or y) >= [the actual x value of the finish line]? Again, I'm not sure what your race track looks like... if it loops around, that might not work, but I'm thinking just to test things to see what's causing the problem.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • britto24britto24 Member Posts: 35
    Thanks!!! The cars are not moving that fast, so I wouldn't think that would be the problem...but maybe, I'll have to check it out!

    It's just a straight track, so I will definitely try to change the rule. That sounds more promising anyway!

    I'm not in front of GS right now, but how would I set up the raceTime displayed text actor to stop after the car crosses the finish line? Now, the car actor has:

    Rule: when
    Event: overlaps or collides with finishLine (I will change this to when attribute self.position.x >= the actual x value of the finish line)
    -changeAttribute: self.endTime To: self.Time
    -changeAttribute: game.raceTime To: self.endTime-self.startTime
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    I wasn't suggesting the self.position.x>= as a solution, but rather as a way of debugging things. The way you have your collide rule set to change self.endTime to self.Time should be what you need to stop the raceTime value. I think it's just not working because the collision isn't happening for some reason.

    I can also take a look at your project file if you want to send me a download link.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • britto24britto24 Member Posts: 35
    Oh ok, gotcha.

    So far I replaced the display time actor...

    Rule: when
    Attribute: scene.Background.car.startTime > 0
    -displayText … Text: scene.Background.car.Time-scene.Background.car.startTime

    WITH

    Rule: when
    Attribute: scene.Background.car.startTime > 0
    -displayText … Text: game.raceTime

    But the time just displays 0 the whole time.

    OK...soooo...after messing with it some more...everything is working how I want it, but the time still does not stop when car crosses finish line...but the youWin actor will spawn when the car crosses finish line...Any other thoughts? If not, I'll try to send you the file in a few minutes! So close...but soo far, lol.

    Thanks for all your help! I appreciate it tons!
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    Sounds like you're close, but yeah if you'd like, send me the file and I can see what's not working.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    edited May 2012
    Here, try this... for the rule you mentioned (below), add a behavior to the Otherwise section that says Constrain Attribute game.raceTime to self.Time-self.startTime.

    Rule: when
    Event: overlaps or collides with finishLine
    -changeAttribute: self.endTime To: self.Time
    -changeAttribute: game.raceTime To: self.endTime-self.startTime

    You may need to set this up a little differently because if the car collides with the finishLine and then does not collide with it (e.g. passes it), it may trigger the Constrain Attribute again. Generally, I would have a boolean such as game.RaceOver that gets set to true when the collision happens, and then have your rule for changing game.endTime and game.raceTime inside of a When attribute game.RaceOver is true rule.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • britto24britto24 Member Posts: 35
    Hmm, I don't know...I have something weird and not right.

    How can I send it to you?
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    @britto24 Compress it as a zip file and then upload it to a service such as dropbox or mediafire. Then post the download link here or send it to me in a private message (click the Inbox link at the top of the forums window).

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • britto24britto24 Member Posts: 35
    Thanks! :)

    http://dl.dropbox.com/u/13117883/Races_03.zip

    Just some quick instructions. After the yellow block disappears, you will have to click on the taxi to make it go forward. (Also note that these are temporary cars/place holders)

    If you could figure out how to stop the time...you are a genius!!!
  • britto24britto24 Member Posts: 35
    Eventually, I will want the time to stop and then be displayed under the you win. It would be like a high score in the level, so if you play it again and beat your old time, the new time would appear. But if you don't beat your time, then the old time appears under the you win as the high score as well as the time you just received. If that made any sense! Anyway, that's probably way over my head at this point, but hopefully in the future I can get that to work. If you have any ideas for that, I'm all ears. :D Thanks again!!!
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    In your raceTime actor, you are using taxiPlayer.time-taxiPlayer.startTime. Because the built-in timer (self.time) never stops, your display just keeps going after the race is over.

    Probably the easiest way to fix this at this point is to add a game.raceOver boolean and then on your raceTime actor add a rule (in the Otherwise section) to use game.raceTime in place of taxiPlayer.time-taxiPlayer.startTime. This will work because when the race is over, game.raceTime has the correct value to display.

    Here's the file with those changes: https://www.dropbox.com/s/jhlwf4gtimtoguj/Races_03 fix.zip

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • britto24britto24 Member Posts: 35
    @tatiang Thank you!!! You are a genius!
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    edited May 2012
    @tatiang Thank you!!! You are a genius!
    I wouldn't go that far, but I'm glad I could help! :)

    The nice thing about using a boolean for the end of the race (or the end of a significant event in any game) is that other actors can use that to trigger other actions. So if you wanted your computer-controlled car to stop when the race is over, it can have a rule When attribute game.raceOver is true Change Velocity to 0, for example.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • britto24britto24 Member Posts: 35
    Great, that's perfect! I probably need to do that. :) I'm liking these booleans, lol. Thanks again!
  • britto24britto24 Member Posts: 35
    Eventually, I will want the time to stop and then be displayed under the you win. It would be like a high score in the level, so if you play it again and beat your old time, the new time would appear. But if you don't beat your time, then the old time appears under the you win as the high score as well as the time you just received. If that made any sense! Anyway, that's probably way over my head at this point, but hopefully in the future I can get that to work. If you have any ideas for that, I'm all ears. :D Thanks again!!!
    So final question, and I'll let your mind rest ;)

    Any thoughts on this?
  • britto24britto24 Member Posts: 35
    I watched @tshirtbooth's videos on high scores...amazing! But, I see two problems that he doesn't have (of course!)

    1. When I play the scene for the first time, everything works, but when I replay the scene, the raceTime actor does not show up anymore. Thoughts?

    2. So the raceTime actor will display the time as 00:36:11 but the bestTime actor will round down the time and displays the best time as 00:36:00. The milliseconds are always zero for the best time. Any ideas?

    Woo, I'm slowly getting there! Thank you!!!
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    1. It depends how you are "replaying" the scene. If you use Reset Game or Reset Scene, those have different effects on actors. It's a good idea to have another boolean (yep!) called game.Reset and whenever your race ends or the player clicks a button, you can set game.Reset to true. In each actor that needs to reset somehow, have a rule When game.Reset is true [move to original location, set self.____ to whatever, etc.].

    2. I assume this is happening because of a "floor" function in your expression. Check both expressions (raceTime and bestTime) to make sure they either both have a "floor" function or both don't have a "floor" function. Floor displays the value rounded down (e.g. floor(3.2)=3 and floor(3.9)=3).

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • britto24britto24 Member Posts: 35
    @tatiang Thank you! I will try creating another attribute called game.Reset. That sounds like it should work how I need it to. But I do want it to keep/save the bestTime. Right now, each time you play the game, it changes the bestTime to the raceTime because each time I play the bestTime is zero. The bestTime always = the raceTime....but I have a rule that says if raceTime is greater than bestTime, then change attribute bestTime to raceTime. But I obviously need to add a save attribute, but how would that rule go? Save attribute bestTime key bestTime?

    2. Yep, both raceTime and bestTime have floor expressions. But only bestTime seems to be rounding like that...
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    @britto24 Yep, you save the attribute to a key of the same name (for ease of use) and then make sure to load that attribute (and any others you plan on saving) at the start of the game or start of the scene.

    If you want to send me a link to the file again, I can check out your expressions.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • britto24britto24 Member Posts: 35
    @tatiang Thanks! I sent a message in your inbox...I think, lol.
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    Yes, I got your message. You're welcome!

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

Sign In or Register to comment.