Skip to content

Commit 0472f45

Browse files
authored
Add files via upload
1 parent 41f1f9f commit 0472f45

File tree

1 file changed

+376
-0
lines changed

1 file changed

+376
-0
lines changed

8_Ball_Pool/8BallPool.py

Lines changed: 376 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,376 @@
1+
# -----------------------------------------------------------------------------
2+
#
3+
# 8 Ball Pool
4+
# Language - Python
5+
# Modules - pygame, sys, random, math
6+
#
7+
# Controls - Mouse, the length of Stick is propotional to Force applied
8+
#
9+
# By - Jatin Kumar Mandav
10+
#
11+
# Website - https://jatinmandav.wordpress.com
12+
#
13+
# YouTube Channel - https://www.youtube.com/channel/UCdpf6Lz3V357cIZomPwjuFQ
14+
# Twitter - @jatinmandav
15+
#
16+
# -----------------------------------------------------------------------------
17+
18+
import pygame
19+
import sys
20+
from math import *
21+
import random
22+
23+
pygame.init()
24+
width = 660
25+
height = 360
26+
outerHeight = 400
27+
margin = 30
28+
display = pygame.display.set_mode((width, outerHeight))
29+
pygame.display.set_caption("8 Ball Pool")
30+
clock = pygame.time.Clock()
31+
32+
background = (51, 51, 51)
33+
white = (236, 240, 241)
34+
35+
gray = (123, 125, 125)
36+
37+
black = (23, 32, 42)
38+
yellow = (244, 208, 63)
39+
blue = (52, 152, 219)
40+
red = (203, 67, 53)
41+
purple = (136, 78, 160)
42+
orange = (230, 126, 34)
43+
green = (40, 180, 99)
44+
brown = (100, 30, 22)
45+
stickColor = (249, 231, 159)
46+
47+
colors = [yellow, blue, red, purple, orange, green, brown, black, yellow, blue, red, purple, orange, green, brown]
48+
49+
balls = []
50+
noBalls = 15
51+
radius = 10
52+
friction = 0.005
53+
54+
# Ball Class
55+
class Ball:
56+
def __init__(self, x, y, speed, color, angle, ballNum):
57+
self.x = x + radius
58+
self.y = y + radius
59+
self.color = color
60+
self.angle = angle
61+
self.speed = speed
62+
self.ballNum = ballNum
63+
self.font = pygame.font.SysFont("Agency FB", 10)
64+
65+
# Draws Balls on Display Window
66+
def draw(self, x, y):
67+
pygame.draw.ellipse(display, self.color, (x - radius, y - radius, radius*2, radius*2))
68+
if self.color == black or self.ballNum == "cue":
69+
ballNo = self.font.render(str(self.ballNum), True, white)
70+
else:
71+
ballNo = self.font.render(str(self.ballNum), True, black)
72+
73+
if self.ballNum > 9:
74+
display.blit(ballNo, (x - 6, y - 5))
75+
else:
76+
display.blit(ballNo, (x - 5, y - 5))
77+
78+
# Moves the Ball around the Screen
79+
def move(self):
80+
self.speed -= friction
81+
if self.speed <= 0:
82+
self.speed = 0
83+
self.x = self.x + self.speed*cos(radians(self.angle))
84+
self.y = self.y + self.speed*sin(radians(self.angle))
85+
86+
if not (self.x < width - radius - margin):
87+
self.x = width - radius - margin
88+
self.angle = 180 - self.angle
89+
if not(radius + margin < self.x):
90+
self.x = radius + margin
91+
self.angle = 180 - self.angle
92+
if not (self.y < height - radius - margin):
93+
self.y = height - radius - margin
94+
self.angle = 360 - self.angle
95+
if not(radius + margin < self.y):
96+
self.y = radius + margin
97+
self.angle = 360 - self.angle
98+
99+
# Pocket Class
100+
class Pockets:
101+
def __init__(self, x, y, color):
102+
self.r = margin/2
103+
self.x = x + self.r + 10
104+
self.y = y + self.r + 10
105+
self.color = color
106+
107+
# Draws the Pockets on Pygame Window
108+
def draw(self):
109+
pygame.draw.ellipse(display, self.color, (self.x - self.r, self.y - self.r, self.r*2, self.r*2))
110+
111+
# Checks if ball has entered the Hole
112+
def checkPut(self):
113+
global balls
114+
ballsCopy = balls[:]
115+
for i in range(len(balls)):
116+
dist = ((self.x - balls[i].x)**2 + (self.y - balls[i].y)**2)**0.5
117+
if dist < self.r + radius:
118+
if balls[i] in ballsCopy:
119+
if balls[i].ballNum == 8:
120+
gameOver()
121+
else:
122+
ballsCopy.remove(balls[i])
123+
124+
balls = ballsCopy[:]
125+
126+
# Cue Stick Class
127+
class CueStick:
128+
def __init__(self, x, y, length, color):
129+
self.x = x
130+
self.y = y
131+
self.length = length
132+
self.color = color
133+
self.tangent = 0
134+
135+
# Applies force to Cue Ball
136+
def applyForce(self, cueBall, force):
137+
cueBall.angle = self.tangent
138+
cueBall.speed = force
139+
140+
# Draws Cue Stick on Pygame Window
141+
def draw(self, cuex, cuey):
142+
self.x, self.y = pygame.mouse.get_pos()
143+
self.tangent = (degrees(atan2((cuey - self.y), (cuex - self.x))))
144+
pygame.draw.line(display, white, (cuex + self.length*cos(radians(self.tangent)), cuey + self.length*sin(radians(self.tangent))), (cuex, cuey), 1)
145+
pygame.draw.line(display, self.color, (self.x, self.y), (cuex, cuey), 3)
146+
147+
148+
# Checks Collision
149+
def collision(ball1, ball2):
150+
dist = ((ball1.x - ball2.x)**2 + (ball1.y - ball2.y)**2)**0.5
151+
if dist <= radius*2:
152+
return True
153+
else:
154+
return False
155+
156+
# Checks if Cue Ball hits any Ball
157+
def checkCueCollision(cueBall):
158+
for i in range(len(balls)):
159+
if collision(cueBall, balls[i]):
160+
if balls[i].x == cueBall.x:
161+
angleIncline = 2*90
162+
else:
163+
u1 = balls[i].speed
164+
u2 = cueBall.speed
165+
166+
balls[i].speed = ((u1*cos(radians(balls[i].angle)))**2 + (u2*sin(radians(cueBall.angle)))**2)**0.5
167+
cueBall.speed = ((u2*cos(radians(cueBall.angle)))**2 + (u1*sin(radians(balls[i].angle)))**2)**0.5
168+
169+
tangent = degrees((atan((balls[i].y - cueBall.y)/(balls[i].x - cueBall.x)))) + 90
170+
angle = tangent + 90
171+
172+
balls[i].angle = (2*tangent - balls[i].angle)
173+
cueBall.angle = (2*tangent - cueBall.angle)
174+
175+
balls[i].x += (balls[i].speed)*sin(radians(angle))
176+
balls[i].y -= (balls[i].speed)*cos(radians(angle))
177+
cueBall.x -= (cueBall.speed)*sin(radians(angle))
178+
cueBall.y += (cueBall.speed)*cos(radians(angle))
179+
180+
181+
# Checks Collision Between Balls
182+
def checkCollision():
183+
for i in range(len(balls)):
184+
for j in range(len(balls) - 1, i, -1):
185+
if collision(balls[i], balls[j]):
186+
if balls[i].x == balls[j].x:
187+
angleIncline = 2*90
188+
else:
189+
u1 = balls[i].speed
190+
u2 = balls[j].speed
191+
192+
balls[i].speed = ((u1*cos(radians(balls[i].angle)))**2 + (u2*sin(radians(balls[j].angle)))**2)**0.5
193+
balls[j].speed = ((u2*cos(radians(balls[j].angle)))**2 + (u1*sin(radians(balls[i].angle)))**2)**0.5
194+
195+
tangent = degrees((atan((balls[i].y - balls[j].y)/(balls[i].x - balls[j].x)))) + 90
196+
angle = tangent + 90
197+
198+
balls[i].angle = (2*tangent - balls[i].angle)
199+
balls[j].angle = (2*tangent - balls[j].angle)
200+
201+
balls[i].x += (balls[i].speed)*sin(radians(angle))
202+
balls[i].y -= (balls[i].speed)*cos(radians(angle))
203+
balls[j].x -= (balls[j].speed)*sin(radians(angle))
204+
balls[j].y += (balls[j].speed)*cos(radians(angle))
205+
206+
def border():
207+
pygame.draw.rect(display, gray, (0, 0, width, 30))
208+
pygame.draw.rect(display, gray, (0, 0, 30, height))
209+
pygame.draw.rect(display, gray, (width - 30, 0, width, height))
210+
pygame.draw.rect(display, gray, (0, height - 30, width, height))
211+
212+
def score():
213+
font = pygame.font.SysFont("Agency FB", 30)
214+
215+
pygame.draw.rect(display, (51, 51, 51), (0, height, width, outerHeight))
216+
for i in range(len(balls)):
217+
balls[i].draw((i + 1)*2*(radius + 1), height + radius + 10)
218+
219+
text = font.render("Remaining Balls: " + str(len(balls)), True, stickColor)
220+
display.blit(text, (width/2 + 50, height + radius/2))
221+
222+
223+
def reset():
224+
global balls, noBalls
225+
noBalls = 15
226+
balls = []
227+
228+
s = 70
229+
230+
b1 = Ball(s, height/2 - 4*radius, 0, colors[0], 0, 1)
231+
b2 = Ball(s + 2*radius, height/2 - 3*radius, 0, colors[1], 0, 2)
232+
b3 = Ball(s, height/2 - 2*radius, 0, colors[2], 0, 3)
233+
b4 = Ball(s + 4*radius, height/2 - 2*radius, 0, colors[3], 0, 4)
234+
b5 = Ball(s + 2*radius, height/2 - 1*radius, 0, colors[4], 0, 5)
235+
b6 = Ball(s, height/2, 0, colors[5], 0, 6)
236+
b7 = Ball(s + 6*radius, height/2 - 1*radius, 0, colors[6], 0, 7)
237+
b8 = Ball(s + 4*radius, height/2, 0, colors[7], 0, 8)
238+
b9 = Ball(s + 8*radius, height/2, 0, colors[8], 0, 9)
239+
b10 = Ball(s + 6*radius, height/2 + 1*radius, 0, colors[9], 0, 10)
240+
b11 = Ball(s + 2*radius, height/2 + 1*radius, 0, colors[10], 0, 11)
241+
b12 = Ball(s, height/2 + 2*radius, 0, colors[11], 0, 12)
242+
b13 = Ball(s + 4*radius, height/2 + 2*radius, 0, colors[12], 0, 13)
243+
b14 = Ball(s + 2*radius, height/2 + 3*radius, 0, colors[13], 0, 14)
244+
b15 = Ball(s, height/2 + 4*radius, 0, colors[14], 0, 15)
245+
246+
balls.append(b1)
247+
balls.append(b2)
248+
balls.append(b3)
249+
balls.append(b4)
250+
balls.append(b5)
251+
balls.append(b6)
252+
balls.append(b7)
253+
balls.append(b8)
254+
balls.append(b9)
255+
balls.append(b10)
256+
balls.append(b11)
257+
balls.append(b12)
258+
balls.append(b13)
259+
balls.append(b14)
260+
balls.append(b15)
261+
262+
263+
264+
def gameOver():
265+
font = pygame.font.SysFont("Agency FB", 75)
266+
if len(balls) == 0:
267+
text = font.render("You Won!", True, (133, 193, 233))
268+
else:
269+
text = font.render("You Lost! Black in Hole!", True, (241, 148, 138))
270+
271+
while True:
272+
for event in pygame.event.get():
273+
if event.type == pygame.QUIT:
274+
close()
275+
if event.type == pygame.KEYDOWN:
276+
if event.key == pygame.K_q:
277+
close()
278+
279+
if event.key == pygame.K_r:
280+
poolTable()
281+
display.blit(text, (50, height/2))
282+
283+
pygame.display.update()
284+
clock.tick()
285+
286+
def close():
287+
pygame.quit()
288+
sys.exit()
289+
290+
# Main Function
291+
def poolTable():
292+
loop = True
293+
294+
reset()
295+
296+
noPockets = 6
297+
pockets = []
298+
299+
p1 = Pockets(0, 0, black)
300+
p2 = Pockets(width/2 - p1.r*2, 0, black)
301+
p3 = Pockets(width - p1.r - margin - 5, 0, black)
302+
p4 = Pockets(0, height - margin - 5 - p1.r, black)
303+
p5 = Pockets(width/2 - p1.r*2, height - margin - 5 - p1.r, black)
304+
p6 = Pockets(width - p1.r - margin - 5, height - margin - 5 - p1.r, black)
305+
306+
pockets.append(p1)
307+
pockets.append(p2)
308+
pockets.append(p3)
309+
pockets.append(p4)
310+
pockets.append(p5)
311+
pockets.append(p6)
312+
313+
cueBall = Ball(width/2, height/2, 0, white, 0, "cue")
314+
cueStick = CueStick(0, 0, 100, stickColor)
315+
316+
317+
start = 0
318+
end = 0
319+
320+
while loop:
321+
for event in pygame.event.get():
322+
if event.type == pygame.QUIT:
323+
close()
324+
if event.type == pygame.KEYDOWN:
325+
if event.key == pygame.K_q:
326+
close()
327+
328+
if event.key == pygame.K_r:
329+
poolTable()
330+
331+
if event.type == pygame.MOUSEBUTTONDOWN:
332+
start = [cueBall.x, cueBall.y]
333+
x, y = pygame.mouse.get_pos()
334+
end = [x ,y]
335+
dist = ((start[0] - end[0])**2 + (start[1] - end[1])**2)**0.5
336+
force = dist/10.0
337+
if force > 10:
338+
force = 10
339+
340+
cueStick.applyForce(cueBall, force)
341+
342+
343+
display.fill(background)
344+
345+
cueBall.draw(cueBall.x, cueBall.y)
346+
cueBall.move()
347+
348+
if not (cueBall.speed > 0):
349+
350+
cueStick.draw(cueBall.x, cueBall.y)
351+
352+
for i in range(len(balls)):
353+
balls[i].draw(balls[i].x, balls[i].y)
354+
355+
for i in range(len(balls)):
356+
balls[i].move()
357+
358+
checkCollision()
359+
checkCueCollision(cueBall)
360+
border()
361+
362+
for i in range(noPockets):
363+
pockets[i].draw()
364+
365+
for i in range(noPockets):
366+
pockets[i].checkPut()
367+
368+
if len(balls) == 1 and balls[0].ballNum == 8:
369+
gameOver()
370+
371+
score()
372+
373+
pygame.display.update()
374+
clock.tick(60)
375+
376+
poolTable()

0 commit comments

Comments
 (0)