Hadi geçmiş olsun.
GitHub - NandeMD/MonsterGame: This is a little monster game made with Python and PyGame.
This is a little monster game made with Python and PyGame. - GitHub - NandeMD/MonsterGame: This is a little monster game made with Python and PyGame.github.com
@jinwo
import pygame
# İlk önce bir ana obje sınıfı oluşturuyoruz, diğer tüm objeler bundan inheritlenecek.
# (Kusura bakmayın, Türkçesini bilmiyorum.)
# Bu tarz oyun projelerinde değişken türlerini belirtmeniz tercihen önemli.
class BaseObject:
def __init__(
self,
surface: pygame.Surface, # Resim buraya gelecek. Pygame resimleri aslında bir "Surface" classı.
xpos: float = 0, # Objenin x konumu
ypos: float = 0, # Objenin y konumu
velocity_x: float = 0, # Objenin x eksenindeki hızı
velocity_y: float = 0, # Objenin y eksenindeki hızı
should_blitted: bool = True # Obje ekrana yansıtılmalı mı?
) -> None:
# Burada class değişkenlerimizin atamasını yapıyoruz.
self.surface: pygame.Surface = surface
self.xpos = xpos
self.ypos = ypos
self.velocity_x = velocity_x
self.velocity_y = velocity_y
self.should_blitted = should_blitted
# Blit'i obje özelinde daha rahat yapabilmek için sınıfın içine taşıyalım.
# Screen'in de bir "Surface" olduğuna dikkat edelim.
def blit(self, main_screen: pygame.Surface):
main_screen.blit(self.surface, (self.xpos, self.ypos))
# Poziston güncellemeyi de obje özelinde daha rahat yapabilmek için buraya taşıyalım.
def update_position(self, s_widt: int, s_height: int):
# Obje eğer x ekseninde dışarı çıkacaksa x eksenindeki hızını ters çevirelim
if self.xpos > s_widt - self.velocity_x or self.xpos < 0:
self.velocity_x = -self.velocity_x
# Obje eğer y ekseninde dışarı çıkacaksa y eksenindeki hızını ters çevirelim
if self.ypos > s_height - self.velocity_y or self.ypos < 0:
self.velocity_y = -self.velocity_y
# x ve y pozisyonlarını hıza göre güncelleyelim.
self.xpos += self.velocity_x
self.ypos += self.velocity_y
import pygame
from base import BaseObject
# Mermi sınıfımızı oluşturalım.
# Merminin ana obje sınıfımızdan tek farkı resminin var olması.
class Bullet(BaseObject):
def __init__(self, xpos: float = 0, ypos: float = 0, velocity_x: float = 0, velocity_y: float = 0, should_blitted: bool = True) -> None:
super().__init__(pygame.image.load("icon.png"), xpos, ypos, velocity_x, velocity_y, should_blitted)
import pygame # Pygame için
import math # Daha hızlı matematik işlemleri için
from bullet import * # Mermi sınıfımızı importluyoruz
from time import sleep # Loop hızını kontrol edebilmek için gerekli
DELAY = 1/60 # While loop'unun gecikmesi.
def update_objects(sc: pygame.Surface, bg: pygame.Surface | None, objs: list[BaseObject]):
if bg is not None:
sc.blit(bg, (0, 0)) # Eğer bir arkaplan resmi varsa arkaplana onu yerleştir
else:
sc.fill((0, 0, 0)) # Eğer bir arkaplan resmi yoksa arkaplanı siyaha boya
for obj in objs: # Tüm objelerin içinden geç
obj.update_position( # obje konumunu güncelle
sc.get_width(), # Ekran genişliği
sc.get_height() # Ekran yüksekliği
)
if obj.should_blitted: # Eğer obje ekranda gözükmeliyse
obj.blit(sc) # objeyi ekrana çiz
def mainloop(): # ana döngü fonksiyonu
pygame.init()
pygame.display.set_caption("Mermiler")
screen = pygame.display.set_mode((400, 400))
START_POINT = (200, 200) # Mermilerin çıkacağı başlangıç noktası
BASE_SPEED = 5 # mermilerin temel sürati
running = True
objects: list[BaseObject] = [] # ekrana düzenli olarak konumları güncellenecek objelerin listesi
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
elif event.type == pygame.MOUSEBUTTONUP: # fare tıklandığında
m_pos = pygame.mouse.get_pos() # tıklama konumunu al
dist_x = m_pos[0] - START_POINT[0] # tıklama konumunun başlangıç konumuna x ekseninde uzaklığı
dist_y = m_pos[1] - START_POINT[1] # tıklama konumunun başlangıç konumuna y ekseninde uzaklığı
# Uzaklıkları 2 kenar olarak kabul edip hayali bir üçgen çizelim.
# Üçgenin hipotenüs uzunluğunu hesaplayalım.
hypotenuse = math.sqrt(math.pow(dist_x, 2) + math.pow(dist_y, 2))
# Mermimizi yaratıp düzenli güncellenecek objeler listesine ekleyelim.
objects.append(
Bullet(
START_POINT[0], # Başlangıç noktası X koordinatı
START_POINT[1], # Başlangıç noktası Y koordinatı
float(BASE_SPEED * dist_x / hypotenuse), # x eksenindeki hız = sürat * cosx
float(BASE_SPEED * dist_y / hypotenuse), # y eksenindeki hız = sürat * sinx
)
)
# Listedeki tüm objeleri güncelleyelim.
update_objects(screen, None, objects)
# Ekranı güncelleyelim.
pygame.display.flip()
# Ayarladığımız gecikme süresi kadar bekleyelim.
sleep(DELAY)
if __name__ == "__main__":
# Çalışsın.
mainloop()
Tekrardan merhaba. Yaşınızı ve bilgi durumunuzu bilmediğiniz için söylüyorum, yanlış anlamayın. İstediğiniz şeyi yapabilmek için (doğru hatırlıyorsam) lise seviyesi matematik ve fizik bilgisine ihtiyacınız var. Özellikle de basit geometriye. Yalnız yaklaşık 4 senedir matematik görmediğim için yeterince detaylı anlatamadıysam maruz görün.
Aslında yapacağınız işlem basit. İlk önce hipotenüsü merminin çıkış noktası ve farenin tıklandığı nokta arasında olan hayali bir üçgen çizeceksiniz. Hipotenüsü merminin hız vektörü olarak düşünün ve daha sonra hız vektörünün X ve Y eksenlerindeki bileşenlerini hesaplayın. Daha sonra ana oyun döngüsünün her adımında merminin X ve Y konumunu bu X ve Y hız bileşenlerine göre güncelleyin.
Kodu olabildiğince açıklamalı yazmaya çalıştım, normalde çizim yaparak da anlatabilmek isterdim ancak şu anda yanımda bir fare yok ve kağıt kalem çıkarıp çizebilecek bir ortamda değilim.
Tüm kod dosyalarını tek bir klasörde topladım ve klasörün düzeni şu şekilde:
- Ana klasör.
- base.py
- bullet.py
- main.py
- İcon. PNG (bunun yerine kendi merminizi koyun)
Kodlar da şu şekilde:
Python:import pygame. # İlk önce bir ana obje sınıfı oluşturuyoruz, diğer tüm objeler bundan inheritlenecek. # (Kusura bakmayın, Türkçesini bilmiyorum.) # Bu tarz oyun projelerinde değişken türlerini belirtmeniz tercihen önemli. class BaseObject: def __init__( self, surface: pygame.Surface, # Resim buraya gelecek. Pygame resimleri aslında bir "Surface" classı. xpos: float = 0, # Objenin x konumu. ypos: float = 0, # Objenin y konumu. velocity_x: float = 0, # Objenin x eksenindeki hızı. velocity_y: float = 0, # Objenin y eksenindeki hızı. should_blitted: bool = True # Obje ekrana yansıtılmalı mı? ) -> None: # Burada class değişkenlerimizin atamasını yapıyoruz. self.surface: pygame.Surface = surface. self.xpos = xpos. self.ypos = ypos. self.velocity_x = velocity_x. self.velocity_y = velocity_y. self.should_blitted = should_blitted. # Blit'i obje özelinde daha rahat yapabilmek için sınıfın içine taşıyalım. # Screen'in de bir "Surface" olduğuna dikkat edelim. def blit(self, main_screen: pygame.Surface): main_screen.blit(self.surface, (self.xpos, self.ypos)) # Poziston güncellemeyi de obje özelinde daha rahat yapabilmek için buraya taşıyalım. def update_position(self, s_widt: int, s_height: int): # Obje eğer x ekseninde dışarı çıkacaksa x eksenindeki hızını ters çevirelim. if self.xpos > s_widt - self.velocity_x or self.xpos < 0: self.velocity_x = -self.velocity_x # Obje eğer y ekseninde dışarı çıkacaksa y eksenindeki hızını ters çevirelim. if self.ypos > s_height - self.velocity_y or self.ypos < 0: self.velocity_y = -self.velocity_y # x ve y pozisyonlarını hıza göre güncelleyelim. self.xpos += self.velocity_x self.ypos += self.velocity_y
Python:import pygame. from base import BaseObject. # Mermi sınıfımızı oluşturalım. # Merminin ana obje sınıfımızdan tek farkı resminin var olması. class Bullet(BaseObject): def __init__(self, xpos: float = 0, ypos: float = 0, velocity_x: float = 0, velocity_y: float = 0, should_blitted: bool = True) -> None: super().__init__(pygame.image.load("icon.png"), xpos, ypos, velocity_x, velocity_y, should_blitted)
Python:import pygame # Pygame için. import math # Daha hızlı matematik işlemleri için. from bullet import * # Mermi sınıfımızı importluyoruz. from time import sleep # Loop hızını kontrol edebilmek için gerekli. DELAY = 1/60 # While loop'unun gecikmesi. def update_objects(sc: pygame.Surface, bg: pygame.Surface | None, objs: list[BaseObject]): if bg is not None: sc.blit(bg, (0, 0)) # Eğer bir arkaplan resmi varsa arkaplana onu yerleştir. else: sc.fill((0, 0, 0)) # Eğer bir arkaplan resmi yoksa arkaplanı siyaha boya. for obj in objs: # Tüm objelerin içinden geç. obj.update_position( # obje konumunu güncelle. sc.get_width(), # Ekran genişliği. sc.get_height() # Ekran yüksekliği. ) if obj.should_blitted: # Eğer obje ekranda gözükmeliyse. obj.blit(sc) # objeyi ekrana çiz. def mainloop(): # ana döngü fonksiyonu. pygame.init() pygame.display.set_caption("Mermiler") screen = pygame.display.set_mode((400, 400)) START_POINT = (200, 200) # Mermilerin çıkacağı başlangıç noktası. BASE_SPEED = 5 # mermilerin temel sürati. running = True. objects: list[BaseObject] = [] # ekrana düzenli olarak konumları güncellenecek objelerin listesi. while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False. pygame.quit() elif event.type == pygame.MOUSEBUTTONUP: # fare tıklandığında. m_pos = pygame.mouse.get_pos() # tıklama konumunu al. dist_x = m_pos[0] - START_POINT[0] # tıklama konumunun başlangıç konumuna x ekseninde uzaklığı. dist_y = m_pos[1] - START_POINT[1] # tıklama konumunun başlangıç konumuna y ekseninde uzaklığı. # Uzaklıkları 2 kenar olarak kabul edip hayali bir üçgen çizelim. # Üçgenin hipotenüs uzunluğunu hesaplayalım. hypotenuse = math.sqrt(math.pow(dist_x, 2) + math.pow(dist_y, 2)) # Mermimizi yaratıp düzenli güncellenecek objeler listesine ekleyelim. objects.append( Bullet( START_POINT[0], # Başlangıç noktası X koordinatı. START_POINT[1], # Başlangıç noktası Y koordinatı. float(BASE_SPEED * dist_x / hypotenuse), # x eksenindeki hız = sürat * cosx. float(BASE_SPEED * dist_y / hypotenuse), # y eksenindeki hız = sürat * sinx. ) ) # Listedeki tüm objeleri güncelleyelim. update_objects(screen, None, objects) # Ekranı güncelleyelim. pygame.display.flip() # Ayarladığımız gecikme süresi kadar bekleyelim. sleep(DELAY) if __name__ == "__main__": # Çalışsın. mainloop()
|
kodlarını kendiniz şu şekilde düzeltebilirsiniz:|
işaretinin bulunduğu tüm dosyaların en üstüne from typing import Optional
yazın.bg: pygame.Surface | None
şeklindeki kodları bg: Optional[pygame.Surface]
şeklinde değiştirin.from typing import List
yazın.objects: list[BaseObject] = []
satırını objects: List[BaseObject] = []
şeklinde değiştirin.Rica ederim, anlamadığınız noktaları sorabilirsiniz bu konu üzerinden. Gördüğüm gibi cevaplamaya çalışacağım.
|
kodlarını kendiniz şu şekilde düzeltebilirsiniz:
|
işaretinin bulunduğu tüm dosyaların en üstünefrom typing import Optional
yazın.- Daha sonra örneğin
bg: pygame.Surface | None
şeklindeki kodlarıbg: Optional[pygame.Surface]
şeklinde değiştirin.
Ayrıca main.py dosyasındaki bir kod için de hata alacaksınız eğer Python 3.10 altı sürüm kullanıyorsanız. Onu da şu şekilde düzeltebilrisiniz:
Şimdi sorunuza gelecek olursak açıkçası bunu sadece pygame özelinde cevaplamak istemiyorum. Bunun sebebi yeni başlayan biri için herhangi bir dili öğrenmek adına 2 haftanın çok kısa bir süre olması. Öncelikle bolca proje yapmanız gerekiyor. Aslında bana kalırsa dil öğrenmenin tek yolu bu. Dillerin Syntax'ını öğrenmek zaten kolaydır genelde ama öğrenmesi zor olan programlama mantığıdır. Bunun için de bolca proje yapıp aklınızda belirli temelleri oturtmalısınız. Yapabiliyorsanız başkalarının yazdığı kodlara bakmalı ve onları anlamaya çalışmalısınız. Ha bir de kesinlikle İngilizce öğrenin.
- main.py dosyasının başına
from typing import List
yazın.objects: list[BaseObject] = []
satırınıobjects: List[BaseObject] = []
şeklinde değiştirin.
Pygame ve genel oyun programlama için konuşacak olursak ben şahsen OOP mantığına kendinizi derhal aşina etmenizi tavsiye ederim. İşiniz çok daha kolay olur. Ayrıca Python başkalarıyla çalışmadığınız veya sunucular içinde çalışacak bir kod yazmadığınız takdirde her daim en son sürümü kullanmaya özen gösterin. Performans artışları kayda değerdir.
Son olarak ana hedefiniz oyun programlamaysa Python yerine C# veya C++ öğrenmenizi tavsiye ederim. Gerçek bir oyun yapmak için bu tarz dillere ihtiyacınız var. C# ile Unity, C++ ile Unreal kullanabilirsiniz. Kendinizi daha da ilerletmek istediğinizde C++ ile OpenGL, DirectX veya sdl2 (bu çok basit şeyler için) kullanarak kendi motorunuzu veya oyun altyapınızı tasarlayıp yazabilirsiniz.
Kendi kodunuzu da atabilirseniz yardımcı olmam kolaylaşır.
import pygame, math, random
pygame.init()
#fps
fps = 30
clock = pygame.time.Clock()
#ekran boyutu
screen_width = 850
screen_height = 600
#ekran
surface = pygame.display.set_mode((screen_width,screen_height))
#renkler
green = 0,255,0
red = 255,0,0
blue = 0,0,255
yellow = 255,255,0
white = 255,255,255
black = 0,0,0
#asker/kare
class Square:
def __init__(self, color, x, y, width, height, speed):
self.rect = pygame.Rect(x,y,width,height)
self.color = color
self.direction = 'E'
self.speed = speed
#asker hareketi
def move(self):
if self.direction == 'E':
self.rect.x = self.rect.x+self.speed
if self.direction == 'W':
self.rect.x = self.rect.x-self.speed
if self.direction == 'N':
self.rect.y = self.rect.y-self.speed
if self.direction == 'S':
self.rect.y = self.rect.y+self.speed
#asker hareket yönlerini
def moveDirection(self, direction):
if direction == 'E':
self.rect.x = self.rect.x+self.speed
if direction == 'W':
self.rect.x = self.rect.x-self.speed
if direction == 'N':
self.rect.y = self.rect.y-self.speed
if direction == 'S':
self.rect.y = self.rect.y+self.speed
#çarpışma fonksiyonunu/detaylandırmak gerek
def collided(self, other_rect):
return self.rect.colliderect(other_rect)
#çizme fonksiyonu/yarı yarıya anladım
def draw(self, surface):
pygame.draw.rect(surface, self.color, self.rect)
#miraslama işlemi/hiç anlamadım
class Bullet(Square):
#bu kısım tam anlamıyla 0 bilgi
def __init__(self, color, x, y, width, height, speed, targetx,targety):
super().__init__(color, x, y, width, height, speed)
angle = math.atan2(targety-y, targetx-x) #get angle to target in radians
print('Angle in degrees:', int(angle*180/math.pi))
self.dx = math.cos(angle)*speed
self.dy = math.sin(angle)*speed
self.x = x
self.y = y
#Override/geçersiz saymak/biraz anladım
def move(self):
self.x = self.x + self.dx
self.y = self.y + self.dy
self.rect.x = int(self.x)
self.rect.y = int(self.y)
#sq adında kare oluşturuyor/bu kısmı anladım ama görsel üzerinde nasıl uyarlayacam bilmiyom
sq = Square(green,200,200,100,100, 10)
#liste elemanları / liste olduğunun farkındayım ama neden lazımlar bi fikrim yok
bullets = []
enemies = []
#program döngü kısmı
done = True
while done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = False
elif event.type == pygame.KEYDOWN:
print(event.key) #burası yapılan işlemi yazdırmak için
#az çok anladım
if event.key==32: # 32 numaralı tuş space
#etkinlik 32 numaralı tuşu algılarsa-ateş etme alt kısımda
spawnx = sq.rect.x + sq.rect.width/2 - 10
b = Square(red, spawnx,sq.rect.y, 10,50, 20) # mermi özellikleri
b.direction = 'N'#space ile kuzeye yani sadece yukarı ateş ediliyor
bullets.append(b) # mermiyi ekrana ekletti
#mouse ile tıklanan yere mermi gönderme/anladım gibi
if event.type == pygame.MOUSEBUTTONDOWN:
x,y = pygame.mouse.get_pos()
#print(x,y)
b = Bullet(red, sq.rect.centerx, sq.rect.centery, 20,20, 20, x,y)
bullets.append(b)
#hareket yönlerine tuş atama
pressed = pygame.key.get_pressed()
if pressed[pygame.K_w]:
sq.moveDirection('N')
if pressed[pygame.K_a]:
sq.moveDirection('W')
if pressed[pygame.K_s]:
sq.moveDirection('S')
if pressed[pygame.K_d]:
sq.moveDirection('E')
#tam anlayamadım
for b in bullets:
b.move()
for e in enemies:
e.move()
#bu kısıma dair hiçbir fikrim yok!
if random.randint(1,30) == 15: #15 doesn't matter
x = random.randint(0,screen_width-40)
e = Square(yellow, x,-40, 40,40, 5)
e.direction = 'S'
enemies.append(e)
#bu kısımı hiç mi hiç anlamadım
for i in reversed(range(len(bullets))):
for j in reversed(range(len(enemies))):
if bullets[i].collided(enemies[j].rect):
#e.color = white #TESTING # test için muhtemelen
del enemies[j]
del bullets[i]
break
#arka planı temizliyor
surface.fill(black)
#mermi ve düşmanları ekrana çizdiriyor
for b in bullets:
b.draw(surface)
for e in enemies:
e.draw(surface)
sq.draw(surface)
#ekranı güncelliyor ve fps değeri ayarlama kısmı
pygame.display.update()
clock.tick(fps)
pygame.quit()
exit()
Şöyle söyleyeyim önerinizi kesinlikle dikkate alacağım,
Python öğrenme amacım aslında bir yerden başlamak için basit bir dil olması mantıkları kavrayana dek buradan devam etmeyi düşünüyorum.
Kendi koduma gelecek olursak benim kodum bir YT kanalının yaptığı 2-3 farklı projeden aldığım kodları bir araya getirmem ile oluştu, yani epey bir baştan sarma onun yerine yabancı kaynaklı olan adamın kodunu baz alarak ilerleyelim.
import pygame, math, random. pygame.init() #fps fps = 30. clock = pygame.time.Clock() #ekran boyutu. screen_width = 850. screen_height = 600. #ekran surface = pygame.display.set_mode((screen_width,screen_height)) #renkler green = 0,255,0 red = 255,0,0 blue = 0,0,255 yellow = 255,255,0 white = 255,255,255 black = 0,0,0 #asker/kare class Square: def __init__(self, color, x, y, width, height, speed): self.rect = pygame.Rect(x,y,width,height) self.color = color. self.direction = 'E'. self.speed = speed. #asker hareketi. def move(self): if self.direction == 'E': self.rect.x = self.rect.x+self.speed if self.direction == 'W': self.rect.x = self.rect.x-self.speed if self.direction == 'N': self.rect.y = self.rect.y-self.speed if self.direction == 'S': self.rect.y = self.rect.y+self.speed #asker hareket yönlerini. def moveDirection(self, direction): if direction == 'E': self.rect.x = self.rect.x+self.speed if direction == 'W': self.rect.x = self.rect.x-self.speed if direction == 'N': self.rect.y = self.rect.y-self.speed if direction == 'S': self.rect.y = self.rect.y+self.speed #çarpışma fonksiyonunu/detaylandırmak gerek. def collided(self, other_rect): return self.rect.colliderect(other_rect) #çizme fonksiyonu/yarı yarıya anladım. def draw(self, surface): pygame.draw.rect(surface, self.color, self.rect) #miraslama işlemi/hiç anlamadım. class Bullet(Square): #bu kısım tam anlamıyla 0 bilgi. def __init__(self, color, x, y, width, height, speed, targetx,targety): super().__init__(color, x, y, width, height, speed) angle = math.atan2(targety-y, targetx-x) #get angle to target in radians. print('Angle in degrees:', int(angle*180/math.pi)) self.dx = math.cos(angle)*speed self.dy = math.sin(angle)*speed self.x = x self.y = y #Override/geçersiz saymak/biraz anladım. def move(self): self.x = self.x + self.dx self.y = self.y + self.dy self.rect.x = int(self.x) self.rect.y = int(self.y) #sq adında kare oluşturuyor/bu kısmı anladım ama görsel üzerinde nasıl uyarlayacam bilmiyom. sq = Square(green,200,200,100,100, 10) #liste elemanları / liste olduğunun farkındayım ama neden lazımlar bi fikrim yok. bullets = [] enemies = [] #program döngü kısmı. done = True. while done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = False. elif event.type == pygame.KEYDOWN: print(event.key) #burası yapılan işlemi yazdırmak için. #az çok anladım. if event.key==32: # 32 numaralı tuş space. #etkinlik 32 numaralı tuşu algılarsa-ateş etme alt kısımda. spawnx = sq.rect.x + sq.rect.width/2 - 10. b = Square(red, spawnx,sq.rect.y, 10,50, 20) # mermi özellikleri. b.direction = 'N'#space ile kuzeye yani sadece yukarı ateş ediliyor. bullets.append(b) # mermiyi ekrana ekletti. #mouse ile tıklanan yere mermi gönderme/anladım gibi. if event.type == pygame.MOUSEBUTTONDOWN: x,y = pygame.mouse.get_pos() #print(x,y) b = Bullet(red, sq.rect.centerx, sq.rect.centery, 20,20, 20, x,y) bullets.append(b) #hareket yönlerine tuş atama. pressed = pygame.key.get_pressed() if pressed[pygame.K_w]: sq.moveDirection('N') if pressed[pygame.K_a]: sq.moveDirection('W') if pressed[pygame.K_s]: sq.moveDirection('S') if pressed[pygame.K_d]: sq.moveDirection('E') #tam anlayamadım. for b in bullets: b.move() for e in enemies: e.move() #bu kısıma dair hiçbir fikrim yok! if random.randint(1,30) == 15: #15 doesn't matter. x = random.randint(0,screen_width-40) e = Square(yellow, x,-40, 40,40, 5) e.direction = 'S'. enemies.append(e) #bu kısımı hiç mi hiç anlamadım. for i in reversed(range(len(bullets))): for j in reversed(range(len(enemies))): if bullets[i].collided(enemies[j].rect): #e.color = white #TESTING # test için muhtemelen. del enemies[j] del bullets[i] break. #arka planı temizliyor. surface.fill(black) #mermi ve düşmanları ekrana çizdiriyor. for b in bullets: b.draw(surface) for e in enemies: e.draw(surface) sq.draw(surface) #ekranı güncelliyor ve fps değeri ayarlama kısmı. pygame.display.update() clock.tick(fps) pygame.quit() exit()
Anladığım noktaları # ile başlıklandırdım ve yine # ile anlamadığım noktaları da başlıklandırdım.
Bu adam kendi oluşturduğu pixel karelerle çalıştı.
Ben ise kendi eklediğim görseller ile çalışmak istiyorum arka plan görseli, karakter için bir pixelart askerim var, düşmanlar için hayalet görselim var, mermi görsellerim ve tabii seslerim var arka plan için oyunu kaybetiğinde çalması için ateş sesi hayaletin bize çarptığındaki ses.
Aklımdaki plan karakterimiz bir adada mahsur hemen hemen merkezde arkaplanımızın merkezinde ada var, hareketlerini ada içerisinde sınırlamayı kendi kodumda yapmıştım,
Hayaletler yani düşmanlar random fonksiyonu ile 4 bir yandan gelecekler askerimiz ateş ederek onları öldürecek hayaletlerin tek vuruşluk canları olsun adamında 10 canı olsun diye kendi aklımda planlamıştım, projem bu2 haftalık biri için büyük mü bilmem,
Kendi kodumda asker adada hareket edebiliyor ve sadece yukarı eksende ateş edebiliyordu, dünden beri her yöne ateş ettirebilmek için uğraşıyorum bunu başardığımda random ve math modülleri ile hayaletleri getirip can olaylarını ekleyecektim ama tökezledim
Technopat'ta da yeniyim nasıl sade güzel görüntülü kodu aktarabilirim bilmiyorum.
Eki Görüntüle 1595834
Sonunda çizmek için de rahat bir ortam bulabildim. Bu şekilde bir üçgen çizmeniz gerekiyor. Ha aklınızda ha kodda olur, fark etmez. Bu üçgene göre gerekli matematiği yapıp ana hızı bileşenlerine ayırıp daha sonra da mermiye hızı girmelisiniz. Bu çizdiğim basit bir 3-4-5 üçgeni ancak karmaşıklarında da işiniz zor değil, işlemler aynı.
Hipotenüsümüz aslında hız vektörlerinin toplamı oluyor, yani ana çizgisel hızımız.
Sonrası ister trigonometri ister geometri ister de düz matematik.
Diyelim ki mermimizin farenin tıklandığı konuma 100 hızında gitmesini istiyoruz. Buna göre vektör toplamımız 100 olmalı. Yalnız mermiyi çapraz hareket ettiremeyiz çünkü ekran, x ve y eksenlerinde dizilmiş piksellerden oluşuyor. Dolayısıyla hareket yalnızca bu eksenler üzerinde sınırlı. O yüzden kuvveti bileşenlerine ayırıyoruz. Bu üçgen çerçevesinde vektör toplamımız 5 çıktı. Kolaylık açısından 5k diyelim.
100 -> 5k ise o zaman y eksenindeki hızımız 4k'dan 80 çıkıyor. x eksenindeki hızımız da 3k'dan 60 çıkıyor. Yani neymiş, ana döngünün her dönüşünde mermimizi x ekseninde 60 birim sağa, y ekseninde de 80 birim yukarı kaydırırsak amacımıza ulaşıyormuşuz. Benim kodda yaptığım şey de aslında bunu döngünün her dönüşünde sürekli yaptırmak.
- Eki Görüntüle 1595856 simgesine tıklayın.
- Eki Görüntüle 1595857 kısmından Python'u seçin.
- Alttaki alana kodunuzu yapıştırın ve "Devam et"e tıklayın.
Bu paylaştığınız şekilde kodunuzun okunması çok zor ne yazık ki. Tüm tab'lar gitmiş durumda.
import pygame, math, random
pygame.init()
#fps
fps = 30
clock = pygame.time.Clock()
#ekran boyutu
screen_width = 850
screen_height = 600
#ekran
surface = pygame.display.set_mode((screen_width,screen_height))
#renkler
green = 0,255,0
red = 255,0,0
blue = 0,0,255
yellow = 255,255,0
white = 255,255,255
black = 0,0,0
#asker/kare
class Square:
def __init__(self, color, x, y, width, height, speed):
self.rect = pygame.Rect(x,y,width,height)
self.color = color
self.direction = 'E'
self.speed = speed
#asker hareketi
def move(self):
if self.direction == 'E':
self.rect.x = self.rect.x+self.speed
if self.direction == 'W':
self.rect.x = self.rect.x-self.speed
if self.direction == 'N':
self.rect.y = self.rect.y-self.speed
if self.direction == 'S':
self.rect.y = self.rect.y+self.speed
#asker hareket yönlerini
def moveDirection(self, direction):
if direction == 'E':
self.rect.x = self.rect.x+self.speed
if direction == 'W':
self.rect.x = self.rect.x-self.speed
if direction == 'N':
self.rect.y = self.rect.y-self.speed
if direction == 'S':
self.rect.y = self.rect.y+self.speed
#çarpışma fonksiyonunu/detaylandırmak gerek
def collided(self, other_rect):
return self.rect.colliderect(other_rect)
#çizme fonksiyonu/yarı yarıya anladım
def draw(self, surface):
pygame.draw.rect(surface, self.color, self.rect)
#miraslama işlemi/hiç anlamadım
class Bullet(Square):
#bu kısım tam anlamıyla 0 bilgi
def __init__(self, color, x, y, width, height, speed, targetx,targety):
super().__init__(color, x, y, width, height, speed)
angle = math.atan2(targety-y, targetx-x) #get angle to target in radians
print('Angle in degrees:', int(angle*180/math.pi))
self.dx = math.cos(angle)*speed
self.dy = math.sin(angle)*speed
self.x = x
self.y = y
#Override/geçersiz saymak/biraz anladım
def move(self):
self.x = self.x + self.dx
self.y = self.y + self.dy
self.rect.x = int(self.x)
self.rect.y = int(self.y)
#sq adında kare oluşturuyor/bu kısmı anladım ama görsel üzerinde nasıl uyarlayacam bilmiyom
sq = Square(green,200,200,100,100, 10)
#liste elemanları / liste olduğunun farkındayım ama neden lazımlar bi fikrim yok
bullets = []
enemies = []
#program döngü kısmı
done = True
while done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = False
elif event.type == pygame.KEYDOWN:
print(event.key) #burası yapılan işlemi yazdırmak için
#az çok anladım
if event.key==32: # 32 numaralı tuş space
#etkinlik 32 numaralı tuşu algılarsa-ateş etme alt kısımda
spawnx = sq.rect.x + sq.rect.width/2 - 10
b = Square(red, spawnx,sq.rect.y, 10,50, 20) # mermi özellikleri
b.direction = 'N'#space ile kuzeye yani sadece yukarı ateş ediliyor
bullets.append(b) # mermiyi ekrana ekletti
#mouse ile tıklanan yere mermi gönderme/anladım gibi
if event.type == pygame.MOUSEBUTTONDOWN:
x,y = pygame.mouse.get_pos()
#print(x,y)
b = Bullet(red, sq.rect.centerx, sq.rect.centery, 20,20, 20, x,y)
bullets.append(b)
#hareket yönlerine tuş atama
pressed = pygame.key.get_pressed()
if pressed[pygame.K_w]:
sq.moveDirection('N')
if pressed[pygame.K_a]:
sq.moveDirection('W')
if pressed[pygame.K_s]:
sq.moveDirection('S')
if pressed[pygame.K_d]:
sq.moveDirection('E')
#tam anlayamadım
for b in bullets:
b.move()
for e in enemies:
e.move()
#bu kısıma dair hiçbir fikrim yok!
if random.randint(1,30) == 15: #15 doesn't matter
x = random.randint(0,screen_width-40)
e = Square(yellow, x,-40, 40,40, 5)
e.direction = 'S'
enemies.append(e)
#bu kısımı hiç mi hiç anlamadım
for i in reversed(range(len(bullets))):
for j in reversed(range(len(enemies))):
if bullets[i].collided(enemies[j].rect):
#e.color = white #TESTING # test için muhtemelen
del enemies[j]
del bullets[i]
break
#arka planı temizliyor
surface.fill(black)
#mermi ve düşmanları ekrana çizdiriyor
for b in bullets:
b.draw(surface)
for e in enemies:
e.draw(surface)
sq.draw(surface)
#ekranı güncelliyor ve fps değeri ayarlama kısmı
pygame.display.update()
clock.tick(fps)
pygame.quit()
exit()
Eki Görüntüle 1595834
Sonunda çizmek için de rahat bir ortam bulabildim. Bu şekilde bir üçgen çizmeniz gerekiyor. Ha aklınızda ha kodda olur, fark etmez. Bu üçgene göre gerekli matematiği yapıp ana hızı bileşenlerine ayırıp daha sonra da mermiye hızı girmelisiniz. Bu çizdiğim basit bir 3-4-5 üçgeni ancak karmaşıklarında da işiniz zor değil, işlemler aynı.
Hipotenüsümüz aslında hız vektörlerinin toplamı oluyor, yani ana çizgisel hızımız.
Sonrası ister trigonometri ister geometri ister de düz matematik.
Diyelim ki mermimizin farenin tıklandığı konuma 100 hızında gitmesini istiyoruz. Buna göre vektör toplamımız 100 olmalı. Yalnız mermiyi çapraz hareket ettiremeyiz çünkü ekran, X ve Y eksenlerinde dizilmiş piksellerden oluşuyor. Dolayısıyla hareket yalnızca bu eksenler üzerinde sınırlı. O yüzden kuvveti bileşenlerine ayırıyoruz. Bu üçgen çerçevesinde vektör toplamımız 5 çıktı. Kolaylık açısından 5K diyelim.
100 -> 5K ise o zaman y eksenindeki hızımız 4K'den 80 çıkıyor. X eksenindeki hızımız da 3K'den 60 çıkıyor. Yani neymiş, ana döngünün her dönüşünde mermimizi X ekseninde 60 birim sağa, y ekseninde de 80 birim yukarı kaydırırsak amacımıza ulaşıyormuşuz. Benim kodda yaptığım şey de aslında bunu döngünün her dönüşünde sürekli yaptırmak.
- Eki Görüntüle 1595856 simgesine tıklayın.
- Eki Görüntüle 1595857 kısmından Python'u seçin.
- Alttaki alana kodunuzu yapıştırın ve "devam et"e tıklayın.
Bu paylaştığınız şekilde kodunuzun okunması çok zor ne yazık ki. Tüm Tab'lar gitmiş durumda.
Hocam OpenGL kullansana. Eziyet çekmezsin.Öncelikle teşekkürler 12.sınıf öğrencisiyim ve 2 haftadır Python ile ilgileniyorum.
Temel seviyede biliyorum, kısa sürede turtle modülü ile çeşitli şeyler yaptım.
Bir temeol orta düzey kurs bitirdim ve merakım olduğu için oyun yapmaya yönelik direkt pygame modülünü öğrenmeye çalıştım, 2 gündür sanırsam uğraşıyorum Türkçe videolu kaynak çok az.
Yeterli İngilizce dilim olmadığı için yabancı adamları da anlayamıyorum.
Aslında İngilizce bir kaynak buldum tam olarak istediğimi yapan kodunu inceledim 3-4 saat ve %30 kadarını falan neyi neden yaptığını anladım. Çoğu şeyi kavrayamadım, kendi projeme katmaya çalıştım onun kullandığı fonksiyonları vs. tabii ki de olmadı,belki mantığını kaparım dedim.
Elinize sağlık bu arada kod yazmışsınız o kadar uzun emek var sonuçta, ama sizin kounuzunda da anlamadığım noktalar oldu, ve pygame modülünü Python 3.11 sürümünde kurmayı başaramadım bu nedenle düşük bir sürüm kurdum sizin kodunuzdaki düz çizgi de 3.10 ve üzeri için tasarlanmış kodu çalıştıramadım,
Yine de elinize sağlık teşekkür ediyorum,
Mümkünse sadece birkaç tavsiye isteyeceğim.
Pygame modülünde gelişmek için nasıl bir yol izleyeyim?
Hocam OpenGL kullansana. Eziyet çekmezsin.
Eki Görüntüle 1595834
Sonunda çizmek için de rahat bir ortam bulabildim. Bu şekilde bir üçgen çizmeniz gerekiyor. Ha aklınızda ha kodda olur, fark etmez. Bu üçgene göre gerekli matematiği yapıp ana hızı bileşenlerine ayırıp daha sonra da mermiye hızı girmelisiniz. Bu çizdiğim basit bir 3-4-5 üçgeni ancak karmaşıklarında da işiniz zor değil, işlemler aynı.
Hipotenüsümüz aslında hız vektörlerinin toplamı oluyor, yani ana çizgisel hızımız.
Sonrası ister trigonometri ister geometri ister de düz matematik.
Diyelim ki mermimizin farenin tıklandığı konuma 100 hızında gitmesini istiyoruz. Buna göre vektör toplamımız 100 olmalı. Yalnız mermiyi çapraz hareket ettiremeyiz çünkü ekran, X ve Y eksenlerinde dizilmiş piksellerden oluşuyor. Dolayısıyla hareket yalnızca bu eksenler üzerinde sınırlı. O yüzden kuvveti bileşenlerine ayırıyoruz. Bu üçgen çerçevesinde vektör toplamımız 5 çıktı. Kolaylık açısından 5K diyelim.
100 -> 5K ise o zaman y eksenindeki hızımız 4K'den 80 çıkıyor. X eksenindeki hızımız da 3K'den 60 çıkıyor. Yani neymiş, ana döngünün her dönüşünde mermimizi X ekseninde 60 birim sağa, y ekseninde de 80 birim yukarı kaydırırsak amacımıza ulaşıyormuşuz. Benim kodda yaptığım şey de aslında bunu döngünün her dönüşünde sürekli yaptırmak.
- Eki Görüntüle 1595856 simgesine tıklayın.
- Eki Görüntüle 1595857 kısmından Python'u seçin.
- Alttaki alana kodunuzu yapıştırın ve "devam et"e tıklayın.
Bu paylaştığınız şekilde kodunuzun okunması çok zor ne yazık ki. Tüm Tab'lar gitmiş durumda.
Forumda ne yazık ki özel mesaj atma var mı yok mu bulamadım. Konuda da şahsi bilgilerimi paylaşmak istemiyorum ne yazık ki.Hocam Discord Instagram veya iletişime geçebileceğimiz bir yer var mı koddaki belirli yerleri sormak istiyorum sadece.