pygame – Bounding Field/Rectangle collision glitches

pygame – Bounding Field/Rectangle collision glitches

[ad_1]

I have been engaged on this golf sport for a few weeks and have been making an attempt to create a dependable collision system for every time a golf ball (mini golf) hits a block. I am utilizing common rectangular field collision to assist me with, however I’ve continuously been operating into glitching points, eg, the golf ball can clip via blocks. I’ve tried many strategies to resolve this however none of them work properly.

The way in which I deal with transferring the ball is sort of easy, is that the participant clicks on the ball, drags and releases, which gives an preliminary velocity and angle, I then get x & y parts and reduce or enhance the place of the golf ball, I even have variables which may make the parts adverse. Code for that is beneath.

    def taking pictures(self):

    self.x_vel = self.initial_vel * (math.cos(math.radians(self.angle)))
    self.y_vel = self.initial_vel * (math.sin(math.radians(self.angle)))
    if self.x_inverse:
        self.x_vel *= -1
    if self.y_inverse:
        self.y_vel *= -1
    self.rect.centerx -= self.x_vel*self.dt
    self.rect.centery -= self.y_vel*self.dt
    self.initial_vel -=  self.resistance * self.dt
    if self.initial_vel <= 10:
        self.shoot = False

My methodology for calculating collisions with a block is simply common bounding field/rectangular field collision, code is beneath.

