Target practice game attempt - need some assistance please

I am trying out a simple target practice game (click on a rectangle) using the cursor and mouse button. If the mouse is within the borders of the rectangle, it will turn green and if there is a mouseclick, you receive a point and an explosion occurs AND the rectangle disappears. The rectangle moves randomly around the screen every 5 seconds.

Two problems so far:

1) I cannot for the life of me get the explosion to be timed. I tried and tried and even though I managed to get the rectangle appearance at 5 seconds, getting the explosion to be time delayed escapes me. I commented out the code at the location I tried it, but unfortunately, me time delay doesn't work.

2) The rectangle appears every 5 seconds. If there is an explosion, the rectangle disappears and a new one appears in a random location. BUT it seems to interfere with the 5 second delay (continually running) which causes flashing. For example, if at 4 seconds, you hit the target, it will disappear. A new one will appear - but only for 1 seconds because the timer is still counting 5 seconds! It flashes and a new one will appear.

Ok, here is what I have so far:

def setup():
    global score, x, y, img, count
    score=0
    count=0
    timer=0
    size(400, 400)
    noStroke()
    fill(0)
    background(255) # white
    textSize(20)
    img=loadImage("explosionsmall.jpg")
    x=random(10, 360)
    y=random(10, 360)


def draw():
    #cursor(CROSS)
    background(255) # white
    fill(0,0,0)
    text("SCORE :", 10, 390) # this is a label for the count
    text(score, 150, 390) # this is the actual variable for the count
    time_delay()


def laser():
    ellipse(200,360, x, y)

def time_delay():
    global count, timer, x, y

    if count<10:
        count=count+1
        timer=millis()

    else:
        random_placement()
        if millis() > timer + 5000:
            count=0
            x=random(10, 360)
            y=random(10, 360)

def random_placement():
      fill(0)
      rect(x,y,5,5) 
      if (mouseX >x) and (mouseX < x+5) and (mouseY > y) and (mouseY < y+5):
        fill(0,255,0)
        rect(x,y,5,5)

def mouseClicked():
    keepscore()

def keepscore():
    global score, x, y, count, timer
    if (mouseX >x) and (mouseX < x+5) and (mouseY > y) and (mouseY < y+5):
        score=score+1
        explosion()
        #if count<10:
         #   count=count+1
          #  timer=millis()
        #else:        
         #   explosion()
          #  if millis() > timer + 2000:
           #     count=0

def explosion():
   global x, y
   image(img,x-5,y-5) 
   x=random(10, 360)
   y=random(10, 360)

