Create repo
BIN
Angry_Birds/Fonts/Comic_Kings.ttf
Normal file
BIN
Angry_Birds/Fonts/arfmoochikncheez.ttf
Normal file
BIN
Angry_Birds/Images/bird.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
Angry_Birds/Images/block1.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
Angry_Birds/Images/block_destroyed1.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
Angry_Birds/Images/game_play1.png
Normal file
|
After Width: | Height: | Size: 217 KiB |
BIN
Angry_Birds/Images/game_play2.png
Normal file
|
After Width: | Height: | Size: 203 KiB |
BIN
Angry_Birds/Images/pig1.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
Angry_Birds/Images/pig3.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
Angry_Birds/Images/pig_damaged.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
Angry_Birds/Images/wall_horizontal.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
Angry_Birds/Images/wall_vertical.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
32
Angry_Birds/README.md
Normal 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>
|
||||
BIN
Angry_Birds/__pycache__/interface.cpython-310.pyc
Normal file
BIN
Angry_Birds/__pycache__/interface.cpython-35.pyc
Normal file
BIN
Angry_Birds/__pycache__/maps.cpython-310.pyc
Normal file
BIN
Angry_Birds/__pycache__/maps.cpython-35.pyc
Normal file
BIN
Angry_Birds/__pycache__/objects.cpython-310.pyc
Normal file
BIN
Angry_Birds/__pycache__/objects.cpython-35.pyc
Normal file
BIN
Angry_Birds/__pycache__/physics_engine.cpython-310.pyc
Normal file
BIN
Angry_Birds/__pycache__/physics_engine.cpython-35.pyc
Normal file
71
Angry_Birds/interface.py
Normal 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
@@ -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
@@ -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
@@ -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
|
||||
393
Angry_Birds/physics_engine.py
Normal 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
|
||||