How to calculate number of rotations (faster than Every Tick)

0 favourites
  • 12 posts
From the Asset Store
Sheeky's Power-ups Sounds
$4.20 USD
30% off
75 power-up sound effects; bonus and notification sounds, fanfares, harp glissandi, stabs, clock ticks, etc.
  • Hi,

    I've made a "Wheel of Fourtune" style interface - I have a wheel on screen you can rotate and spin by clicking/dragging or "swiping" and I programmed it to decelerate to a stop.

    However, I would like it to rotate at least 3 full rotations before it begins to decelerate and I am having trouble working this out...

    I am using the "rotate" behavior to make the wheel rotate and to count rotations, I attempted to compare the wheel angle (If more than 359, rotationCount = rotationCount + 1) in order to count the rotations on Every Tick, figuring that every time the wheel hits 360 degrees the counter would advance.

    In theory, this works (at very slow speeds). The issue is that if the wheel spins too fast (greater than 60deg/sec), the Every Tick is missing the point at which the wheel is at 360degrees and so the counter never advances (or at least advances only sporadically when the stars align). This is obviously related to the speed of "Every Tick."

    I feel like I am missing something obvious, but is there a way to run this check faster than "Every Tick" or is there a better way to count rotations that someone can suggest?

    I tried putting the wheel position comparison code outside of Every Tick, but the result is the same. I also know I have run loops before that iterate the entire loop, more or less, instantaneously so I know code can be executed faster, It seems like I am just missing something obvious here.

    Thank you for the help!

    J

  • One way would be to calculate how long three rotations would take from the speed. There’s a general formula rate*time=distance which you can think of as angularSpeed*time=numberOfDegrees. Just solve for time, time=numberOfDegrees/anglulareSpeed.

    Anyways, here’s a possible way to utilize that. It just takes two variables: speed and deceleration.

    On click
    — set speed to 500
    — set deceleration to 0
    — wait 3*360/speed seconds
    — set deceleration to 100
    
    Every tick
    — set speed to max(0, speed-deceleration*dt)
    — wheel: rotate speed*dt degrees clockwise

    You can set speed to whatever you’re doing now to set the speed.

  • Can't you just give it more time by using greater than 355 degrees instead of 359, and add trigger once while true, so it does not get triggered more than once while between 355 and 360

  • Can't you just give it more time by using greater than 355 degrees instead of 359, and add trigger once while true, so it does not get triggered more than once while between 355 and 360

    A wheel spinning at just 1 revolution per second will progress 6 degrees every frame, assuming 60 fps. That can still pass the window between 355 and 360, and 1 rps is not particularly fast.

    Keeping track of and comparing the total rotations by summing up angular momentum over time is the way to go.

  • Another way to measure the amount the wheel rotated is to use a signed angle difference. It’s like the anglediff(a,b) expression but is negative if counter clockwise.

    angle(0,0,cos(b-a),sin(b-a))

    Will work as long as the rotation is less than 180 in a frame. You could also just use anglediff in this case I suppose since the wheel is rotating only one way.

    TotalRotation=0
    PrevAngle=0
    
    Every tick
    — add angle(0,0,cos(wheel.angle-prevAngle),sin(wheel.angle-prevAngle)) to totalRotation
    — set prevAngle to wheel.angle
  • R0J0hound - Thank you for this suggestion. This could definitely work. I am already setting a max speed for the wheel. (I've been experimenting, but a max speed of 450 deg/s seems to look OK. Any faster and the wheel is just too fast that doesn't look realistic.)

    So based on this, my max speed should take about 2.4s to begin deceleration.

    Calculating the time dynamically when the wheel starts rotating and then comparing to the elapsed time on each tick should get me a good solution - I will give this a go shortly.

    Thank you for the suggestion.

    J

  • Can't you just give it more time by using greater than 355 degrees instead of 359, and add trigger once while true, so it does not get triggered more than once while between 355 and 360

    BadMario - Thanks for the suggestion. I actually did try this as a possible solution and also to prove to myself why my idea of using >359 wasn't working...

    I kept lowering the number (358, 355, 340, etc) just to see what would happen and I also slowed down the max speed. When the wheel is spinning very fast, it has the same issue as using 359 - the wheel is just blowing through the angles so fast that Every Tick was missing them. So as oosyrag pointed out, the wheel, even at 1 RPM just goes too fast.

    When I slowed the wheel down, the rotation count just shot up 1-2-3-4... as the wheel passed through 356,357,358, etc. because the condition "wheel.angle > 355" was being met repeatedly. This wasn't useful for my game, but it did prove to me that the "code was working," the wheel had just been moving too fast to catch it at the right position.

  • Can't you just give it more time by using greater than 355 degrees instead of 359, and add trigger once while true, so it does not get triggered more than once while between 355 and 360

    Sorry BadMario, I forgot to mention the "once while true" part... I don't think I realized a "once while true" condition existed. In theory that should "debounce" the repetitive counts on Every Tick, but I would still have to make the gap very large to catch the wheel position at higher speeds that it would probably affect the wheel at slower speeds. (>350 might still be too short of a gap, but >300 on a slow spin could still find a wheel that hasn't reached 360 yet when the next Tick comes around). I could probably finesse the numbers and find a close-enough spot that works for most spins, but I would feel more comfortable if I could control it more accurately.

    J

  • Another way to measure the amount the wheel rotated is to use a signed angle difference. It’s like the anglediff(a,b) expression but is negative if counter clockwise.

    angle(0,0,cos(b-a),sin(b-a))

    Will work as long as the rotation is less than 180 in a frame. You could also just use anglediff in this case I suppose since the wheel is rotating only one way.

    TotalRotation=0
    PrevAngle=0
    
    Every tick
    — add angle(0,0,cos(wheel.angle-prevAngle),sin(wheel.angle-prevAngle)) to totalRotation
    — set prevAngle to wheel.angle

    R0J0hound - I think I like your time-based idea better, but could you tell me if I am understanding what you're suggesting here...

    Are you essentially saying that I'd keep adding the changes in angle to itself and take note when the number increases a multiple of 360?

    (I don't mean to make myself sound dumb, just trying to simplify the concept).

    Thanks, again,

    J

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • See Rojohound's first post.

    Multiply the number of degrees per second (speed) by the number of seconds since starting. If the number is over 1080 (360*3), then you have completed at least three rotations.

  • So I went with time-based as per R0J0hound initial suggestion... works great!

    I'm getting the initial speed value from calculating the time from the swipe speed...

    I have a condition:

    if speed > maxWheelSpeed: speed = maxWheelSpeed

    Then I calculate a variable:

    timeTillDecel = 360 * 3 / speed

    And I timestamp when the wheel starts:

    wheelStartTime = time

    Then on every tick I am checking elapsed time:

    if time - wheelStartTime > timeTillDecel:

    If the condition is met, I keep decrementing my wheel rotation speed.

    This is working like a charm. Thank you for helping me with this!

    J

  • Yeah, that’s correct. You’d just check to see if totalRotation is a multiple of 360.

    Edit:

    Cool. Glad the other suggestion was useful.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)