Create repo

This commit is contained in:
2023-04-10 00:48:44 +02:00
commit 75e0a1f679
79 changed files with 7029 additions and 0 deletions

Binary file not shown.

Binary file not shown.

BIN
Angry_Birds/Images/bird.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

BIN
Angry_Birds/Images/pig1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
Angry_Birds/Images/pig3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

32
Angry_Birds/README.md Normal file
View File

@@ -0,0 +1,32 @@
# Angry Birds
Here is a Small Attempt to Recreate One of the popular Games, Angry Birds in Python using Pygame
Link to 14 Hour Time Lapse of coding the game from Scratch: [Angry Birds - 14 Hour Time Lapse](https://youtu.be/6in-mdiumcA)
Link to Blog: [Angry Birds in Python Using PyGame](https://jatinmandav.wordpress.com/2018/05/25/angry-birds-in-python-using-pygame/)
### Requirements:
[Pygame Module](https://www.pygame.org)
pip install pygame
## Usage:
wget https://github.com/jatinmandav/Gaming-in-Python/tree/master/Angry_Birds
From Angry_Birds/ Directory:
$ python3 main.py or
$ python main.py
### Game Play Screenshot:
<p align="center"> <img src="Images/game_play1.png"/> </p>
<p align="center"> <img src="Images/game_play2.png"/> </p>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

71
Angry_Birds/interface.py Normal file
View File

@@ -0,0 +1,71 @@
'''
Game: Angry Birds
File: interface.py
Contents: Class Buttons and Class Labels for User Interface
Requirements: Pygame, sys
By: Jatin Kumar Mandav
Blog: https://www.jatinmandav.wordpress.com
Twitter: @jatinmandav
YouTube: https://www.youtube.com/mandav
'''
import pygame
import sys
pygame.init()
display = None
def init(screen):
global display
display = screen
class Button:
def __init__(self, x, y, w, h, action=None, colorNotActive=(189, 195, 199), colorActive=None):
self.x = x
self.y = y
self.w = w
self.h = h
self.colorActive = colorActive
self.colorNotActive = colorNotActive
self.action = action
self.font = None
self.text = None
self.text_pos = None
def add_text(self, text, size=20, font="Times New Roman", text_color=(0, 0, 0)):
self.font = pygame.font.Font(font, size)
self.text = self.font.render(text, True, text_color)
self.text_pos = self.text.get_rect()
self.text_pos.center = (self.x + self.w/2, self.y + self.h/2)
def draw(self):
if self.isActive():
if not self.colorActive == None:
pygame.draw.rect(display, self.colorActive, (self.x, self.y, self.w, self.h))
else:
pygame.draw.rect(display, self.colorNotActive, (self.x, self.y, self.w, self.h))
if self.text:
display.blit(self.text, self.text_pos)
def isActive(self):
pos = pygame.mouse.get_pos()
if (self.x < pos[0] < self.x + self.w) and (self.y < pos[1] < self.y + self.h):
return True
else:
return False
class Label(Button):
def draw(self):
if self.text:
display.blit(self.text, self.text_pos)

91
Angry_Birds/main.py Normal file
View File

@@ -0,0 +1,91 @@
'''
Game: Angry Birds
File: main.py
Contents: The Main file to Start the Game!
Requirements: Pygame, sys, random, math
Supporting Modules: interface.py, physics_engine.py, maps.py, objects.py
Usage:
Angry_Birds/$ python3 main.py or
Angry_Birds/$ python main.py
By: Jatin Kumar Mandav
Blog: https://www.jatinmandav.wordpress.com
Twitter: @jatinmandav
YouTube: https://www.youtube.com/mandav
'''
import pygame
import sys
import random
from math import *
import physics_engine
import objects
import maps
import interface
pygame.init()
width = 1800
height = 700
display = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
physics_engine.init(display)
objects.init(display)
maps.init(display)
interface.init(display)
background = (51, 51, 51)
def close():
pygame.quit()
sys.exit()
def start_game(map):
map.draw_map()
def GAME():
map = maps.Maps()
welcome = interface.Label(700, 100, 400, 200, None, background)
welcome.add_text("ANGRY BIRDS", 80, "Fonts/arfmoochikncheez.ttf", (236, 240, 241))
start = interface.Button(500, 400, 300, 100, start_game, (244, 208, 63), (247, 220, 111))
start.add_text("START GAME", 60, "Fonts/arfmoochikncheez.ttf", background)
exit = interface.Button(1000, 400, 300, 100, close, (241, 148, 138), (245, 183, 177))
exit.add_text("QUIT", 60, "Fonts/arfmoochikncheez.ttf", background)
mandav = interface.Button(width - 300, height - 80, 300, 100, None, background)
mandav.add_text("MANDAV", 60, "Fonts/arfmoochikncheez.ttf", (41, 41, 41))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
close()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
close()
if event.type == pygame.MOUSEBUTTONDOWN:
if exit.isActive():
exit.action()
if start.isActive():
start_game(map)
display.fill(background)
start.draw()
exit.draw()
welcome.draw()
mandav.draw()
pygame.display.update()
clock.tick(60)
GAME()

645
Angry_Birds/maps.py Normal file
View File

@@ -0,0 +1,645 @@
'''
Game: Angry Birds
File: maps.py
Contents: Class MAPS, that puts everything in action!
Requirements: Pygame, sys
Supporting Modules: physics_engine, interface, objects
By: Jatin Kumar Mandav
Blog: https://www.jatinmandav.wordpress.com
Twitter: @jatinmandav
YouTube: https://www.youtube.com/mandav
'''
import pygame
import sys
import physics_engine
import objects
import interface
pygame.init()
width = None
height = None
display = None
clock = pygame.time.Clock()
ground = 50
d_velocity = 2.0
def init(screen):
global width, height, display
display = screen
(width, height) = display.get_rect().size
height -= ground
interface.init(display)
def all_rest(pigs, birds, blocks):
threshold = 0.15
for pig in pigs:
if pig.velocity.magnitude >= threshold:
return False
for bird in birds:
if bird.velocity.magnitude >= threshold:
return False
for block in blocks:
if block.velocity.magnitude >= threshold:
return False
return True
def close():
pygame.quit()
sys.exit()
class Maps:
def __init__(self):
self.level = 1
self.max_level = 15
self.color = {'background': (51, 51, 51)}
self.score = 0
def wait_level(self):
time = 0
while time < 3:
for event in pygame.event.get():
if event.type == pygame.QUIT:
close()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
close()
time += 1
clock.tick(1)
return
def check_win(self, pigs, birds):
if pigs == []:
print("WON!")
return True
if (not pigs == []) and birds == []:
print("LOST!")
return False
def pause(self):
pause_text = interface.Label(700, 200, 400, 200, None, self.color['background'])
pause_text.add_text("GAME PAUSED", 70, "Fonts/Comic_Kings.ttf", (236, 240, 241))
replay = interface.Button(350, 500, 300, 100, self.draw_map, (244, 208, 63), (247, 220, 111))
replay.add_text("RESTART", 60, "Fonts/arfmoochikncheez.ttf", self.color['background'])
resume = interface.Button(750, 500, 300, 100, None, (88, 214, 141), (171, 235, 198))
resume.add_text("RESUME", 60, "Fonts/arfmoochikncheez.ttf", self.color['background'])
exit = interface.Button(1150, 500, 300, 100, close, (241, 148, 138), (245, 183, 177))
exit.add_text("QUIT", 60, "Fonts/arfmoochikncheez.ttf", self.color['background'])
mandav = interface.Label(width - 270, height + ground - 70, 300, 100, None, self.color['background'])
mandav.add_text("MANDAV", 60, "Fonts/arfmoochikncheez.ttf", ( 113, 125, 126 ))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
close()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
close()
if event.key == pygame.K_p:
return
if event.key == pygame.K_ESCAPE:
return
if event.type == pygame.MOUSEBUTTONDOWN:
if replay.isActive():
replay.action()
if resume.isActive():
return
if exit.isActive():
exit.action()
replay.draw()
resume.draw()
exit.draw()
pause_text.draw()
mandav.draw()
pygame.display.update()
clock.tick(60)
def draw_map(self):
birds = []
pigs = []
blocks = []
walls = []
self.score = 0
if self.level == 1:
for i in range(3):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1100, height - 40, 20))
pigs.append(physics_engine.Pig(1500, height - 40, 20))
blocks.append(physics_engine.Block(1300, height - 60, 60))
elif self.level == 2:
for i in range(3):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1000, height - 40, 20))
pigs.append(physics_engine.Pig(1400, height - 40, 20))
blocks.append(physics_engine.Block(1200, height - 60, 60))
blocks.append(physics_engine.Block(1200, height - 2*35, 60))
blocks.append(physics_engine.Block(1500, height - 60, 60))
elif self.level == 3:
for i in range(3):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1200, height - 60, 30))
pigs.append(physics_engine.Pig(1300, height - 60, 30))
blocks.append(physics_engine.Block(1000, height - 100, 100))
blocks.append(physics_engine.Block(1000, height - 2*60, 100))
blocks.append(physics_engine.Block(1500, height - 100, 100))
blocks.append(physics_engine.Block(1500, height - 2*60, 100))
elif self.level == 4:
for i in range(3):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1200, 500 - 60, 30))
pigs.append(physics_engine.Pig(1300, height - 60, 30))
walls.append(objects.Slab(1000, 450, 500, 20))
blocks.append(physics_engine.Block(1100, height - 100, 100))
elif self.level == 5:
for i in range(3):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1300, 500 - 60, 25))
pigs.append(physics_engine.Pig(1300, height - 60, 25))
walls.append(objects.Slab(500, 400, 100, height - 400))
walls.append(objects.Slab(1000, 450, 500, 30))
blocks.append(physics_engine.Block(1150, 500 - 100, 100))
blocks.append(physics_engine.Block(1100, height - 100, 100))
elif self.level == 6:
for i in range(3):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1300, 500 - 60, 25))
pigs.append(physics_engine.Pig(1300, height - 60, 25))
walls.append(objects.Slab(1000, 0, 30, 450))
walls.append(objects.Slab(1000, 450, 500, 30))
blocks.append(physics_engine.Block(1150, 500 - 100, 100))
blocks.append(physics_engine.Block(1100, height - 100, 100))
elif self.level == 7:
for i in range(4):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1100, 500 - 60, 25))
pigs.append(physics_engine.Pig(1300, 500 - 60, 25))
pigs.append(physics_engine.Pig(1200, height - 60, 25))
walls.append(objects.Slab(1200, 250, 30, 200))
walls.append(objects.Slab(1000, 450, 500, 30))
elif self.level == 8:
for i in range(3):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1100, height - 60, 25))
pigs.append(physics_engine.Pig(1200, height - 60, 25))
walls.append(objects.Slab(700, 250, 30, height - 250))
elif self.level == 9:
for i in range(3):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1100, height - 60, 25))
pigs.append(physics_engine.Pig(1450, height - 60, 25))
blocks.append(physics_engine.Block(1250, height - 100, 100))
blocks.append(physics_engine.Block(1250, height - 2*60, 100))
walls.append(objects.Slab(700, 400, 30, height - 400))
elif self.level == 10:
for i in range(3):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1100, height - 60, 25))
pigs.append(physics_engine.Pig(1450, height - 60, 25))
blocks.append(physics_engine.Block(1250, height - 100, 100))
blocks.append(physics_engine.Block(1250, height - 2*60, 100))
blocks.append(physics_engine.Block(900, height - 100, 100))
walls.append(objects.Slab(900, 400, 500, 30))
elif self.level == 11:
for i in range(3):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1100, height - 60, 25))
pigs.append(physics_engine.Pig(1450, height - 60, 25))
blocks.append(physics_engine.Block(1250, height - 100, 100))
blocks.append(physics_engine.Block(1250, height - 2*60, 100))
walls.append(objects.Slab(900, 400, 500, 30))
walls.append(objects.Slab(900, 400, 30, height - 400))
elif self.level == 12:
for i in range(3):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1100, height - 60, 25))
pigs.append(physics_engine.Pig(1450, height - 60, 25))
walls.append(objects.Slab(900, 400, 500, 30))
walls.append(objects.Slab(1200, 500, 30, height - 500))
elif self.level == 13:
for i in range(4):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1100, height - 60, 25))
pigs.append(physics_engine.Pig(1200, 400 - 60, 25))
pigs.append(physics_engine.Pig(1450, height - 60, 25))
blocks.append(physics_engine.Block(900, height - 100, 100))
blocks.append(physics_engine.Block(900, height - 2*60, 100))
walls.append(objects.Slab(900, 400, 500, 40))
walls.append(objects.Slab(1200, 500, 30, height - 500))
elif self.level == 14:
for i in range(4):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(1100, height - 60, 25))
pigs.append(physics_engine.Pig(1100, 400 - 60, 25))
pigs.append(physics_engine.Pig(1450, height - 60, 25))
blocks.append(physics_engine.Block(900, height - 100, 100))
blocks.append(physics_engine.Block(1300, 400 - 100, 100))
walls.append(objects.Slab(900, 400, 500, 40))
walls.append(objects.Slab(900, 0, 30, 400))
elif self.level == 15:
for i in range(5):
new_bird = physics_engine.Bird(40*i + 5*i, height - 40, 20, None, "BIRD")
birds.append(new_bird)
pigs.append(physics_engine.Pig(900, height - 60, 25))
pigs.append(physics_engine.Pig(width - 400, 400 - 60, 25))
pigs.append(physics_engine.Pig(1700, height - 60, 25))
walls.append(objects.Slab(800, 400, 30, height - 400))
walls.append(objects.Slab(1000, 500, 30, height - 500))
walls.append(objects.Slab(width - 500, 400, 500, 40))
walls.append(objects.Slab(width - 500, 150, 60, 400 - 150))
self.start_level(birds, pigs, blocks, walls)
def replay_level(self):
self.level -= 1
self.draw_map()
def start_again(self):
self.level = 1
self.draw_map()
def level_cleared(self):
self.level += 1
level_cleared_text = interface.Label(700, 100, 400, 200, None, self.color['background'])
if self.level <= self.max_level:
level_cleared_text.add_text("LEVEL " + str(self.level - 1) + " CLEARED!", 80, "Fonts/Comic_Kings.ttf", (236, 240, 241))
else:
level_cleared_text.add_text("ALL LEVEL CLEARED!", 80, "Fonts/Comic_Kings.ttf", (236, 240, 241))
score_text = interface.Label(750, 300, 300, 100, None, self.color['background'])
score_text.add_text("SCORE: " + str(self.score), 55, "Fonts/Comic_Kings.ttf", (236, 240, 241))
replay = interface.Button(350, 500, 300, 100, self.replay_level, (244, 208, 63), (247, 220, 111))
replay.add_text("PLAY AGAIN", 60, "Fonts/arfmoochikncheez.ttf", self.color['background'])
if self.level <= self.max_level:
next = interface.Button(750, 500, 300, 100, self.draw_map, (88, 214, 141), (171, 235, 198))
next.add_text("CONTINUE", 60, "Fonts/arfmoochikncheez.ttf", self.color['background'])
else:
next = interface.Button(750, 500, 300, 100, self.start_again, (88, 214, 141), (171, 235, 198))
next.add_text("START AGAIN", 60, "Fonts/arfmoochikncheez.ttf", self.color['background'])
exit = interface.Button(1150, 500, 300, 100, close, (241, 148, 138), (245, 183, 177))
exit.add_text("QUIT", 60, "Fonts/arfmoochikncheez.ttf", self.color['background'])
mandav = interface.Label(width - 270, height + ground - 70, 300, 100, None, self.color['background'])
mandav.add_text("MANDAV", 60, "Fonts/arfmoochikncheez.ttf", ( 113, 125, 126 ))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
close()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
close()
if event.type == pygame.MOUSEBUTTONDOWN:
if replay.isActive():
replay.action()
if next.isActive():
next.action()
if exit.isActive():
exit.action()
replay.draw()
next.draw()
exit.draw()
level_cleared_text.draw()
score_text.draw()
mandav.draw()
pygame.display.update()
clock.tick(60)
def level_failed(self):
level_failed_text = interface.Label(700, 100, 400, 200, None, self.color['background'])
level_failed_text.add_text("LEVEL FAILED!", 80, "Fonts/Comic_Kings.ttf", (236, 240, 241))
score_text = interface.Label(750, 300, 300, 100, None, self.color['background'])
score_text.add_text("SCORE: " + str(self.score), 55, "Fonts/Comic_Kings.ttf", (236, 240, 241))
replay = interface.Button(500, 500, 300, 100, self.draw_map, (244, 208, 63), (247, 220, 111))
replay.add_text("TRY AGAIN", 60, "Fonts/arfmoochikncheez.ttf", self.color['background'])
exit = interface.Button(1000, 500, 300, 100, close, (241, 148, 138), (245, 183, 177))
exit.add_text("QUIT", 60, "Fonts/arfmoochikncheez.ttf", self.color['background'])
mandav = interface.Label(width - 270, height + ground - 70, 300, 100, None, self.color['background'])
mandav.add_text("MANDAV", 60, "Fonts/arfmoochikncheez.ttf", ( 113, 125, 126 ))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
close()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
close()
if event.type == pygame.MOUSEBUTTONDOWN:
if replay.isActive():
replay.action()
if exit.isActive():
exit.action()
replay.draw()
exit.draw()
level_failed_text.draw()
score_text.draw()
mandav.draw()
pygame.display.update()
clock.tick(60)
def start_level(self, birds, pigs, blocks, walls):
loop = True
slingshot = physics_engine.Slingshot(200, height - 200, 30, 200)
birds[0].load(slingshot)
mouse_click = False
flag = 1
pigs_to_remove = []
blocks_to_remove = []
score_text = interface.Label(50, 10, 100, 50, None, self.color['background'])
score_text.add_text("SCORE: " + str(self.score), 25, "Fonts/Comic_Kings.ttf", (236, 240, 241))
birds_remaining = interface.Label(120, 50, 100, 50, None, self.color['background'])
birds_remaining.add_text("BIRDS REMAINING: " + str(len(birds)), 25, "Fonts/Comic_Kings.ttf", (236, 240, 241))
pigs_remaining = interface.Label(110, 90, 100, 50, None, self.color['background'])
pigs_remaining.add_text("PIGS REMAINING: " + str(len(pigs)), 25, "Fonts/Comic_Kings.ttf", (236, 240, 241))
mandav = interface.Label(width - 270, height + ground - 70, 300, 100, None, self.color['background'])
mandav.add_text("MANDAV", 60, "Fonts/arfmoochikncheez.ttf", ( 113, 125, 126 ))
while loop:
for event in pygame.event.get():
if event.type == pygame.QUIT:
close()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
close()
if event.key == pygame.K_r:
self.draw_map()
if event.key == pygame.K_p:
self.pause()
if event.key == pygame.K_ESCAPE:
self.pause()
if event.type == pygame.MOUSEBUTTONDOWN:
if birds[0].mouse_selected():
mouse_click = True
if event.type == pygame.MOUSEBUTTONUP:
mouse_click = False
if birds[0].mouse_selected():
flag = 0
if (not birds[0].loaded) and all_rest(pigs, birds, blocks):
print("LOADED!")
birds.pop(0)
if self.check_win(pigs, birds) == 1:
self.score += len(birds)*100
self.level_cleared()
elif self.check_win(pigs,birds) == 0:
self.level_failed()
if not birds == []:
birds[0].load(slingshot)
flag = 1
if mouse_click:
birds[0].reposition(slingshot, mouse_click)
if not flag:
birds[0].unload()
#display.fill(self.color['background'])
color = self.color['background']
for i in range(3):
color = (color[0] + 5, color[1] + 5, color[2] + 5)
pygame.draw.rect(display, color, (0, i*300, width, 300))
pygame.draw.rect(display, (77, 86, 86), (0, height, width, 50))
slingshot.draw(birds[0])
for i in range(len(pigs)):
for j in range(len(blocks)):
pig_v, block_v = pigs[i].velocity.magnitude, blocks[j].velocity.magnitude
pigs[i], blocks[j], result_block_pig = physics_engine.collision_handler(pigs[i], blocks[j], "BALL_N_BLOCK")
pig_v1, block_v1 = pigs[i].velocity.magnitude, blocks[j].velocity.magnitude
if result_block_pig:
if abs(pig_v - pig_v1) > d_velocity:
blocks_to_remove.append(blocks[j])
blocks[j].destroy()
if abs(block_v - block_v1) > d_velocity:
pigs_to_remove.append(pigs[i])
pigs[i].dead()
for i in range(len(birds)):
if not (birds[i].loaded or birds[i].velocity.magnitude == 0):
for j in range(len(blocks)):
birds_v, block_v = birds[i].velocity.magnitude, blocks[j].velocity.magnitude
birds[i], blocks[j], result_bird_block = physics_engine.collision_handler(birds[i], blocks[j], "BALL_N_BLOCK")
birds_v1, block_v1 = birds[i].velocity.magnitude, blocks[j].velocity.magnitude
if result_bird_block:
if abs(birds_v - birds_v1) > d_velocity:
if not blocks[j] in blocks_to_remove:
blocks_to_remove.append(blocks[j])
blocks[j].destroy()
for i in range(len(pigs)):
pigs[i].move()
for j in range(i+1, len(pigs)):
pig1_v, pig2_v = pigs[i].velocity.magnitude, pigs[j].velocity.magnitude
pigs[i], pigs[j], result = physics_engine.collision_handler(pigs[i], pigs[j], "BALL")
pig1_v1, pig2_v1 = pigs[i].velocity.magnitude, pigs[j].velocity.magnitude
result = True
if result:
if abs(pig1_v - pig1_v1) > d_velocity:
if not pigs[j] in pigs_to_remove:
pigs_to_remove.append(pigs[j])
pigs[j].dead()
if abs(pig2_v - pig2_v1) > d_velocity:
if not pigs[i] in pigs_to_remove:
pigs_to_remove.append(pigs[i])
pigs[i].dead()
for wall in walls:
pigs[i] = wall.collision_manager(pigs[i])
pigs[i].draw()
for i in range(len(birds)):
if (not birds[i].loaded) and birds[i].velocity.magnitude:
birds[0].move()
for j in range(len(pigs)):
bird_v, pig_v = birds[i].velocity.magnitude, pigs[j].velocity.magnitude
birds[i], pigs[j], result_bird_pig = physics_engine.collision_handler(birds[i], pigs[j], "BALL")
bird_v1, pig_v1 = birds[i].velocity.magnitude, pigs[j].velocity.magnitude
result = True
if result_bird_pig:
if abs(bird_v - bird_v1) > d_velocity:
if not pigs[j] in pigs_to_remove:
pigs_to_remove.append(pigs[j])
pigs[j].dead()
if birds[i].loaded:
birds[i].project_path()
for wall in walls:
birds[i] = wall.collision_manager(birds[i])
birds[i].draw()
for i in range(len(blocks)):
for j in range(i + 1, len(blocks)):
block1_v, block2_v = blocks[i].velocity.magnitude, blocks[j].velocity.magnitude
blocks[i], blocks[j], result_block = physics_engine.block_collision_handler(blocks[i], blocks[j])
block1_v1, block2_v1 = blocks[i].velocity.magnitude, blocks[j].velocity.magnitude
if result_block:
if abs(block1_v - block1_v1) > d_velocity:
if not blocks[j] in blocks_to_remove:
blocks_to_remove.append(blocks[j])
blocks[j].destroy()
if abs(block2_v - block2_v1) > d_velocity:
if not blocks[i] in blocks_to_remove:
blocks_to_remove.append(blocks[i])
blocks[i].destroy()
blocks[i].move()
for wall in walls:
blocks[i] = wall.collision_manager(blocks[i], "BLOCK")
blocks[i].draw()
for wall in walls:
wall.draw()
score_text.add_text("SCORE: " + str(self.score), 25, "Fonts/Comic_Kings.ttf", (236, 240, 241))
score_text.draw()
birds_remaining.add_text("BIRDS REMAINING: " + str(len(birds)), 25, "Fonts/Comic_Kings.ttf", (236, 240, 241))
birds_remaining.draw()
pigs_remaining.add_text("PIGS REMAINING: " + str(len(pigs)), 25, "Fonts/Comic_Kings.ttf", (236, 240, 241))
pigs_remaining.draw()
mandav.draw()
pygame.display.update()
if all_rest(pigs, birds, blocks):
for pig in pigs_to_remove:
if pig in pigs:
pigs.remove(pig)
self.score += 100
for block in blocks_to_remove:
if block in blocks:
blocks.remove(block)
self.score += 50
pigs_to_remove = []
blocks_to_remove = []
clock.tick(60)

