event hook
nedir lütfen açıklayabilir misiniz ?
benim istediğim update
metodunun içinde olması benim yerime her şeyi yapması
değil size sorduğum size gösterdiğim metodlar işime yararmı
benim demeye çalıştığım
şu kodu kullanmak istemediğim:
if event.type == pg.MOUSEBUTTONDOWN
benim istediğim:
import pygame as pg
display = pg.display.set_mode((500,500))
class Button():
butonlar = []
def __init__(self, *, command, image_path, pos):
self.command = command
self.sprite = pg.image.load(image_path).convert()
self.rect = self.sprite.get_rect(topleft= pos)
self.butonlar.append(self)
def update(self, *args):
mouse = pg.mouse.get_pos()
clicked = pg.mouse.get_pressed()
if clicked[0]:
if self.rect.collidepoint(mouse):
self.command(mouse)
def delete(self):
self.butonlar.remove(self)
buton1 = Button(command = lambda event: print("1. buton basıldı"), image_path="Buton.png", pos=(100,100))
buton2 = Button(command = lambda event: print("2. buton basıldı"), image_path="Buton.png", pos=(200,200))
while True:
display.fill((255,255,255))
for event in pg.event.get():
if event.type == pg.QUIT:
exit()
for but in Button.butonlar:
but.update()
for buton in Button.butonlar:
display.blit(buton.sprite,buton.rect)
pg.display.update()
sizce bu kodu kullansam olur mu veya daha kısa bir yol varmı
bu kodu daha iyi hale nasıl getiririm (yani ButtonDown değişkeni ile yaptığım işi daha iyi nasıl yaparım)
import pygame as pg
pg.init()
#------------------Button Widget------------------
class Button(pg.sprite.Sprite):
def __init__(self, *, command, image, pos):
pg.sprite.Sprite.__init__(self)
self.command = command
self.image = pg.image.load(image).convert()
self.rect = self.image.get_rect(topleft= pos)
self.ButtonDown = False
def update(self, *args):
mouse = pg.mouse.get_pos()
clicked = pg.mouse.get_pressed()
if self.rect.collidepoint(mouse):
if clicked[0] and self.ButtonDown == False:
self.ButtonDown = True
self.command()
elif not clicked[0]:
self.ButtonDown = False
display = pg.display.set_mode((500,500))
buton1 = Button(command = lambda : print("1. buton basıldı"), image="BUTONIMG.png", pos=(100,100))
buton2 = Button(command = lambda : print("2. buton basıldı"), image="BUTONIMG.png", pos=(100,200))
while True:
display.fill((255,255,255))
for event in pg.event.get():
if event.type == pg.QUIT:
exit()
buton1.update()
buton2.update()
display.blit(buton1.image,buton1.rect)
display.blit(buton2.image,buton2.rect)
pg.display.update()
Olur olur.
Var, event loop.
Event loop kullanarak.
@aib çok güzel ve öz cevaplamış Kodunuzda
Button.update
metodunun içinde pg.mouse.get_pos()
ve clicked = pg.mouse.get_pressed()
fonksiyonları çağrıldığı için defalarca aynı fonksiyonu çağırıyorsunuz. update
metodunda yapacağınız bu işi bir defa yapmanız lazım. Bunu event loop’da yapmanızın hiçbir sakıncası yok. Ama siz illaki öyle bir kod istemiyorum diye tutturdunuz. Sebebini anlayabilmiş değilim. Çok istiyorsanız Button
sınıfı için bir sınıf metodu (classmethod
) oluşturun, döngüyü de onun içinde -bir defa- yapın.
Mesela klavyede a
tuşuna basıldığında siz kodunuzda hiçbir kontrol yapmadan önceden belirlediğiniz bir fonksiyon çalıştırılıyorsa bu bir event hook
oluyor. Yani belli bir event
(olay) gerçekleştiğinde belli bir fonksiyon çağırılılıyor (bu da hook
).
Event loop kullanmayı istemiyorum cunku
Bu olayı button classı içinde nasıl kullanıcağmı
Bilmediğimden dolayi sunu denedim ama yaramadı
def update (self):
for event in pg.event.get ():
#....
Ama bu event loopunun içine yazdığım kod calismadi
Bunun çalışmama sebebi pg.event.get()
fonksiyonunun queue’den eventleri silmesi. Yani bu fonksiyonu çağırdığınızda daha önce elinize geçmeyen bütün eventleri alıyorsunuz, ve bu eventler pygame’den siliniyor. Eğer bu fonksiyonu ana döngünüzde iki defa çağırırsanız istediğiniz gibi çalışmaz.
Bir de cümlelerinizde nokta kullanırsanız sizi daha rahat anlayacağım.
Peki bunu nasıl yapabilirim
Yani event loop’u nasıl dahil edebilirim (button class icinde)
Eventleri kontrol ettiğiniz ana döngüde bu işlemleri yapabilirsiniz.
Bu kodu inceleyin istiyorsanız.
import pygame as pg
pg.init()
#------------------Button Widget------------------
class Button(pg.sprite.Sprite):
def __init__(self, *, command, image, pos):
pg.sprite.Sprite.__init__(self)
self.command = command
self.image = pg.image.load(image).convert()
self.rect = self.image.get_rect(topleft= pos)
self.ButtonDown = False
def update(self, pos):
if self.rect.collidepoint(pos):
self.command()
### yapılacak işlemler
@classmethod
def update_buttons(cls, *buttons):
pos = pg.mouse.get_pos()
for buton in buttons:
buton.update(pos)
display = pg.display.set_mode((500,500))
buton1 = Button(command = lambda : print("1. buton basıldı"), image="1.png", pos=(100,100))
buton2 = Button(command = lambda : print("2. buton basıldı"), image="2.png", pos=(100,200))
while True:
display.fill((255,255,255))
for event in pg.event.get():
if event.type == pg.QUIT:
exit()
if event.type == pg.MOUSEBUTTONDOWN:
Button.update_buttons(buton1, buton2)
display.blit(buton1.image,buton1.rect)
display.blit(buton2.image,buton2.rect)
pg.display.update()
Event loop event aldiginda (for event in pygame.event.get(): ...
) dugmelerin update
fonksiyonlarina bu event
’i parametre olarak yollayabilir. Mouse move/click event’i olup olmadigi update
’in icinde de, disinda da kontrol edilebilir. (Birden fazla event icin birden fazla update
de yazilabilir.) Buton/koordinat kontrolunun iceride yapmasi daha mantikli olur diye dusunuyorum.
benim event loop buttonu kullanıcağım yerden başka bir betikte
o zaman ne yapıcağım
Her şey bir tek event loopda kontrol edilecek, normalde pygame kullanırken herkesin yaptığı gibi.
Saolun anladım ve yaptım özür dilerim pygame de yeniyim
kodum:
import pygame as pg
pg.init()
#------------------Button Widget------------------
class Button(pg.sprite.Sprite):
def __init__(self, *, command, image, pos):
pg.sprite.Sprite.__init__(self)
self.command = command
self.image = pg.image.load(image).convert()
self.orginalimg = self.image.copy()
self.rect = self.image.get_rect(topleft= pos)
self.ButtonDown = False
def handle_event(self, event):
mouse = pg.mouse.get_pos()
clicked = pg.mouse.get_pressed()
if self.rect.collidepoint(mouse):
self.image = pg.image.load("BUTONDOWNIMG.png").convert()
if event.type == pg.MOUSEBUTTONDOWN:
self.command()
else:
self.image = self.orginalimg
Aslında hala her button örneği için aynı fonksiyonlar çağırılmış oluyor ama ne diyeyim. Bir de clicked
değişkenini tanımlamışsınız ama kullanmamışsınız.
Kopyala-yapistir yaptığım için silmeyi ubuttum
Kodunuza tekrar baktım da buton her tıklandığında BUTONDOWNIMG.png
dosyası tekrar diskten okunuyor. Böyle işlemlerden kaçınarak programınızın başlarında bir defa okuyup bir değişkene atamanız daha doğru olacaktır.
Anladım ve aklıma bir şey geldi
.convert()
ile .convert_alpha()
arasında bir fark varmı?
Evet. convert_alpha
metodu transparent resimler için kullanılıyor.