Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions physics/box2d_chain_terrain/all.texture_profiles
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
path_settings {
path: "**"
profile: "Default"
}
profiles {
name: "Default"
platforms {
os: OS_ID_GENERIC
formats {
format: TEXTURE_FORMAT_RGBA
compression_level: BEST
compression_type: COMPRESSION_TYPE_DEFAULT
}
mipmaps: false
max_texture_size: 0
premultiply_alpha: true
}
}
95 changes: 95 additions & 0 deletions physics/box2d_chain_terrain/box2D_V2.appmanifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
platforms:
arm64-ios:
context:
excludeLibs: []
excludeSymbols: []
symbols: []
libs: []
frameworks: []
linkFlags: []
x86_64-ios:
context:
excludeLibs: []
excludeSymbols: []
symbols: []
libs: []
frameworks: []
linkFlags: []
armv7-android:
context:
excludeLibs: []
excludeJars: []
excludeSymbols: []
symbols: []
libs: []
linkFlags: []
jetifier: true
arm64-android:
context:
excludeLibs: []
excludeJars: []
excludeSymbols: []
symbols: []
libs: []
linkFlags: []
jetifier: true
arm64-osx:
context:
excludeLibs: []
excludeSymbols: []
symbols: []
libs: []
frameworks: []
linkFlags: []
x86_64-osx:
context:
excludeLibs: []
excludeSymbols: []
symbols: []
libs: []
frameworks: []
linkFlags: []
x86_64-linux:
context:
excludeLibs: []
excludeSymbols: []
symbols: []
libs: []
linkFlags: []
arm64-linux:
context:
excludeLibs: []
excludeSymbols: []
symbols: []
libs: []
linkFlags: []
x86-win32:
context:
excludeLibs: []
excludeSymbols: []
symbols: []
libs: []
linkFlags: []
x86_64-win32:
context:
excludeLibs: []
excludeSymbols: []
symbols: []
libs: []
linkFlags: []
wasm-web:
context:
excludeLibs: []
excludeJsLibs: []
excludeSymbols: []
symbols: []
libs: []
linkFlags: []
wasm_pthread-web:
context:
excludeLibs: []
excludeJsLibs: []
excludeSymbols: []
symbols: []
libs: []
linkFlags: []
100 changes: 100 additions & 0 deletions physics/box2d_chain_terrain/box2D_V3.appmanifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
platforms:
armv7-ios:
context:
excludeLibs: [physics, box2d_defold, script_box2d_defold]
excludeSymbols: []
libs: [physics_2d, box2d, script_box2d, physics_3d]
arm64-ios:
context:
excludeLibs: [physics, box2d_defold, script_box2d_defold]
excludeSymbols: []
symbols: []
libs: [physics_2d, box2d, script_box2d, physics_3d]
frameworks: []
linkFlags: []
x86_64-ios:
context:
excludeLibs: [physics, box2d_defold, script_box2d_defold]
excludeSymbols: []
symbols: []
libs: [physics_2d, box2d, script_box2d, physics_3d]
frameworks: []
linkFlags: []
armv7-android:
context:
excludeLibs: [physics, box2d_defold, script_box2d_defold]
excludeJars: []
excludeSymbols: []
symbols: []
libs: [physics_2d, box2d, script_box2d, physics_3d]
linkFlags: []
jetifier: true
arm64-android:
context:
excludeLibs: [physics, box2d_defold, script_box2d_defold]
excludeJars: []
excludeSymbols: []
symbols: []
libs: [physics_2d, box2d, script_box2d, physics_3d]
linkFlags: []
jetifier: true
arm64-osx:
context:
excludeLibs: [physics, box2d_defold, script_box2d_defold]
excludeSymbols: []
symbols: []
libs: [physics_2d, box2d, script_box2d, physics_3d]
frameworks: []
linkFlags: []
x86_64-osx:
context:
excludeLibs: [physics, box2d_defold, script_box2d_defold]
excludeSymbols: []
symbols: []
libs: [physics_2d, box2d, script_box2d, physics_3d]
frameworks: []
linkFlags: []
x86_64-linux:
context:
excludeLibs: [physics, box2d_defold, script_box2d_defold]
excludeSymbols: []
symbols: []
libs: [physics_2d, box2d, script_box2d, physics_3d]
linkFlags: []
arm64-linux:
context:
excludeLibs: [physics, box2d_defold, script_box2d_defold]
excludeSymbols: []
symbols: []
libs: [physics_2d, box2d, script_box2d, physics_3d]
linkFlags: []
x86-win32:
context:
excludeLibs: [libphysics, libbox2d_defold, script_box2d_defold]
excludeSymbols: []
symbols: []
libs: [libphysics_2d.lib, libbox2d.lib, libscript_box2d.lib, libphysics_3d.lib]
linkFlags: []
x86_64-win32:
context:
excludeLibs: [libphysics, libbox2d_defold, script_box2d_defold]
excludeSymbols: []
symbols: []
libs: [libphysics_2d.lib, libbox2d.lib, libscript_box2d.lib, libphysics_3d.lib]
linkFlags: []
wasm-web:
context:
excludeLibs: [physics, box2d_defold, script_box2d_defold]
excludeJsLibs: []
excludeSymbols: []
symbols: []
libs: [physics_2d, box2d, script_box2d, physics_3d]
linkFlags: []
wasm_pthread-web:
context:
excludeLibs: [physics, box2d_defold, script_box2d_defold]
excludeJsLibs: []
excludeSymbols: []
symbols: []
libs: [physics_2d, box2d, script_box2d, physics_3d]
linkFlags: []
47 changes: 47 additions & 0 deletions physics/box2d_chain_terrain/example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
tags: physics, box2d
title: Box2D Chain Terrain
brief: Create Box2D chain terrain from script using scripting with Box2D V2 (legacy) and V3.
author: Defold Foundation
scripts: box2d_chain_terrain_v3.script, box2d_chain_terrain_v2.script
thumbnail: thumbnail.webp
---