103
Angry_Birds/objects.py Normal file
View File

@@ -0,0 +1,103 @@
'''
Game: Angry Birds
File: objects.py
Contents: Class SLAB or WALL
Requirements: Pygame, sys, math
Supporting Modules: physics_engine
By: Jatin Kumar Mandav
Blog: https://www.jatinmandav.wordpress.com
Twitter: @jatinmandav
YouTube: https://www.youtube.com/mandav
'''
import pygame
import sys
from math import *
import physics_engine
pygame.init()
display = None
width = None
height = None
clock = pygame.time.Clock()
ground = 50
def init(screen):
global width, height, display
display = screen
(width, height) = display.get_rect().size
height -= ground
class Slab:
def __init__(self, x, y, w, h, color=(255, 255, 255)):
self.x = x
self.y = y
self.w = w
self.h = h
if self.w > self.h:
self.image = pygame.image.load("Images/wall_horizontal.png")
else:
self.image = pygame.image.load("Images/wall_vertical.png")
self.image = pygame.transform.scale(self.image, (self.w, self.h))
self.color = color
def draw(self):
display.blit(self.image, (self.x, self.y))
def collision_manager(self, ball, type="BALL"):
if type == "BALL":
if (ball.y + ball.r > self.y) and (ball.y < self.y + self.h):
if (ball.x < self.x + self.w) and (ball.x + ball.r > self.x + self.w):
ball.x = 2*(self.x + self.w) - ball.x
ball.velocity.angle = - ball.velocity.angle
ball.velocity.magnitude *= physics_engine.elasticity
elif ball.x + ball.r > self.x and (ball.x < self.x):
ball.x = 2*(self.x - ball.r) - ball.x
ball.velocity.angle = - ball.velocity.angle
ball.velocity.magnitude *= physics_engine.elasticity
if (ball.x + ball.r > self.x) and (ball.x < self.x + self.w):
if ball.y + ball.r > self.y and ball.y < self.y:
ball.y = 2*(self.y - ball.r) - ball.y
ball.velocity.angle = pi - ball.velocity.angle
ball.velocity.magnitude *= physics_engine.elasticity
elif (ball.y < self.y + self.h) and (ball.y + ball.r > self.y + self.h):
ball.y = 2*(self.y + self.h) - ball.y
ball.velocity.angle = pi - ball.velocity.angle
ball.velocity.magnitude *= physics_engine.elasticity
return ball
else:
block = ball
if (block.y + block.h > self.y) and (block.y < self.y + self.h):
if (block.x < self.x + self.w) and (block.x + block.w > self.x + self.w):
block.x = 2*(self.x + self.w) - block.x
block.velocity.angle = - block.velocity.angle
block.rotateAngle = - block.velocity.angle
block.velocity.magnitude *= physics_engine.elasticity
elif block.x + block.w > self.x and (block.x < self.x):
block.x = 2*(self.x - block.w) - block.x
block.velocity.angle = - block.velocity.angle
block.rotateAngle = - block.velocity.angle
block.velocity.magnitude *= physics_engine.elasticity
if (block.x + block.w > self.x) and (block.x < self.x + self.w):
if block.y + block.h > self.y and block.y < self.y:
block.y = 2*(self.y - block.h) - block.y
block.velocity.angle = pi - block.velocity.angle
block.rotateAngle = pi - block.velocity.angle
block.velocity.magnitude *= physics_engine.elasticity
elif (block.y < self.y + self.h) and (block.y + block.h > self.y + self.h):
block.y = 2*(self.y + self.h) - block.y
block.velocity.angle = pi - block.velocity.angle
block.rotateAngle = pi - block.velocity.angle
block.velocity.magnitude *= physics_engine.elasticity
return block

