Browse Source

Added example on how to apply force to physics collision objects.

paweljarosz 2 weeks ago
parent
commit
8007c96e3c

+ 18 - 0
physics/apply_force/all.texture_profiles

@@ -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
+  }
+}

BIN
physics/apply_force/assets/SourceSansPro-Semibold.ttf


BIN
physics/apply_force/assets/images/elementMetal001.png


BIN
physics/apply_force/assets/images/elementStone019.png


BIN
physics/apply_force/assets/images/elementStone023.png


+ 15 - 0
physics/apply_force/assets/sprites.atlas

@@ -0,0 +1,15 @@
+images {
+  image: "/assets/images/elementStone019.png"
+}
+images {
+  image: "/assets/images/elementStone023.png"
+}
+images {
+  image: "/assets/images/elementMetal001.png"
+}
+animations {
+  id: "coin"
+  playback: PLAYBACK_LOOP_FORWARD
+  fps: 8
+}
+extrude_borders: 2

+ 5 - 0
physics/apply_force/assets/text48.font

@@ -0,0 +1,5 @@
+font: "/assets/SourceSansPro-Semibold.ttf"
+material: "/builtins/fonts/font.material"
+size: 48
+outline_alpha: 0.0
+outline_width: 0.0

+ 38 - 0
physics/apply_force/example.md

@@ -0,0 +1,38 @@
+---
+tags: physics
+title: Apply force
+brief: This example demonstrates how to apply directional force to all dynamic blocks on touch/click and draws debug direction lines.
+thumbnail: thumbnail.png
+scripts: apply_force.script
+---
+
+This example demonstrates how to apply directional force to all dynamic blocks on touch/click and draws debug direction lines.
+
+## Setup
+
+![setup](setup.png)
+
+Scene consists of a few game objects:
+
+- `controller`
+  - Main object that contains `/example/apply_force.script` and a label with usage text.
+- `block1`, `block2`, `block3`, `block4`
+  - Dynamic rigid bodies (sprite + dynamic collision object).
+- `walls`
+  - Static boundary collision object around the screen.
+
+Proposed settings regarding physics in the `game.project` file:
+
+![gameproject](gameproject.png)
+
+## Script flow
+
+A single controller script handles input for the whole scene.  
+When you touch/click, it loops over all dynamic blocks, computes a force vector for each one, applies the force, and draws a debug line that visualizes the direction.
+
+1. acquires input focus in `init()`
+2. listens to `hash("touch")` in `on_input()`
+3. iterates over all block ids
+4. computes `force = (touch - center) * force_factor`
+5. posts `apply_force` to each block
+6. posts `@render: draw_line` for debug visualization

+ 312 - 0
physics/apply_force/example/apply_force.collection

