0

I've been learning to use Python for around one month with pygame. I want to realize my first small project, it's a Zelda-like game where you navigate a small octopus, avoid enemies (later also fight) and collect treasures.

I am able to move my character and also the enemies can walk by themself. I can use the rect method to detect collision between the player and enemy and also by walking over a rectangle to switch to another part (map) in the level.

Now I want to create obstacle which you cant pass (palm trees, rocks, etc.) the player should be forced to walk around this obstacles.

I learned already how to clip the position/side (up, bottom, right, left) from which my character (octopus) touches the obstacle (palmtree). But still my octopus will walk trough the palmtree.

def collision(source, target):
if not source.colliderect(target): return
overlap = source.clip(target)

if overlap.width > overlap.height:     #verticale collision
    if source.y < target.y:            #top
        source.bottom = target.top
        #print ("oben")
    else:
        source.top = target.bottom
        #print ("Tako_oben =" + str(source.top) + "Palme UNTEN =" + str(target.bottom))
        print("Tako_oben =" + str(source.top) + "Tako_unten =" + str(source.bottom))
        #print("unten")

else:                                  # horizontale collision
    if source.x < target.x:            #linke Seite
        source.right = target.left
        print("links")
    else:
        source.left = target.right
        #print("rechts")

Here is the place from where I call my function:

class Map :
def __init__(self,game, x, y):
    self.game = game #stellt Bezug zum Spiel

    #self.tako_chan = Tako_Chan(self,x,y)


    self.x = x  #wird in unteren Methode () verwendet
    self.y = y  #wird in unteren Methode () verwendet




    self.map_01 = pygame.image.load("map_01.PNG")
    self.map_02 = pygame.image.load("map_02.PNG")

    self.warp_point = pygame.Rect(630, 620, 150,80 ) #x y width height
    self.warp_point_2 = pygame.Rect(500, -70, 150, 80)  # x y width height

    self.palm_rec = pygame.Rect(450, 300, 60, 150)  # x y width height



def update (self):




    if self.game.location == "01":
        self.game.screen.blit(self.map_01, (self.x, self.y))  # Bild/Position Vorgänger
        pygame.draw.rect(self.game.screen, (0, 255, 0), self.warp_point, 4)
        pygame.draw.rect(self.game.screen, (150, 200, 0), self.palm_rec, 5)
        self.game.snake.move_horizon()
        self.game.snake.update()

        if self.game.tako_chan.tako_chan_rect.colliderect(self.palm_rec):
            
            None


            
        collision (self.game.tako_chan.tako_chan_rect, self.palm_rec)
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
cdstar99
  • 11
  • 2
  • Welcome to Stack Overflow. I want to make sure I understand the question. You have working code to detect whether two things collide, and you use it to check if the player collides with the octopus or the palm tree? And this works properly, and you can fix the player's position when there is a collision? And the problem is that the code does not detect when the octopus collides with the palm tree? Well - did you try **using the same collision detection function** to check whether the octopus collides with the palm tree? I don't understand why there is any difficulty. – Karl Knechtel Oct 02 '22 at 19:06
  • https://youtu.be/KLSbeLh9ly4 – cdstar99 Oct 03 '22 at 13:07

1 Answers1

0

If you need collision in pygame, you can use the pygame.Rect() method which takes in 3 arguments, (x,y,width,height), and in this method you can detect if the player hits the one of the sides of the player.

The way that i code collision in pygame is by first detecting collision between the 2 rects, which in your case is the player and palm tree (if im not mistaking)

I dont know how you created the player movement, so im just going to show you my way and hope it helps:

import pygame
pygame.init()

screen = pygame.display.set_mode((500,500))
x,y = 50,50
run = True
player_speed = 1

while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            run = False
    key = pygame.key.get_pressed()
    if key[pygame.K_a]:
        x -= player_speed
    if key[pygame.K_d]:
        x += player_speed
    player_rect = pygame.Rect(x,y,player_width,player_height)
    palm_tree_rect = pygame.Rect(palm_x,palm_y,palm_width,palm_height)
    if player_rect.colliderect(palm_tree_rect):
        if player_rect.right >= palm_tree_rect.x and player_rect.right <= palm_tree_rect.x + (player_speed + 2) :
            player_rect.x = palm_tree_rect.x - player_rect.width
        if player_rect.left >= palm_tree_rect.right - (player_speed + 2) and player_rect.left <= palm_tree_rect.right:
            player_rect.x = palm_tree_rect.right
        if player_rect.top <= palm_tree_rect.bottom and player_rect.top >= palm_tree_rect.bottom - (player_speed + 2):
            player_rect.y = palm_tree_rect.bottom
        if player_rect.bottom >= palm_tree_rect.top and player_rect.bottom <= palm_tree_rect.top + (player_speed + 2):
            player_rect.y = palm_tree_rect.top - player_rect.height
    pygame.display.flip()

The only reason i put the player_speed + 2 is because, for example you are detecting collision between 5 pixel from the block to the player and the player moves like 10 pixel a second, you cant be able to detect 5 pixel collision from the block to the player, because the player doesnt reach 5 pixel so it will enter the block before detecting it.

Hope this helps :) enjoy pygame.

Also i have an engine i created like pygame called pyeasygame, you can install it at pip install pyeasygame in command prompt, you can use it freely, it makes work like creating the player, collision boxes, writen in one line of code, if you have any confusion using my engine if you do use it, locate the file by typing in cmd also pip install pyeasygame and it will say it is already installed located at ...\site-packages, go to that location in the file explorer, locate the folder named pyeasygame and open it and locate the file init.py and in there you will find all the code, it shouldnt be hard to understand because it is written in pygame also.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Morris
  • 55
  • 6