collision.c was 383 lines that re-implemented akgl_physics_simulate's own arithmetic, because movementlogicfunc runs before gravity, drag and the move and so had to predict where the actor would end up. The whole file goes. What replaces it is three lines in main.c, a shape on the player and the blob, and a `collidable` property on the map's terrain layer -- which also retires SS_TERRAIN_LAYER_ID, a compiled-in layer id that broke whenever somebody reordered layers in Tiled. grounded stays a probe rather than becoming a contact test. A contact says something pushed back this step; grounded asks whether there is a floor to push off, and that stays true through the frame after landing. The blob keeps its own wall and ledge probes for the same reason: the resolver does not say which side of the blob it was pushed from, and says nothing at all about a floor that is missing. The summary line now carries the player's resting position, because exiting 0 was not evidence that collision ran. It reports 136.0,160.0 grounded after 240 autoplay frames -- feet at y=192, flush on the surface of terrain row 12. The tutorial's collision section is rewritten around the library's, keeping the quarter-of-a-pixel story as what a predicting resolver costs. The docs harness learns `json excerpt=`, so the map property the chapter quotes is checked against the map. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
48 lines
2.1 KiB
CMake
48 lines
2.1 KiB
CMake
# The sidescroller tutorial game.
|
|
#
|
|
# A real target, built by default, so docs/19-tutorial-sidescroller.md cannot
|
|
# quote a program that does not compile -- and registered as a headless smoke
|
|
# test, so it cannot quote one that does not run.
|
|
|
|
get_filename_component(SS_ASSET_DIR
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/../../docs/tutorials/assets/sidescroller" ABSOLUTE)
|
|
|
|
add_executable(sidescroller
|
|
main.c
|
|
player.c
|
|
actors.c
|
|
)
|
|
|
|
target_include_directories(sidescroller PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
target_compile_options(sidescroller PRIVATE ${AKGL_WARNING_FLAGS})
|
|
|
|
# Baked in rather than looked up at runtime, so the smoke test can be launched
|
|
# from any working directory. `--assets DIR` overrides it for a reader who has
|
|
# moved the art somewhere else.
|
|
target_compile_definitions(sidescroller PRIVATE "SS_ASSET_DIR=\"${SS_ASSET_DIR}\"")
|
|
|
|
target_link_libraries(sidescroller
|
|
PRIVATE akstdlib::akstdlib akerror::akerror akgl SDL3::SDL3 SDL3_ttf::SDL3_ttf
|
|
SDL3_image::SDL3_image SDL3_mixer::SDL3_mixer jansson::jansson -lm)
|
|
|
|
# A vendored build leaves the SDL satellite libraries in per-project
|
|
# subdirectories that are not on the loader's default search path, which is the
|
|
# same problem AKGL_VENDORED_RPATH solves for the test executables.
|
|
if(AKGL_VENDORED_DEPENDENCIES)
|
|
set_target_properties(sidescroller PROPERTIES BUILD_RPATH "${AKGL_VENDORED_RPATH}")
|
|
endif()
|
|
|
|
# Four seconds of scripted play under the headless drivers: the level loads, the
|
|
# player walks and jumps, the swept collision runs against real terrain, and the
|
|
# program tears down and exits 0. A tutorial that stops working fails here rather
|
|
# than in front of a reader.
|
|
#
|
|
# add_test() rather than _add_test(): the root CMakeLists.txt shadows it only
|
|
# while this project is top-level, and by the time examples/ is added the
|
|
# suppression has already been lifted. An embedded build gets the builtin.
|
|
add_test(NAME example_sidescroller COMMAND sidescroller --frames 240 --autoplay)
|
|
set_tests_properties(example_sidescroller PROPERTIES
|
|
TIMEOUT 120
|
|
ENVIRONMENT "SDL_VIDEODRIVER=dummy;SDL_RENDER_DRIVER=software;SDL_AUDIODRIVER=dummy"
|
|
)
|