@@ -0,0 +1,312 @@
+name: "default"
+scale_along_z: 0
+embedded_instances {
+  id: "walls"
+  data: "embedded_components {\n"
+  "  id: \"collisionobject\"\n"
+  "  type: \"collisionobject\"\n"
+  "  data: \"type: COLLISION_OBJECT_TYPE_STATIC\\n"
+  "mass: 0.0\\n"
+  "friction: 0.9\\n"
+  "restitution: 0.1\\n"
+  "group: \\\"default\\\"\\n"
+  "mask: \\\"default\\\"\\n"
+  "embedded_collision_shape {\\n"
+  "  shapes {\\n"
+  "    shape_type: TYPE_BOX\\n"
+  "    position {\\n"
+  "      x: -50.0\\n"
+  "      y: 360.0\\n"
+  "    }\\n"
+  "    rotation {\\n"
+  "    }\\n"
+  "    index: 0\\n"
+  "    count: 3\\n"
+  "  }\\n"
+  "  shapes {\\n"
+  "    shape_type: TYPE_BOX\\n"
+  "    position {\\n"
+  "      x: 770.0\\n"
+  "      y: 360.0\\n"
+  "    }\\n"
+  "    rotation {\\n"
+  "    }\\n"
+  "    index: 3\\n"
+  "    count: 3\\n"
+  "  }\\n"
+  "  shapes {\\n"
+  "    shape_type: TYPE_BOX\\n"
+  "    position {\\n"
+  "      x: 360.0\\n"
+  "      y: 770.0\\n"
+  "    }\\n"
+  "    rotation {\\n"
+  "    }\\n"
+  "    index: 6\\n"
+  "    count: 3\\n"
+  "  }\\n"
+  "  shapes {\\n"
+  "    shape_type: TYPE_BOX\\n"
+  "    position {\\n"
+  "      x: 360.0\\n"
+  "      y: -50.0\\n"
+  "    }\\n"
+  "    rotation {\\n"
+  "    }\\n"
+  "    index: 9\\n"
+  "    count: 3\\n"
+  "  }\\n"
+  "  data: 50.0\\n"
+  "  data: 360.0\\n"
+  "  data: 10.0\\n"
+  "  data: 50.0\\n"
+  "  data: 360.0\\n"
+  "  data: 10.0\\n"
+  "  data: 460.0\\n"
+  "  data: 50.0\\n"
+  "  data: 10.0\\n"
+  "  data: 460.0\\n"
+  "  data: 50.0\\n"
+  "  data: 10.0\\n"
+  "}\\n"
+  "\"\n"
+  "}\n"
+  ""
+}
+embedded_instances {
+  id: "block1"
+  data: "embedded_components {\n"
+  "  id: \"collisionobject\"\n"
+  "  type: \"collisionobject\"\n"
+  "  data: \"type: COLLISION_OBJECT_TYPE_DYNAMIC\\n"
+  "mass: 2.0\\n"
+  "friction: 0.5\\n"
+  "restitution: 0.2\\n"
+  "group: \\\"default\\\"\\n"
+  "mask: \\\"default\\\"\\n"
+  "embedded_collision_shape {\\n"
+  "  shapes {\\n"
+  "    shape_type: TYPE_BOX\\n"
+  "    position {\\n"
+  "    }\\n"
+  "    rotation {\\n"
+  "    }\\n"
+  "    index: 0\\n"
+  "    count: 3\\n"
+  "  }\\n"
+  "  data: 109.4645\\n"
+  "  data: 68.3975\\n"
+  "  data: 10.0\\n"
+  "}\\n"
+  "linear_damping: 0.8\\n"
+  "angular_damping: 0.8\\n"
+  "event_collision: false\\n"
+  "event_contact: false\\n"
+  "event_trigger: false\\n"
+  "\"\n"
+  "}\n"
+  "embedded_components {\n"
+  "  id: \"sprite\"\n"
+  "  type: \"sprite\"\n"
+  "  data: \"default_animation: \\\"elementStone019\\\"\\n"
+  "material: \\\"/builtins/materials/sprite.material\\\"\\n"
+  "textures {\\n"
+  "  sampler: \\\"texture_sampler\\\"\\n"
+  "  texture: \\\"/assets/sprites.atlas\\\"\\n"
+  "}\\n"
+  "\"\n"
+  "}\n"
+  ""
+  position {
+    x: 220.14
+    y: 559.457
+  }
+}
+embedded_instances {
+  id: "block2"
+  data: "embedded_components {\n"
+  "  id: \"sprite\"\n"
+  "  type: \"sprite\"\n"
+  "  data: \"default_animation: \\\"elementStone023\\\"\\n"
+  "material: \\\"/builtins/materials/sprite.material\\\"\\n"
+  "textures {\\n"
+  "  sampler: \\\"texture_sampler\\\"\\n"
+  "  texture: \\\"/assets/sprites.atlas\\\"\\n"
+  "}\\n"
+  "\"\n"
+  "}\n"
+  "embedded_components {\n"
+  "  id: \"collisionobject\"\n"
+  "  type: \"collisionobject\"\n"
+  "  data: \"type: COLLISION_OBJECT_TYPE_DYNAMIC\\n"
+  "mass: 1.0\\n"
+  "friction: 0.5\\n"
+  "restitution: 0.2\\n"
+  "group: \\\"default\\\"\\n"
+  "mask: \\\"default\\\"\\n"
+  "embedded_collision_shape {\\n"
+  "  shapes {\\n"
+  "    shape_type: TYPE_BOX\\n"
+  "    position {\\n"
+  "    }\\n"
+  "    rotation {\\n"
+  "    }\\n"
+  "    index: 0\\n"
+  "    count: 3\\n"
+  "  }\\n"
+  "  data: 68.0\\n"
+  "  data: 68.3975\\n"
+  "  data: 10.0\\n"
+  "}\\n"
+  "linear_damping: 0.8\\n"
+  "angular_damping: 0.8\\n"
+  "event_collision: false\\n"
+  "event_contact: false\\n"
+  "event_trigger: false\\n"
+  "\"\n"
+  "}\n"
+  ""
+  position {
+    x: 385.289
+    y: 385.021
+  }
+}
+embedded_instances {
+  id: "block3"
+  data: "embedded_components {\n"
+  "  id: \"sprite\"\n"
+  "  type: \"sprite\"\n"
+  "  data: \"default_animation: \\\"elementStone023\\\"\\n"
+  "material: \\\"/builtins/materials/sprite.material\\\"\\n"
+  "size {\\n"
+  "  x: 140.0\\n"
+  "  y: 140.0\\n"
+  "}\\n"
+  "textures {\\n"
+  "  sampler: \\\"texture_sampler\\\"\\n"
+  "  texture: \\\"/assets/sprites.atlas\\\"\\n"
+  "}\\n"
+  "\"\n"
+  "}\n"
+  "embedded_components {\n"
+  "  id: \"collisionobject\"\n"
+  "  type: \"collisionobject\"\n"
+  "  data: \"type: COLLISION_OBJECT_TYPE_DYNAMIC\\n"
+  "mass: 1.0\\n"
+  "friction: 0.5\\n"
+  "restitution: 0.2\\n"
+  "group: \\\"default\\\"\\n"
+  "mask: \\\"default\\\"\\n"
+  "embedded_collision_shape {\\n"
+  "  shapes {\\n"
+  "    shape_type: TYPE_BOX\\n"
+  "    position {\\n"
+  "    }\\n"
+  "    rotation {\\n"
+  "    }\\n"
+  "    index: 0\\n"
+  "    count: 3\\n"
+  "  }\\n"
+  "  data: 68.0\\n"
+  "  data: 68.3975\\n"
+  "  data: 10.0\\n"
+  "}\\n"
+  "linear_damping: 0.8\\n"
+  "angular_damping: 0.8\\n"
+  "event_collision: false\\n"
+  "event_contact: false\\n"
+  "event_trigger: false\\n"
+  "\"\n"
+  "}\n"
+  ""
+  position {
+    x: 508.289
+    y: 547.021
+  }
+}
+embedded_instances {
+  id: "block4"
+  data: "embedded_components {\n"
+  "  id: \"sprite\"\n"
+  "  type: \"sprite\"\n"
+  "  data: \"default_animation: \\\"elementStone023\\\"\\n"
+  "material: \\\"/builtins/materials/sprite.material\\\"\\n"
+  "size {\\n"
+  "  x: 140.0\\n"
+  "  y: 140.0\\n"
+  "}\\n"
+  "textures {\\n"
+  "  sampler: \\\"texture_sampler\\\"\\n"
+  "  texture: \\\"/assets/sprites.atlas\\\"\\n"
+  "}\\n"
+  "\"\n"
+  "}\n"
+  "embedded_components {\n"
+  "  id: \"collisionobject\"\n"
+  "  type: \"collisionobject\"\n"
+  "  data: \"type: COLLISION_OBJECT_TYPE_DYNAMIC\\n"
+  "mass: 1.0\\n"
+  "friction: 0.5\\n"
+  "restitution: 0.2\\n"
+  "group: \\\"default\\\"\\n"
+  "mask: \\\"default\\\"\\n"
+  "embedded_collision_shape {\\n"
+  "  shapes {\\n"
+  "    shape_type: TYPE_BOX\\n"
+  "    position {\\n"
+  "    }\\n"
+  "    rotation {\\n"
+  "    }\\n"
+  "    index: 0\\n"
+  "    count: 3\\n"
+  "  }\\n"
+  "  data: 68.0\\n"
+  "  data: 68.3975\\n"
+  "  data: 10.0\\n"
+  "}\\n"
+  "linear_damping: 0.8\\n"
+  "angular_damping: 0.8\\n"
+  "event_collision: false\\n"
+  "event_contact: false\\n"
+  "event_trigger: false\\n"
+  "\"\n"
+  "}\n"
+  ""
+  position {
+    x: 608.289
+    y: 395.021
+  }
+}
+embedded_instances {
+  id: "controller"
+  data: "components {\n"
+  "  id: \"apply_force\"\n"
+  "  component: \"/example/apply_force.script\"\n"
+  "}\n"
+  "embedded_components {\n"
+  "  id: \"label\"\n"
+  "  type: \"label\"\n"
+  "  data: \"size {\\n"
+  "  x: 700.0\\n"
+  "  y: 50.0\\n"
+  "}\\n"
+  "color {\\n"
+  "  x: 0.101960786\\n"
+  "  y: 0.2\\n"
+  "  z: 0.6\\n"
+  "}\\n"
+  "text: \\\"Click to apply force to all blocks\\\"\\n"
+  "font: \\\"/assets/text48.font\\\"\\n"
+  "material: \\\"/builtins/fonts/label.material\\\"\\n"
+  "\"\n"
+  "  position {\n"
+  "    x: 360.0\n"
+  "    y: 680.0\n"
+  "  }\n"
+  "  scale {\n"
+  "    x: 0.75\n"
+  "    y: 0.75\n"
+  "  }\n"
+  "}\n"
+  ""
+}

