SHOW:
|
|
- or go back to the newest paste.
| 1 | # -*- coding: utf-8 -*- | |
| 2 | """ | |
| 3 | Created on Tue Mar 31 13:38:20 2020 | |
| 4 | ||
| 5 | - | @author: ssoni |
| 5 | + | |
| 6 | Turns out, the red would get reinfected and reset his timeInfected | |
| 7 | back to zero on each collision, while already red. | |
| 8 | So, I turned the elapsed time down to 3, and some circles would heal to green. | |
| 9 | ||
| 10 | Another bug was is that once green, there is no immunity yet, | |
| 11 | so green turns back to red when it hits another red. | |
| 12 | """ | |
| 13 | ||
| 14 | ||
| 15 | from tkinter import * | |
| 16 | import random | |
| 17 | import time | |
| 18 | import sys | |
| 19 | ||
| 20 | # Constants | |
| 21 | HEIGHT = 700 | |
| 22 | WIDTH = 900 | |
| 23 | TIME_TO_HEAL = 5 | |
| 24 | SPEED = 10 | |
| 25 | - | TIME_TO_HEAL = 3 |
| 25 | + | |
| 26 | NUM_BALLS = 100 | |
| 27 | COLOR_START = 'blue' | |
| 28 | COLOR_INFECTED = 'red' | |
| 29 | COLOR_HEALED = 'green' | |
| 30 | ||
| 31 | class Ball: | |
| 32 | ||
| 33 | # New BALL gnerates a random x,y location for the ball | |
| 34 | # The internal canvas graphics variable is NAMED shape | |
| 35 | # Also, init the x and y move increment (speed) as dx & dy | |
| 36 | def __init__(self, color, size): | |
| 37 | x1 = random.randrange(0,WIDTH) | |
| 38 | y1 = random.randrange(0,HEIGHT) | |
| 39 | self.shape = canvas.create_oval(x1, y1, x1+size, y1+size, fill=color) | |
| 40 | self.dx = random.randrange(-SPEED,SPEED) | |
| 41 | self.dy = random.randrange(-SPEED,SPEED) | |
| 42 | self.infectedTime = 0 | |
| 43 | self.infected = False | |
| 44 | ||
| 45 | def checkHealed(self): | |
| 46 | if self.infected == True: | |
| 47 | totalTimeSick = time.time() - self.infectedTime | |
| 48 | ||
| 49 | if (totalTimeSick > TIME_TO_HEAL): | |
| 50 | canvas.itemconfig(self.shape, fill=COLOR_HEALED) | |
| 51 | self.infected = False | |
| 52 | self.infectedTime = 0 | |
| 53 | ||
| 54 | def move(self): | |
| 55 | ||
| 56 | #Move the ball (shape variable in the ball instance | |
| 57 | canvas.move(self.shape, self.dx, self.dy) | |
| 58 | ||
| 59 | #get location of the ball | |
| 60 | pos = canvas.coords(self.shape) | |
| 61 | ||
| 62 | #Bounce off the edges of the window | |
| 63 | if pos[3] > HEIGHT or pos[1] < 0: | |
| 64 | self.dy = -self.dy | |
| 65 | if pos[0] < 0 or pos[2] > WIDTH: | |
| 66 | self. dx = -self.dx | |
| 67 | ||
| 68 | for b2 in balls: | |
| 69 | ||
| 70 | #ball can't hit itself, otherwise, you'll collide once in every loop | |
| 71 | if (balls.index(b2) == balls.index(self)): | |
| 72 | continue | |
| 73 | ||
| 74 | # Check if rectangles are overlapping | |
| 75 | # position = [x1,y1,x2,y2] | |
| 76 | # position = [LEFT, TOP, RIGHT, BOTTOM] | |
| 77 | pos2 = canvas.coords(b2.shape) | |
| 78 | if (pos[2] > pos2[0]) and (pos[0] < pos2[2]) and \ | |
| 79 | (pos[3] > pos2[1]) and (pos[1] < pos2[3]) : | |
| 80 | self.dx = -self.dx | |
| 81 | self.dy = -self.dy | |
| 82 | ||
| 83 | # I should really check that if EITHER is red, | |
| 84 | # then they both become red. Not just one direction. | |
| 85 | # You can't get infected if HEALED or already SICK | |
| 86 | # So, you can only get infected is color= START color | |
| 87 | if (canvas.itemcget(self.shape,"fill") == COLOR_START): | |
| 88 | if (canvas.itemcget(b2.shape,"fill") == COLOR_INFECTED): | |
| 89 | canvas.itemconfig(self.shape, fill=COLOR_INFECTED) | |
| 90 | self.infected = True | |
| 91 | self.infectedTime = time.time() | |
| 92 | ||
| 93 | # Check if there are no more infected balls in the list | |
| 94 | # Assume eradicated unless proved otherwise | |
| 95 | def checkEradicated(balls): | |
| 96 | eradicated = True | |
| 97 | for b in balls: | |
| 98 | if (b.infected == True): | |
| 99 | eradicated = False | |
| 100 | return eradicated | |
| 101 | ||
| 102 | ||
| 103 | # Initialize the drawing graphics canvas | |
| 104 | tk = Tk() | |
| 105 | canvas = Canvas(tk, width=WIDTH, height=HEIGHT) | |
| 106 | tk.title("Virus!")
| |
| 107 | canvas.pack() | |
| 108 | ||
| 109 | timeStart = time.time() | |
| 110 | ||
| 111 | # Declare a list of balls | |
| 112 | balls = [] | |
| 113 | ||
| 114 | # Create balls and add to the list | |
| 115 | for i in range(NUM_BALLS): | |
| 116 | b = Ball(COLOR_START, BALL_SIZE) | |
| 117 | balls.append(b) | |
| 118 | ||
| 119 | # Make the first ball infected | |
| 120 | canvas.itemconfig(balls[0].shape, fill=COLOR_INFECTED) | |
| 121 | balls[0].infected = True | |
| 122 | balls[0].infectedTime = time.time() | |
| 123 | ||
| 124 | # Main loop to animate. | |
| 125 | # Iterate thru ball list | |
| 126 | eradicated = False | |
| 127 | while (eradicated == False): | |
| 128 | - | while True: |
| 128 | + | |
| 129 | for ball in balls: | |
| 130 | ball.checkHealed() | |
| 131 | ball.move() | |
| 132 | tk.update() | |
| 133 | #time.sleep(.05) | |
| 134 | ||
| 135 | if (checkEradicated(balls) == True): | |
| 136 | elapsedTime = time.time() - timeStart | |
| 137 | print("Elapsed time to eradicate virus: {0}".format(elapsedTime))
| |
| 138 | - | #break |
| 138 | + | eradicated = True |
| 139 | - | #sys.exit() |
| 139 | + | |
| 140 | # keeps main window open to prevent crash | |
| 141 | # can gracefull close window manually | |
| 142 | tk.mainloop() |