Answers

  • edited August 2017

    Here is a concept for any timed event -- you can make one timer, ten, or 10,000 timers with this approach.

    The time is currently 5217 milliseconds since the program started. An event (like a hit) happened I need to do something 1 second (1000 milliseconds) later.

    if (mouseX >x) and (mouseX < x+5) and (mouseY > y) and (mouseY < y+5):
      delayed_event
    

    For my delayed event I set a future event time by recording the future "do it!" time in a variable:

    timer=millis() + 1000
    

    Ok, now I know that at 6217 milliseconds (5217+1000), something should happen.

    Now, to make the event happen. Every frame I can check my timer by checking if it is set (!=0) and checking if the time has passed (>millis()). If the timer is set and has passed, I clear the timer and do the thing.

    if((timer!=0) and (timer>millis()):
      timer=0
      do_something
    

    A draw frame loads, the if is checked, and the time is 6779. That's more than the timer of 6217. I set the timer to 0 and do something. Next frame the timer is 0, so it will not check.

  • edited August 2017

    Ok I am trying to follow what you are saying. I am going to include your work in my code, but it is still not working so obviously I am not understanding it.

    Here is a simple test code that I was working on with help from a friend. It seems to work :

    x=20
    y=20
    count=0
    
    def setup():
        global timer, x ,y , m, n
        size(400, 400)
        background(255) # white
    
    def draw():
        global x, count, timer
        timer_event()
    
    def timer_event():
        global count, timer, x, y
        if count<10:
            count=count+1
            timer=millis()
            print("waiting for 2 seconds to pass")
            draw_ellipse()
        elif millis()> timer+2000:
            print("2 seconds has passed")
            x=x+50
            count=0
    
    def draw_ellipse():
            ellipse(x,y,36,76)
    

    So from what I understand, the WAITING period (during the count=count+1 is where I want the explosion to happen, correct? Ok so this works for me because it draws out the ellipse every 2 seconds. After completing this, I wanted to incorporate your code/explanation into the same idea above, but unfortunately, I couldn't get it to work. I tried all different ways, shapes and forms, but I can't get this to work with your code. Here is what I tried after many failed attempts (using your explanation as I understood it):

    x=20
    y=20
    timer=0
    
    def setup():
        global timer, x ,y
        size(400, 400)
        background(255) # white
    
    def draw():
        global timer, x
        background(255)
        fill(0,0,0)
        timer_event()
        draw_ellipse()
        x=x+1
        if ((timer!=0) and (timer>millis())):
            timer=0
            # do something ????? draw the ellipse?
    
    def timer_event():
        timer=millis()+3000
    
    def draw_ellipse():
        ellipse(x,y,36,76)
    
  • You have commented out "# do something ????? draw the ellipse?" -- what are you trying to do?

  • edited August 2017

    I was echoing back what you were saying - in this case, I want the ellipse to be drawn every 3 seconds, as in the last post, but in the target game, I want the explosion to last 1 second. I was just using the recent code as an example.

  • You don't want an ellipse drawing to flash on the screen every 3 seconds. You want an ellipse-shaped object to appear every 3 seconds and stay present, yes?

    If so your event is the creation of an object, not a drawing command.

  • edited August 2017

    Well in the prior code, I had the ellipse drawn and then moved over 50 and then drawn again. I just didn't get that far with your code because I couldn't figure it out. Again this was just an example, in my target game, I wanted the explosion to last 1-2 seconds and I am not at the stage of OOP yet.

  • edited August 2017

    Ok, I realised how this might be confusing. I think I was mixing up the difference between time delay FOR 2 seconds and something happening AFTER a time delay of 2 seconds.

    Here is the new code for the simple target game. I cannot get the explosion to last 1 second and I am well aware that my code is brute force and not elegant by any means. I changed the frame rate to slow down for the explosion because I am still lost on the time delay stuff. Also, there is a lot of print stuff to the console because I needed to see what was happening with the x and y coordinates etc. There a lot of a fixes I am sure, but right now I am just trying to get:

    1. The explosion to happen for 1 second (stay on the screen for 1 second)
    2. Ensure that once a target is destroyed, the clock starts again for the next target.
  •     def setup():
            global score, x, y, img, count, count_two, bx, by, targets
            score=0
            targets=1
            count=0
            count_two=0
            timer=0
            bx=200
            by=350
            size(400, 400)
            fill(0)
            background(255) # white
            textSize(20)
            img=loadImage("explosionsmall.jpg")
            x=int(random(10, bx))
            y=int(random(10, by))
    
        def draw():
            frameRate(30)
            #cursor(CROSS)
            background(255) # white
            fill(0,0,0)
            rect(0,360, width, 5)
            rect(195,355, 10, 10)
            text("SCORE :", 10, 390) # this is a label for the count
            text(score, 150, 390) # this is the actual variable for the count
            text("TARGETS : ", 250, 390)
            text(targets, 360, 390)
            time_delay()
    
        def time_delay():
            global count, timer, x, y, targets
            if count<10:
                count=count+1
                timer=millis()
                print("waiting to place new target")
            else:
                random_placement()
    
                if millis() > timer + 2000:
                    count=0
                    targets=targets+1
                    x=int(random(10, bx))
                    y=int(random(10, by))
    
        def random_placement():
              fill(0)
              rect(x,y,5,5) 
              if (mouseX >x) and (mouseX < x+5) and (mouseY > y) and (mouseY < y+5):
                fill(0,255,0)
                rect(x,y,5,5)
    
        def mouseClicked():
            keepscore()
    
        def keepscore():
            global score, x, y, count_two, timer, targets
            if (mouseX >x) and (mouseX < x+5) and (mouseY > y) and (mouseY < y+5):
                targets=targets+1
                score=score+1
                bullet_time()
                print("back after bullet time")
                count_two=0
                if count_two<10:
                    count_two=count_two+1
                    timer=millis()
                    print("Waiting for 2 seconds to pass")
                    explosion()
                elif millis()> timer+2000:
                    print("2 seconds has passed")
                    count_two=0        
    
        def explosion():
           global x, y, bx, by
           image(img,x-5,y-5) 
           x=int(random(10, bx))
           y=int(random(10, by))
    
        def bullet_time():
            global bx, by
            strokeWeight(1)
            if bx > x and by > y:
                    print("First")
                    frameRate(5)
                    fill(255,0,0)
                    line(bx,by,x,y)
    
            elif bx == x and by > y:
                    print("Second")
                    frameRate(5)
                    fill(255,0,0)
                    line(bx,by,x,y)
    
            elif bx < x and by > y:
                    print("Third")
                    frameRate(5)
                    line(bx,by,x,y)
    
            print("hit")
    
  • edited September 2017

    Re:

    I think I was mixing up the difference between time delay FOR 2 seconds and something happening AFTER a time delay of 2 seconds. [...] I cannot get the explosion to last 1 second

    You can build a duration timer with a timer and a switch. Turn on the switch, and turn it off after the timer expires.

    1. trigger/start: If click happens
      • boolean exploding = true (start now)
      • timer = millis()+2000 (stop in 2 seconds)
    2. do: if exploding
      • draw explosion
    3. stop: if millis() > timer && timer != 0
      • exploding = false
      • timer = 0

    Or, for a timed duration in the future, use a start and stop timer to turn the switch on and off.

    1. trigger: If click happens
      • timer_start = millis+1000 (start in 1 second)
      • timer_stop = millis+3000 (sop in 3 seconds -- 2 second duration)
    2. start: if millis() > timer_start && timer_start != 0
      • boolean exploding = true (start now)
    3. do: if exploding
      • draw explosion
    4. stop: if millis() > timer_stop && timer_stop != 0
      • exploding = false
      • timer_start = 0
      • timer_stop = 0
Sign In or Register to comment.