Compare commits

...

2 Commits

  1. 21
      README.md
  2. 104
      README_PRO_STUDENTY.md
  3. 11
      pygame/fix_syntax.py
  4. 0
      pygame/main.py
  5. BIN
      pygame/main.zip
  6. 25
      pygame/patch.py
  7. 29
      pygame/patch_safe.py

21
README.md

@ -60,3 +60,24 @@ Pokud nevíte jak začít, zkuste se držet těchto bodů:
5. **Dělejte si zálohy:** Často ukládejte a pokud něco začne fungovat, udělejte si kopii souboru (nebo použijte Git!), než do toho začnete vrtat dál.
Hodně štěstí při vývoji! Nezapomeňte, že primárním cílem Game Jamu je se něco nového naučit a pobavit se u toho.
---
## 🌐 Optimalizace pro Školní Webový Portál (GameGlass)
Aby vaše hry fungovaly nejen u vás na počítači (Desktopu), ale šly bez problémů nahrát a hrát přímo ve webovém prohlížeči v našem školním systému, musíte dodržet několik důležitých technických pravidel:
### 1. Pygame hry (Nutnost použít asynchronní kód)
Webový prohlížeč neumožňuje tzv. "nekonečné blokovací smyčky" (zamrzla by vám celá záložka v prohlížeči). Vaše hlavní herní smyčka proto **musí** být napsána asynchronně pomocí modulu `asyncio`:
* **Pravidlo 1:** Hlavní smyčka hry musí být definována jako `async def hlavni_smycka():`.
* **Pravidlo 2:** Uvnitř `while True:` smyčky musíte na konec každého kola (typicky za `pygame.display.flip()`) přidat `await asyncio.sleep(0)`. Tento příkaz "na milisekundu" uvolní prohlížeč, aby stihl vykreslit obraz.
* **Pravidlo 3:** 🚫 **ZÁKAZ** používání `pygame.time.wait()` nebo `pygame.time.delay()`. Tyto funkce na webu totálně zamrazí celou obrazovku. Pokud potřebujete hru na vteřinu uspat (např. při chybě v Pexesu), použijte `await asyncio.sleep(1)`.
* **Pravidlo 4:** Spuštění hry na samotném konci souboru musí vypadat takto: `asyncio.run(hlavni_smycka())`
*(Prohlédněte si naše ukázky v adresáři `pygame/`, všechny jsou už pro web plně optimalizované!)*
### 2. Balení her pro odevzdání (ZIP)
Na portál se hry nahrávají ve formátu `.zip`. Je ale velmi důležité, co do ZIPu zabalíte:
* **Pygame a Čistý Python:** Hlavní spouštěcí soubor vaší hry by měl být umístěn přímo v kořenovém adresáři ZIPu (nezašívejte ho hluboko do složek). Náš portál se ho pokusí najít a pokud se jmenuje `main.py`, je to ideální. Spolu se zdrojovým kódem nezapomeňte do ZIPu přibalit i složku se zvuky a grafikou (např. `/assets`).
* **Ren'Py (Vizuální novely):** Nemusíte z Ren'Py enginu dělat žádný složitý "Web Export"! Stačí, když vezmete celou složku s vaším projektem (tu, která obsahuje podsložku `game/` se soubory `script.rpy` atd.) a rovnou ji zazipujete. Náš webový portál si tento ZIP automaticky rozbalí a nasadí do něj svůj vlastní webový RenPy motor. Je to naprosto bez starostí!

104
README_PRO_STUDENTY.md

