Ok, I started working on a pinball game. And I’m having issues with physics (again). It appears to me as if it’s buggy but it could be me.
Right now I just have a ball and a flipper and the behavior is off. I need this to work perfectly before I commit to this project so hopefully someone can help me out.
-- ball.script
local gravity = -981 -- Gravity force
local ball_mass = 1 -- Mass of the ball
function init(self)
self.velocity = vmath.vector3(0, 0, 0) -- Initial velocity of the ball
self.position = go.get_position() -- Get the initial position of the ball
end
function on_input(self, action_id, action)
-- Input handling is not required for the ball
end
function update(self, dt)
-- Apply gravity to the ball
self.velocity.y = self.velocity.y + gravity * dt / ball_mass
-- Update the ball's position based on its velocity
self.position = self.position + self.velocity * dt
-- Set the new position of the ball
go.set_position(self.position)
end
function on_message(self, message_id, message, sender)
if message_id == hash("contact_point_response") then
-- Simple collision response
-- Reflect the velocity vector based on the normal of the collision
local normal = message.normal
if normal and normal.x and normal.y then
self.velocity = self.velocity - 2 * vmath.dot(self.velocity, normal) * normal
-- If the collision was with the flipper, add the flipper's velocity
if sender == hash("/right_flipper") then
local flipper_velocity = go.get("/right_flipper", "velocity")
self.velocity = self.velocity + flipper_velocity
elseif sender == hash("/left_flipper") then
local flipper_velocity = go.get("/left_flipper", "velocity")
self.velocity = self.velocity + flipper_velocity
end
end
end
end
-- flipper.script
go.property("flipper_side", "left") -- Set this to "left" or "right" in the editor for each flipper
local flipper_speed = 400 -- Speed at which the flipper moves
local max_rotation = math.rad(60) -- Maximum rotation angle in radians
function init(self)
msg.post(".", "acquire_input_focus") -- Acquire input focus to receive input events
self.rotation = go.get_rotation() -- Get the initial rotation of the flipper
self.active = false -- Is the flipper active (moving)?
end
function on_input(self, action_id, action)
if self.flipper_side == "left" and action_id == hash("left_flipper") then
self.active = action.pressed
elseif self.flipper_side == "right" and action_id == hash("right_flipper") then
self.active = action.pressed
end
end
function update(self, dt)
if self.active then
local rotation_change = flipper_speed * dt
if self.flipper_side == "left" then
self.rotation.z = math.min(self.rotation.z + rotation_change, max_rotation)
else
self.rotation.z = math.max(self.rotation.z - rotation_change, -max_rotation)
end
go.set_rotation(self.rotation)
end
end
And this is what I get:
What am I doing wrong? Shouldn’t this be consistent? And the ball should never pass through the flipper? All objects are kinematic. I’m not using dynamic physics.