sleepoz sleepoz - 6 months ago 12
Python Question

The Pong ball is going through the paddle and hitting the wall and reflecting rather hitting the paddle

I am making a pong game which will eventually have a block/turrent in the middle with like cannons that will either shoot balls or powerups and ill end up adding different features but right now I cant even get the ball to hit the paddle correctly.....
import pygame

BLACK = (0,0,0)
WHITE = (255,255,255)
RED = (255,0,0)
GOLD = (201,168,168)
Call = pygame.sprite.Group(())
got = pygame.sprite.Group(())
SCR_WID, SCR_HEI = 640, 480
backg = pygame.image.load("background.png")


class Player(pygame.sprite.Sprite):
def __init__(self, name):
pygame.sprite.Sprite.__init__(self)
if name == "george":
self.x, self.y = 16, SCR_HEI/2
elif name =="frank":
self.x, self.y = SCR_WID-16, SCR_HEI/2
self.name = name
self.speed = 3
self.padWid, self.padHei = 8, 64
self.score = 0
self.scoreFont = pygame.font.Font("imagine_font.ttf", 64)



def scoring(self):
scoreBlit = self.scoreFont.render(str(self.score), 1, (255, 255, 255))
if self.name == "george":
screen.blit(scoreBlit, (32, 16))
if self.score == 10:
print ("player 1 wins!")
exit()
elif self.name == "frank":
screen.blit(scoreBlit, (SCR_HEI+92, 16))
if self.score == 10:
print ("Player 2 wins!")
exit()

def movement(self):

keys = pygame.key.get_pressed()
if self.name == "george":
if keys[pygame.K_w]:
self.y -= self.speed
elif keys[pygame.K_s]:
self.y += self.speed
elif self.name == "frank":
if keys[pygame.K_UP]:
self.y -= self.speed
elif keys[pygame.K_DOWN]:
self.y += self.speed

if self.y <= 0:
self.y = 0
elif self.y >= SCR_HEI-64:
self.y = SCR_HEI-64

def draw(self):
pygame.draw.rect(screen, (255, 255, 255), (self.x, self.y, self.padWid, self.padHei))


The ball is going through the enemy paddle. It does not actually go through it will block it but it goes past the paddle. I have been trying different ways but I am new to this and am struggling.

This is the class I believe is causing me the trouble, I am not getting any errors by the way its just not hitting the paddle as id like it to. player paddle works fine its just the enemy one that is not doing it correctly.

class Ball(pygame.sprite.Sprite):
image = pygame.image.load("bong.png")
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.rect = self.image.get_rect()

self.rect.x, self.rect.y = SCR_WID/2, SCR_HEI/2
self.speed_x = -3
self.speed_y = 3
self.size = 8

def movement(self):
self.rect.x += self.speed_x
self.rect.y += self.speed_y


if self.rect.y <= 0:
self.speed_y *= -1
elif self.rect.y >= SCR_HEI-self.size:
self.speed_y *= -1

if self.rect.x <= 0:
self.__init__()
enemy.score += 1
elif self.rect.x >= SCR_WID-self.size:
self.__init__()
self.speed_x = 3
player.score += 1

for n in range(-self.size, player.padHei):
if self.rect.y == player.y + n:
if self.rect.x <= player.x + player.padWid:
self.speed_x *= -1
break
n += 1
for n in range(-self.size, enemy.padHei):
if self.rect.y == enemy.y + n:
if self.rect.x >= enemy.x - enemy.padWid:
self.speed_x *= -1
break


I also am struggling with adding collision to the block so the ball will bounce off. Ive tried a couple of different ways but noticed that the ball was going through the paddle and had to fix that first. This is my next step. Any help is appreciated.

class Block(pygame.sprite.Sprite):
image = pygame.image.load("brick.png")


def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.rect = self.image.get_rect()
self.rect.x = 300
self.rect.y = 0





SCR_WID, SCR_HEI = 640, 480
screen = pygame.display.set_mode((SCR_WID, SCR_HEI))
pygame.display.set_caption("Pong")
pygame.font.init()
clock = pygame.time.Clock()
FPS = 60
pygame.init()

def main():
backgscale = pygame.transform.scale(backg,(SCR_WID, SCR_HEI))

global player
player = Player("george")

global enemy
enemy = Player("frank")

block = Block ()
got.add(block)

ball = Ball()
Call.add(ball)

while True:

for event in pygame.event.get():
if event.type == pygame.QUIT:
print("Game exited by user")
exit()

screen.blit(backg,(0,0))
got.update()
Call.update()
backgscale = pygame.transform.scale(backg,(SCR_WID, SCR_HEI))
got.draw(screen)
Call.draw(screen)
player.movement()
enemy.movement()
ball.movement()

player.draw()
player.scoring()
enemy.draw()
enemy.scoring()





pygame.display.flip()
clock.tick(FPS)

main()


I do not know if I am calling things wrong or not.

I've tried creating sprite groups and displaying them that way I don't know a better way to display them and still have them to move...

