1. Prázdný projekt a fyzikální svět
Založte prázdný GML projekt, importujte runtime zdroje a ověřte spuštění i ukončení jednoho managed světa.
Test Etapy 4 sestavil oddělený projekt z lokálních zdrojů. Nedokládá ruční import .yymps přes editor. Pro první pokus lze pracovat v samostatné kopii kompletního vývojového projektu: založte novou prázdnou rm_tutorial, nastavte ji jako startovní a vložte pouze o_tutorial. Původní demo controllery do této místnosti nepřidávejte. Původní projekt ponechte jako zdroj závislostí.
Kam vložit jednotlivé soubory#
Otevřete objekt o_tutorial a pro každý řádek použijte Add Event. Zvolte GML Code, pokud se editor ptá na typ kódu. Obsah souboru vložte do editoru dané události; nevytvářejte z těchto souborů samostatné Script assety. Objekt musí mít Visible zapnuté a Persistent vypnuté; sprite není potřeba.
| Soubor | Add Event |
|---|---|
| Create_0.gml | Create |
| Step_0.gml | Step → Step |
| Step_2.gml | Step → End Step |
| Draw_0.gml | Draw → Draw |
| Draw_64.gml | Draw → Draw GUI |
| CleanUp_0.gml | Clean Up |
Postup#
- Vytvořte prázdný GML projekt s cílem Windows x64. Návod ověřujeme proti runtime 2023.11.1.160; ostatní cíle tím nejsou ověřené.
- Importujte rozšíření JoltPhysics včetně dodané DLL, jeho současné skripty jolt_* a shadery sh_jolt_debug_3d / sh_jolt_debug_primitive_batch. Kompletní sada skriptů odkazuje i na typy BBMOD: importujte také odpovídající BBMOD skripty, shadery a zdroje. Návod nepotřebuje modelové soubory ani instanci BBMOD rendereru. Nekopírujte ukázkové řídicí objekty nebo místnosti.
- S prázdným projektem pokračujte pouze tehdy, pokud už máte odpovídající kompletní balíček zdrojů od správce projektu. Instalace popisuje plánovaný import lokálního balíčku; automatické sestavení tento import přes editor neověřilo. Bez balíčku použijte samostatnou kopii kompletního vývojového projektu a prázdnou výukovou místnost podle postupu výše. Samotná DLL nestačí.
- Vytvořte místnost rm_tutorial o velikosti 1280×720, s tmavým pozadím, vypnutou vestavěnou fyzikou místnosti i viewport kamerami. Vytvořte objekt o_tutorial bez spritu a vložte do místnosti přesně jednu instanci. Místnost nastavte jako první; o_tutorial nesmí být persistent.
- Do o_tutorial přidejte šest níže uvedených událostí. Do každé vložte celý odpovídající blok. Kód vlastní jediný Jolt svět; nepřidávejte další objekt s jolt_update.
Pořadí událostí#
Create vytvoří zdroje. Step načte vstup a připraví kameru. End Step aktualizuje Grabber, zavolá jediný jolt_update a obnoví kameru po simulaci. Draw kreslí 3D debug; Draw GUI kreslí text. Clean Up uvolní pomocníky, Character, tělesa a nakonec svět.
o_tutorial — Create#
game_set_speed(60, gamespeed_fps);
floor_body = undefined;
crate = undefined;
player = undefined;
carry = undefined;
frame_seconds = 1 / 60;
mouse_locked = false;
carry_mouse_input = false;
yaw = 90;
pitch = -17;
sensitivity = 0.12;
if (!jolt_start()) {
show_error(jolt_get_error_message(), true);
exit;
}
jolt_debug_enable(true);
jolt_debug_set(0);
jolt_debug_set(JOLT_DEBUG_SHAPES, true);
camera = {
Position: {X:8, Y:-10, Z:7},
Target: {X:0, Y:0, Z:1},
Up: {X:0, Y:0, Z:1}
};
refresh_camera = function() {
if (is_undefined(player)) return;
var _feet = player.get_position();
camera.Position = {X:_feet.x, Y:_feet.y, Z:_feet.z + 1.6};
camera.Target = {
X:camera.Position.X + dcos(yaw) * dcos(pitch),
Y:camera.Position.Y + dsin(yaw) * dcos(pitch),
Z:camera.Position.Z + dsin(pitch)
};
};
refresh_camera();
o_tutorial — Step#
frame_seconds = clamp(delta_time / 1000000, 0, 0.05);
o_tutorial — Step → End Step#
if (!is_undefined(carry)) carry.update_controls();
if (jolt_update(frame_seconds) < 0) {
show_error(jolt_get_error_message(), true);
exit;
}
refresh_camera();
o_tutorial — Draw#
var _world = matrix_get(matrix_world);
var _view = matrix_get(matrix_view);
var _projection = matrix_get(matrix_projection);
var _p = camera.Position;
var _t = camera.Target;
matrix_set(matrix_world, matrix_build_identity());
matrix_set(matrix_view, matrix_build_lookat(
_p.X, _p.Y, _p.Z, _t.X, _t.Y, _t.Z, 0, 0, 1));
matrix_set(matrix_projection, matrix_build_projection_perspective_fov(
70, room_width / room_height, 0.05, 100));
jolt_debug_draw();
matrix_set(matrix_world, _world);
matrix_set(matrix_view, _view);
matrix_set(matrix_projection, _projection);
o_tutorial — Draw → Draw GUI#
draw_set_colour(c_white);
draw_text(16, 16, "World: " + string(jolt_is_started()));
if (!is_undefined(crate)) {
draw_text(16, 40, "Crate Z: " + string_format(crate.get_position().z, 1, 2));
}
if (!is_undefined(player)) {
draw_text(16, 64, "Tab: mouse | WASD: move | Space: jump");
var _cx = display_get_gui_width() * 0.5;
var _cy = display_get_gui_height() * 0.5;
draw_line(_cx - 5, _cy, _cx + 5, _cy);
draw_line(_cx, _cy - 5, _cx, _cy + 5);
}
if (!is_undefined(carry)) {
draw_text(16, 88, "LMB: grab/release | RMB: rotate | R: realign | F: throw");
draw_text(16, 112, "Holding: " + string(carry.is_holding()));
draw_text(16, 136, "Grab reason: " + carry.get_last_reason());
}
o_tutorial — Clean Up#
window_mouse_set_locked(false);
window_set_cursor(cr_default);
if (is_struct(carry)) carry.destroy();
if (is_struct(player)) player.destroy();
if (is_struct(crate)) crate.destroy();
if (is_struct(floor_body)) floor_body.destroy();
jolt_stop();
Vyzkoušejte krok za krokem#
| Akce v okně hry | Očekávaný výsledek |
|---|---|
| Spusťte projekt tlačítkem Run (F5). | V okně hry je World: 1. Prázdná tmavá scéna je v první lekci správně; zatím nevytváříme žádné těleso. |
| Zavřete okno hry a spusťte projekt znovu. | Svět se znovu spustí bez chybové hlášky. Před úpravou kódu musí předchozí běh skončit. |
Jde o kontrolní postup pro čtenáře, nikoliv o tvrzení, že byly všechny ruční kroky úspěšně odzkoušeny. Skutečný rozsah ověření je uveden na stránce Ověření příkladů.
Ověření výsledku#
V GUI musí být World: 1. Prázdný svět zatím nemá co vykreslit. Při ukončení nesmí vzniknout chyba neplatného handle.
Když to nefunguje#
- Neznámá jolt_* funkce nebo BBMOD typ: chybí součást importu, nikoliv další nastavení objektu.
- World: 0 nebo chyba DLL: ověřte cílovou platformu x64 a odpovídající DLL podle Instalace.
- World: 1, ale nic nevidíte: ověřte Draw událost, oba debug shadery, viditelnost objektu a vypnuté viewport kamery. Fyzikální těleso samo nevytváří herní model.
- Příliš rychlý pohyb: v místnosti nesmí běžet druhý controller s jolt_update; delta_time se převádí z mikrosekund na sekundy.
- Chyba při odchodu z místnosti: uvolňujte Grabber před Characterem a svět jako poslední. Nepoužívejte zde persistent controller.
Soubory příkladu#
Rozsah ověření#
Tyto stejné soubory používá oddělený testovací projekt. Stav kompilace a runtime kontrol je uveden na stránce Ověření praktických příkladů. Automatický test nenahrazuje ruční posouzení pocitu z myši a vzhledu scény.