Created
October 4, 2023 12:25
-
-
Save maschere/7e5d048c33ca360671e62980835becbf to your computer and use it in GitHub Desktop.
Example script for the level editor in JOY OF PROGRAMMING
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### INIT CODE - DO NOT CHANGE ### | |
from pyjop import * | |
from types import SimpleNamespace | |
SimEnv.connect() | |
editor = LevelEditor.first() | |
data = SimpleNamespace() # use this to share mutable data between your function calls | |
### END INIT CODE ### | |
### IMPORTS - Add your imports here ### | |
import random | |
### END IMPORTS ### | |
### CONSTRUCTION CODE ### | |
editor.select_map(SpawnableMaps.ParkingLot) | |
editor.spawn_entity( | |
SpawnableEntities.ServiceDrone, "drone", location=(0, random.random(), 0) | |
) | |
editor.spawn_entity(SpawnableEntities.RangeFinder, "range", location=(0, 10, 0.75)) | |
editor.spawn_static_mesh( | |
SpawnableMeshes.Cube, | |
material=SpawnableMaterials.SimpleColor, | |
location=(0, 10, 0), | |
scale=(1, 1, 1.5), | |
color=Colors.Slategray, | |
) | |
### END CONSTRUCTION CODE ### | |
### GOAL CODE ### | |
data.parking_duration = 0.0 | |
data.ts = 1.0 | |
def parking_goal(goal_name: str): | |
rangefinder = RangeFinder.first() | |
d = rangefinder.get_distance() | |
m = SimEnvManager.first() | |
ts2 = m.get_sim_time() | |
dts = max(0, ts2 - data.ts) | |
data.ts = ts2 | |
if 2.99 < d < 3.01: | |
data.parking_duration += dts | |
else: | |
data.parking_duration = 0 | |
editor.set_goal_progress( | |
goal_name, | |
data.parking_duration / 5, | |
f"Move the drone precisely 3m in front of the RangeFinder and stop there for at least 5 seconds. Distance: {d:.3f}m, Parking duration: {data.parking_duration:.2f}s", | |
) | |
def time_limit(goal_name: str): | |
ts = SimEnvManager.first().get_sim_time() | |
time_remain = max(0.0, 15 - ts) | |
s = GoalState.Unknown | |
if editor.get_goal_progress("parking") > 0.98: | |
if time_remain > 0.001: | |
s = GoalState.Success | |
elif time_remain > 0.2: | |
s = GoalState.Open | |
else: | |
s = GoalState.Fail | |
if s == GoalState.Unknown: | |
return | |
editor.set_goal_state( | |
goal_name, | |
s, | |
f"Park the drone within 15 seconds \\(Time remaining: {time_remain:.2f}\\)", | |
) | |
editor.specify_goal( | |
"parking", | |
f"Move the drone precisely 3m in front of the RangeFinder and stop there for at least 5 seconds.", | |
parking_goal, | |
1, | |
True, | |
False, | |
) | |
editor.specify_goal( | |
"timelimit", f"Park the drone within 15 seconds.", time_limit, 0, True, True | |
) | |
### END GOAL CODE ### | |
### HINTS CHAT - Define custom hints as question / answer pairs that the player can get answers to via the "AI Ass" chat in-game. ### | |
### redacted | |
### END HINTS ### | |
### DYNAMIC LEVEL CODE ### | |
def begin_play(): | |
print("begin play") | |
editor.set_enabled("drone", is_enabled=False, component_name="DistanceLeft") | |
editor.set_enabled("drone", is_enabled=False, component_name="DistanceRight") | |
editor.set_enabled("drone", is_enabled=False, component_name="Camera") | |
editor.on_begin_play(begin_play) | |
### END DYNAMIC LEVEL CODE ### | |
### ON LEVEL RESET CODE ### | |
def on_reset(): | |
editor.set_location("drone", (0, random.random(), 0)) | |
data.time_over = False | |
editor.on_level_reset(on_reset) | |
### END ON LEVEL RESET CODE ### | |
### EOF CODE - DO NOT CHANGE ### | |
editor.run_editor_level() | |
### EOF ### |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment