Python Forum

Full Version: PYGAME draw ball
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi everyone,
I am working on a game with python 3.6 and PYGAME and with the Geany 1.36 text editor.

It is a game where a ball falls randomly from top to bottom and you have to catch it.
The problem is that when loading the image of the ball it is not drawn in the window when executing it.

Help me, find where I am making the mistake?
or I need to add something


catch!.py
import pygame
from pygame.sprite import Group

from settings import Settings
import game_functions as gf
from character import Character
from background import Background
from gamestats import GameStats
from button import Button
from scoreboard import Scoreboard

def run_game():
    pygame.init()
    c_settings = Settings()
    screen = pygame.display.set_mode(
	    (c_settings.screen_width, c_settings.screen_height))
    pygame.display.set_caption("Welcome to Catch")
    catch = pygame.mixer.Sound("sounds/jumping2.wav")
    end = pygame.mixer.music.load("sounds/end.wav")
    pygame.mixer.music.load("sounds/music.ogg")
    stats = GameStats(c_settings)
    sb = Scoreboard(screen, c_settings, stats)
    background = Background(screen)
    character = Character(screen)
    balls = Group()
    gf.create_balls(screen, c_settings, balls)
    play_button = Button(c_settings, screen, "Play")
    
    while True:
	    gf.check_key_events(character, screen, stats, c_settings, balls,
	        play_button, sb)
	    if stats.game_active == True:
		    gf.update_balls(screen, balls, c_settings, character, stats, sb, catch, end)
		    character.update(c_settings)
	    gf.update_screen(screen, c_settings, character, balls, 
		background, stats, play_button, sb)

run_game()	

        
game_functions.py
import sys
import pygame
from ball import Ball
from time import sleep


def check_key_events(character, screen, stats, c_settings, balls,
    play_button, sb): 
	
    for event in pygame.event.get():
	    if event.type == pygame.QUIT:
		    sys.exit()
	    elif event.type == pygame.MOUSEBUTTONDOWN:
		    mouse_x, mouse_y = pygame.mouse.get_pos()
		    check_play_button(stats, play_button, mouse_x, mouse_y, 
		        character, c_settings, balls, sb)
		
	    elif event.type == pygame.KEYDOWN:
		    keydown_event(event, character, screen, stats, c_settings,
		        balls, sb)
		    
	    elif event.type == pygame.KEYUP:
		    keyup_event(event, character) 
		    
def keydown_event(event, character, screen, stats, c_settings, balls, 
    sb):
	
    if event.key == pygame.K_q:
	    sys.exit()
    if event.key == pygame.K_p:
	    if not stats.game_active:
		    start_game(stats, character, c_settings, balls, sb)
    if event.key == pygame.K_LEFT:
	    character.moving_left = True
    if event.key == pygame.K_RIGHT:
	    character.moving_right = True
    if event.key == pygame.K_SPACE:
	    if not stats.game_active:
		    start_game(stats, character, c_settings, balls, sb)
	    else:
		    if character.bottom >= character.screen_rect.bottom:
			    character.jumping = True
			    
def keyup_event(event, character):
	
    if event.key == pygame.K_LEFT:
	    character.moving_left = False
    if event.key == pygame.K_RIGHT:
	    character.moving_right = False
    if event.key == pygame.K_SPACE:
	    character.jumping = False 	  				      

def check_play_button(stats, play_button, mouse_x, mouse_y, character,
    c_settings, balls, sb):
	
    button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
    if button_clicked and not stats.game_active:
	    start_game(stats, character, c_settings, balls, sb)
	    
def start_game(stats, character, c_settings, balls, sb):
	
    pygame.mixer.music.set_volume(1.0)
    pygame.mixer.music.play(-1, 0.0)
    balls.empty()
    character.reset_position()
    pygame.mouse.set_visible(False)
    stats.dynamic_settings()
    c_settings.initialize_dynamic_settings()
    sb.prep_score()
    sb.prep_lives_left()
    stats.game_active = True
    
def create_balls(screen, c_settings, balls):
	
    ball = Ball(screen, c_settings)
    balls.add(ball)
    
def update_balls(screen, balls, c_settings, character, stats, sb, catch,
    end):
	
    for ball in balls:
	    ball.update(c_settings)
	    if ball.rect.bottom >= c_settings.screen_height:
		    lose_life(screen, c_settings, balls, character, stats, sb,
		        end)
	    if pygame.sprite.spritecollideany(character, balls):
		    catch.play()
		    balls.empty()
		    stats.score += 10 * (c_setting.catch_points +
		        (character.screen_rect.bottom - character.rect.bottom))
		    sb.prep_score()
		    check_high_score(stats, sb)
	    if len(balls) == 0:
		    c_settings.increase_speed()
		    create_balls(screen, c_settings, balls)
		    
def check_high_score(stats, sb):
    if stats.score > stats.high_score:
	    stats.high_score = stats.score
	    sb.prep_high_score()
	    filename = 'high_score.txt'
	    with open(filename, 'w') as file_object:
	        file_object.write(str(stats.high_score))
	        
def lose_life(screen, c_settings, balls, character, stats, sb, end):
	
    if stats.lives_left > 0:
	    stats.lives_left -= 1
	    sb.prep_lives_left()
	    #lista vacia de bolas
	    balls.empty()
	    #crear una nueva bola
	    create_balls(screen, c_settings, balls)
	    #reestablecer banderas de movimiento
	    character.moving_left = False
	    character.moving_right = False
	    character.jumping = False
	    #Establecer su posicion del personaje
	    character_reset_position()
	    #Reestablecer la velovidad del juego
	    c_settings.initialize_dynamic_settings()
	    #pausa del juego
	    sleep(0.5)
    else:
	    end.play()
	    pygame.mixer.music.stop()
	    stats.game_active = False
	    pygame.mouse.set_visible(True)
	    
def update_screen(screen, c_settings, character, balls, background, 
    stats, play_button, sb):
	
    screen.fill(c_settings.bg_color)
    background.blitme()
    character.blitme()
    balls.draw(screen)
    sb.show_score()
    if not stats.game_active:
	    play_button.draw_button()
    pygame.display.flip()	
scoreboard.py
import pygame.font
from pygame.sprite import Group
from character import Character

class Scoreboard():
	
	def __init__(self, screen, c_settings, stats):
		
	    self.screen = screen 
	    self.screen_rect = screen.get_rect()
	    self.c_settings = c_settings
	    self.stats = stats
			
	    self.text_color = (30, 30, 30)
	    self.font = pygame.font.SysFont(None, 48)
	    
	    self.prep_score()
	    self.prep_high_score()
	    self.prep_lives_left()
	    
	def prep_score(self):
		
	    rounded_score = round(self.stats.score, -1)
	    score_str = 'Score: ' + "{:,}".format(rounded_score)
	    self.score_image = self.font.render(score_str, True,
	        self.text_color)
	     
	    self.score_rect = self.score_image.get_rect()
	    self.score_rect.right = self.screen_rect.right - 20
	    self.score_rect.top = 20
	    
	def prep_high_score(self):
		
	    high_score = round(self.stats.high_score, -1)
	    high_score_str = 'High: ' + "{:,}".format(high_score)
	    self.high_score_image = self.font.render(high_score_str, True,
	        self.text_color)
	        
	    self.high_score_rect = self.high_score_image.get_rect()
	    self.high_score_rect.top = self.score_rect.top
	    self.high_score_rect.left = 20
	    
	def prep_lives_left(self):
		
	    self.lives = Group()
	    for life_number in range(self.stats.lives_left):
		    life = Character(self.screen)
		    life.rect.right = self.screen_rect.right - 10 - (life.rect.width * life_number)
		    life.rect.y = self.score_rect.bottom + 10
		    self.lives.add(life)
		    
	def show_score(self):
		
	    self.screen.blit(self.score_image, self.score_rect)
	    self.screen.blit(self.high_score_image, self.high_score_rect)
	    self.lives.draw(self.screen)			
ball.py
import pygame
from pygame.sprite import Sprite
from random import randint


class Ball(Sprite):
	
	def __init__(self, screen, c_settings):
	    super().__init__()
	    self.screen = screen
	    self.image = pygame.image.load('images/ball.png')
	    self.rect = self.image.get_rect()
	    self.screen_rect = screen.get_rect()
	    
	    self.half_width = self.rect.width / 2
	    self.rect.top = self.screen_rect.top - self.rect.height
	    x_position = randint(self.half_width, (self.screen_rect.right -
	        self.half_width))
	    self.rect.centerx = x_position
	    
	    self.y = float(self.rect.centery)
	    
	def update(self, c_settings):
	    self.y += c_settings.drop_speed
	    self.rect.centery = self.y
	    
	def blitme(self):
		#Draw the ball to the screen
	    self.screen.blit(self.image, self.rect)
	      	
character.py
import pygame
from pygame.sprite import Sprite

