Python Forum
[PyGame] Making Player Sprite Ricochet of walls
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] Making Player Sprite Ricochet of walls
#3
Use clipping rect size. Determine which is smaller. Width or Height. If even then you can says it hit both angles.
Then you can compare rect.centerx or rect.centery to collision rect.centerx or rect.centery.

I like displacement the best. It the easiest to start with.
Example.
import os
import pygame
import random
from pygame.sprite import Sprite, Group, spritecollide

class Block(Sprite):
    def __init__(self, image, position, group):
        Sprite.__init__(self)
        # Reference the image. Doesn't make new one
        self.image = image
        # Collision group reference
        self.group = group
        self.rect = image.get_rect()
        self.rect.topleft = position
        # Hold the floats position. Since rect only does int
        self.position = pygame.Vector2(position)
        self.direction = pygame.Vector2(
            (random.randint(0, 600) - 300) / 100 / Game.fps,
            (random.randint(0, 600) - 300) / 100 / Game.fps)

    def update(self):
        self.position += self.direction * Game.delta
        self.rect.topleft = self.position
        self.collision()

    def collision(self):
        self.wall_bounce()
        blocks = spritecollide(self, self.group, False)
        for block in blocks:
            if block != self:
                # Simple displacement
                w, h = self.rect.clip(block.rect).size
                if w < h:
                    if self.rect.centerx > block.rect.centerx:
                        self.rect.left = block.rect.right
                        self.position.x = self.rect.x
                        self.direction.x = abs(self.direction.x)
                        block.direction.x = -abs(block.direction.x)
                    else:
                        self.rect.right = block.rect.left
                        self.position.x = self.rect.x
                        self.direction.x = -abs(self.direction.x)
                        block.direction.x = abs(block.direction.x)
                else:
                    if self.rect.centery > block.rect.centery:
                        self.rect.top = block.rect.bottom
                        self.position.y = self.rect.y
                        self.direction.y = abs(self.direction.y)
                        block.direction.y = -abs(block.direction.y)
                    else:
                        self.rect.bottom = block.rect.top
                        self.position.y = self.rect.y
                        self.direction.y = -abs(self.direction.y)
                        block.direction.y = abs(block.direction.y)

    def wall_bounce(self):
        clamp = self.rect.clamp(Game.rect)

        if clamp.x != self.rect.x:
            self.rect.x = clamp.x
            self.position.x = clamp.x
            self.direction.x = -self.direction.x

        if clamp.y != self.rect.y:
            self.rect.y = clamp.y
            self.position.y = clamp.y
            self.direction.y = -self.direction.y

class Scene:
    def __init__(self):
        self.sprites = Group()
        self.create_block_images()
        self.add_blocks(15)

    def add_blocks(self, number):
        for n in range(number):
            image = random.choice(self.block_images)
            position = (random.randint(30, Game.rect.width - 30),
                        random.randint(30, Game.rect.height - 30))

            block = Block(image, position, self.sprites)
            block.add(self.sprites)

    def create_block_images(self):
        self.block_images = []

        for x in range(20):
            color = pygame.Color('black')
            while color.r < 100 and color.g < 100 and color.b < 100:
                color.r = random.randint(0, 255)
                color.g = random.randint(0, 255)
                color.b = random.randint(0, 255)

            low, high = 20, 30
            size = random.randint(low, high), random.randint(low, high)
            surface = pygame.Surface(size)
            surface.fill(color)
            self.block_images.append(surface)

    def draw(self, surface):
        self.sprites.draw(surface)
        self.sprites.update()

# Namespace for pygame game loop
class Game:
    @classmethod
    def setup(cls, title, width, height):
        # Basic pygame setup
        pygame.display.set_caption(title)
        cls.surface = pygame.display.set_mode((width, height))
        cls.rect = cls.surface.get_rect()
        cls.clock = pygame.time.Clock()
        cls.delta = 0
        cls.fps = 30

        cls.scene = Scene()

    @classmethod
    def mainloop(cls):
        cls.running = True
        while cls.running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    cls.running = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        cls.running = False

            cls.surface.fill(pygame.Color('black'))
            cls.scene.draw(cls.surface)
            pygame.display.flip()
            cls.delta = cls.clock.tick(cls.fps)

if __name__ == '__main__':
    pygame.init()
    os.environ['SDL_VIDEO_CENTERED'] = '1'
    Game.setup('Block Bouncing', 800, 600)
    Game.mainloop()
    pygame.quit()
99 percent of computer problems exists between chair and keyboard.
Reply


Messages In This Thread
RE: Making Player Sprite Ricochet of walls - by Windspar - Jun-03-2019, 02:03 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyGame] pygame, help with making a function to detect collision between player and enemy. Kris1996 3 3,326 Mar-07-2020, 12:32 PM
Last Post: Kris1996
  [PyGame] Sprite image.get_rect() moves sprite to 0, 0 michael1789 2 4,599 Dec-13-2019, 08:37 PM
Last Post: michael1789
  How to place walls in random dungeon ? michael1789 5 4,025 Nov-11-2019, 12:12 AM
Last Post: michael1789
  Sprite not rendering Clunk_Head 2 2,140 Oct-03-2019, 11:27 AM
Last Post: Clunk_Head
  Need help making a sprite GalaxyCoyote 4 3,238 Aug-11-2019, 09:12 PM
Last Post: metulburr
  moving a sprite pfaber11 3 2,587 May-15-2019, 12:52 PM
Last Post: pfaber11
  Raycasting(again) walls with different heights robie972003 0 2,456 Mar-23-2019, 01:18 AM
Last Post: robie972003
  [PyGame] Need Help With Sprite ghost0fkarma 2 3,283 Jan-09-2018, 02:14 PM
Last Post: ghost0fkarma

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020