Arkanoid
unknown
python
9 months ago
5.3 kB
11
Indexable
import pygame
import math
import numpy as np
import sys
# --- Stałe gry ---
SZEROKOSC = 800
WYSOKOSC = 600
KOLOR_TLO = (20, 20, 20)
KOLOR_CEGIELKA = (200, 80, 80)
KOLOR_PALKA = (80, 200, 80)
KOLOR_PILKA = (80, 80, 200)
# Rozmiary paletki
PALETKA_SZER = 100
PALETKA_WYS = 10
# Rozmiary cegiełek
CEGIELKA_SZER = 75
CEGIELKA_WYS = 30
# Parametry piłki
PILKA_PROMIEN = 8
PILKA_PREDKOSC = 5
def generuj_dzwiek(frequency=440, duration=0.2, volume=1.0, sample_rate=44100):
"""
Tworzy prosty dźwięk sinusoidalny (mono), ale zwraca w formacie stereo
(aby pasował do domyślnego trybu 2 kanałów w pygame.mixer).
"""
n_samples = int(sample_rate * duration)
t = np.linspace(0, duration, n_samples, endpoint=False)
# Fala sinusoidalna (16-bit)
wave = 32767 * volume * np.sin(2 * math.pi * frequency * t)
wave = wave.astype(np.int16)
# Replikacja do dwóch kanałów (stereo), tak aby uniknąć błędu:
# "ValueError: Array depth must match number of mixer channels"
wave_stereo = np.column_stack((wave, wave))
sound_obj = pygame.sndarray.make_sound(wave_stereo)
return sound_obj
class Paletka(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((PALETKA_SZER, PALETKA_WYS))
self.image.fill(KOLOR_PALKA)
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.centery = y
self.predkosc = 7
def update(self, keys):
if keys[pygame.K_LEFT]:
self.rect.x -= self.predkosc
if keys[pygame.K_RIGHT]:
self.rect.x += self.predkosc
# Zabezpieczenie przed wyjechaniem za ekran
if self.rect.left < 0:
self.rect.left = 0
if self.rect.right > SZEROKOSC:
self.rect.right = SZEROKOSC
class Pilka(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((PILKA_PROMIEN * 2, PILKA_PROMIEN * 2), pygame.SRCALPHA)
pygame.draw.circle(self.image, KOLOR_PILKA, (PILKA_PROMIEN, PILKA_PROMIEN), PILKA_PROMIEN)
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.dx = PILKA_PREDKOSC
self.dy = -PILKA_PREDKOSC # startuje w górę
def update(self):
self.rect.x += self.dx
self.rect.y += self.dy
# Odbicia od lewej i prawej krawędzi
if self.rect.left <= 0 or self.rect.right >= SZEROKOSC:
self.dx = -self.dx
# Odbicie od górnej krawędzi
if self.rect.top <= 0:
self.dy = -self.dy
class Cegielka(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((CEGIELKA_SZER, CEGIELKA_WYS))
self.image.fill(KOLOR_CEGIELKA)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def main():
pygame.init()
# Można jawnie zainicjalizować mikser, ale domyślnie będzie 2-kanałowy (stereo).
# pygame.mixer.init(frequency=44100, size=-16, channels=2)
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Prosty Arkanoid")
zegar = pygame.time.Clock()
# Przygotowanie obiektów gry
paletka = Paletka(SZEROKOSC // 2, WYSOKOSC - 30)
pilka = Pilka(SZEROKOSC // 2, WYSOKOSC // 2)
paletka_grupa = pygame.sprite.Group()
paletka_grupa.add(paletka)
pilka_grupa = pygame.sprite.Group()
pilka_grupa.add(pilka)
cegielki_grupa = pygame.sprite.Group()
# Układ cegiełek w kilku rzędach
for wiersz in range(5):
for kolumna in range(10):
x = 10 + kolumna * (CEGIELKA_SZER + 5)
y = 50 + wiersz * (CEGIELKA_WYS + 5)
cegielka = Cegielka(x, y)
cegielki_grupa.add(cegielka)
# Proste efekty dźwiękowe - kolizje
dzwiek_kolizja_cegielka = generuj_dzwiek(frequency=500, duration=0.05, volume=0.5)
dzwiek_kolizja_paletka = generuj_dzwiek(frequency=200, duration=0.05, volume=0.5)
running = True
while running:
zegar.tick(60) # 60 FPS
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Sterowanie paletką
keys = pygame.key.get_pressed()
paletka.update(keys)
# Aktualizacja piłki
pilka.update()
# Sprawdzenie kolizji piłki z paletką
if pygame.sprite.spritecollide(pilka, paletka_grupa, False):
pilka.dy = -pilka.dy
dzwiek_kolizja_paletka.play()
# Sprawdzenie kolizji piłki z cegiełkami
trafione_cegielki = pygame.sprite.spritecollide(pilka, cegielki_grupa, True)
if trafione_cegielki:
pilka.dy = -pilka.dy
dzwiek_kolizja_cegielka.play()
# Sprawdzenie, czy piłka spadła poniżej dolnej krawędzi
if pilka.rect.top > WYSOKOSC:
# Tutaj można zakończyć grę, odpalić ekran "Game Over", itp.
running = False
# Rysowanie
ekran.fill(KOLOR_TLO)
paletka_grupa.draw(ekran)
pilka_grupa.draw(ekran)
cegielki_grupa.draw(ekran)
pygame.display.flip()
pygame.quit()
sys.exit()
if __name__ == "__main__":
main()
Editor is loading...
Leave a Comment