Monday, July 20, 2015

Bouncing Box animation in Python using PyGame

Bouncy is a class which demonstrates Bouncing rectangle animation which options like resolution, bouncy rectangle size, speed. Whenever it collides with the borders or wall it plays a sound. The code doesn't have any Magic Numbers, everything has been named pretty well so that it is readable to most and many error handling cases has been handled (These being the reason that the code is long else it can be reduced).


How to use ?

Just initialize the class with the parameters. if you don't give any params a default value is taken.


Parameters :-

1. resolution : Takes a tuple of values for Screen Size like (800, 600). Default Value : (640, 480)
2. rectobj_size : Takes a tuple of values for rectangle object size like (40, 30). Default Value : (50, 50)
3. speed : Animation Speed. Min value 1

Example :-

Bouncy( ( 600, 400 ), ( 40, 40 ), 5 ) or Bouncy( resolution = ( 600, 400 ), rectobj_size = ( 40, 40 ), speed = 5 )

Code:

"""
Copyright (C) 2014 Animesh Shaw. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY Animesh Shaw ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
import os
import sys
import pygame
from pygame.constants import NOFRAME, K_ESCAPE, KEYUP
from pygame.mixer import Sound
class Bouncy:
def __init__(self, resolution=(640, 480), rectobj_size=(50, 50), speed=5):
pygame.init()
# Center the SDL Window on the Display Screen
os.environ['SDL_VIDEO_CENTERED'] = '1'
self.screen_depth = 32
self.rCBack = (27, 27, 27)
self.border = (227, 227, 227)
self.rCRed = (227, 27, 27)
"""
Check is resolution parameter is supplied, if yes then check if its valid or not.
If the values are acceptable then it is accepted else ValueError Exception is raised.
"""
if type(resolution) is tuple and resolution is not None:
self.width, self.height = resolution
else:
raise ValueError("Tuple of Screen size (width, height) expected but found" + type(resolution))
# Set the Display Screen Mode
self.screen = pygame.display.set_mode(resolution, NOFRAME, self.screen_depth)
# Set the Padding for both sides for rectangular border
self.pad = 10
# Sets the thickness of the border
self.border_thickness = 3
# Set the Framerate
self.fps = 30
self.timer = pygame.time.Clock()
# Set the dimensions for rectangular border size
self.rect_border_size = (self.pad, self.pad, self.width - 2 * self.pad,
self.height - 2 * self.pad)
"""
Rectangular Object coordinates which will bounce.
Check is rectobj_size parameter is supplied, if yes then check if its valid or not.
If the values are acceptable then it is accepted else ValueError Exception is raised.
"""
if type(rectobj_size) is tuple and rectobj_size is not None:
self.rectx, self.recty = self.pad + self.border_thickness, self.pad + self.border_thickness
self.rect_width, self.rect_height = rectobj_size
else:
raise ValueError("Tuple of RectObject size (width, height) expected but found" + type(rectobj_size))
"""
Check if the speed supplied is valid or not. Minimum value is 1. if Conditions are
not met a ValueError Exception is raised.
"""
if type(speed) == int and speed is not None and speed > 1:
self.speed = speed
else:
raise ValueError("Speed must be int and greater than 0 but found " + type(speed))
# Draw the rectangle which will bounce
pygame.draw.rect(self.screen, self.rCRed, (self.rectx, self.recty, self.rect_width, self.rect_height))
# Initially fill the background and initialize other variables.
self.fill_background()
# Start the main game loop.
self.__game_loop()
def __game_loop(self):
# Create a sound object with a music file to play when the object hits
sound = Sound("resources/sounds/hitwall.wav")
speedx, speedy = self.speed, self.speed
# Inner Function to Play sound when object collides with wall
def play_sound():
sound.play(1)
# Values from where the object will return after collision
bottom_collision_offset = self.rect_bounce_area.bottom - self.rect_height - self.border_thickness
right_collision_offset = self.rect_bounce_area.right - self.rect_width - self.border_thickness
# Main game loop
while True:
for event in pygame.event.get():
if event.type == KEYUP and event.key == K_ESCAPE:
pygame.quit()
sys.exit()
self.fill_background()
pygame.draw.rect(self.screen, self.rCRed, (self.rectx, self.recty, self.rect_width, self.rect_height))
self.rectx += speedx
self.recty += speedy
# Check for wall collision.
if self.recty > bottom_collision_offset or self.recty < (self.pad + self.border_thickness):
speedy *= -1
play_sound()
if self.rectx > right_collision_offset or self.rectx < (self.pad + self.border_thickness):
speedx *= -1
play_sound()
pygame.display.update()
self.timer.tick(self.fps)
# Fill the background wil color and the border
def fill_background(self):
self.screen.fill(self.rCBack)
self.rect_bounce_area = pygame.draw.rect(self.screen, self.border,
self.rect_border_size, self.border_thickness)
def main():
Bouncy(resolution=(600, 400), rectobj_size=(40, 40), speed=2)
if __name__ == '__main__':
main()
view raw Bouncy.py hosted with ❤ by GitHub


Related Posts:

Follow Me!

Followers

Visitor Map