3 Replies - 2047 Views - Last Post: 19 October 2011 - 05:33 AM Rate Topic: -----

#1 dmorgan7  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 06-September 11

Python Cannonball Project

Posted 17 October 2011 - 04:08 PM

good afternoon guys,

i'm working with a python project with 6 classes.

cannon
from cannonball import Cannonball
import pygame
import math


class Cannon():
    '''
    Represents a cannon for the active_cannonball game.
    '''
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    GRAY = (105, 105, 105)
    GRASS_COLOR = (77, 189, 51)
    SKY_BLUE = (0, 191, 255)
    RED = (255, 0, 0)

    def __init__(self, x, y, launch_velocity, launch_angle_degrees):
        '''
        Initializes the data members with the specified values.
        '''
        self.x = x
        self.y = y
        self.launch_velocity = launch_velocity
        self.launch_angle_in_degrees = launch_angle_degrees
        self.launch_angle = (math.pi * launch_angle_degrees) / 180.0   
        self.active_cannonball = None
        self.ground = 650
        
        
    def display_cannon(self, window):
        '''
        Draws the cannon as a gray line with a black circle for its wheel.
        '''
        barrel_start_position = (round(self.x), 
                                 round(self.y + self.ground))
        
        barrel_end_position = (round(self.x + 20), 
                               round(self.y + self.ground - 20))
        
        pygame.draw.line(window, Cannon.GRAY, 
                         barrel_start_position, barrel_end_position, 10)
        
        wheel_position = (self.x + 4, self.y + self.ground)
        pygame.draw.circle(window, Cannon.BLACK, wheel_position, 7)
    
    def move_left(self, window):
        self.x -= 3
        self.display_cannon(window)
    
    def move_right(self, window):
        self.x += 3
        self.display_cannon(window)
   
    #TODO def aim_up(self, window):
        
    #TODO def aim_down(self):
    

    def fire(self, time_interval):
        '''
        Shoots the cannon, setting the active cannonball so that
        it can move on its trajectory.
        '''
        self.active_cannonball = Cannonball(self.x, self.y, 
                                     self.launch_angle, self.launch_velocity,
                                     time_interval)

cannonball
import math
import pygame
class Cannonball(object):
    '''
    Represents a cannonball to be shot in the cannon game.
    '''
    BLACK = (0,0,0)
    RED = (255,0,0)
    def __init__(self, x, y, launch_angle, launch_velocity, time_interval):
        '''
        Initializes the instance variables to the specified values,
        calculates the horizontal distance the ball travels on each move,
        and sets the  ball's status to flying. 
        '''
        
        self.x = x
        self.y = y
        self.x_velocity = launch_velocity * math.cos(launch_angle)
        self.y_velocity = launch_velocity * math.sin(launch_angle)
        self.time_interval = time_interval
        self.x_delta = self.time_interval * self.x_velocity
        self.ground = 650
        #self.elapsed_time = 0
        self.is_flying = True
        #self.cannonball_rect = pygame.Rect(self.x - 3, self.ground - self.y - 4, 8, 8)
        
    def move(self):
        '''
        Changes the ball's (x,y) location using the formulas for
        ballistic trajectory.
        '''

#        Trajectory quations from hyperphysics.phy-astr.gsu.edu/hbase/traj.html
#        self.elapsed_time += self.time_interval
#        self.x = round(self.x_velocity * self.elapsed_time)
#        self.y = round((self.y_velocity * self.elapsed_time) -
#                        4.9 * self.elapsed_time * self.elapsed_time)
        
        prev_y_velocity = self.y_velocity
        self.y_velocity = self.y_velocity - (9.8 * self.time_interval)
        self.y = (self.y + (self.time_interval * 
                                 ((prev_y_velocity + self.y_velocity)/ 2)))
        self.y = max(self.y, 0)
        self.x += (self.x_delta)
        self.is_flying = (self.y > 0)


    def draw_cannonball(self, window):
        ball_position = (round(self.x), 
                         round(self.ground - self.y))
        #pygame.draw.rect(window, Cannonball.RED, self.cannonball_rect)
        pygame.draw.circle(window, Cannonball.BLACK, ball_position, 4)

    

target
'''
Created on Oct 12, 2011

@author: Darius
'''
import pygame

class Target():
    '''
    classdocs
    '''
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    GRAY = (105, 105, 105)
    GRASS_COLOR = (77, 189, 51)
    SKY_BLUE = (0, 191, 255)

    def __init__(self, window, x, y):
        '''
        Constructor
        '''
        target_x = x
        target_y = y
        self.target_rect = pygame.Rect(target_x, target_y, 80, 40)
        pygame.draw.rect(window, Target.GRAY, self.target_rect)
        pygame.draw.ellipse(window, Target.BLACK, (target_x, target_y, 80, 40), 0)
        pygame.draw.ellipse(window, Target.WHITE, (target_x + 20, target_y + 9, 40, 20), 0)
        pygame.draw.circle(window, Target.BLACK, (target_x + 40, target_y + 19), 8)
        


fire_controller
'''
Created on Sep 28, 2011

@author: dmorgan7
'''

class FireController(object):
    '''
    Controller for the user story "fire the cannon," which
    shoots the cannon and moves the cannonball through its
    trajectory.
    '''


    def __init__(self, cannon, time_interval):
        '''
        Initializes the cannon with the specified values.
        '''
        self.cannon = cannon
        self.time_interval = time_interval
        
    def fireCannon(self):
        '''
        Tells the cannon to shoot and sets the active cannonball
        to be the one shot by the cannon.
        '''
        self.cannon.fire(self.time_interval)
        self.active_cannonball = self.cannon.active_cannonball
        
    def move_cannonball(self):
        '''
        Tells the cannonball to move to the next position in its
        trajectory.
        '''
        self.active_cannonball.move()
        

gui
import pygame
from cannon import Cannon 
from target import Target
from fire_controller import FireController

class Gui():
    '''
    Gui defines the GUI for the active_cannonball game.
    '''
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    GRAY = (105, 105, 105)
    GRASS_COLOR = (77, 189, 51)
    SKY_BLUE = (0, 191, 255)
    RED = (255, 0, 0)
    
    def __init__(self, width, height, launch_velocity, launch_angle, time_interval):
        '''
        Creates a Gui object, initializing the display surface,
        the window title, and the instance variables.
        '''
        
        self.width = width
        self.height = height
        self.launch_velocity = launch_velocity
        self.launch_angle = launch_angle
        self.time_interval = time_interval
        self.ground_y = self.height - 50
        self.window = pygame.display.set_mode((self.width, self.height))
        pygame.display.set_caption("Cannonball Shooter")    
        self.cannon = Cannon(x=50, y=0, 
                             launch_velocity=self.launch_velocity, 
                             launch_angle_degrees=self.launch_angle)
        self.active_cannonball = None
        
        self.fire_controller = FireController(self.cannon, 
                                              self.time_interval)
        self.target = None
        self.cannon_hits = 0
        self.cannon_misses = 0
        
    
    def display_grass(self):
        '''
        Draws the grass as a thick green line.
        '''
        ground_start_position = (0, self.ground_y + 50)
        ground_end_position = (self.width, 
                               self.ground_y + 50)
        pygame.draw.line(self.window, Gui.GRASS_COLOR, 
                         ground_start_position, 
                         ground_end_position, 
                         100)
        
    def display_cannon(self):
        '''
        Draws the cannon as a gray line with a black circle for its wheel.
        '''
        self.cannon.display_cannon(self.window)
         
    def move_cannon_left(self):
        self.active_cannonball = None
        self.cannon.move_left(self.window)
        self.display()
        
    def move_cannon_right(self):
        self.active_cannonball = None
        self.cannon.move_right(self.window)
        self.display()
    
    def aim_cannon_up(self):
        self.active_cannonball = None
        self.cannon.aim_up(self.window)
        self.display()
        
    def display_cannonball(self):
        '''
        Draws the active_cannonball as a black circle.
        '''
        cannonball_rect = pygame.Rect(self.active_cannonball.x - 3, self.ground_y - self.active_cannonball.y - 4, 8, 8)
        self.active_cannonball.draw_cannonball(self.window)
        
        if cannonball_rect.colliderect(self.target_rect):
            print("it hit it")
            self.add_hit()
        elif not cannonball_rect.colliderect(self.target_rect) and not self.active_cannonball.is_flying:
            self.add_miss()
    
    def display_target(self, target_x, target_y):
        '''
        Draws one target and sets its rect value to self.target_rect.
        ''' 
        #todo: collision detection must be done for multiple targets
        thisTarget = Target(self.window, target_x, target_y)
        self.target_rect =  thisTarget.target_rect
        
    def display_score(self):
        # Display some text
        font = pygame.font.Font(None, 36)
        text = font.render("Hits:"+ str(self.cannon_hits) + " Misses:" + str(self.cannon_misses), 1, (10, 10, 10))
        # Blit everything to the screen
        self.window.blit(text, (0, 0))
        
    def add_hit(self):
        self.cannon_hits += 1
        self.display_score()
        
    def add_miss(self):
        self.cannon_misses += 1
        self.display_score()
        
    def display(self):
        '''
        Draws the grass, cannon and, if it has been initialized, the active_cannonball.
        '''
        self.window.fill(Gui.SKY_BLUE)
        self.display_grass()
        self.display_cannon()
        self.display_target(1050, self.ground_y + 2 )
        self.display_score()
        if self.active_cannonball:
            self.display_cannonball()
        pygame.display.flip()
        


    def handle_move_cannonball_event(self):
        '''
        Tells the controller to move the active_cannonball 
        until it is not flying.
        '''
        while self.active_cannonball.is_flying:
            self.fire_controller.move_cannonball()
            pygame.time.wait(0)
            self.display()

    def handle_fire_event(self):
        '''
        Tells the controller to fire the cannon, which
        creates the active_cannonball.
        '''
        self.fire_controller.fireCannon()
        self.active_cannonball = self.cannon.active_cannonball
            
    def run(self):  
        '''
        Executes the animation loop, handling the "fire cannon" and "move
        active cannonball" events. Exits when the user clicks the quit button.
        '''      
        self.display()
        
        keepPlaying = True
        
        while keepPlaying:  
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    keepPlaying = False  
                elif event.type == pygame.KEYDOWN and event.key == pygame.K_f:
                    self.handle_fire_event()
                    self.handle_move_cannonball_event()
                elif event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
                    self.move_cannon_left()
                elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
                    self.move_cannon_right()
                elif event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
                    self.aim_cannon_up()
        



game_controller
'''
Defines the entry point for the application and
defines constant values for the GUI and game objects.
'''
from gui import Gui
import pygame
import configparser

config = configparser.ConfigParser()
config.read("cannon_config.ini")
TIME_INTERVAL = 0.05
LAUNCH_VELOCITY = config.getint("cannon","launch_velocity")
LAUNCH_ANGLE_IN_DEGREES = config.getint("cannon","launch_angle")

DISPLAY_WIDTH = 1200
DISPLAY_HEIGHT = 700

def main():
    pygame.init()
    Gui(DISPLAY_WIDTH, DISPLAY_HEIGHT, 
        LAUNCH_VELOCITY, 
        LAUNCH_ANGLE_IN_DEGREES, 
        TIME_INTERVAL ).run()
    pygame.quit()
    
    
if __name__ == "__main__":
    main()


1. in the gui class i'm using pygame.font to display a scoreboard at the top right of the screen. but unfortunately, every time the cannonball hits the target, the gui writes over the score instead of i guess deleting it and writing 1 so if the score were zero and it hit the target it would look like this.


2. I have to aim the cannon using the up and down arrows. how would i go about doing this?
any help would be appreciated
thanks

Is This A Good Question/Topic? 0
  • +

Replies To: Python Cannonball Project

#2 Motoma  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 452
  • View blog
  • Posts: 796
  • Joined: 08-June 10

Re: Python Cannonball Project

Posted 18 October 2011 - 05:35 AM

1. In your game loop, you will call display_score() twice, once inside display(), once inside either add_hit() or add_miss(). You will only want to draw the score once, preferably after the score is properly set.

2. In your event loop, create functions in cannon for aim_up() and aim_down(). These will adjust cannon.launch_angle appropriately.
Was This Post Helpful? 0
  • +
  • -

#3 dmorgan7  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 06-September 11

Re: Python Cannonball Project

Posted 18 October 2011 - 07:30 PM

thanks for the reply Motoma,

for 1. i had to search online and i found a helpful book on google that properly utilized the pygame.font.render and modified my display_score() function as seen below
def display_score(self):
        # Display some text
        font = pygame.font.Font(None, 36)
        text = font.render("Hits:"+ str(self.cannon_hits) + " Misses:" + str(self.cannon_misses), 1, (10, 10, 10))
        textpos = text.get_rect()
        # Blit everything to the screen
        self.window.fill(Gui.SKY_BLUE, textpos)
        self.window.blit(text, (0, 0))
        pygame.display.update(textpos)



for 2. your advice helped out a lot and i edited the cannon class accordingly using an online trigonometric calculator for the cannon barrel's xy values.
Was This Post Helpful? 0
  • +
  • -

#4 Motoma  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 452
  • View blog
  • Posts: 796
  • Joined: 08-June 10

Re: Python Cannonball Project

Posted 19 October 2011 - 05:33 AM

Glad I could help. Come back if you have any more questions.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1