Note that there are some explanatory texts on larger screens.

plurals
  1. POPygame Collison Detection
    text
    copied!<p><strong>MY PROBLEM:</strong></p> <p>At the point I'm at in my game I want to add a couple features like double jumps, wall jumps, etc.<br> However I've run into a problem with my collision detection and I can't seem to straighten it out.<br> The problem is that when my character collides with the ground it registers a collision.<br> However the next tick it no longer is registering a collision even if I'm on the ground.<br> This creates problems with detecting if I've collided with a wall or if I'm currently colliding with the ground etc.<br> This creates even more of a problem because when its not detecting a collision my y-velocity will constantly decrease.<br> So, my player has a constant y-velocity that is increasing instead of it just being 0 when on the ground. </p> <p><strong>EXAMPLE:</strong></p> <p><a href="https://imgur.com/uRCkjpF" rel="nofollow noreferrer"><img src="https://i.imgur.com/uRCkjpF.gif" alt="" title="Hosted by imgur.com" /></a></p> <p>As you can see in the left hand corner my y-velocity is bouncing through numbers like this: </p> <pre><code>0 0 0.3 0.6 0.9 </code></pre> <p>then it starts over.<br> What I really need is for this to constantly be 0 when I'm on the ground and for the code to recognize that I'm on the ground.<br> But It's not and I can't figure out why, Can anyone help?</p> <p><strong>CODE:</strong></p> <pre><code>import pygame from pygame import * WIN_WIDTH = 800 WIN_HEIGHT = 640 HALF_WIDTH = int(WIN_WIDTH / 2) HALF_HEIGHT = int(WIN_HEIGHT / 2) DISPLAY = (WIN_WIDTH, WIN_HEIGHT) DEPTH = 32 FLAGS = 0 CAMERA_SLACK = 30 def main(): pygame.init() screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH) #pygame.display.set_caption("Use arrows to move!") timer = pygame.time.Clock() up = down = left = right = space = False bg = Surface((32,32)) bg.convert() bg.fill(Color("#0094FF")) entities = pygame.sprite.Group() player = Player(32, 32) platforms = [] plants = [] space_num = 0 x = 0 y = 0 level = [ "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP", "P P", "P P", "P P", "P P", "P P", "P P", "P P", "P P", "P P", "P P", "P P", "P P", "P P", "P P", "P P", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP PPPPPPP", "P PPPP", "P PPPP", "P PPPP", "PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP", "PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP", "PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP", "PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP", "PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP", "PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP", "PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP", "PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP", "PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP", "PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP", "PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP", "PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",] # build the level for row in level: for col in row: if col == "P": p = Platform(x, y) platforms.append(p) entities.add(p) if col == "E": e = ExitBlock(x, y) platforms.append(e) entities.add(e) if col == "p": p = Plant(x, y) plants.append(p) entities.add(p) x += 32 y += 32 x = 0 total_level_width = len(level[0]) * 32 total_level_height = len(level) * 32 camera = Camera(complex_camera, total_level_width, total_level_height) entities.add(player) while 1: timer.tick(60) for e in pygame.event.get(): if e.type == QUIT: raise SystemExit, "QUIT" if e.type == KEYDOWN and e.key == K_ESCAPE: raise SystemExit, "ESCAPE" if e.type == KEYDOWN and e.key == K_UP: up = True if e.type == KEYDOWN and e.key == K_DOWN: down = True if e.type == KEYDOWN and e.key == K_LEFT: left = True if e.type == KEYDOWN and e.key == K_RIGHT: right = True if e.type == KEYDOWN and e.key == K_SPACE: if space_num &lt; 6: space = True space_num += 1 if e.type == KEYUP and e.key == K_UP: up = False if e.type == KEYUP and e.key == K_DOWN: down = False if e.type == KEYUP and e.key == K_LEFT: left = False if e.type == KEYUP and e.key == K_RIGHT: right = False if e.type == KEYUP and e.key == K_SPACE: space = False # draw background for y in range(20): for x in range(25): screen.blit(bg, (x * 32, y * 32)) camera.update(player) # update player, draw everything else player.update(up, down, left, right, platforms, space) for e in entities: screen.blit(e.image, camera.apply(e)) pygame.display.update() class Camera(object): def __init__(self, camera_func, width, height): self.camera_func = camera_func self.state = Rect(0, 0, width, height) def apply(self, target): return target.rect.move(self.state.topleft) def update(self, target): self.state = self.camera_func(self.state, target.rect) #def simple_camera(camera, target_rect): # l, t, _, _ = target_rect # _, _, w, h = camera # return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h) def complex_camera(camera, target_rect): l, t, _, _ = target_rect _, _, w, h = camera l, t, _, _ = -l + HALF_WIDTH, -t+HALF_HEIGHT, w, h l = min(0, l) # stop scrolling left l = max(-(camera.width-WIN_WIDTH), l) # stop scrolling right t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling bottom return Rect(l, t, w, h) class Entity(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) class Player(Entity): def __init__(self, x, y): Entity.__init__(self) self.xvel = 0 self.yvel = 0 self.onGround = False self.image = Surface((32,32)) self.image.fill(Color("#0000FF")) self.image.convert() self.rect = Rect(400, 400, 32, 32) def update(self, up, down, left, right, platforms, space): if space: if not self.onGround: self.yvel = -12 if self.onGround: self.yvel = 0 else: if up: if self.onGround: self.yvel -= 10 # only jump if on the ground if down: pass if left: self.xvel = -8 if right: self.xvel = 8 if not self.onGround: self.yvel += 0.3 # only accelerate with gravity if in the air if self.yvel &gt; 40: self.yvel = 40 # max falling speed if not(left or right): self.xvel = 0 self.rect.left += self.xvel # increment in x direction self.collide(self.xvel, 0, platforms) # do x-axis collisions self.rect.top += self.yvel # increment in y direction self.onGround = False; # assuming we're in the air self.collide(0, self.yvel, platforms) # do y-axis collisions def collide(self, xvel, yvel, platforms): for p in platforms: if pygame.sprite.collide_rect(self, p): if isinstance(p, ExitBlock): pygame.event.post(pygame.event.Event(QUIT)) if xvel &gt; 0: self.rect.right = p.rect.left if xvel &lt; 0: self.rect.left = p.rect.right if yvel &gt; 0: self.rect.bottom = p.rect.top self.onGround = True self.yvel = 0 if yvel &lt; 0: self.rect.top = p.rect.bottom class Platform(Entity): def __init__(self, x, y): Entity.__init__(self) self.image = Surface((32, 32)) self.image.convert() self.image.fill(Color("#DDDDDD")) self.rect = Rect(x, y, 32, 32) def update(self): pass class ExitBlock(Platform): def __init__(self, x, y): Platform.__init__(self, x, y) self.image = pygame.image.load("bush.png") class Decoration(Entity): def __init__(self): pygame.sprite.Sprite.__init__(self) class Plant(Decoration): def __init__(self, x, y): Entity.__init__(self) self.image = Surface((64, 64)) self.image.convert() #self.image = pygame.image.load("bush.png") self.rect = Rect(x, y, 64, 64) if __name__ == "__main__": main() </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload