Search code examples
pythonprocessing

How do i make my wheel of fortune spin slow in Processing (with python)


I have a Project for school in which i have to make applications with python in processing 3.5.4, now after many attempts i have made a wheel of fortune that can spin and stop after mouseclicking the middle button. I basically want to make my wheel of fortune spin slower when the 'stop' button is pressed and eventually come to a halt, i have tried using a variable like 'loop_number' that gets checked and if it is a low loop number the velocity of the wheel goes down, but this doesnt seem to work with me since processing is built into a big while loop that 'refreshes' all your variables at the start of the loop again. anyway here's my code (i know it's not perfect i'm still learning).

import math
from time import sleep

totalWidth = 1000
totalHeight = 1000
circleX = totalWidth // 2
circleY = totalHeight // 2
circleDist = 0  # this will be defined outside of the functions so we can use this variable globally
outerCircleRadius = (circleX + circleY) // 2 - 60
innerCircleRadius = 75
line_points = {}  # used to store the values of all the line points
turningWheel = False  # used to determine if the wheel has to be turning or not
all_chances = ['Je vind 25 FashionPoints op straat!', 'Je verliest 30 FashionPoints!', 'Je wint een Ov-Kaart van 3 stations!',
               'Draai het geluksrad nogmaals!', 'Je verliest je duurste schoen!', 'Je wint 20 Fashionpoints!', 
               'Je goedkoopste shirt word beroofd!', '    Betaal een boete van 20 FashionPoints', 'Je wint 1x erg dure kleding']
degree_points = [0, 360]  # this will be used to position the lines along the outside of the circle
velocity = [0, 0]  # this will be used to determine how fast the circle turns

def setup():
    size(totalWidth, totalHeight)
    ellipseMode(RADIUS) # the ellipses get made through their radiuses and not x and y
    
    
def draw():
    global number
    global circleDist
    global velocity
    global degree_points
    
    background(255, 255, 255)
    strokeWeight(2)
    
    circleDist = dist(mouseX, mouseY, circleX, circleY)  # the distance of the middle to the mouse, this will be used later with the inner circle
    
    # the black line of the outer circle
    fill(0, 0, 0)
    ellipse(circleX, circleY,  # the middle of the created circle
            outerCircleRadius + 20, outerCircleRadius + 20)
    
    # outer circle; TODO: change the color
    fill(255, 255, 255)
    ellipse(circleX, circleY,  # the middle of the created circle
            outerCircleRadius, outerCircleRadius)
    
    # IMPORTANT: this section covers drawing in the circle with the triangles(lines) and chances
    # the cosin and sin variable are here to help with finding the right coordinates
    # along the line of the circle
    if turningWheel:
        degree_points[0] += velocity[0]
        degree_points[1] += velocity[1]
        
    for index, angle in enumerate(range(degree_points[0], degree_points[1], 40)):
        # the first two coordinates will help to calculate how far the point is from the center of the circle
        x1 = outerCircleRadius * cos(angle * math.pi / 180)
        y1 = outerCircleRadius * sin(angle * math.pi / 180)
        x2 = circleX + x1
        y2 = circleY + y1

        # line function works like this: line(beginX, beginY, endX, endY)
        textAlign(CENTER, LEFT)
        line(circleX, circleY, x2, y2)
        line_points.setdefault('line' + str(index), [x2, y2])  # adding the line point to a dictionary
        # getting the text in the right place
        
        # this section covers centering the chance text in the middle of each triangle
        textSize(16)
        middle_x = circleX + outerCircleRadius * cos((angle + 20) * math.pi / 180)
        middle_y = circleY + outerCircleRadius * sin((angle + 20) * math.pi / 180)
        textX = circleX + ((middle_x - circleX) / 2)
        textY = circleY + ((middle_y - circleY) / 2)
        pushMatrix()  # opens a change for the matrix (recentering the matrix for the rotation)
        translate(textX, textY)  # sets the new center for rotation
        fill(255, 0, 0)
        rotate((angle + 20) * math.pi / 180)
        text(all_chances[index], 0, 0)
        popMatrix()  # closes the change for the matrix
    
    # inner circle; TODO: this has to be filled in last
    # otherwise the chances will overlap this circle
    fill(255, 0, 0)
    ellipse(circleX, circleY, innerCircleRadius, innerCircleRadius)
    
    # text inside the inner circle
    textSize(35)
    fill(255, 255, 255)
    textAlign(CENTER, CENTER)
    if turningWheel:
        text('STOP', circleX, circleY)
    else:
        text('START', circleX, circleY)
    
    # triangle on the side of the circle; this has to be filled in last,
    # after all the chances have been filled in, otherwise this gets overlapped, 
    fill(255, 0, 0)
    triangle(totalWidth - 115, totalHeight // 2,  # tip of the triangle pointing towards the middle
        totalWidth - 10, totalHeight // 2 + 50,  # uppermost corner of the triangle
        totalWidth - 10, totalHeight // 2 - 50)  # lowermost corner of the triangle
    
def mousePressed():
    global turningWheel
    global degree_points
    global velocity

    if circleDist < innerCircleRadius:
        turningWheel = not turningWheel

    if turningWheel:
        velocity = [4, 4]

Solution

  • Se if this code makes sense for you, I'm using a boolean flag called stop, if you click with the mouse middle button (or if you press the spacebar) it will become True and that will trigger a reduction of %5 of angular_vel every frame (like angular_vel = angular_vel * 0.95) until it is close to zero (angular_vel < 0.1) and then it will be set to 0 and the stop flag will be set back to False.

    stop = False
    angular_vel = 3  # degrees per frame
    angle = 0  # degrees
    
    def setup():
        size(400, 400)
        frameRate(20) # slower frame rate
        
    def draw():
        global angle, angular_vel, stop
        background(128)
        fill(255)
        circle(200, 200, 400)
        translate(200, 200)
        rotate(radians(angle))
        if angular_vel == 0:
            fill(255, 0, 0)
        else:
            fill(0)
        circle(180, 0, 20)
        
        angle += angular_vel
        if stop:
            angular_vel *= 0.95
        if angular_vel < 0.1:
            stop = False
            angular_vel = 0
    
    def mousePressed():
        global stop
        if mouseButton == CENTER:
            stop = True
    
    def keyPressed():
        global stop, angular_vel
        if key == " ":
            stop = True
        if key == "r":    # make it spin again
            angular_vel = 3
    

    code output

    PS: Note that Processing gives you a PI constant, no need to import math