Pyprocessing 3d collisions

I am nearly done with my pyprocessing 3d pong-esque game… I have ran into trouble with the paddle-ball collisions. Sometimes, the collisions are more accurate than others…

from processing import *
from math import *

kDict = {32: False, 90: False}
width, height, c_m, g_m, s, l = 555, 500, 1, "start", 0, 5

class P(object):
    def __init__(self, x, y, z, c, w, h):
        self.cor, self.c, self.w, self.h = PVector(x, y, z), c, w, h
        
    def drawSelf(self):
        noStroke(); fill(self.c[0], self.c[1], self.c[2])
        pushMatrix()
        translate(self.cor.x, self.cor.y, self.cor.z + 50)
        box(self.w, self.h, 20)        
        popMatrix()
        
class B(object):
    def __init__(self, x, y, z, r, c, vel_x, vel_y, vel_z):
        self.cor, self.r, self.c, self.vel = PVector(x, y, z), r, c, PVector(vel_x, vel_y, vel_z)
        
    def drawSelf(self):
        noStroke(); fill(self.c[0], self.c[1], self.c[2])
        pushMatrix()
        translate(self.cor.x, self.cor.y, self.cor.z)
        sphereDetail(15)
        sphere(self.r)
        popMatrix()
        
    def moveSelf(self):           
        self.cor.x, self.cor.y, self.cor.z = self.cor.x + self.vel.x, self.cor.y + self.vel.y, self.cor.z + self.vel.z
        
    def checkSelf(self):
        global s, g_m, l, reg
        if self.cor.x - self.r <= 0 or self.cor.x + self.r >= width: self.vel.x = -self.vel.x
            
        if self.cor.y - self.r <= 0 or self.cor.y + self.r >= height: self.vel.y = -self.vel.y
            
        if self.cor.z - self.r <= -830: self.vel.z += 1 if self.vel.z > 0 else -1; self.vel.z = -self.vel.z
             
        if self.cor.z + self.r >= 100: 
            if l > 1: l, self.cor, g_m =  l - 1, PVector(width / 2, height - 60, -200), "start"
            else: l, g_m = l - 1, "lost"
        
        if self.cor.x + self.r > (pl.cor.x - pl.w / 2) and self.cor.x + self.r < (pl.cor.x + pl.w / 2):
            if self.cor.y + self.r > (pl.cor.y - pl.h / 2) and self.cor.y + self.r < (pl.cor.y + pl.h / 2):
                if self.cor.z - self.r < pl.cor.z + 10: self.vel.z = -self.vel.z      

def setup():
    global pl, b
    size(width, height, P3D)
    pl = P(width / 2, height - 75, 50, [0, 0, 255], 100, 100)
    b = B(width / 2, height - 60, -200, 20, [255, 255, 255], 4, -4, 4)
    
def draw():
    global g_m
    background(255)
    
    camera(width / 2, height / 2, (height / 2) / tan(PI * 30 / 180), width / 2, height / 2, -400, 0, 1, 0) if c_m == 1 else camera(width / 2, height / 2, -980, width / 2, height / 2, -400, 0, 1, 0)
    lights()
    
    stroke(0); fill(20)
    pl.cor.x, pl.cor.y = mouse.x, mouse.y

    pushMatrix()
    translate(0, 0, 400); rect(0, 0, width, height)
    popMatrix()

    pushMatrix()
    translate(0, 0, -950); rect(0, 0, width, height)
    popMatrix()

    pushMatrix()
    translate(0, 0, 400); rotateY(PI / 2); rect(0, 0, 1350, height)
    popMatrix()

    pushMatrix()
    translate(width, 0, -950); rotateY(-PI / 2); rect(0, 0, 1350, height)
    popMatrix()

    pushMatrix()
    translate(0, 0, -950); rotateX(PI / 2); rect(0, 0, width, 1350)
    popMatrix()   

    pushMatrix()
    translate(0, height, 400); rotateX(-PI / 2); rect(0, 0, width, 1350)
    popMatrix()  
    
    pushMatrix()
    translate(0, 0, -920); fill(255)
    textSize(60); text("Score: {} \nLives: {}".format(s, l), 180, 150)
    popMatrix()

    pl.drawSelf()
    
    if g_m == "start":
        textSize(60)
        text("'Space' to Play", 100, 200)
        
        if kDict[32]:
            g_m = "game_on"
        
    if g_m == "game_on":
        b.drawSelf(); b.moveSelf(); b.checkSelf()
        
    if g_m == "lost":
        translate(0, 0, 0)
        textSize(60)
        text("Score: {}".format(s), 180, 50)
        exitp()
        
def keyPressed():
    global c_m, kDict
    kDict[keyboard.keyCode] = True
    
    if kDict[90]: 
        if c_m == 2: c_m = 1; camera(width / 2, height / 2, (height / 2) / tan(PI * 30 / 180), width / 2, height / 2, 0, 0, 1, 0)
        else: c_m = 2; camera(width / 2, height / 2, (height / 2) / tan(PI * 30 / 180), width / 2, height / 2, 0, 0, 1, 0)
    
def keyReleased():
    global kDict
    kDict[keyboard.keyCode] = False

run()
1 Like

in these lines

if self.cor.x - self.r <= 0 or self.cor.x + self.r >= width: self.vel.x = -self.vel.x
        

you treat left and right border in ONE line. In both situations you react with self.vel.x = -self.vel.x

This is common, even on the website. I don’t like it, since it can lead to brief stuttering.

Suggestion

Instead I separate this and use abs() (I don’t know if we have this abs() in python):

if self.cor.x - self.r <= 0: self.vel.x = abs(self.vel.x)

if self.cor.x + self.r >= width: self.vel.x = - abs(self.vel.x)
        

same for the other checks

(why do you increase / decrease z vel?)

Chrisir

1 Like

You can simply check its reference page: :face_with_hand_over_mouth: Reference

Here’s the 1 for abs(): abs() \ Language (API)

1 Like