@ -0,0 +1,104 @@
# 🎮 Návod pro studenty: Jak připravit hru pro GameGlass Portál
Ahoj! Abys mohl/a svou hru nahrát na náš školní GameGlass portál a ukázat ji všem ostatním přímo ve webovém prohlížeči, stačí dodržet několik jednoduchých pravidel.
---
## 1. Pravidla pro Pygame (Grafické hry)
Aby tvoje Pygame hra mohla běžet uvnitř internetového prohlížeče, musí být strukturována tzv. "asynchronně" (aby nezamrzla prohlížeč).
**Musíš udělat přesně tyto 3 kroky ve svém kódu:**
1. **Importuj `asyncio`:**
Na úplný začátek souboru, hned k `import pygame`, přidej:
```python
import pygame
import asyncio
```
2. **Zabal hru do asynchronní funkce:**
Celý kód tvé hry (nebo alespoň tvoji hlavní herní smyčku) musíš zabalit do asynchronní funkce (např. `async def main():`).
A na úplný konec souboru pak hru spustit pomocí `asyncio.run(main())`.
3. **Přidej odpočinkovou pauzu do smyčky:**
Do tvé hlavní smyčky `while True:` musíš (ideálně nakonec smyčky) přidat magické zaříkávadlo:
```python
await asyncio.sleep(0)
```
*Tento příkaz řekne prohlížeči: "Teď si můžeš na milisekundu odpočinout a vykreslit obrazovku". Bez tohoto příkazu hra okamžitě zamrzne a spadne!*
**Ukázková kostra správné Pygame hry:**
```python
import pygame
import asyncio
# --- Zde dej své funkce a nastavení ---
async def main():
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Zde se děje logika hry a vykreslování...
screen.fill((0, 0, 0))
pygame.display.flip()
# Omezení FPS
clock.tick(60)
# MAGICKÝ PŘÍKAZ (NUTNÉ PRO WEB!)
await asyncio.sleep(0)
pygame.quit()
# Spuštění asynchronní hry
if __name__ == "__main__":
asyncio.run(main())
```
---
## 2. Pravidla pro terminálové hry (Čistý Python textovky)
Pokud děláš obyčejnou textovou hru (pouze příkazy `print` a `input`), je to velmi jednoduché:
- Nemusíš používat `asyncio` vůbec.
- Můžeš normálně používat `input("Zadej volbu: ")`. Portál sám vytvoří interaktivní textové pole.
- Pokud chceš "vyčistit obrazovku" terminálu, můžeš použít klasický příkaz:
```python
import os
os.system('cls') # nebo os.system('clear')
```
---
## 3. Pravidla pro Ren'Py (Vizuální Novely)
- Tvoje hra bude spuštěna přes Web Assembly engine Ren'Py.
- **Krok navíc:** Před zabalením do ZIPu jdi do složky své hry a zazipuj POUZE obsah složky `game/` (tedy soubory `.rpy` a složku s obrázky `images/`). Portál nepotřebuje zbytek enginu (soubory `.exe`, `.sh`), engine už v portálu je.
---
## ⚠️ DŮLEŽITÉ UPOZORNĚNÍ K CESTÁM V KÓDU (Pro všechny hry)
**NIKDY** ve svém kódu nepoužívejte tzv. "natvrdo zadrátované cesty" k obrázkům nebo k vašemu disku! (Tzv. Absolutní cesty).
❌ **ŠPATNĚ (Na webu to spadne):**
```python
os.chdir(r"C:\Users\Student\Plocha\MojeHra") # NIKDY!
image = pygame.image.load(r"C:\Users\Student\Plocha\MojeHra\assets\hrdina.png")
```
✅ **SPRÁVNĚ (Relativní cesty):**
Aplikace běží v paměti na internetu (kde disk C:\ vůbec neexistuje). Používejte relativní cesty:
```python
image = pygame.image.load("assets/hrdina.png")
```
Až budeš mít hotovo, všechny své soubory a složky označ a zabal přímo do archivu **.ZIP** a nahraj do formuláře na portálu!

11
pygame/fix_syntax.py

@ -1,11 +0,0 @@
import os
import glob
os.chdir(r'C:\gitprojekty_skola\python_gamejam_examples\pygame')
for f in glob.glob('*.py'):
if f.startswith('patch'): continue
with open(f, 'r', encoding='utf-8') as file:
content = file.read()
content = content.replace('async def hlavni_smycka():', 'async def hlavni_smycka():')
with open(f, 'w', encoding='utf-8') as file:
file.write(content)

0
pygame/07_had.py → pygame/main.py

BIN
pygame/main.zip

Binary file not shown.

25
pygame/patch.py

@ -1,25 +0,0 @@
import os
import glob
import re
os.chdir(r'C:\gitprojekty_skola\python_gamejam_examples\pygame')
for f in glob.glob('*.py'):
with open(f, 'r', encoding='utf-8') as file:
content = file.read()
# 1. async def
content = re.sub(r'(\s*)def hlavni_smycka\(\):', r'\1async def hlavni_smycka():', content)
# 2. Add await to hlavni_smycka() calls
content = re.sub(r'(\s+)hlavni_smycka\(\)', r'\1await hlavni_smycka()', content)
# 3. Fix asyncio.sleep(0)
# Odstranime stary await asyncio.sleep(0) a jeho komentar
content = re.sub(r'[ \t]*# PØIDÁNO PRO WEB: Dáme prohlížeèi šanci pøekreslit obrazovku\s+await asyncio\.sleep\(0\)\s*', '\n', content)
# Pridame ho tesne za hodiny.tick(...) se stejnym odsazenim
content = re.sub(r'([ \t]*)(.*hodiny\.tick.*)', r'\1\2\n\1# PØIDÁNO PRO WEB: Dáme prohlížeèi šanci pøekreslit obrazovku\n\1await asyncio.sleep(0)', content)
with open(f, 'w', encoding='utf-8') as file:
file.write(content)
print(f'Opraveno: {f}')

29
pygame/patch_safe.py

@ -1,29 +0,0 @@
import os
import glob
import re
os.chdir(r'C:\gitprojekty_skola\python_gamejam_examples\pygame')
for f in glob.glob('*.py'):
if f == 'patch.py':
continue
with open(f, 'r', encoding='utf-8') as file:
content = file.read()
# 1. async def
content = re.sub(r'(\s*)def hlavni_smycka\(\):', r'\1async async def await hlavni_smycka():', content)
# 2. Add await to await hlavni_smycka() calls
content = re.sub(r'(\s+)hlavni_smycka\(\)', r'\1await await hlavni_smycka()', content)
# 3. Fix asyncio.sleep(0)
# Match the old comment containing WEB without needing special chars
content = re.sub(r'[ \t]*#.*WEB.*\s+await asyncio\.sleep\(0\)\s*', '\n', content)
# Pridame ho tesne za hodiny.tick(...) se stejnym odsazenim
# PRIDANO PRO WEB
await asyncio.sleep(0)
content = re.sub(r'([ \t]*)(.*hodiny\.tick.*)', r'\1\2\n\1# PRIDANO PRO WEB\n\1await asyncio.sleep(0)', content)
with open(f, 'w', encoding='utf-8') as file:
file.write(content)
print(f'Opraveno: {f}')
Loading…
Cancel
Save