Pygame obje etkileşim

Selam hocam;
Uğraştım aradım araştırdım bir çözüm bulamadım.

İki küp var
Mavi küp yeşil küp
Mavi küple yeşil küpü ittirerek sağa, sola, aşağı, yukarı nasıl sürükleyebiliriz?
Aşağıdaki kod benim yapmaya çalışıp yapamadığım kod, örnek olsun diye ekledim.
cheese terminator oyunundaki gibi bir şey yapmak istiyorum.

import pygame
pygame.init()

size= width, height = 600,400

blue=(0,0,250)
green=(0,250,0)
black=(0,0,0)
speed=25

win=pygame.display.set_mode((size))

a1=pygame.Rect(200,200,50,50)#mavi.küp
a2=pygame.Rect(300,300,50,50)#yesil.küp

drm=True
while drm:
	
	for event in pygame.event.get():
		if event.type==pygame.KEYDOWN:
			if event.key== pygame.K_d:
				a1.x+=speed
		if event.type==pygame.KEYDOWN:
			if event.key== pygame.K_a:
				a1.x-=speed
		if event.type==pygame.KEYDOWN:
			if event.key== pygame.K_w:
				a1.y-=speed
		if event.type==pygame.KEYDOWN:
			if event.key== pygame.K_s:
				a1.y+=speed
				
		if a1.colliderect(a2):
			if a1.midright == a1.midright:
				a2.x += speed
				
		if a1.midleft==a2.midright:
				a2.x -= speed
				
		if a1.colliderect(a2):
			if a1.bottom== a1.midtop:
				a2.y += speed
				
		if a1.midtop==a2.midbottom:
				a2.y -= speed
		
				
	win.fill((black))
	pygame.draw.rect(win,green,a2)#yeşil.küp
	pygame.draw.rect(win,blue,a1)#mavi.küp
	pygame.display.update()

Sen colliderectle ilgili bişi yapmışsın
O if lere mavi küpün yönü neyse diğer küpün yönünü de o yapmalısın çarpmada

Ama ben o küpün yönünü algılayamıyorum kodun çok mantıksız geliyor bana

İyi yapmışsınız. Kopyalanbilir düzgün bir kod parçası bırakınca hem değişkenlere nasıl baktığınızı görebiliyor, hem de sizin kodlarınıza uygun değişiklikler yapma şansı yakalıyoruz.

Şöyle bir şey yapabilirsiniz.

import pygame
import sys

size= width, height = 600,400
blue=(0,0,250)
green=(0,250,0)
black=(0,0,0)

a1=pygame.Rect(200,200,50,50)#mavi.küp
a2=pygame.Rect(300,300,50,50)#yesil.küp

win=pygame.display.set_mode((size))
pygame.display.set_caption("Test Game")

class Player(object):
    def __init__(self):
        self.rect = a1 #mavi küp
        self.rect2 = a2 #yeşil küp
        
    def handle_keys(self):
      
        if event.type == pygame.QUIT: # Pencere üzerindeki X tuşu ile kapatmak için.
            pygame.quit()
            exit()
    
        key = pygame.key.get_pressed()
        dist = 1
        
        if key[pygame.K_LEFT]:
           if self.rect.midleft== self.rect2.midright: # Çarpışma testi soldan
               self.rect2.move_ip(-1, 0)
           self.rect.move_ip(-1, 0)
                
        if key[pygame.K_RIGHT]:
           if self.rect.midright== self.rect2.midleft: # Çarpışma testi sağdan
               self.rect2.move_ip(1, 0)
           self.rect.move_ip(1, 0)
        
        if key[pygame.K_UP]:
           if self.rect.midtop == self.rect2.midbottom: # Çarpışma testi alttan
               self.rect2.move_ip(0, -1)
           self.rect.move_ip(0, -1)
        
        if key[pygame.K_DOWN]:
           if self.rect.midbottom == self.rect2.midtop: # Çarpışma testi üstten
               self.rect2.move_ip(0, 1)
           self.rect.move_ip(0, 1)
           
        if key[pygame.K_ESCAPE]: # Esc Tuşu ile çıkmak için.
           pygame.quit()
           exit()

    def draw(self, surface):
        pygame.draw.rect(surface, green, self.rect)
        pygame.draw.rect(surface, blue, self.rect2)

pygame.init()
player = Player()
clock = pygame.time.Clock()

running = True       

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            break
            running = False

    win.fill((black))
    player.draw(win)
    player.handle_keys()
    pygame.display.update()
    
    clock.tick(50)

