Hello,
at a specific point in my Python Delightex Project I get this Error (only occures on iPad/Phone, but not on PC.
This is my code:
from delightex import *
=== Szenenobjekte ===
start_knopf = scene.get_item(“Gi57DR3X”)
start_knopf_hitbox = scene.get_item(“srjPadIr”)
weiter_knopf_hitbox = scene.get_item(“FPq1EsKH”)
weiter_knopf = scene.get_item(“3QpevabJ”)
small_cube = scene.get_item(“38QgFiG5”)
stange = scene.get_item(“BfKXvEL8”)
platte = scene.get_item(“KZlBN0Gw”)
pyramid = scene.get_item(“Gbd0pMUW”)
Improvisation, weil man den Würfel im AR mode net unsichtbar machen kann…, statt im Würfel sind die jetzt auf dem Würfel
=== Alle Objekte um 10 Z-Einheiten erhöhen (Höhe) ===
sceneObjects = [start_knopf, start_knopf_hitbox, weiter_knopf_hitbox, weiter_knopf, small_cube, stange, platte, pyramid]
DEBUG
if None in sceneObjects:
warn(“EINES DER SZENEN-OBJEKTE IST NONE!!”)
for item in sceneObjects:
pos = item.transform.position
item.transform.position = Vector3(pos.x, pos.y, pos.z + 10)
=== Hilfsfunktionen ===
def set_opacity(opacity, *items):
for item in items:
if item is not None:
item.opacity = opacity
else:
print(“WARNUNG: set_opacity-Objekt ist None!”)
def highlight_button(button, scale_factor=1.1, duration=0.2):
original_scale = button.transform.scale
button.transform.scale = original_scale * scale_factor
def reset():
button.transform.scale = original_scale
time.schedule(reset, duration)
def sichtbar(*items):
set_opacity(1.0, *items)
def unsichtbar(*items):
set_opacity(0.0, *items)
def update_info(text, *, done=False):
if not done: titel = f"Aufgabe {current_task_index + 1}"
else: titel = “Volumen”
gui.hud.show_info_panel(titel, text)
print(f"DEBUG: HUD-Text gesetzt:\n{titel}\n {text}")
def shush(*items):
for item in items:
if item is not None:
item.speech = None
print(f"{item.name} hört nun auf zu reden.")
else:
print(“WARNUNG: shush-Objekt ist None!”)
def move_to(item, position): # Y != HÖHE, Z = HÖHE
item.transform.position = position
print(f"DEBUG: {item.name} moved to position {position}")
def add_object(obj):
objects[current_task_index].append(obj)
basically nur für task 0 bzw 1
def spawn_series(base_model, offset, target_list, count=5, include_original=True, delay=0.5, on_done=None, info_text=“”):
base_pos = base_model.transform.position
add_object(base_model)
if include_original:
sichtbar(base_model)
target_list.append(base_model)
print(f"DEBUG: Original {base_model.name} retained at {base_pos}")
def spawn(i):
new_item = base_model.copy()
add_object(new_item)
new_pos = Vector3(
base_pos.x + offset[0] * i,
base_pos.y + offset[1] * i,
base_pos.z + offset[2] * i
)
move_to(new_item, new_pos)
sichtbar(new_item)
target_list.append(new_item)
print(f"DEBUG: New {base_model.name} {i + 1} created at {new_pos}")
start = 1 if include_original else 0
for i in range(start, count):
time.schedule(lambda i=i: spawn(i), delay * (i - start))
if on_done is not None:
time.schedule(on_done, delay * (count - start) + 0.1)
update_info(info_text)
=== Aufgabensteuerung ===
isRunning = False
tasks =
current_task_index = 0
current_step_index = 0
step_running = False
objects = [, , , , ] # für cleanup
=== Schritt beenden ===
def finish_step():
global step_running
step_running = False
highlight_button(weiter_knopf, scale_factor=1.05, duration=0.1)
=== Schritt starten ===
def run_next_step():
global current_step_index, step_running, current_task_index
highlight_button(weiter_knopf)
if step_running:
update_info("Bitte warte, ein Schritt läuft noch!")
return
steps = tasks[current_task_index]
if current_step_index < len(steps):
step_running = True
steps[current_step_index](lambda: finish_step())
current_step_index += 1
else:
print("DEBUG: Aufgabe abgeschlossen.")
time.schedule(next_task, 0.5)
=== Aufgabe 0: Würfel erklären ===
def setup_task_0():
def step_1(done):
update_info(“Hallo! Willkommen zu unserem Volumen-Abenteuer. Heute lernst du, wie man das Volumen von Würfeln berechnet.”)
time.schedule(done, 0.5)
def step_2(done):
sichtbar(small_cube)
update_info("Schau dir diesen Würfel an. Er ist 1 lang, 1 hoch und 1 breit.")
time.schedule(done, 0.5)
small_cubes = []
def step_3(done):
spawn_series(
small_cube,
offset=(-2, 0, 0),
target_list=small_cubes,
on_done=done,
info_text="Jetzt haben wir 5 kleine Würfel in einer Reihe."
)
def step_4(done):
update_info("Diese 5 Würfel ergeben eine Stange: 5 lang, 1 hoch, 1 breit.")
time.schedule(done, 0.5)
def step_5(done):
unsichtbar(*small_cubes)
sichtbar(stange)
time.schedule(done, 0.5)
stangen = []
def step_6(done):
spawn_series(
base_model=stange,
offset=(0, 2, 0),
target_list=stangen,
on_done=done,
info_text="Jetzt haben wir 5 Stangen in die Tiefe gestapelt: 5 x 1 x 5."
)
platten = []
def step_7(done):
unsichtbar(*stangen)
sichtbar(platte)
platten.append(platte)
update_info("Diese Stangen werden zu einer Platte mit 5 x 5 x 1.")
time.schedule(done, 0.5)
def step_8(done):
spawn_series(
base_model=platte,
offset=(0, 0, 2),
target_list=platten,
on_done=done,
info_text="Jetzt haben wir 5 Platten gestapelt: ein Würfel mit 5 x 5 x 5."
)
def step_9(done):
update_info("Das Volumen dieses Würfels ist Länge × Breite × Höhe.")
time.schedule(done, 0.5)
def step_10(done):
update_info("Das ergibt 5 × 5 × 5 = 125 Kubikeinheiten.")
time.schedule(done, 0.5)
return [step_1, step_2, step_3, step_4, step_5, step_6, step_7, step_8, step_9, step_10]
=== Aufgabe 1: Volumeneinheiten ===
def setup_task_1():
def step_1(done):
update_info(“Volumen misst, wie viel in einen Körper passt – z. B. in cm³, dm³ oder m³.”)
time.schedule(done, 0.5)
def step_2(done):
update_info("Ein Würfel mit 1 cm Kantenlänge hat 1 cm³ Volumen.")
time.schedule(done, 0.5)
def step_3(done):
update_info("Ein Würfel mit 10cm = 1dm Kantenlänge hat 1000 cm³ = 1 dm³.")
time.schedule(done, 0.5)
def step_4(done):
update_info("1 dm³ ist genauso viel wie 1 Liter. Also: 1 l = 1 dm³.")
time.schedule(done, 0.5)
def step_5(done):
update_info("Und 1 Liter sind z. B. 1000 ml, wie in einer Wasserflasche.")
time.schedule(done, 0.5)
return [step_1, step_2, step_3, step_4, step_5]
=== Aufgabe 2: Volumenformel beim Quader ===
def setup_task_2():
cubes =
def step_1(done):
update_info("Ein Quader hat unterschiedliche Seitenlängen.")
time.schedule(done, 1.5)
def step_2(done):
update_info("Angenommen, ein Quader ist 2 lang, 3 breit und 4 hoch.")
base = small_cube.transform.position + Vector3(-4, 0, 0) # weiter rechts bauen
count = 0
for x in range(2): # Länge
for y in range(3): # Breite
for z in range(4): # Höhe (Z!)
def spawn(i=count, x=x, y=y, z=z):
cube = small_cube.copy()
move_to(cube, Vector3(
base.x + x * 2,
base.y + y * 2,
base.z + z * 2
))
sichtbar(cube)
cubes.append(cube)
add_object(cube)
time.schedule(spawn, count * 0.15)
count += 1
time.schedule(done, count * 0.15 + 0.5)
def step_3(done):
update_info("Das Volumen ist: 2 × 3 × 4 = 24 Kubikeinheiten.")
time.schedule(done, 3.0)
return [step_1, step_2, step_3]
=== Aufgabe 3: Volumen verschiedener Körper ===
Diese Aufgabe zeigt einen 3D-Körper (Raumkreuz) mit Volumen-Quiz.
def setup_task_3():
cubes =
def step_1(done):
update_info("Jetzt schauen wir uns verschiedene Körper und ihr Volumen an.")
time.schedule(done, 0.5)
def step_2(done):
update_info("Hier bauen wir eine 3D-Kreuzform als Beispielkörper.")
base = small_cube.transform.position + Vector3(-4, 4, 4)
directions = [
Vector3(1, 0, 0), Vector3(-1, 0, 0), # X-Achse
Vector3(0, 1, 0), Vector3(0, -1, 0), # Y-Achse
Vector3(0, 0, 1), Vector3(0, 0, -1) # Z-Achse
]
count = 0
def place_cube(pos):
cube = small_cube.copy()
move_to(cube, pos)
sichtbar(cube)
cubes.append(cube)
add_object(cube)
# Mittelwürfel
place_cube(base)
# In alle 6 Richtungen je 2 Blöcke raus
for dir in directions:
for i in range(1, 3):
pos = base + dir * (i * 2)
time.schedule(lambda pos=pos: place_cube(pos), count * 0.15)
count += 1
time.schedule(done, count * 0.15 + 0.5)
def step_3(done):
update_info("Wie viel Volumen hat dieses Kreuz?")
def on_correct():
update_info("Richtig! Das Kreuz besteht aus 13 kleinen Würfeln.")
time.schedule(done, 2.0)
def on_wrong():
update_info("Fast! Das Kreuz besteht aus 13 kleinen Würfeln.")
time.schedule(done, 2.0)
gui.hud.show_quiz_panel(
question="Wie viele kleine Würfel hat das Kreuz insgesamt?",
answer1="11",
answer2="13",
correct_answer=2,
answer3="15",
answer4="12",
on_correct=on_correct,
on_wrong=on_wrong
)
return [step_1, step_2, step_3]
=== Aufgabe 4: Volumen einer Pyramide ===
def setup_task_4():
def step_1(done):
update_info(“Jetzt betrachten wir das Volumen einer Pyramide.”)
sichtbar(pyramid)
add_object(pyramid)
time.schedule(done, 1.5)
def step_2(done):
update_info("Diese Pyramide hat eine Grundfläche von 5 × 5 = 25 und eine Höhe von 5.")
time.schedule(done, 1.5)
def step_3(done):
update_info("Die Volumenformel lautet: V = \u2153 \u00d7 Grundfläche \u00d7 Höhe")
time.schedule(done, 2.0)
def step_4(done):
update_info("Also: V = \u2153 \u00d7 25 \u00d7 5 = ?")
def on_correct():
update_info("Richtig! Das Volumen der Pyramide ist \u2153 \u00d7 25 \u00d7 5 \u2248 41,67 Einheiten³.")
time.schedule(done, 3.0)
def on_wrong():
update_info("Fast! Richtig ist: \u2153 \u00d7 25 \u00d7 5 \u2248 41,67 Einheiten³.")
time.schedule(done, 3.0)
gui.hud.show_quiz_panel(
question="Wie groß ist das Volumen dieser Pyramide?",
answer1="50",
answer2="62.5",
answer3="41.67",
correct_answer=3,
answer4="25",
on_correct=on_correct,
on_wrong=on_wrong
)
return [step_1, step_2, step_3, step_4]
=== Aufgabe 5: Abschlusstest ===
def setup_task_5():
def step_1(done):
update_info(“Jetzt zeigen wir, dass du Volumen auch im Alltag berechnen kannst!”)
time.schedule(done, 1.5)
def step_2(done):
def on_correct():
update_info("Richtig! Der Blumenkasten fasst 60 dm³ Erde.")
time.schedule(done, 2.0)
def on_wrong():
update_info("Fast! Der Blumenkasten hat 100 cm × 30 cm × 20 cm = 60000 cm³ = 60 dm³.")
time.schedule(done, 2.0)
gui.hud.show_quiz_panel(
question="Ein Blumenkasten ist 1 m lang, 30 cm breit und 20 cm hoch. Wieviel Erde passt hinein?",
answer1="60 dm³",
answer2="6 dm³",
correct_answer=1,
answer3="600 dm³",
answer4="18 dm³",
on_correct=on_correct,
on_wrong=on_wrong
)
def step_3(done):
def on_correct():
update_info("Genau! 5 × 5 × 1 = 25 Würfel.")
time.schedule(done, 2.0)
def on_wrong():
update_info("Nicht ganz. Es sind 5 × 5 = 25 Würfel in der Schachtel.")
time.schedule(done, 2.0)
gui.hud.show_quiz_panel(
question="Eine Schachtel ist 5 cm lang, 5 cm breit und 1 cm hoch. Wieviele 1 cm³-Würfel passen hinein?",
answer1="25",
answer2="10",
correct_answer=1,
answer3="5",
answer4="50",
on_correct=on_correct,
on_wrong=on_wrong
)
def step_4(done):
def on_correct():
update_info("Sehr gut! Das Volumen des Eimers ist 10 × 10 × 30 = 3000 cm³ = 3 Liter.")
time.schedule(done, 2.0)
def on_wrong():
update_info("Nicht ganz. Der Eimer fasst 10 × 10 × 30 = 3000 cm³ = 3 Liter.")
time.schedule(done, 2.0)
gui.hud.show_quiz_panel(
question="Ein kleiner Eimer ist 10 cm lang, 10 cm breit und 30 cm hoch. Wieviel Liter Wasser passt rein?",
answer1="3 l",
answer2="30 l",
correct_answer=1,
answer3="0,3 l",
answer4="10 l",
on_correct=on_correct,
on_wrong=on_wrong
)
def step_5(done):
def restart():
global isRunning
isRunning = False
sichtbar(start_knopf)
update_info("Super gemacht! Du hast den Abschlusstest bestanden.", done=True)
time.schedule(done, 2.5)
time.schedule(restart, 3)
return [step_1, step_2, step_3, step_4, step_5]
=== Cleanups ===
def cleanupTask():
for obj in objects[current_task_index]:
unsichtbar(obj)
shush(obj)
“”" Auskommentiert weil nicht gebraucht
if not current_task_index in cleanups: return
cleanupscurrent_task_index
def cleanup_task_3():
# dann kann ich hier so specific cleanups machen
pass
cleanups = {
3: cleanup_task_3
}
“”"
=== Steuerung ===
def start():
global isRunning
if isRunning: return
isRunning = True
global current_task_index, current_step_index
shush(start_knopf)
unsichtbar(start_knopf)
current_task_index = 0
current_step_index = 0
update_info(“Spiel wurde gestartet.”)
sichtbar(weiter_knopf)
run_next_step()
=== Nächste Aufgabe laden ===
def next_task():
global current_task_index, current_step_index
cleanupTask()
current_task_index += 1
current_step_index = 0
if current_task_index < len(tasks):
update_info("Neue Aufgabe gestartet!")
run_next_step()
else:
update_info("Alle Aufgaben abgeschlossen!", done=True)
print("DEBUG: Alle Aufgaben abgeschlossen.")
=== Initialisierung ===
def main():
sichtbar(start_knopf)
start_knopf_hitbox.input.on_click(start)
weiter_knopf_hitbox.input.on_click(run_next_step)
print(“Main eingeleitet”)
=== Aufgabenliste aufbauen ===
tasks = [setup_task_0(), setup_task_1(), setup_task_2(), setup_task_3(), setup_task_4(), setup_task_5()]
main()