def bounced(self, golf_ball):

    if golf_ball.rect.colliderect(self.rect):
        if abs(self.rect.left - golf_ball.rect.proper) <= 5:

            if golf_ball.rect.proper > self.rect.left:
                golf_ball.rect.proper = self.rect.left
                golf_ball.rect.proper -= 1
            if golf_ball.x_inverse:
                golf_ball.x_inverse = False
            else:
                golf_ball.x_inverse = True  # Left

        if abs(self.rect.proper - golf_ball.rect.left) <= 5:

            if golf_ball.rect.left < self.rect.proper:
                golf_ball.rect.left = self.rect.proper
                golf_ball.rect.left += 1

            if golf_ball.x_inverse:
                golf_ball.x_inverse = False
            else:
                golf_ball.x_inverse = True  

        if abs(self.rect.backside - golf_ball.rect.high) <= 5:  # Backside

            if golf_ball.rect.high < self.rect.backside:
                golf_ball.rect.high = self.rect.backside
                golf_ball.rect.high += 1
            if golf_ball.y_inverse:
                golf_ball.y_inverse = False
            else:
                golf_ball.y_inverse = True

        if abs(self.rect.high - golf_ball.rect.backside) <= 5:
            if golf_ball.rect.backside > self.rect.high:
                golf_ball.rect.backside = self.rect.high
                golf_ball.rect.backside -= 1

            if golf_ball.y_inverse:
                golf_ball.y_inverse = False
            else:
                golf_ball.y_inverse = True`

My challenge arises when the ball is launched at excessive speeds close to the block, the golf ball can glitch via the block, which is clearly undesirable.
Golf Ball glitching in block

Beneath is my code and picture for golf ball and field/block, the precise elements of code value is the taking pictures methodology and bounce_detection within the golf ball class, and the bounced methodology within the block class, the one cause I added all different code, is as a way to check out the code, and try to resolve the problem.

import pygame
import math

pygame.init()
display = pygame.show.set_mode((640, 480))
clock = pygame.time.Clock()
mouse_pos = pygame.mouse.get_pos()
dt = clock.tick(70) / 1000


class Golf_Ball:
 def __init__(self, x_pos, y_pos, mass, w, h, mouse_pos, display, dt):
     self.display = display
     self.resisting = False

     # self.dt = dt
     self.mass = mass
     self.w = w
     self.h = h
     self.seen = True
     self.initial_vel = 0
     self.x_vel, self.y_vel = 0, 0
     self.resultant = 0
     self.mouse_pos = mouse_pos
     self.fired = True
     self.hit_time = 0
     self.held_down = False
     self.line = False
     self.fired_resultant = 0
     self.x_pos = x_pos
     self.y_pos = y_pos
     self.angle = 0
     self.shoot = False
     self.resistance = 100
     self.velocity_constant = 0.3
     self.spin_angel = 0
     self.picture = pygame.picture.load('Property/golf.png').convert_alpha()
     self.image_copy = pygame.remodel.rotate(self.picture, 0)
     self.rect = self.picture.get_rect(middle=(self.x_pos, self.y_pos))
     self.x_inverse, self.y_inverse = False, False

 def mouse_click_manager(self):
     if pygame.mouse.get_pressed()[0] == True and self.shoot == False:

         if self.rect.collidepoint(self.mouse_pos):

             if self.line == False and self.held_down == False:
                 self.held_down = True
                 self.line = True
         if self.line and self.held_down == False:
             self.held_down = True
             self.line = False

             self.fired_resultant = self.resultant * self.velocity_constant
             self.initial_vel = int(spherical(((self.fired_resultant / self.mass) * 1), 0))
             print("Hit", self.initial_vel)
             self.shoot = True
             self.x_inverse, self.y_inverse = False, False

     elif not pygame.mouse.get_pressed()[0]:
         self.held_down = False

 def line_manager(self):
     if self.line:

         if abs(self.rect.centerx - self.mouse_pos[0]) != 0:
             self.angle = math.levels(
                 math.atan(abs(self.rect.centery - self.mouse_pos[1]) / abs(self.rect.centerx - self.mouse_pos[0])))
             if self.mouse_pos[1] < self.rect.centery:
                 self.angle = self.angle * -1
             if self.mouse_pos[0] < self.rect.centerx:
                 self.angle = abs(self.angle - 90) + 90
         elif abs(self.rect.centerx - self.mouse_pos[0]) == 0:
             if self.mouse_pos[1] > self.rect.centery:
                 self.angle = 90
             else:
                 self.angle = -90

         self.resultant = math.sqrt(
             abs(self.rect.centerx - self.mouse_pos[0]) ** 2 + abs(self.rect.centery - self.mouse_pos[1]) ** 2)

         pygame.draw.line(self.display, "Black", (self.rect.centerx, self.rect.centery), self.mouse_pos, 3)

 def taking pictures(self):

     self.x_vel = self.initial_vel * (math.cos(math.radians(self.angle)))
     self.y_vel = self.initial_vel * (math.sin(math.radians(self.angle)))
     if self.x_inverse:
         self.x_vel *= -1
     if self.y_inverse:
         self.y_vel *= -1
     self.rect.centerx -= self.x_vel * self.dt
     self.rect.centery -= self.y_vel * self.dt
     self.initial_vel -= self.resistance * self.dt
     if self.initial_vel <= 10:
         self.shoot = False

 def bounce_detection(self):
     if self.rect.left <= 0:  # Left
         if self.rect.left < 0:
             self.rect.left = 1

         if self.x_inverse:
             self.x_inverse = False
         else:
             self.x_inverse = True

     if self.rect.proper >= 640:  # Proper
         if self.rect.proper > 640:
             self.rect.proper = 639
         if self.x_inverse:
             self.x_inverse = False
         else:
             self.x_inverse = True

     if self.rect.high <= 0:  # High
         if self.rect.high < 0:
             self.rect.high = 1
         if self.y_inverse:
             self.y_inverse = False
         else:
             self.y_inverse = True

     if self.rect.backside >= 480:  # Backside
         if self.rect.backside > 480:
             self.rect.backside = 479
         if self.y_inverse:
             self.y_inverse = False
         else:
             self.y_inverse = True

 def replace(self, mouse_pos, dt):
     self.mouse_pos = mouse_pos
     self.dt = dt
     if self.seen:
         if self.shoot:
             self.taking pictures()
             self.bounce_detection()
             self.spin_angel += self.initial_vel * 10 * self.dt
             self.image_copy = pygame.remodel.rotate(self.picture, self.spin_angel)

         else:
             self.mouse_click_manager()
             self.line_manager()
         self.resistance = 300
         self.display.blit(self.image_copy, (self.rect.centerx - int(self.image_copy.get_width() / 2),
                                            self.rect.centery - int(self.image_copy.get_height() / 2)))
         pygame.draw.rect(self.display, 'White', self.rect, 1)


class Block:

 def __init__(self, x_pos, y_pos, width, peak, display, disabled, dt):
     self.x_pos = x_pos
     self.y_pos = y_pos
     self.display = display
     self.disabled = disabled
     self.width = width
     self.peak = peak
     self.picture = pygame.remodel.smoothscale(pygame.picture.load('AssetsWooden_Block.png'),
                                               (self.width, self.peak))
     self.rect = self.picture.get_rect(topleft=(self.x_pos, self.y_pos))
     self.masks = pygame.masks.from_surface(self.picture)
     self.dt = dt

     self.clock = 0
     self.counter = 0
     self.dummy_rect = pygame.Rect((self.x_pos - 5, self.y_pos - 5), (self.rect.width + 10, self.rect.peak + 10))
     self.course = True
     self.in_block = False

 def bounced(self, golf_ball):

     if golf_ball.rect.colliderect(self.rect):
         if abs(self.rect.left - golf_ball.rect.proper) <= 5:

             if golf_ball.rect.proper > self.rect.left:
                 golf_ball.rect.proper = self.rect.left
                 golf_ball.rect.proper -= 1
             if golf_ball.x_inverse:
                 golf_ball.x_inverse = False
             else:
                 golf_ball.x_inverse = True  # Left

         if abs(self.rect.proper - golf_ball.rect.left) <= 5:

             if golf_ball.rect.left < self.rect.proper:
                 golf_ball.rect.left = self.rect.proper
                 golf_ball.rect.left += 1

             if golf_ball.x_inverse:
                 golf_ball.x_inverse = False
             else:
                 golf_ball.x_inverse = True

         if abs(self.rect.backside - golf_ball.rect.high) <= 5:  # Backside

             if golf_ball.rect.high < self.rect.backside:
                 golf_ball.rect.high = self.rect.backside
                 golf_ball.rect.high += 1
             if golf_ball.y_inverse:
                 golf_ball.y_inverse = False
             else:
                 golf_ball.y_inverse = True

         if abs(self.rect.high - golf_ball.rect.backside) <= 5:
             if golf_ball.rect.backside > self.rect.high:
                 golf_ball.rect.backside = self.rect.high
                 golf_ball.rect.backside -= 1

             if golf_ball.y_inverse:
                 golf_ball.y_inverse = False
             else:
                 golf_ball.y_inverse = True

 def replace(self, golf_ball):
     self.bounced(golf_ball)

     self.display.blit(self.picture, self.rect)
     pygame.draw.rect(self.display, 'Black', self.rect, 1)


golf_ball = Golf_Ball(200, 200, 0.04593, 20, 20, mouse_pos, display, dt)
block_1 = Block(100, 300, 50, 20, display, False, dt)

block = pygame.remodel.rotate(
 pygame.remodel.smoothscale(pygame.picture.load('AssetsWooden_Block.png').convert_alpha(), (100, 50)), 45)
block_rect = block.get_rect(topleft=(300, 200))

operating = True
whereas operating:
 for occasion in pygame.occasion.get():
     if occasion.sort == pygame.QUIT:
         operating = False
     elif occasion.sort == pygame.KEYDOWN:

         key = occasion.key
         if occasion.key == pygame.K_ESCAPE:
             operating = False

 mouse_pos = pygame.mouse.get_pos()
 display.fill('Inexperienced')
 golf_ball.replace(mouse_pos, dt)
 block_1.replace(golf_ball)

 # display.blit(block, block_rect)
 clock.tick(70)
 dt = clock.tick(70) / 1000
 pygame.show.flip()

pygame.give up()

golf ball imageBlock image

[ad_2]

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply