RealoFoxtrot
RealoFoxtrot

Reputation: 47

pygame: Stopping movement behind line

I am attempting to create a game that lets a block move "jump" and land on a platform above it. Then, jump again to the next platform.

Unfortunately, my code currently just stops when the block touches the bottom of the platform and moves no further. I am unsure why as i believe it should only stop when the bottom of the block hits the line

Specifically am looking at this bit of code, but full code below for context:

    #the floor landing code
def hasJumperLanded(rect1, rect2):
    for a, b in [(rect1, rect2), (rect2, rect1)]:
        if isFloorTouching(a.bottom, b):
            return True

def isFloorTouching(y, rect):
    if (y > rect.top) and (y < rect.bottom):
        return True
    else:
        return False

snip

    #stop when land on floor
for n in range(len(floors)):
    if (hasJumperLanded(j['rect'], floors[n]['line'])):
        j['jump'] = STILL

Full code context:

import pygame, sys, time
from pygame.locals import *

    #the deadzone collision code
def doRectsOverlap(rect1, rect2):
    for a, b in [(rect1, rect2), (rect2, rect1)]:
        if ((isPointInsideRect(a.left, a.top, b)) or
            (isPointInsideRect(a.left, a.bottom, b)) or
            (isPointInsideRect(a.right, a.top, b)) or
            (isPointInsideRect(a.right, a.bottom, b))):
            return True

    return False

def isPointInsideRect(x, y, rect):
    if (x > rect.left) and (x < rect.right) and (y > rect.top) and (y < rect.bottom):
        return True
    else:
        return False


    #the floor landing code
def hasJumperLanded(rect1, rect2):
    for a, b in [(rect1, rect2), (rect2, rect1)]:
        if isFloorTouching(a.bottom, b):
            return True

def isFloorTouching(y, rect):
    if (y > rect.top) and (y < rect.bottom):
        return True
    else:
        return False


# set up pygame
pygame.init()
mainClock = pygame.time.Clock()

# set up the window
WINDOWWIDTH = 480
WINDOWHEIGHT = 800
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Jumper')

#Directions
LEFT = 4
RIGHT = 6
UP = 8
DOWN = 2
STILL = 5

#blocks location for jumping
#BLOCKLOCY = 700

#Binary for stopping movement
#STOPPER = 0

MOVESPEED = 1

# set up the colors
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)


j = {'rect':pygame.Rect(240, 700, 20, 20), 'color':GREEN, 'dir':LEFT, 'jump':STILL}


f1 = {'line':pygame.Rect(0,720,480,2), 'color':GREEN, 'dir':STILL}
f2 = {'line':pygame.Rect(0,650,480,2), 'color':GREEN, 'dir':STILL}
floors = [f1,f2]

# run the game loop
while True:
    # check for the QUIT event
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()



    # draw the black background onto the surface
    windowSurface.fill(BLACK)


        # This way or that way. Speed Code
    if j['dir'] == LEFT:
        j['rect'].left -= MOVESPEED
    if j['dir'] == RIGHT:
        j['rect'].left += MOVESPEED

        #JUST JUMP ALREADY!
    if j['jump'] == UP:
        j['rect'].bottom -= MOVESPEED
        #BLOCKLOCY -= MOVESPEED

        #Bouce when side hitting
    if j['rect'].left < 0:
        j['dir'] = RIGHT
    if j['rect'].left > WINDOWWIDTH-j['rect'].width:
        j['dir'] = LEFT

        #Press to Jump
     if event.type == KEYDOWN:
        if event.key == K_SPACE:
             j['jump'] = UP

        #stop when land on floor
    for n in range(len(floors)):
         if (hasJumperLanded(j['rect'], floors[n]['line'])):
            j['jump'] = STILL


    #Floor controll code for moving level - not working currently
    for f in floors:
        #if f['dir'] == DOWN:
          #  f['line'].y += MOVESPEED

      #  if event.type == KEYDOWN:
          #  if event.key == K_SPACE:
              # f['dir'] = DOWN

     #   if f['line'].top == BLOCKLOCY:
      #      f['dir'] = STILL
       #     STOPPER = 1

        #if f['line'].bottom == BLOCKLOCY:
         #   f['dir'] = STILL
          #  STOPPER = 1




        # draw the block onto the surface
        pygame.draw.rect(windowSurface, j['color'], j['rect'])

        pygame.draw.rect(windowSurface, f['color'], f['line'])


    # draw the window onto the screen
    pygame.display.update()
    mainClock.tick(1000)

Upvotes: 0

Views: 89

Answers (1)

kstenger
kstenger

Reputation: 374

#the floor landing code
def hasJumperLanded(rect1, rect2):
    for a, b in [(rect1, rect2), (rect2, rect1)]:  ## **
        if isFloorTouching(a.bottom, b):
            return True

Take a look at the line I marked in this snippet.

Here You are checking the rects to collide both ways.

So you loose the meaning of which one is the floor and which one is moving.

If you just check (rect1, rect2) you will see the difference.

--

EDIT:

Check this out

def hasJumperLanded(rect1, rect2):
    for a, b in [(rect1, rect2), (rect2, rect1)]:
        if isFloorTouching(rect1, rect2):
            return True

def isFloorTouching(y, rect):
    if (y.bottom > rect.top) and (y.bottom < rect.bottom):
        return True
    else:
        return False

It is more logical to handle the meaning of the floor inside the isFloorTouching() function.

Upvotes: 1

Related Questions