Bottom Page

• 0 Vote(s) - 0 Average
• 1
• 2
• 3
• 4
• 5
 [PyGame] Making Player Sprite Ricochet of walls michael1789 Minister of Silly Walks Posts: 318 Threads: 28 Joined: May 2019 Reputation: 29 Likes received: 37 #1 Jun-03-2019, 07:58 AM I have vector ("Asteroids") type movement and I want my player sprite to bounce of things they bump into. It is best to use 2 .spritecollide checks, one for vertical walls and one for horizontal? That won't work for a tile that can be hit from both angles. I'm sure it's been done a million times, but I could sure use help finding where to start. Can I somehow check what side of a tile is hit? metulburr The Castle of aaarrrrggh Posts: 4,775 Threads: 295 Joined: Sep 2016 Reputation: 152 Likes received: 1257 #2 Jun-03-2019, 12:28 PM (This post was last modified: Jun-03-2019, 12:29 PM by metulburr. Edited 3 times in total.) You can easily adapt a pong game to use. As the ball is meant to bounce of the top and bottom, and two paddles on right and left. https://github.com/metulburr/pong/blob/m...all.py#L53 The part that actually changes the velocity is ``` self.vel[1] *= -1 self.vel[0] *= -1```which reverse the velocity of the objects direction once it hits another object, making it appear to bounce off objects like a ball. By tile; do you mean tilemaps or do you mean a 4 sided object? It doesnt matter what the angle the object that is being hit at. The angle of the object in which is initiating the hit, is. Unless you want to take into account of that angle too. Recommended Tutorials: BBcode, Forum Rules and Instructions, How to ask smart questions, the Basics, Classes, Python Gotchas Windspar Minister of Silly Walks Posts: 494 Threads: 13 Joined: Oct 2016 Reputation: 36 Likes received: 90 #3 Jun-03-2019, 02:03 PM (This post was last modified: Jun-03-2019, 02:03 PM by Windspar. Edited 2 times in total.) 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. hobby-programmer.com michael1789 Minister of Silly Walks Posts: 318 Threads: 28 Joined: May 2019 Reputation: 29 Likes received: 37 #4 Jun-03-2019, 06:12 PM (Jun-03-2019, 12:28 PM)metulburr Wrote: By tile; do you mean tilemaps or do you mean a 4 sided object? It's txt file that is read and translated into a map of 32X32 tile sprites. I'll look at the pong code and see what it is, but if there are sprite groups for walls and paddles, that won't be useful if there is a single tile in the room that can be hit from all sides. Will it?? (Jun-03-2019, 02:03 PM)Windspar Wrote: 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. ok... I think i sort of get it. Long story short, if the smallest of the remainders of the rect.centery or rect.centerx comparison will determine if it is a vertical surface or a horizontal surface? I'll look into all of this and see where I get. Thanks guys Windspar Minister of Silly Walks Posts: 494 Threads: 13 Joined: Oct 2016 Reputation: 36 Likes received: 90 #5 Jun-03-2019, 10:45 PM Here. I try to explain it better. Displacement collision. Moving Object hit a Stationary Object. 1. get the clipping rect size `width, height = object.rect.clip(collision.rect).size`2. Determine the Axis. ```if width < height: # X Axis else: # Y Axis ```3. Determine which side. Displace object and Change direction. ```# Determine Axis X or Y if width < height: # X Axis # Determine which side if object.rect.centerx > collision.rect.centerx: # Displace object object.rect.left = collision.rect.right else: # Displace object object.rect.right = collision.rect.left # Change direction object.direction.x = -object.direction.x else: # Y Axis # ... ``` 99 percent of computer problems exists between chair and keyboard. hobby-programmer.com « Next Oldest | Next Newest »

Top Page

 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 430 Mar-07-2020, 12:32 PM Last Post: Kris1996 [PyGame] Sprite image.get_rect() moves sprite to 0, 0 michael1789 2 362 Dec-13-2019, 08:37 PM Last Post: michael1789 How to place walls in random dungeon ? michael1789 5 456 Nov-11-2019, 12:12 AM Last Post: michael1789 Need help making a sprite GalaxyCoyote 4 656 Aug-11-2019, 09:12 PM Last Post: metulburr Raycasting(again) walls with different heights robie972003 0 499 Mar-23-2019, 01:18 AM Last Post: robie972003

Forum Jump:

Users browsing this thread: 1 Guest(s)