+ 53 - 0
physics/apply_force/example/apply_force.script

@@ -0,0 +1,53 @@
+-- Multiplier applied to the touch->block direction vector.
+local force_factor = 30
+
+-- Debug line color used by @render:draw_line.
+local debug_line_color = vmath.vector4(0, 0.5, 1, 1)
+
+-- Game object ids of dynamic blocks controlled by this script.
+-- The script is attached to the "controller" object in the collection.
+local blocks = {
+	[1] = "block1",
+	[2] = "block2",
+	[3] = "block3",
+	[4] = "block4",
+}
+
+function init(self)
+	-- <1> Receive touch/mouse input in on_input().
+	msg.post(".", "acquire_input_focus")
+end
+
+-- Pre-hashed action id for the touch action.
+local touch_action_id = hash("touch")
+
+function on_input(self, action_id, action)
+	-- <2> Built-in "touch" also maps mouse clicks on desktop.
+	if action_id == touch_action_id then
+		-- <3> Iterate over all blocks and apply force to each.
+		for _, block in pairs(blocks) do
+			-- <4> Compute the force vector by subtracting the block center from the touch position.
+			local center = go.get_world_position(block)
+			local touch = vmath.vector3(action.x, action.y, center.z)
+			local force = (touch - center) * force_factor
+
+			-- <5> Send force to the block's dynamic collision object.
+			msg.post(block, "apply_force", {
+				force = force,
+				position = center
+			})
+
+			-- <6> Visualize direction from touch point to block center.
+			msg.post("@render:", "draw_line", {
+				start_point = touch,
+				end_point = center,
+				color = debug_line_color
+			})
+		end
+	end
+end
+
+function final(self)
+	-- Stop receiving input when the controller is destroyed.
+	msg.post(".", "release_input_focus")
+end