View File

@@ -0,0 +1,393 @@
'''
Game: Angry Birds
File: physics_engine.py
Contents: Class Vector
Class PIG
Class BIRD
Class BLOCK
Class SLINGSHOT
func collision_handler, block_collision_handler
Requirements: Pygame, sys, math, random
By: Jatin Kumar Mandav
Blog: https://www.jatinmandav.wordpress.com
Twitter: @jatinmandav
YouTube: https://www.youtube.com/mandav
'''
import pygame
import sys
from math import *
import random
pygame.init()
width = None
height = None
display = None
ground = 50
clock = pygame.time.Clock()
def init(screen):
global width, height, display
display = screen
(width, height) = display.get_rect().size
height -= ground
class Vector:
def __init__(self, magnitude=0, angle=radians(0)):
self.magnitude = magnitude
self.angle = angle
def add_vectors(vector1, vector2):
x = sin(vector1.angle)*vector1.magnitude + sin(vector2.angle)*vector2.magnitude
y = cos(vector1.angle)*vector1.magnitude + cos(vector2.angle)*vector2.magnitude
new_angle = 0.5*pi - atan2(y, x)
new_magnitude = hypot(x, y)
new_vector = Vector(new_magnitude, new_angle)
return new_vector
gravity = Vector(0.2, pi)
inverse_friction = 0.99
elasticity = 0.8
block_elasticity = 0.7
class Pig:
def __init__(self, x, y, r, v=None, type="PIG", loaded = False, color=(255, 255, 255)):
self.x = x
self.y = y
self.r = r
if v == None:
self.velocity = Vector()
else:
self.velocity = v
self.pig1_image = pygame.image.load("Images/pig1.png")
self.pig2_image = pygame.image.load("Images/pig3.png")
self.pig_dead = pygame.image.load("Images/pig_damaged.png")
self.bird_image = pygame.image.load("Images/bird.png")
if type == "PIG":
self.image = random.choice([self.pig1_image, self.pig2_image])
else:
self.image = self.bird_image
self.type = type
self.color = color
self.loaded = loaded
self.path = []
self.count = 0
self.animate_count = 0
self.isDead = False
def draw(self):
self.animate_count += 1
if self.type == "BIRD" and not self.loaded:
for point in self.path:
pygame.draw.ellipse(display, self.color, (point[0], point[1], 3, 3), 1)
if (self.type == "PIG") and (not self.animate_count%20) and (not self.isDead):
self.image = random.choice([self.pig1_image, self.pig2_image])
display.blit(self.image, (self.x - self.r, self.y - self.r))
def dead(self):
self.isDead = True
self.image = self.pig_dead
def move(self):
self.velocity = add_vectors(self.velocity, gravity)
self.x += self.velocity.magnitude*sin(self.velocity.angle)
self.y -= self.velocity.magnitude*cos(self.velocity.angle)
self.velocity.magnitude *= inverse_friction
if self.x > width - self.r:
self.x = 2*(width - self.r) - self.x
self.velocity.angle *= -1
self.velocity.magnitude *= elasticity
elif self.x < self.r:
self.x = 2*self.r - self.x
self.velocity.angle *= -1
self.velocity.magnitude *= elasticity
if self.y > height - self.r:
self.y = 2*(height - self.r) - self.y
self.velocity.angle = pi - self.velocity.angle
self.velocity.magnitude *= elasticity
elif self.y < self.r:
self.y = 2*self.r - self.y
self.velocity.angle = pi - self.velocity.angle
self.velocity.magnitude *= elasticity
self.count += 1
if self.count%1 == 0:
self.path.append((self.x, self.y))
class Bird(Pig):
def load(self, slingshot):
self.x = slingshot.x
self.y = slingshot.y
self.loaded = True
def mouse_selected(self):
pos = pygame.mouse.get_pos()
dx = pos[0] - self.x
dy = pos[1] - self.y
dist = hypot(dy, dx)
if dist < self.r:
return True
return False
def reposition(self, slingshot, mouse_click):
pos = pygame.mouse.get_pos()
if self.mouse_selected():
self.x = pos[0]
self.y = pos[1]
dx = slingshot.x - self.x
dy = slingshot.y - self.y
self.velocity.magnitude = int(hypot(dx, dy)/2)
if self.velocity.magnitude > 80:
self.velocity.magnitude = 80
self.velocity.angle = pi/2 + atan2(dy, dx)
def unload(self):
self.loaded = False
def project_path(self):
if self.loaded:
path = []
ball = Pig(self.x, self.y, self.r, self.velocity, self.type)
for i in range(30):
ball.move()
if i%5 == 0:
path.append((ball.x, ball.y))
for point in path:
pygame.draw.ellipse(display, self.color, (point[0], point[1], 2, 2))
class Block:
def __init__(self, x, y, r, v=None, color=( 120, 40, 31 ), colorBoundary = ( 28, 40, 51 )):
self.r = 50
self.w = 100
self.h = 100
self.x = x
self.y = y
self.block_image = pygame.image.load("Images/block1.png")
self.block_destroyed_image = pygame.image.load("Images/block_destroyed1.png")
self.image = self.block_image
if v == None:
self.velocity = Vector()
else:
self.velocity = v
self.color = color
self.colorDestroyed = ( 100, 30, 22 )
self.colorBoundary = colorBoundary
self.rotateAngle = radians(0)
self.anchor = (self.r/2, self.r/2)
self.isDestroyed = False
def rotate(self, coord, angle, anchor=(0, 0)):
corr = 0
return ((coord[0] - anchor[0])*cos(angle + radians(corr)) - (coord[1] - anchor[1])*sin(angle + radians(corr)),
(coord[0] - anchor[0])*sin(angle + radians(corr)) + (coord[1] - anchor[1])*cos(angle + radians(corr)))
def translate(self, coord):
return [coord[0] + self.x, coord[1] + self.y]
def draw(self):
pygame.transform.rotate(self.image, self.rotateAngle)
display.blit(self.image, (self.x - self.w/2, self.y))
def destroy(self):
self.isDestroyed = True
self.image = self.block_destroyed_image
def move(self):
self.velocity = add_vectors(self.velocity, gravity)
self.x += self.velocity.magnitude*sin(self.velocity.angle)
self.y -= self.velocity.magnitude*cos(self.velocity.angle)
self.velocity.magnitude *= inverse_friction
if self.x > width - self.w:
self.x = 2*(width - self.w) - self.x
self.velocity.angle *= -1
self.rotateAngle = - self.velocity.angle
self.velocity.magnitude *= block_elasticity
elif self.x < self.w:
self.x = 2*self.w - self.x
self.velocity.angle *= -1
self.rotateAngle = - self.velocity.angle
self.velocity.magnitude *= block_elasticity
if self.y > height - self.h:
self.y = 2*(height - self.h) - self.y
self.velocity.angle = pi - self.velocity.angle
self.rotateAngle = pi - self.velocity.angle
self.velocity.magnitude *= block_elasticity
elif self.y < self.h:
self.y = 2*self.h - self.y
self.velocity.angle = pi - self.velocity.angle
self.rotateAngle = pi - self.velocity.angle
self.velocity.magnitude *= block_elasticity
class Slingshot:
def __init__(self, x, y, w, h, color=( 66, 73, 73 )):
self.x = x
self.y = y
self.w = w
self.h = h
self.color = color
def rotate(self, coord, angle, anchor=(0, 0)):
corr = 0
return ((coord[0] - anchor[0])*cos(angle + radians(corr)) - (coord[1] - anchor[1])*sin(angle + radians(corr)),
(coord[0] - anchor[0])*sin(angle + radians(corr)) + (coord[1] - anchor[1])*cos(angle + radians(corr)))
def translate(self, coord):
return [coord[0] + self.x, coord[1] + self.y]
def draw(self, loaded=None):
pygame.draw.rect(display, self.color, (self.x, self.y + self.h*1/3, self.w, self.h*2/3))
if (not loaded == None) and loaded.loaded:
pygame.draw.line(display, ( 100, 30, 22 ), (self.x - self.w/4 + self.w/4, self.y + self.h/6), (loaded.x, loaded.y + loaded.r/2), 10)
pygame.draw.line(display, ( 100, 30, 22 ), (self.x + self.w, self.y + self.h/6), (loaded.x + loaded.r, loaded.y + loaded.r/2), 10)
pygame.draw.rect(display, self.color, (self.x - self.w/4, self.y, self.w/2, self.h/3), 5)
pygame.draw.rect(display, self.color, (self.x + self.w - self.w/4, self.y, self.w/2, self.h/3), 5)
def collision_handler(b_1, b_2, type):
collision = False
if type == "BALL":
dx = b_1.x - b_2.x
dy = b_1.y - b_2.y
dist = hypot(dx, dy)
if dist < b_1.r + b_2.r:
tangent = atan2(dy, dx)
angle = 0.5*pi + tangent
angle1 = 2*tangent - b_1.velocity.angle
angle2 = 2*tangent - b_2.velocity.angle
magnitude1 = b_2.velocity.magnitude
magnitude2 = b_1.velocity.magnitude
b_1.velocity = Vector(magnitude1, angle1)
b_2.velocity = Vector(magnitude2, angle2)
b_1.velocity.magnitude *= elasticity
b_2.velocity.magnitude *= elasticity
overlap = 0.5*(b_1.r + b_2.r - dist + 1)
b_1.x += sin(angle)*overlap
b_1.y -= cos(angle)*overlap
b_2.x -= sin(angle)*overlap
b_2.y += cos(angle)*overlap
collision = True
#print(collision)
#print(collision)
return b_1, b_2, collision
elif type == "BALL_N_BLOCK":
dx = b_1.x - b_2.x
dy = b_1.y - b_2.y
dist = hypot(dx, dy)
if dist < b_1.r + b_2.w:
tangent = atan2(dy, dx)
angle = 0.5*pi + tangent
angle1 = 2*tangent - b_1.velocity.angle
angle2 = 2*tangent - b_2.velocity.angle
magnitude1 = b_2.velocity.magnitude
magnitude2 = b_1.velocity.magnitude
b_1.velocity = Vector(magnitude1, angle1)
b_2.velocity = Vector(magnitude2, angle2)
b_1.velocity.magnitude *= elasticity
b_2.velocity.magnitude *= block_elasticity
overlap = 0.5*(b_1.r + b_2.w - dist + 1)
b_1.x += sin(angle)*overlap
b_1.y -= cos(angle)*overlap
b_2.x -= sin(angle)*overlap
b_2.y += cos(angle)*overlap
collision = True
return b_1, b_2, collision
def block_collision_handler(block, block2):
collision = False
if (block.y + block.h > block2.y) and (block.y < block2.y + block2.h):
if (block.x < block2.x + block2.w) and (block.x + block.w > block2.x + block2.w):
block.x = 2*(block2.x + block2.w) - block.x
block.velocity.angle = - block.velocity.angle
block.rotateAngle = - block.velocity.angle
block.velocity.magnitude *= block_elasticity
block2.velocity.angle = - block2.velocity.angle
block2.rotateAngle = - block2.velocity.angle
block2.velocity.magnitude *= block_elasticity
collision = True
elif block.x + block.w > block2.x and (block.x < block2.x):
block.x = 2*(block2.x - block.w) - block.x
block.velocity.angle = - block.velocity.angle
block.rotateAngle = - block.velocity.angle
block.velocity.magnitude *= block_elasticity
block2.velocity.angle = - block2.velocity.angle
block2.rotateAngle = - block2.velocity.angle
block2.velocity.magnitude *= block_elasticity
collision = True
if (block.x + block.w > block2.x) and (block.x < block2.x + block2.w):
if block.y + block.h > block2.y and block.y < block2.y:
block.y = 2*(block2.y - block.h) - block.y
block.velocity.angle = pi - block.velocity.angle
block.rotateAngle = pi - block.velocity.angle
block.velocity.magnitude *= block_elasticity
block2.velocity.angle = pi - block2.velocity.angle
block2.rotateAngle = pi - block2.velocity.angle
block2.velocity.magnitude *= block_elasticity
collision = True
elif (block.y < block2.y + block2.h) and (block.y + block.h > block2.y + block2.h):
block.y = 2*(block2.y + block2.h) - block.y
block.velocity.angle = pi - block.velocity.angle
block.rotateAngle = pi - block.velocity.angle
block.velocity.magnitude *= block_elasticity
block2.velocity.angle = pi - block2.velocity.angle
block2.rotateAngle = pi - block2.velocity.angle
block2.velocity.magnitude *= block_elasticity
collision = True
return block, block2, collision