Help with movement bug

I’ve been following the tutorial-movement, the one with the spaceship, and I decided to make the spaceship gradually slow down when move/accelerate key is released. I got that part working ok for left, right, up and down but the problem comes when moving on a diagonal. Initially it is ok and moves in a straight line but when switching back to non-diagonal it starts moving on a curve as if something isn’t being reset correctly; but I can’t figure out what. I’m sure it’s something obvious but I’ve been banging my head against a wall over this for days now :frowning:
Thanks in advance!

local function accelerate(self, dt)
	local acceleration = self.input * self.max_speed

	local dv = acceleration * dt
	local v0 = self.velocity
	local v1 = self.velocity + dv
	local movement = (v0 + v1) * dt * 0.5

	local p = go.get_position()
	go.set_position(p + movement)

	self.velocity = v1
	self.input = vmath.vector3()
end

local function brake(self, dt)
	local acceleration = self.braking_direction * self.max_speed

	local dv = acceleration * dt
	local v0 = self.velocity
	local v1 = self.velocity + dv

	-- this isn't really speed but the result of braking_direction and velocity being in the exact opposite direction
	local speed = vmath.dot(self.braking_direction, self.velocity)
	if speed >=0 then
		pprint("stopping")
		self.braking_direction = vmath.vector3()
		self.velocity = vmath.vector3()
		self.moving = false
		return
	end

	local movement = (v0 + v1) * dt * 0.7

	local p = go.get_position()
	go.set_position(p + movement)

	self.velocity = v1
	self.input = vmath.vector3()
end

function update(self, dt)
	if vmath.length_sqr(self.input) > 1 then
		self.input = vmath.normalize(self.input)
	end
	if self.moving then
		if self.accelerating then
			accelerate(self, dt)
		else
			brake(self, dt)
		end
	end
	self.input = vmath.vector3()
end

function on_input(self, action_id, action)
	if action_id == hash("up") then
		if action.released then
			self.accelerating = false
		else
			self.input.y = 1
			self.braking_direction.y = -1
			self.accelerating = true
			self.moving = true
		end

Can you share the full project as a zip file (exclude the build and .internal folders)?

1 Like

Movement tutorial.zip (720.8 KB)

Thank you :slight_smile:

Well, the issue you have whilst braking after you’ve moved diagonally is that the braking direction is diagonal and your velocity is either horizontal or vertical (depending on which key you released first).

Would it not make more sense to simply start reducing the velocity by an opposite force? Something like this (modified your brake function):

local function brake(self, dt)
	local dv = -self.velocity * 1 * dt
	local v0 = self.velocity
	local v1 = self.velocity + dv

	local movement = (v0 + v1) * dt * 0.5

	local p = go.get_position()
	go.set_position(p + movement)
		
	if vmath.length(movement) <= 0.001 then
		pprint("stopping")
		self.braking_direction = vmath.vector3()
		self.velocity = vmath.vector3()
		self.moving = false
		return
	end

	self.velocity = v1
	self.input = vmath.vector3()
end
2 Likes

That make perfect sense now you’ve pointed it out. I thought I was doing something similar by altering the acceleration. There’s something not quite right with this but I it gives me a starting point.
Many thanks for your help :heart_eyes_cat:

1 Like