This example creates connected Box2D chain terrain at runtime. It works with both Box2D V2 and V3 by attaching one script for each backend. Each script checks `b2d.get_version()` during `init()` and becomes a no-op when the other backend is active.

Click or tap the window to reset the ball and watch it roll over the same chain again.

## What You'll Learn

- How to get a Box2D body from a Defold collision object
- How to detect the active Box2D version with `b2d.get_version()`
- How to create chain terrain with `b2d.body.create_fixture()` in Box2D V2 Legacy Defold version.
- How to create chain terrain with `b2d.body.create_chain()` in Box2D V3.

## Setup

The collection contains a static `terrain` game object with one collision object. This is required because the runtime-created terrain is attached to an existing Box2D body. Defold creates that body from the collision object in the collection.

The small box shape on `terrain` sits below the view. It is only a placeholder that gives the script a static body to attach the runtime chain to; the visible terrain is the chain itself, drawn with `@render:draw_line`.

The `controller` game object has both backend scripts, a label, and a local factory component named `ball_factory`. The factory points at `/example/ball.go`, a shared prototype with one sprite and one dynamic circle collision object.

![setup](setup.png)

The `game.project` of this example is configured to build with `/box2D_V3.appmanifest` by default. To test V2 locally after downloading the example, change `Native Extensions -> App Manifest` in `game.project` to `/box2D_V2.appmanifest`.

![game_project](game_project.png)

## How It Works

Both scripts read `b2d.get_version()` once. `box2d_chain_terrain_v2.script` only continues when the major version is 2 (Defold legacy version), while `box2d_chain_terrain_v3.script` only continues when the major version is 3.

`b2d.get_body()` returns the Box2D body owned by the hidden `terrain` collision object. The active script then builds the chain with the backend-specific chain API.

In Box2D V2 Legacy Defold version., the script passes a chain shape definition to `b2d.body.create_fixture()`, which creates connected segments on the same static body.

