Skip to content
Advertisement

How can i collide with a 45 degree slope?

I have spent the past 3 days trying to understand this but with every article I have read and every youtube video I have watched I have failed to comprehend the concept. I have given this my best go at listening and reading from what I have seen online, before asking here.

I just want one rectangle to go up one slope. I am not after a function for this. Each tutorial/article/video I watch explains how their function/class works. Some are using lists of classes and functions that call other functions inside them. It gets very abstract and it is to much for me right now.

I need someone to really baby this down for me it seems. No functions and no classes. I just want to move one rectangle up one 45 degree slope.

One youtube video explained that I need y = mx + b. But did not explain how to use this function. So if anyone out there has a formula for a basic 45 degree slope and can show me in my own code how to use it without functions or classes, i will be grateful.

After I understand it I can make my own functions and classes for implementing it. My attempt at this has been to make a rectangle behind my ramp image. Is this wrong? Should I be using a single line?

My attempt at code:

import pygame
import sys

pygame.init()
clock = pygame.time.Clock()
screensize = (800, 600)
screen = pygame.display.set_mode(screensize)
colour = [(0, 0, 0), (255, 0, 0), (255, 255, 255), (114, 216, 242), (200, 200, 200), (255, 199, 241), (50, 50, 50)]
          # black 0    #red   1     #white    2      #light_blue 3    #gray   4        #light_pink  5   #dark_gray 6
moving_up = False
moving_down = False
moving_left = False
moving_right = False
gravity = 5


def collide(rect, rectangle_list):
    hit_list = []
    for rectangle in rectangle_list:
        if rect.colliderect(rectangle):
            hit_list.append(rectangle)
    return hit_list


def move(rect, movement, tiles):
    collision_types = {'top': False, 'bottom': False, 'right': False, 'left': False}

    rect.x += movement[0]
    hit_list = collide(rect, tiles)
    for tile in hit_list:
        if movement[0] > 0:
            rect.right = tile.left
            collision_types['right'] = True
        elif movement[0] < 0:
            rect.left = tile.right
            collision_types['left'] = True

    rect.y += movement[1]
    hit_list = collide(rect, tiles)
    for tile in hit_list:
        if movement[1] > 0:
            rect.bottom = tile.top
            collision_types['bottom'] = True
        elif movement[1] < 0:
            rect.top = tile.bottom
            collision_types['top'] = True
    return rect, collision_types

player_rect = pygame.Rect(100, 51, 50, 50)
while True:
    screen.fill(colour[6])
    pygame.draw.polygon(screen, (255, 0, 255), [(300, 500), (300, 550), (250, 550)])

# ~~~~~~ List of rectangles
    rectlist = []
    small_rect = pygame.Rect(200, 200, 50, 50)
    bottomrect_1 = pygame.Rect(0, screensize[1] - 50, screensize[0], 50)
    bottomrect_2 = pygame.Rect(300, screensize[1] - 100, screensize[0], 50)
    D_rect = pygame.Rect(250, screensize[1] - 100, 50, 50)
    rectlist.append(small_rect)
    rectlist.append(bottomrect_1)
    rectlist.append(bottomrect_2)

# ~~~~~~ Player Movement
    player_movement = [0, 0]
    if moving_up:
        player_movement[1] -= 2
    if moving_down:
        player_movement[1] += 2
    if moving_left:
        player_movement[0] -= 2
    if moving_right:
        player_movement[0] += 2

    player_movement[1] += gravity

# ~~~~~~ Player Collision
    my_rect, collision = move(player_rect, player_movement, rectlist)







    # my attempt at this diagonal humbug. D_rect is the diagonal rect. (the slope)
    if my_rect.colliderect(D_rect):
        yy = D_rect.height + (my_rect.x - D_rect.x) * 1
        my_rect.y -= yy/3.6







# ~~~~~~ Event Loop
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
                sys.exit()
            if event.key == pygame.K_w:
                moving_up = True
            if event.key == pygame.K_s:
                moving_down = True
            if event.key == pygame.K_a:
                moving_left = True
            if event.key == pygame.K_d:
                moving_right = True
            if event.key == pygame.K_SPACE:
                gravity = -gravity

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_w:
                moving_up = False
            if event.key == pygame.K_s:
                moving_down = False
            if event.key == pygame.K_a:
                moving_left = False
            if event.key == pygame.K_d:
                moving_right = False

    # ~~~~~~ Draw.
    pygame.draw.rect(screen, (0, 255, 125), D_rect, 1)
    pygame.draw.rect(screen, colour[3], small_rect)
    pygame.draw.rect(screen, colour[4], my_rect)
    pygame.draw.rect(screen, colour[5], bottomrect_1)
    pygame.draw.rect(screen, colour[5], bottomrect_2)
    pygame.display.update()
    clock.tick(60)

Advertisement

Answer

Calculate the height of the diagonal rectangle on the right edge of the moving rectangle (my_rect.right):

dia_height = D_rect.height * (my_rect.right-D_rect.left) / D_rect.width

Compute the top of the the diagonal rectangle on the right edge of the moving rectangle:

D_rect_top = D_rect.bottom - round(dia_height)

The top of the the diagonal rectangle on the right edge of the moving rectangle is the bottom of the moving rectangle:

my_rect.bottom = D_rect_top

If the diagonal is in the opposite direction, find the height of the diagonal on the left edge (my_rect.left) instead of the right edge (my_rect.right).

The formula y = mx + b is hidden in this code:

x is my_rect.right - D_rect.left
m is -D_rect.height / D_rect.width
b is D_rect.bottom
y is my_rect.bottom


while True:
    # [...]

    if my_rect.colliderect(D_rect):
        dia_height = D_rect.height * (my_rect.right-D_rect.left) / D_rect.width
        D_rect_top = D_rect.bottom - round(dia_height)
        my_rect.bottom = D_rect_top

    # [....]
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement