I am currently developing a 2d pinball game in python using the pygame library, I opted for the mask collision detection, here is a link to a post where it's well explained:
2D Collision detection for Pinball Game
I think I did everything but it's not working as wanted .
Here is my code for the physiscs of the ball:
from math import *
from Constants import *
def Getcolor(ballx,bally,screen,resources):
screen.blit(resources["CollisionMain"], (220, 0))
color=screen.get_at((ballx,bally))
colore=color[1]
return colore
def UpdateBall(ball,color):
ballx=ball[1][0]
bally=ball[1][1]
lastpos = ball[1][0], ball[1][1]
velocity=ball[2]
if -FRICTION_BALL <= velocity <= FRICTION_BALL :
velocity = 0
else:
velocity += FRICTION_BALL if velocity < 0 else -FRICTION_BALL
ball[2] = velocity
ball[1][0] += velocity
vectorx = sin(color / 255 * 2 * pi)
vectory = cos(color / 255 * 2 * pi)
if ballx+Ball_width<screen_width:
ballx=screen_width-Ball_width
if (bally+Ball_len)>screen_lenght:
bally=screen_lenght-Ball_len
#ball[1][1] -= 10
else:
if color == 255:
ball[1][1] += Gravity
else:
ball[1][0],ball[1][1]=lastpos
ball[1][0] += vectorx
ball[1][1] += vectory
def DrawBall(screen,ball,resources):
screen.blit(ball[0],(ball[1][0],ball[1][1]))
and here is my game engine code:
import pygame
import sys
from pygame.locals import *
from Constants import *
from ball import *
def Init():
pygame.init()
screen = pygame.display.set_mode((screen_width,screen_lenght))
pygame.display.set_caption('Supinball')
pygame.key.set_repeat(150,150)
pygame.mixer.init(44100, -16, 2, 1024)
return screen
def LoadResources():
resources= dict()
resources["MainLayer"] = pygame.image.load("resources/images/main_layer.png")
resources["Ball"] = pygame.image.load("resources/images/Ball.png")
resources["CollisionMain"] = pygame.image.load("resources/images/collision_main.png")
resources["CollisionSpec"] = pygame.image.load("resources/images/collision_special.png")
resources["Rflipper"] = pygame.image.load("resources/images/right_flipper.png")
resources["Lflipper"] = pygame.image.load("resources/images/left_flipper.png")
resources["Spring"] = pygame.image.load("resources/images/spring.png")
resources["Music"] = pygame.mixer.Sound("resources/sounds/music.ogg")
resources["Coin"] = pygame.mixer.Sound("resources/sounds/Coin.wav")
resources["Hit"] = pygame.mixer.Sound("resources/sounds/hit.wav")
resources["Tilted"] = pygame.mixer.Sound("resources/sounds/tilted.wav")
resources["GameOver"] = pygame.mixer.Sound("resources/sounds/GameOver.ogg")
resources["Font"] = pygame.font.Font('resources/Vdj.ttf', 30)
return resources
def GameLoop(screen,resources):
gameRunning = True
ball = [resources["Ball"],[300,20],0]
fpsClock = pygame.time.Clock()
while gameRunning:
ev = GetEvent(ball)
gameRunning = ev[GAME_RUNNING]
#resources["Music"].play(-1)
color=Getcolor(int(ball[1][0]), int(ball[1][1]), screen, resources)
print(color)
UpdateBall(ball,color)
#screen.blit(resources["MainLayer"], (0,0))
DrawBall(screen,ball,resources)
pygame.display.update()
fpsClock.tick(FPS)
def GetEvent(ball):
ev = [True,False,False,False,False,False,False,False,False,False]
for event in pygame.event.get():
if event.type == QUIT:
ev[GAME_RUNNING] = False
if event.type == MOUSEBUTTONUP:
mousepos = pygame.mouse.get_pos()
ball[1][0],ball[1][1]=mousepos
if event.type == KEYDOWN:
if event.key == K_DOWN:#compress spring
ev[KEY_DOWN] = True
if event.key == K_UP: #relax spring
ev[KEY_UP] = True
if event.key == K_LSHIFT: #left flipper
ev[KEY_LSHIFT] = True
if event.key == K_RSHIFT: #right flipper
ev[KEY_RSHIFT] = True
if event.type == KEYUP:
if event.key == K_q: #insert coin
ev[KEY_Q] = True
if event.key == K_SPACE: #launch ball
ev[KEY_SPACE] = True
if event.key == K_LEFT:#tilt left
ev[KEY_LEFT] = True
if event.key == K_RIGHT:#tilt right
ev[KEY_RIGHT] = True
if event.key == K_p:#pause
ev[KEY_P] = True
return ev
def DestroyGame():
pygame.quit()
and the constants code:
#screen
screen_lenght = 256
screen_width= 600
#fps
FPS=100
#events
GAME_RUNNING = 0
KEY_Q = 1
KEY_DOWN = 2
KEY_UP = 3
KEY_SPACE = 4
KEY_LSHIFT = 5
KEY_RSHIFT = 6
KEY_RIGHT = 7
KEY_LEFT = 8
KEY_P = 9
#ball physics
FRICTION_BALL=0.5
Gravity=1.9
Ball_width=11
Ball_len=9
But when I run it the ball is not colliding perfectly it's only colliding with the darkest spots and going through the light grey colors
If you look at this picture
the ball shouldn't be able to go through the bumpers but it does—I am sorry if my code is garbage, I am a beginner. :)
Here is a youtube link to a kinda working version of what I want to achieve:
https://www.youtube.com/watch?v=SXegewcVx8A