In Box2D V3, the script uses `b2d.body.create_chain()`, which creates a true chain with segment adjacency and ghost vertices.

The shape definition includes `prev_vertex` and `next_vertex`. These are ghost vertices placed just outside the first and last terrain points. They do not add visible terrain segments; they tell Box2D how the open chain would continue past its endpoints so endpoint collision normals stay consistent.

The script redraws the chain vertices each frame with `@render:draw_line`, because the chain itself is a physics shape and has no sprite. The ball is created from the factory, given an initial velocity with `b2d.body.set_linear_velocity()`, and then reset on a timer or when the user clicks or taps.
43 changes: 43 additions & 0 deletions physics/box2d_chain_terrain/example/ball.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
embedded_components {
id: "sprite"
type: "sprite"
data: "default_animation: \"ball\"\n"
"material: \"/builtins/materials/sprite.material\"\n"
"size {\n"
" x: 254.0\n"
" y: 254.0\n"
"}\n"
"textures {\n"
" sampler: \"texture_sampler\"\n"
" texture: \"/textures/textures.atlas\"\n"
"}\n"
""
scale {
x: 0.5
y: 0.5
}
}
embedded_components {
id: "collisionobject"
type: "collisionobject"
data: "type: COLLISION_OBJECT_TYPE_DYNAMIC\n"
"mass: 0.5\n"
"friction: 0.4\n"
"restitution: 0.05\n"
"group: \"default\"\n"
"mask: \"default\"\n"
"embedded_collision_shape {\n"
" shapes {\n"
" shape_type: TYPE_SPHERE\n"
" position {\n"
" }\n"
" rotation {\n"
" }\n"
" index: 0\n"
" count: 1\n"
" }\n"
" data: 31.5\n"
"}\n"
"angular_damping: 0.02\n"
""
}
70 changes: 70 additions & 0 deletions physics/box2d_chain_terrain/example/box2d_chain_terrain.collection
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: "box2d_chain_terrain"
scale_along_z: 0
embedded_instances {
id: "terrain"
data: "embedded_components {\n"
" id: \"collisionobject\"\n"
" type: \"collisionobject\"\n"
" data: \"type: COLLISION_OBJECT_TYPE_STATIC\\n"
"mass: 0.0\\n"
"friction: 0.65\\n"
"restitution: 0.0\\n"
"group: \\\"default\\\"\\n"
"mask: \\\"default\\\"\\n"
"embedded_collision_shape {\\n"
" shapes {\\n"
" shape_type: TYPE_BOX\\n"
" position {\\n"
" x: 360.0\\n"
" y: -120.0\\n"
" }\\n"
" rotation {\\n"
" }\\n"
" index: 0\\n"
" count: 3\\n"
" }\\n"
" data: 10.0\\n"
" data: 10.0\\n"
" data: 10.0\\n"
"}\\n"
"event_collision: false\\n"
"event_contact: false\\n"
"event_trigger: false\\n"
"\"\n"
"}\n"
""
}
embedded_instances {
id: "controller"
data: "components {\n"
" id: \"box2d_v2\"\n"
" component: \"/example/box2d_chain_terrain_v2.script\"\n"
"}\n"
"components {\n"
" id: \"box2d_v3\"\n"
" component: \"/example/box2d_chain_terrain_v3.script\"\n"
"}\n"
"embedded_components {\n"
" id: \"label\"\n"
" type: \"label\"\n"
" data: \"size {\\n"
" x: 640.0\\n"
" y: 100.0\\n"
"}\\n"
"text: \\\"Click or touch to reset\\\"\\n"
"font: \\\"/fonts/text28.font\\\"\\n"
"material: \\\"/builtins/fonts/label-df.material\\\"\\n"
"\"\n"
" position {\n"
" x: 360.0\n"
" y: 660.0\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"ball_factory\"\n"
" type: \"factory\"\n"
" data: \"prototype: \\\"/example/ball.go\\\"\\n"
"\"\n"
"}\n"
""
}
Loading
Loading