Answer

I had to change the images to Surfaces as I don't have the images, but this works fine for me.

import pygame
from pygame.locals import *

SCR_WID, SCR_HEI = 640, 480
screen = pygame.display.set_mode((SCR_WID, SCR_HEI))
pygame.display.set_caption("Pong")
pygame.font.init()
clock = pygame.time.Clock()
FPS = 60
pygame.init()


BLACK = (0,0,0)
WHITE = (255,255,255)
RED = (255,0,0)
GOLD = (201,168,168)
Call = pygame.sprite.Group(())
got = pygame.sprite.Group(())
#SCR_WID, SCR_HEI = 640, 480
backg = pygame.Surface((SCR_WID, SCR_HEI)) #pygame.image.load("background.png")


class Player(pygame.sprite.Sprite):
        def __init__(self, name):
                pygame.sprite.Sprite.__init__(self)
                if name == "george":
                        self.x, self.y = 16, SCR_HEI/2
                elif name =="frank":
                        self.x, self.y = SCR_WID-16, SCR_HEI/2
                self.name = name
                self.speed = 3
                self.padWid, self.padHei = 8, 64
                self.score = 0
                self.scoreFont = pygame.font.SysFont("Arial", 32) #imagine_font.ttf", 64)           



        def scoring(self):
                scoreBlit = self.scoreFont.render(str(self.score), 1, (255, 255, 255))
                if self.name == "george":
                        screen.blit(scoreBlit, (32, 16))
                        if self.score == 10:
                                print ("player 1 wins!")
                                exit()
                elif self.name == "frank":        
                        screen.blit(scoreBlit, (SCR_HEI+92, 16))
                        if self.score == 10:
                                print ("Player 2 wins!")
                                exit()

        def movement(self):

                keys = pygame.key.get_pressed()
                if self.name == "george":
                        if keys[pygame.K_w]:
                                self.y -= self.speed
                        elif keys[pygame.K_s]:
                                self.y += self.speed
                elif self.name == "frank":
                        if keys[pygame.K_UP]:
                                self.y -= self.speed
                        elif keys[pygame.K_DOWN]:
                                self.y += self.speed

                if self.y <= 0:
                        self.y = 0
                elif self.y >= SCR_HEI-64:
                        self.y = SCR_HEI-64

        def draw(self):
                pygame.draw.rect(screen, (255, 255, 255), (self.x, self.y, self.padWid, self.padHei))

class Ball(pygame.sprite.Sprite):
    image = pygame.Surface((8,8)) #pygame.image.load("bong.png")
    image.fill((255,255,255))
    def __init__(self):
            pygame.sprite.Sprite.__init__(self)
            self.rect = self.image.get_rect()

            self.rect.x, self.rect.y = SCR_WID/2, SCR_HEI/2
            self.speed_x = -3
            self.speed_y = 3
            self.size = 8

    def movement(self):
            self.rect.x += self.speed_x
            self.rect.y += self.speed_y


            if self.rect.y <= 0:
                    self.speed_y *= -1
            elif self.rect.y >= SCR_HEI-self.size:
                    self.speed_y *= -1

            if self.rect.x <= 0:
                    self.__init__()
                    enemy.score += 1
            elif self.rect.x >= SCR_WID-self.size:
                    self.__init__()
                    self.speed_x = 3
                    player.score += 1

            for n in range(-self.size, player.padHei):
                    if self.rect.y == player.y + n:
                            if self.rect.x <= player.x + player.padWid:
                                    self.speed_x *= -1
                                    break
                    n += 1
            for n in range(-self.size, enemy.padHei):
                    if self.rect.y == enemy.y + n:
                            if self.rect.x >= enemy.x - enemy.padWid:
                                    self.speed_x *= -1
                                    break

    def draw(self, screen):
        pygame.draw.rect(screen, (255,255,255), (self.rect.x, self.rect.y, self.size, self.size))

class Block(pygame.sprite.Sprite):
        image = pygame.Surface((20,20)) #image.load("brick.png")


        def __init__(self):
                pygame.sprite.Sprite.__init__(self)
                self.rect = self.image.get_rect()
                self.rect.x = 300
                self.rect.y = 0






def main():
    backgscale = pygame.transform.scale(backg,(SCR_WID, SCR_HEI))

    global player
    player = Player("george") 

    global enemy
    enemy = Player("frank")

    block = Block ()
    got.add(block)

    ball = Ball()
    Call.add(ball)

    while True:

            for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                            print("Game exited by user")
                            exit()

            screen.blit(backg,(0,0))                  
            got.update()
            Call.update()
            backgscale = pygame.transform.scale(backg,(SCR_WID, SCR_HEI))
            got.draw(screen)
            Call.draw(screen)
            player.movement()
            enemy.movement()
            ball.movement()

            player.draw()
            player.scoring()
            enemy.draw()
            enemy.scoring()





            pygame.display.flip()
            clock.tick(FPS)

if __name__ == "__main__":
    main()
Comments