+ 67 - 0
physics/apply_force/game.project

@@ -0,0 +1,67 @@
+[project]
+title = Defold-examples
+version = 0.1
+
+[bootstrap]
+main_collection = /example/apply_force.collectionc
+
+[input]
+game_binding = /builtins/input/all.input_bindingc
+repeat_interval = 0.05
+
+[display]
+width = 720
+height = 720
+high_dpi = 1
+
+[physics]
+scale = 0.02
+gravity_y = -900.0
+use_fixed_timestep = 1
+max_fixed_timesteps = 20
+
+[script]
+shared_state = 1
+
+[collection_proxy]
+max_count = 256
+
+[label]
+subpixels = 1
+
+[sprite]
+subpixels = 1
+max_count = 32765
+
+[windows]
+iap_provider = 
+
+[android]
+package = com.defold.examples
+
+[ios]
+bundle_identifier = com.defold.examples
+
+[osx]
+bundle_identifier = com.defold.examples
+
+[html5]
+show_fullscreen_button = 0
+show_made_with_defold = 0
+scale_mode = no_scale
+heap_size = 64
+
+[graphics]
+texture_profiles = /all.texture_profiles
+
+[collection]
+max_instances = 32765
+
+[particle_fx]
+max_emitter_count = 1024
+
+[render]
+clear_color_blue = 1.0
+clear_color_green = 1.0
+clear_color_red = 1.0
+

BIN
physics/apply_force/gameproject.png


BIN
physics/apply_force/setup.png


BIN
physics/apply_force/thumbnail.png