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() |