Aadarsh Jha
Aadarsh Jha

Reputation: 25

Wall collision detection in pygame

I was working on a game, similar to Pong on pygame, and I had come across the problem of wall collision detection. It works with the two paddles, but does not work with the ball itself. The code makes sense, but it doesn't actually work.

import pygame, sys
from pygame.locals import *
x = 25
xc = 404
yc = 300
y = 225
x1 = 740
movey1 = 0
y1 = 225
movex = 0
movey = 0
movebx = 2
moveby = 2
WHITE = (255,255,255)
GREEN = (0,255,0)
BLUE = (0,0,128)
RANDOM = (255,0, 0)
BLACK = (0,0,0)
width = 600
pygame.init()
display = pygame.display.set_mode((800,600))
pygame.display.set_caption("Pong!")
img = pygame.image.load("pongbg.jpg")
pygame.mixer.music.load("stay.mp3")
pygame.mixer.music.play(0)

while True:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_m:
                pygame.mixer.music.load("stay.mp3")
                pygame.mixer.music.play(0)
            if event.key == pygame.K_w:
                movey = -2
                pygame.display.flip() 
                if y  <= 0 or y>=600:
                    print "hello"
                    movey = -movey
            if event.key == pygame.K_s:
                movey = 2
                pygame.display.flip()
                if y >= 600 or y <0:
                    print "hello"
                    movey = -movey
            if event.key == pygame.K_UP:
                movey1 = -2
                if y1  <= 0 or y1> 600:
                    print "hello"
                    movey1 = -movey1
            if event.key == pygame.K_DOWN:
                movey1 = 1.5 
                if y1  <= 0 or y1> 600:
                    print "hello"
                    movey1 = -movey1
            if yc < 0 or yc >= 600 or yc >= 500:
                print "hello"
                moveby = -moveby
            if xc < 0 or xc > 800:
                print "hello"
                moveby = -moveby
        if event.type == pygame.KEYUP:
            movey1 = 0
            movey = 0
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    x += movex
    y += movey
    y1 += movey1
    xc+=movebx
    yc+=moveby
    #xc += movey
    #yc +=movey1
    pygame.display.flip()
    display.blit(img, (0,0))
    asdf = pygame.draw.rect(display, RANDOM, (x,y,34, 154))
    ghjk = pygame.draw.rect(display,RANDOM, (x1,y1,34,154))
    qwerty = pygame.draw.circle(display,GREEN, (xc,yc), 25,0)
    pygame.display.flip()
    pygame.display.update()

Everything else is pretty much done, I have looked around in stack overflow, but could not find a detailed answer.

Thanks, AJ

Upvotes: 0

Views: 1512

Answers (4)

knowledge
knowledge

Reputation: 403

I can just say how my program with collision work:

import pygame
from pygame.locals import*
import sys

pygame.init()

screen = pygame.display.set_mode((1200, 700))

ticket1 = True
f = [0, 0]

pa = 600
pb = 650
a = 600
b = 650
color = (100, 180, 100)
while ticket1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            ticket1 = False
            pygame.quit()
            sys.exit()

screen.fill((255, 250, 245))

pygame.draw.circle(screen, color, (a, b), 50)
pa += f[0]
pb += f[1]
a = int(pa)
b = int(pb)
if a-50 < 0:
    f[0] = -f[0]
    a = 51
    pa = 51
elif a+50 > 1200:
    f[0] = -f[0]
    a = 1149
    pa = 1149

if b-50 < 0:
    f[1] = -f[1]
    b = 51
    pb = 51
elif b+50 > 700:
    f[1] = -f[1]
    b = 650
    pb = 650

If you think that this is bad answer this program works so maybe you have to write

if yc < 0 or yc >= 600 or yc >= 500:
                print "hello"
                moveby = -moveby
            if xc < 0 or xc > 800:
                print "hello"
                moveby = -moveby

outside of:

for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:

but I'm not sure.

For the paddles I think that answers before have good idea.

Upvotes: 0

Bartlomiej Lewandowski
Bartlomiej Lewandowski

Reputation: 11170

I'm afraid you paddle detection does not work as well. My advice would be to divide your code into classes. This way the paddles will be informed of the intent of moving, but they will decide if it is possible to move. I have also noticed that you are flipping the screen inside the event loop. The event loop should not update the screen, only move the sprites around.

Here is something you can start with:

class Paddle:
    def __init__(self,x,y):
        self.vy = 0
        self.y = y
        self.x = x
    def move(self):
        if( self.vy == 1 and canMoveUp(self.y) or self.vy == -1 and canMoveDown(self.y):
            self.y+=vy
    def draw(self,screen):
        screen.blit()

class Ball:
    def __init__(self,x,y):
        self.vx = 1
        self.vy = 0
        self.x = y
        self.y = x
    def move(self):
        #check for collisions same as with paddles
    def draw(self,screen):
        screen.blit()

Upvotes: 0

Toalp
Toalp

Reputation: 362

You can use rects or you can use loads of if's statments.

you know the ball's x and the ball's y. you know the ball's width and height, and the paddles' too.

all you have to do is check if the ball's right (xc+25) is greater than the right paddle's left (x1). same with the left paddle.

with rects in pygame, you can use the function b.colliderect(a) which returns True if b and a collide.

Upvotes: 0

TheCrazyRussian
TheCrazyRussian

Reputation: 33

Read up about pygame.rect and pygame.rect.colliderect

you could make the walls rects and put rects on the bumpers and detect when the bumper collides with the wall.

Sorry about the short answer.

Upvotes: 1

Related Questions