General Overview

Project Mission

This project introduces “AustroKids” an interactive game designed to teach the wonders of the universe in a fun, anti-boredom format. We move away from traditional explanations, using animations, colors, and motion to capture students’ attention as they explore a space-inspired environment.

Visuals & Mechanics

◼
  • Friendly Design: The system renders a starry background and a cartoon-style Jupiter, making the planet look approachable and attractive to children.
  • ◼
  • Interactive Physics: Players click to launch projectiles, allowing them to visually observe trajectories, distances, and movement effects in real-time.
  • ◼
  • Simulation Feedback: Every impact reduces the planet’s “health,” demonstrating how actions have specific consequences within a simulated system.
  • ◼
  • Educational Impact: By combining interactivity, visualization, and scientific curiosity, the game makes learning about space intuitive and exciting. It serves as a simple yet effective tool to introduce fundamental concepts of physics, motion, and astronomy through the power of play.
  • Phase 1

    What it is

    An Association that stores static values per planet: “Radius”, “OrbitalDistance”, “OrbitalPeriod”, “Color”, “Symbol”.

    Purpose

    Single source of truth for calculations and visualization. Change here to update everything.

    Practical note

    Distances are in millions of km and radii in km; you can add “Mass”, “Inclination” or normalize units if desired.

    CalculateOrbitPosition

    ◼
  • Input: planetName, time (days), and orbitMultiplier (visual scale).
  • ◼
  • Process: Takes OrbitalDistance and OrbitalPeriod from PlanetOrbitData, calculates the orbital angle = 2π * Mod[time, period] / period (prevents infinite growth with Mod) and returns {x,y,z} = {D cosθ, D sinθ, 0}.
  • ◼
  • Result: 2D position in the XY plane; z=0 (no inclination). For inclined orbits, the position would need to be rotated.
  • Main 3D Drawing (ShowPlanetOrbit3D) - General Structure

    Takes planet data and the orbitMultiplier. Calculates orbitDistance and planetPosition using the previous function.
    scaledSize controls the visual size of planets and objects (separate from the actual Radius).

    Scene Details in ShowPlanetOrbit3D

    ◼
  • Starfield background: Generate 100 small Spheres with RandomReal to simulate stars (better to generate once outside for reproducibility).
  • ◼
  • Orbit: Creates a parametric Tube around the Sun with radius orbitDistance.
  • ◼
  • Sun: Yellow Sphere at {0,0,0} with Specularity.
  • ◼
  • Planet: Sphere at planetPosition with color taken from planetData[“Color”].
  • ◼
  • Decorations (happy face): Two eyes and a mouth built with Sphere and Tube, positioned with relative offsets to scaledSize.
  • ◼
  • Conditional rocket: If[showRocket, ...] draws Cone/Cylinder/Sphere around the planet when showRocket is True.
  • ◼
  • Labels: Planet name and symbol, “Days: ...” text, and Sun label.
  • ◼
  • Render options: ImageSize, PlotRange (use orbitDistance to adjust), Lighting, ViewPoint, Background, SphericalRegion.
  • Information Panel (DisplayPlanetInfo)

    ◼
  • Extracts planetData, calculates relativeSize = Round[Radius/6371] for comparison with Earth.
  • ◼
  • Displays a Panel with name+symbol, distance to the Sun (multiplied by orbitMultiplier), period in days, relative size, and a “fun fact” depending on the planet.
  • ◼
  • Useful for teaching data while viewing the animation.
  • ◼
  • Main Interface (CreatePlanetSelector3D) - State and Controls
  • ◼
  • Uses DynamicModule with variables: selectedPlanet, orbitTime, animationRunning, animationSpeed, viewPoint, orbitMultiplier, showRocket.
  • Included controls

    ◼
  • PopupMenu to select planet (shows emoji).
  • ◼
  • Sliders for animationSpeed and orbitMultiplier.
  • ◼
  • Buttons: launch rocket, pause, resume, reset (resets orbitTime, orbitMultiplier, showRocket).
  • ◼
  • View buttons: change viewPoint to predefined positions.
  • ◼
  • Dynamics: Inside the main Dynamic, if animationRunning is True then orbitTime += animationSpeed and the scene is redrawn with ShowPlanetOrbit3D and DisplayPlanetInfo.
  • Tip: Use Mod in the position calculation (already in CalculateOrbitPosition) to prevent orbitTime from growing without limit.

    Startup Messages

    Simple print messages to notify system started, brief instructions.

    Phase 2

    1. Global Variable Declaration We initialize three key variables to manage the game state:

    ◼
  • projectiles → A list that stores all active shots.
  • ◼
  • jupiterHealth → Jupiter’s health counter (starts at 100).
  • ◼
  • gameRunning → A boolean to control if the game is active or paused.
  • 2. Projectile Launch Function The LaunchProjectile function handles the input:

    ◼
  • It detects the mouse position upon clicking.
  • ◼
  • It generates a projectile with specific attributes: initial position, velocity vector (aimed at the center), radius, and color.
  • ◼
  • It appends this new object to the projectiles list.
  • 3. Projectile Updates (The Physics Engine) The UpdateProjectiles function is the heartbeat of the movement:

    ◼
  • Iterates through every projectile in the list.
  • ◼
  • Calculates the new position based on velocity.
  • Collision Detection:

    ◼
  • Impact: If distance to center < 2, Jupiter takes 5 damage.
  • ◼
  • Bounds: Checks if the projectile is still within the game area (distance < 25).
  • ◼
  • Cleanup: Removes projectiles that hit the target or flew off-map to save memory.
  • 4. Main Game Engine: JupiterGame[] This function renders the visuals and ties physics to graphics:

    ◼
  • Logic: Updates projectiles only if gameRunning is true and triggers “Game Over” if health hits 0.
  • ◼
  • Graphics: Renders the Space Background, Stars, Jupiter (with a face), and Health Text.
  • ◼
  • Interaction: Uses EventHandler to detect clicks and trigger the launch function.
  • 5. Minimalist Interface CreateGame[] assembles the user experience (UX):

    ◼
  • Displays a Control Panel with instructions.
  • ◼
  • Includes a Reset Button to restore variables and restart.
  • ◼
  • Uses Dynamic to ensure the animation updates in real-time without lag.
  • 6. Game Initialization

    ◼
  • Finally, the script prints a console message and executes CreateGame[] to launch the full interface.
  • Code

    In[]:=
    🚀 ¡SISTEMA SOLAR 3D INICIADO!
    🌍 Selecciona un planeta para explorar
    🎮 Usa los controles para cambiar la vista y velocidad
    Out[]=
    🚀
    SISTEMA SOLAR 3D ESFÉRICO
    🌠
    🎮 CONTROLES
    🌍 PLANETA
    Earth 🌍
    ⚡ VELOCIDAD
    Velocidad: 1x
    🪐 ÓRBITA
    Multiplicador: 1x
    🚀 ENVIAR COHETE
    ⏸️ PAUSAR
    ▶️ REANUDAR
    🔄 REINICIAR
    👀 VISTA:
    🛰️ Satélite
    👨‍🚀 Cercana
    🌞 Solar
    ShowPlanetOrbit3D[Earth,0,1,False,{2,1,1}]
    DisplayPlanetInfo[Earth,1]
    🎮 Usa los controles para cambiar la vista y velocidad
    🌍 Selecciona un planeta para explorar
    🚀 ¡SISTEMA SOLAR 3D INICIADO!
    In[]:=
    (*JuegoSimple:DispararaJupiter*)ClearAll[JupiterGame,LaunchProjectile,UpdateProjectiles];​​​​(*Variablesglobales*)​​projectiles={};​​jupiterHealth=100;​​gameRunning=True;​​​​(*Funcionparalanzarproyectil*)​​LaunchProjectile[mousePos_]:=Module[{newProjectile},newProjectile=<|"Position"->mousePos,"Velocity"->-Normalize[mousePos]*3,"Radius"->0.2,"Color"->Red|>;​​projectiles=Append[projectiles,newProjectile];]​​​​(*Actualizarproyectiles*)​​UpdateProjectiles[]:=Module[{newProjectiles={},hit=False},Do[Module[{proj=p,newPos,distance},newPos=proj["Position"]+proj["Velocity"]*0.2;​​distance=Norm[newPos];​​If[distance<2,(*ColisionconJupiter*)jupiterHealth=Max[0,jupiterHealth-5];​​hit=True;,If[distance<25,(*Proyectilactivo*)AppendTo[newProjectiles,<|"Position"->newPos,"Velocity"->proj["Velocity"],"Radius"->proj["Radius"],"Color"->proj["Color"]|>];]]],{p,projectiles}];​​projectiles=newProjectiles;​​If[hit,Print["¡Impacto! Salud: "<>ToString[jupiterHealth]]];]​​​​(*Juegoprincipal*)​​JupiterGame[]:=DynamicModule[{},If[gameRunning,UpdateProjectiles[]];​​If[jupiterHealth<=0&&gameRunning,gameRunning=False;​​Print["¡Jupiter destruido!"];];​​EventHandler[Graphics[{(*Fondo*){Black,Rectangle[{-25,-25},{25,25}]},(*Estrellas*){White,PointSize[0.002],Table[Point[{RandomReal[{-25,25}],RandomReal[{-25,25}]}],{100}]},(*Jupiter*){RGBColor[0.9,0.7,0.3],Disk[{0,0},2]},{Black,Thickness[0.01],Circle[{0,0},2]},(*CaradeJupiter*){Yellow,Disk[{-0.8,0.5},0.3]},(*Ojoizquierdo*){Yellow,Disk[{0.8,0.5},0.3]},(*Ojoderecho*){Black,Disk[{-0.8,0.5},0.1]},(*Pupilaizquierda*){Black,Disk[{0.8,0.5},0.1]},(*Pupiladerecha*){Red,Thickness[0.03],BezierCurve[{{-1.2,-0.5},{0,-1},{1.2,-0.5}}]},(*Boca*)(*Proyectiles*)Sequence@@Table[{p["Color"],Disk[p["Position"],p["Radius"]]},{p,projectiles}],(*Interfaz*)Text[Style["DISPARA A JUPITER",20,Bold,White],{0,22},{0,0}],Text[Style["Salud: "<>ToString[jupiterHealth],16,Bold,If[jupiterHealth>50,Green,Red]],{0,19},{0,0}],If[!gameRunning,Text[Style["¡JUPITER DESTRUIDO!",24,Bold,Red],{0,0},{0,0}],{}]},PlotRange->{{-25,25},{-25,25}},ImageSize->600],{"MouseClicked":>If[gameRunning,LaunchProjectile[MousePosition["Graphics"]]]}]]​​​​(*Interfazminimalista*)​​CreateGame[]:=Column[{Panel[Column[{Style["¡DISPARA A JUPITER!",22,Bold,White,Background->Red],Style["Haz clic en cualquier lugar para disparar",12,White]}]],Button["Reiniciar",projectiles={};​​jupiterHealth=100;​​gameRunning=True;​​Print["Juego reiniciado"],Background->Green],Spacer[10],Dynamic[Refresh[JupiterGame[],UpdateInterval->0.1]]}]​​​​(*Iniciarjuego*)​​Print["¡Juego listo! Haz clic para disparar a Jupiter"];​​CreateGame[]