mirror of
https://github.com/peter-tanner/starcore-explorer-bad.git
synced 2024-12-03 02:20:28 +08:00
283 lines
10 KiB
Plaintext
283 lines
10 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "f7b8452d-61fe-4356-8084-cac603096fef",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import sys\n",
|
|
"if \"pyodide\" in sys.modules:\n",
|
|
" import piplite\n",
|
|
" await piplite.install('pyb2d-jupyterlite-backend>=0.4.2')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "0bfa61e4-9817-4bea-aa66-6a660a423ae6",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from b2d.testbed import TestbedBase\n",
|
|
"import random\n",
|
|
"import numpy\n",
|
|
"import b2d\n",
|
|
"import math\n",
|
|
"\n",
|
|
"class Rocket(TestbedBase):\n",
|
|
"\n",
|
|
" name = \"Rocket\"\n",
|
|
"\n",
|
|
" def __init__(self, settings=None):\n",
|
|
" super(Rocket, self).__init__(gravity=(0, 0), settings=settings)\n",
|
|
"\n",
|
|
" # gravitational constant\n",
|
|
" self.gravitational_constant = 6.0\n",
|
|
"\n",
|
|
" self.planets = {}\n",
|
|
"\n",
|
|
" # home planet\n",
|
|
" home_planet = self.world.create_kinematic_body(\n",
|
|
" position=(10, 0),\n",
|
|
" fixtures=b2d.fixture_def(shape=b2d.circle_shape(radius=20)),\n",
|
|
" user_data=\"home_planet\",\n",
|
|
" )\n",
|
|
"\n",
|
|
" # target planet\n",
|
|
" target_planet = self.world.create_kinematic_body(\n",
|
|
" position=(100, 100),\n",
|
|
" fixtures=b2d.fixture_def(shape=b2d.circle_shape(radius=10)),\n",
|
|
" user_data=\"target_planet\",\n",
|
|
" )\n",
|
|
"\n",
|
|
" # black hole\n",
|
|
" black_hole = self.world.create_kinematic_body(\n",
|
|
" position=(0, 400),\n",
|
|
" fixtures=b2d.fixture_def(shape=b2d.circle_shape(radius=1)),\n",
|
|
" user_data=\"black_hole\",\n",
|
|
" )\n",
|
|
"\n",
|
|
" self.planets = {\n",
|
|
" home_planet: dict(radius=20, density=1, color=(0, 0.2, 1)),\n",
|
|
" target_planet: dict(radius=10, density=1, color=(0.7, 0.7, 0.7)),\n",
|
|
" black_hole: dict(radius=1, density=10000, color=(0.1, 0.1, 0.1)),\n",
|
|
" }\n",
|
|
"\n",
|
|
" # a tiny rocket\n",
|
|
" self.rocket = self.world.create_dynamic_body(\n",
|
|
" position=(10, 10),\n",
|
|
" fixtures=[\n",
|
|
" b2d.fixture_def(shape=b2d.polygon_shape(box=[1, 1]), density=1),\n",
|
|
" b2d.fixture_def(\n",
|
|
" shape=b2d.polygon_shape(vertices=[(-1, 1), (0, 4), (1, 1)]),\n",
|
|
" density=1,\n",
|
|
" ),\n",
|
|
" ],\n",
|
|
" angular_damping=0.5,\n",
|
|
" linear_damping=0.2,\n",
|
|
" user_data=\"rocket\",\n",
|
|
" )\n",
|
|
" # check if the rocket is gone\n",
|
|
" self.touched_black_hole = False\n",
|
|
"\n",
|
|
" # particle system\n",
|
|
" pdef = b2d.particle_system_def(\n",
|
|
" viscous_strength=0.9,\n",
|
|
" spring_strength=0.0,\n",
|
|
" damping_strength=100.5,\n",
|
|
" pressure_strength=1.0,\n",
|
|
" color_mixing_strength=0.05,\n",
|
|
" density=0.1,\n",
|
|
" )\n",
|
|
"\n",
|
|
" psystem = self.world.create_particle_system(pdef)\n",
|
|
" psystem.radius = 0.1\n",
|
|
" psystem.damping = 0.5\n",
|
|
"\n",
|
|
" self.emitters = []\n",
|
|
" self.key_map = {\"w\": 0, \"a\": 1, \"d\": 2}\n",
|
|
"\n",
|
|
" angle_width = (math.pi * 2) / 16\n",
|
|
" emitter_def = b2d.RandomizedRadialEmitterDef()\n",
|
|
" emitter_def.emite_rate = 2000\n",
|
|
" emitter_def.lifetime = 1.0\n",
|
|
" emitter_def.enabled = False\n",
|
|
" emitter_def.inner_radius = 1\n",
|
|
" emitter_def.outer_radius = 1\n",
|
|
" emitter_def.velocity_magnitude = 10.0\n",
|
|
" emitter_def.start_angle = math.pi / 2 - angle_width / 2.0\n",
|
|
" emitter_def.stop_angle = math.pi / 2 + angle_width / 2.0\n",
|
|
" emitter_def.body = self.rocket\n",
|
|
"\n",
|
|
" delta = 0.2\n",
|
|
" self.emitter_local_anchors = [\n",
|
|
" (0, -delta), # main\n",
|
|
" (-delta, -0.5), # left,\n",
|
|
" (delta, -0.5), # right\n",
|
|
" ]\n",
|
|
" self.emitter_local_rot = [math.pi, math.pi / 2, -math.pi / 2] # main\n",
|
|
"\n",
|
|
" # main trust\n",
|
|
" emitter_def.emite_rate = 2000\n",
|
|
" world_anchor = self.rocket.get_world_point(self.emitter_local_anchors[0])\n",
|
|
" emitter_def.transform = b2d.Transform(\n",
|
|
" world_anchor, b2d.Rot(self.emitter_local_rot[0])\n",
|
|
" )\n",
|
|
" emitter = b2d.RandomizedRadialEmitter(psystem, emitter_def)\n",
|
|
" self.emitters.append(emitter)\n",
|
|
"\n",
|
|
" # left\n",
|
|
" emitter_def.emite_rate = 200\n",
|
|
" world_anchor = self.rocket.get_world_point(self.emitter_local_anchors[1])\n",
|
|
" emitter_def.transform = b2d.Transform(\n",
|
|
" world_anchor, b2d.Rot(self.emitter_local_rot[1])\n",
|
|
" )\n",
|
|
" emitter = b2d.RandomizedRadialEmitter(psystem, emitter_def)\n",
|
|
" self.emitters.append(emitter)\n",
|
|
"\n",
|
|
" # right\n",
|
|
" emitter_def.emite_rate = 200\n",
|
|
" world_anchor = self.rocket.get_world_point(self.emitter_local_anchors[1])\n",
|
|
" emitter_def.transform = b2d.Transform(\n",
|
|
" world_anchor, b2d.Rot(self.emitter_local_rot[1])\n",
|
|
" )\n",
|
|
" emitter = b2d.RandomizedRadialEmitter(psystem, emitter_def)\n",
|
|
" self.emitters.append(emitter)\n",
|
|
"\n",
|
|
" def pre_step(self, dt):\n",
|
|
"\n",
|
|
" # check if the rocket has died\n",
|
|
" if self.touched_black_hole:\n",
|
|
" if self.rocket is not None:\n",
|
|
" self.world.destroy_body(self.rocket)\n",
|
|
" self.rocket = None\n",
|
|
" else:\n",
|
|
" rocket_center = self.rocket.world_center\n",
|
|
" rocket_mass = self.rocket.mass\n",
|
|
" # compute gravitational forces\n",
|
|
" net_force = numpy.zeros([2])\n",
|
|
" for planet, planet_def in self.planets.items():\n",
|
|
" radius = planet_def[\"radius\"]\n",
|
|
" planet_center = planet.position\n",
|
|
" planet_mass = planet_def[\"density\"] * radius ** 2 * math.pi\n",
|
|
" delta = rocket_center - planet_center\n",
|
|
" distance = delta.normalize()\n",
|
|
" f = (\n",
|
|
" -self.gravitational_constant\n",
|
|
" * rocket_mass\n",
|
|
" * planet_mass\n",
|
|
" / (distance * distance)\n",
|
|
" )\n",
|
|
" net_force += delta * f\n",
|
|
" f = float(net_force[0]), float(net_force[1])\n",
|
|
" self.rocket.apply_force_to_center(f)\n",
|
|
"\n",
|
|
" # run the rockets engines\n",
|
|
" for emitter, local_anchor, local_rotation in zip(\n",
|
|
" self.emitters, self.emitter_local_anchors, self.emitter_local_rot\n",
|
|
" ):\n",
|
|
" world_anchor = self.rocket.get_world_point(local_anchor)\n",
|
|
" emitter.position = world_anchor\n",
|
|
" emitter.angle = self.rocket.angle + local_rotation\n",
|
|
" emitter.step(dt)\n",
|
|
"\n",
|
|
" def begin_contact(self, contact):\n",
|
|
" body_a = contact.body_a\n",
|
|
" body_b = contact.body_b\n",
|
|
" if body_b.user_data == \"rocket\":\n",
|
|
" body_a, body_b = body_b, body_a\n",
|
|
"\n",
|
|
" user_data_a = body_a.user_data\n",
|
|
" user_data_b = body_b.user_data\n",
|
|
" if body_a.user_data == \"rocket\":\n",
|
|
" if user_data_b == \"black_hole\":\n",
|
|
" self.touched_black_hole = True\n",
|
|
"\n",
|
|
" def on_keyboard_down(self, key):\n",
|
|
" if key in self.key_map:\n",
|
|
" self.emitters[self.key_map[key]].enabled = True\n",
|
|
" return True\n",
|
|
" return False\n",
|
|
"\n",
|
|
" def on_keyboard_up(self, key):\n",
|
|
" if key in self.key_map:\n",
|
|
" self.emitters[self.key_map[key]].enabled = False\n",
|
|
" return False\n",
|
|
" return False\n",
|
|
"\n",
|
|
" def pre_debug_draw(self):\n",
|
|
" pass\n",
|
|
"\n",
|
|
" def post_debug_draw(self):\n",
|
|
" for planet, planet_def in self.planets.items():\n",
|
|
" pos = planet.position\n",
|
|
" self.debug_draw.draw_solid_circle(\n",
|
|
" pos, planet_def[\"radius\"] + 0.1, axis=None, color=planet_def[\"color\"]\n",
|
|
" )\n",
|
|
" if planet.user_data == \"black_hole\":\n",
|
|
" self.debug_draw.draw_circle(\n",
|
|
" pos, planet_def[\"radius\"] * 5, color=(1, 1, 1), line_width=0.1\n",
|
|
" )"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "357866b3-876e-421f-8d2a-77d6697551d3",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Controlls\n",
|
|
"* To play this game, use 'w','a','s','d' on your keyboard to steer the rocket\n",
|
|
"* try to land on the other planet\n",
|
|
"* avoid the black hole\n",
|
|
"* Use the mouse-wheel to zoom in/out, a\n",
|
|
"* Click and drag in the empty space to translate the view."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "7bab75b7-cec1-4348-b95d-9ffd282ded5c",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from pyb2d_jupyterlite_backend.async_jupyter_gui import JupyterAsyncGui\n",
|
|
"s = JupyterAsyncGui.Settings()\n",
|
|
"s.resolution = [1000,1000]\n",
|
|
"s.scale = 3\n",
|
|
"tb = b2d.testbed.run(Rocket, backend=JupyterAsyncGui, gui_settings=s);"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "674c57c8-b5b1-45a9-b75e-5ddc487f7d9b",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.10.4"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|