Soru güzeldi. Ortalıkta da güzel örnek yoktu mecburen yaptım. Şimdi bir kaç husus var. Gerekli açıklamaları kodun içine koydum ama yine de belirteyim. Öncelikle küplerinizin merkez üst, merkez alt, merkez sağ ve sol referansları ile çarpışma kontrolü yapıyoruz bu nedenle küpü ancak tam hizasına getirdiğinizde itebilirsiniz. Bir pixel bile kaymış olsa itemez içinden geçersiniz. Buna belirli bir tolerans vererek çarpışma kontrolünüzü geliştirebilirsiniz.

Bir de kodun içinde çarpıya basarak veya ESC tuşuna basarak çıkamıyorduk. İlgili tuşları da ekledim açıklamalarını da yanına yazdım.

Programı başlattığımızda:

image

Kutuyu sağa sürükleyelim:

image

Kutuyu yukarı sürükleyelim:

image

Kutuyu sola ve sonra aşağı sürükleyelim:

image

Tam hizalamadığınızda içinden geçmesine dair bir örnek:

image

Bu nedenle çarpışma testlerini yaptığınız kontrol koşullarını geliştirmeniz daha faydalı olacaktır.

Kolay gelsin.

EDIT 1:

Çarpışma testi ile ilgili çalışırken fikir vermesi maksadıyla koordinatlarını da görmeniz belki sınır koşulları belirlerken faydalı olabilir diye, koda ufak bir ekleme yaptım.

import pygame
import sys

size= width, height = 600,400
blue=(0,0,250)
green=(0,250,0)
black=(0,0,0)
red = (250,0,0)
a1=pygame.Rect(200,200,50,50)#mavi.küp
a2=pygame.Rect(300,300,50,50)#yesil.küp

win=pygame.display.set_mode((size))
pygame.display.set_caption("Test Game")

######################################################
class Player(object):
    def __init__(self):
        self.rect = a1 #mavi küp
        self.rect2 = a2 #yeşil küp
        
    def handle_keys(self):
        if event.type == pygame.QUIT: # Pencere üzerindeki X tuşu ile kapatmak için.
            pygame.quit()
            exit()
    
        key = pygame.key.get_pressed()
        dist = 1
        
        if key[pygame.K_LEFT]:
           if self.rect.midleft== self.rect2.midright: # Çarpışma testi soldan
               self.rect2.move_ip(-1, 0)
           self.rect.move_ip(-1, 0)
           
                        
        if key[pygame.K_RIGHT]:
           if self.rect.midright == self.rect2.midleft  : # Çarpışma testi sağdan
              self.rect2.move_ip(1, 0)
           self.rect.move_ip(1, 0)
        
        if key[pygame.K_UP]:
           if self.rect.midtop == self.rect2.midbottom: # Çarpışma testi alttan
               self.rect2.move_ip(0, -1)
           self.rect.move_ip(0, -1)
        
        if key[pygame.K_DOWN]:
           if self.rect.midbottom == self.rect2.midtop: # Çarpışma testi üstten
               self.rect2.move_ip(0, 1)
           self.rect.move_ip(0, 1)
           
        if key[pygame.K_ESCAPE]: # Esc Tuşu ile çıkmak için.
           pygame.quit()
           exit()

    def draw(self, surface):
        pygame.draw.rect(surface, green, self.rect)
        pygame.draw.rect(surface, blue, self.rect2)
        
        self.text =font.render(str(self.rect.center),False,red)
        win.blit(self.text, (self.rect.midleft))
        
        self.text2 =font.render(str(self.rect2.center),False,red)
        win.blit(self.text2, (self.rect2.midleft))

######################################################

pygame.init()

font = pygame.font.SysFont('calibri', 12,bold= True)

player = Player()

clock = pygame.time.Clock()

running = True       

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            break
            running = False

    win.fill((black))
    
    player.draw(win)
    player.handle_keys()
    pygame.display.update()
    
    clock.tick(50)


Bu sayade hareket ederken koordinatlarını da gözlemleyebilirsiniz.

image

Ayrıca ;

pygame in çarpışma kontrolü ile ilgili özelliklerine de mutlaka göz atmalısınız.

Adding Collisions Using pygame.Rect.colliderect in Pygame - GeeksforGeeks

Özellikle şu kodu da görmeniz ve çalıştırıp denemeniz de faydalı olabilir.

Rect Collision Response (pygame.org)