class Character(Sprite):
	
    def __init__(self, screen):
		
	    super().__init__()
	    self.screen = screen
	    self.image = pygame.image.load('images/sprite_r.png')
	    self.rect = self.image.get_rect()
	    self.screen_rect = screen.get_rect()
	    
	    self.rect.bottom = self.screen_rect.bottom
	    self.rect.centerx = self.screen_rect.centerx
	    
	    self.x = float(self.rect.centerx)
	    self.bottom = float(self.rect.bottom)
	    
	    self.moving_left = False
	    self.moving_right = False
	    self.jumping = False
	    
	    self.jump_height = self.screen_rect.bottom - 2 * self.rect.height
	    
    def update(self, c_settings):
		
	    if self.moving_left and self.rect.left >= 0:
		    self.image = pygame.image.load('images/sprite_1.png')
		    if self.jumping:
			    self.x -= c_settings.jumpx_speed
		    else:
			    self.x -= c_settings.movement_speed
	    if self.moving_right and self.rect.right <= self.screen_rect.right:
		    self.image = pygame.image.load('images/sprite_r.png')
		    if self.jumping:
			    self.x += c_settings.jumpx_speed
		    else:
			    self.x += c_settings.movement_speed
	    self.rect.centerx = self.x
	    
	    if self.jumping and self.bottom > self.jump_height:
		    self.bottom -= c_settings.jumpy_speed
	    if self.jumping and self.bottom <= self.jump_height:
		    self.jumping = False
	    if self.jumping == False and self.bottom < self.screen_rect.bottom:
		    self.bottom += c_settings.jumpy_speed
	    self.rect.bottom = self.bottom
	    
    def reset_position(self):
	    self.x = self.screen_rect.centerx
	    self.rect.centerx = self.x
	    self.bottom = self.screen_rect.bottom
	    self.rect.bottom = self.bottom
	    
    def blitme(self):
		
	    self.screen.blit(self.image, self.rect)	 				
			
			     		
button.py
import pygame.font

class Button():
	
	def __init__(self, c_settings, screen, msg):
	    	    
	    self.screen = screen
	    self.screen_rect = screen.get_rect()
	    
	    self.width, self.height = 200, 50
	    self.button_color = (0, 255, 0)
	    self.text_color = (255, 255, 255)
	    self.font = pygame.font.SysFont(None, 48)
	    
	    self.rect = pygame.Rect(0, 0, self.width, self.height)
	    self.rect.center = self.screen_rect.center
	    
	    self.prep_msg(msg)
	    
	def prep_msg(self, msg):
		
	    self.msg_image = self.font.render(msg, True, self.text_color,
	        self.button_color)
	    self.msg_image_rect = self.msg_image.get_rect()
	    self.msg_image_rect.center = self.rect.center
	    
	def draw_button(self):
	    self.screen.fill(self.button_color, self.rect)
	    self.screen.blit(self.msg_image, self.msg_image_rect)		 
gamestats.py
class GameStats():
	
	
	def __init__(self, c_settings):

	    self.c_settings = c_settings
	    filename = 'high_score.txt'
	    with open(filename) as file_object:
		    self.high_score = int(file_object.read())
		    
		
	    self.game_active = False
	    
	    
	    self.dynamic_settings()
	    
	    
	def dynamic_settings(self):
		
	    self.lives_left = 2
	    self.score = 0				
settings.py
import pygame

class Settings:
	
	def __init__(self):
	    self.screen_width = 1200
	    self.screen_height = 631
	    self.bg_color = (0, 0, 255)
	    self.speedup_scale = 1.01
		
	    self.initialize_dynamic_settings()
	    
	def initialize_dynamic_settings(self):
	    self.movement_speed = 20
	    self.jumpx_speed = 30
	    self.jumpy_speed = 10
	    self.drop_speed = 10
	    self.catch_points = 100
	    
	def increase_speed(self):
	    self.movement_speed *= self.speedup_scale
	    self.jumpx_speed *= self.speedup_scale
	    self.jumpy_speed *= self.speedup_scale
	    self.drop_speed *= self.speedup_scale		    
	    
		 
background.py
import pygame

class Background():
	
	def __init__(self, screen):
	    self.screen = screen
	    self.image = pygame.image.load('images/fondo.png')
	    
	    self.rect = self.image.get_rect()
	    self.screen_rect = screen.get_rect()
	    
	    self.rect.top = 0
	    self.rect.left = 0
	    
	def blitme(self):
	    self.screen.blit(self.image, self.rect)
(Nov-08-2019, 02:51 AM)gean Wrote: [ -> ]The problem is that when loading the image of the ball it is not drawn in the window when executing it.
You are defining your draw method as blitme
    def blitme(self):
        #Draw the ball to the screen
        self.screen.blit(self.image, self.rect)
and in game_functions you are
    balls.draw(screen)
Either change blitme to draw or draw to blitme