Help with making a moving car (SOLVED)

#1

Hello, I’m working on a top-down racer game and I am struggling with the movement of the car. I want my car to be controlled with WASD, with W and S making it go forwards and backwards and A and S making it turn left or right. Currently my code rotates the car on the spot but I want my code to have A and S rotate the car then W and D will move the car in the direction it’s facing. I’m very new to defold so please help me out.

function init(self)
	msg.post(".", "acquire_input_focus")
	self.direction = vmath.vector3()
	self.rotate = 0
	self.angular_velocity = 10
end

function final(self)
	-- Add finalization code here
	-- Remove this function if not needed
end

function update(self, dt)
	self.speed = 600
	local pos = go.get_position()
	local var = pos + self.direction * self.speed * dt
	print(self.direction)
	go.set_position(var)


	self.rotation = go.get_rotation()
	if self.rotate ~= 0 then
		self.rotation = self.rotation * vmath.quat_rotation_z(self.angular_velocity * self.rotate * dt)
		go.set_rotation(self.rotation)
		
	end
	self.rotate = 0
self.direction = vmath.vector3()
end

function on_message(self, message_id, message, sender)
	-- Add message-handling code here
	-- Remove this function if not needed
end

function on_input(self, action_id, action)
	if action_id == hash("forward") then
		self.direction.y = 1
	elseif action_id == hash("backward") then
		self.direction.y = -1
	end
	if action_id == hash("left") then
		self.rotate = 1
	elseif action_id == hash("right") then
		self.rotate = -1
	end
end	
function on_reload(self)
	-- Add reload-handling code here
	-- Remove this function if not needed
end
0 Likes

#2

Hi and welcome!
britzl wrote some great examples on various topics for defold. check this out

2 Likes

#3

Here is a small “edit” of your code.
This time I prefered using rotation and speed instead of a direction vector.
Also put in so that rotation is dependent on speed.
Hope it helps somewhat

local ACC = 50
local FRICTION = 0.9
local ANGULAR_VELOCITY = 10
local MAX_SPEED = 10
function init(self)
	msg.post(".", "acquire_input_focus")
	self.speed = 0
	self.rotation = 0
	self.input = vmath.vector3()
end

function update(self, dt)
	self.speed = (self.speed + self.input.y * ACC * dt) * FRICTION
	
	local pos = go.get_position()
	pos.x = pos.x + -self.speed * math.sin(self.rotation)
	pos.y = pos.y + self.speed * math.cos(self.rotation)
	go.set_position(pos)

	if self.input.x ~= 0 then
		self.rotation = self.rotation + ANGULAR_VELOCITY * self.input.x * dt * (self.speed/MAX_SPEED)
		go.set_rotation(vmath.quat_rotation_z(self.rotation))
	end
	self.input = vmath.vector3()
end

function on_input(self, action_id, action)
	if action_id == hash("forward") then
		self.input.y = 1
	elseif action_id == hash("backward") then
		self.input.y = -1
	end
	if action_id == hash("left") then
		self.input.x = 1
	elseif action_id == hash("right") then
		self.input.x = -1
	end
end
4 Likes

#4

I’ve tried your code just to see how that would change my game but I got these errors?

0 Likes

#5

Could you please show the code? What is pox? (misspell of pos.x?) What is on line 18?

0 Likes

#6

Oh yes I misspelt pos.x but I’ve corrected it but my code is still receiving errors

local acc = 50
local friction = 0.9
local max_speed = 10
local angular_velocity = 10
function init(self)
	msg.post(".", "acquire_input_focus")
	--self.current_animation = nil
	self.rotatation = 0
	self.speed = 0
	self.input = vmath.vector3()
end

function final(self)
	-- Add finalization code here
	-- Remove this function if not needed
end

function update(self, dt)
	self.speed = (self.speed + self.input.y * acc * dt) * friction
	local pos = go.get_position()
	pos.x = pos.x + -self.speed * math.sin(self.rotation)
	pos.y = pos.y + self.speed * math.cos(self.rotation)
	print(self.direction)
	go.set_position(pos)

	if self.input.x ~= 0 then
		self.rotation = self.rotation + angular_velocity * self.input.x * dt * (self.speed/max_speed)
		go.set_rotation(vmath.quat_rotation_z(self.rotation))
	end
	self.input = vmath.vector3()
end
--local animation = forward
--if self.direction.x > 0 then
--	animation = right
--elseif self.direction.x < 0 then
--	animation = left
--end
--if self.direction.y > 0 then
--	animation = forward
--elseif self.direction.y < 0 then
--		animation = backward
--	end


function on_message(self, message_id, message, sender)
	-- Add message-handling code here
	-- Remove this function if not needed
end

function on_input(self, action_id, action)
	if action_id == hash("forward") then
		self.input.y = 1
	elseif action_id == hash("backward") then
		self.input.y = -1
	end
	if action_id == hash("left") then
		self.input.x = 1
	elseif action_id == hash("right") then
		self.input.x = -1
	end
end
--		if animation ~= self.current_animation then
--			msg.post("#sprite", "play_animation", { id = animation})
--			self.current_animation = animation
--		end
--		self.direction.x = 0
--		self.direction.y = 0
--	end
function on_reload(self)
	-- Add reload-handling code here
	-- Remove this function if not needed
end

0 Likes

#7

Check spell in init. This breaks the initiation of rotation and also doesnt reassign it later in update.

0 Likes

#8

Oh yes, that fixed it haha. Thanks a lot.

I’m sorry that I’m very new to this, is there any chance you could explain what your edits actually did so I can get a better understanding of it?

0 Likes

#9

Sure:
As the update loop is where the magic happens lets go through that one.

First I calculate the speed. The speed is direction independent and is just increased by your input * the acceleration * deltatime. BUT it is also decreased all the time by friction so if you are not giving input it will come to a stop quite soon (actually it is always removing 10%/second of the speed so it will always have some speed left but quickly it is too small to be noticed).

Then the position. It is adding the speed to the position depending on the rotation the car has using classic trigonometry. If rotation is 0 then it will add full speed to y-axis. If it is pi/2 it will put all speed to x-axis.

Last it is the rotation.
The input is increasing/decreasing the rotation of the car BUT you want it to change depending on the speed. A car not moving will not rotate, right? The faster it goes, the faster it should rotate. (self.speed/max_speed) does this. If car is in max_speed then it will rotate the car with angular_velocity * 1. If it is half max_speed it will rotate the car angular_velocity * 0.5 etc…

This is maybe not a foundation to continue on if you want to do a more “physics based” car game but it is a start to get something running.
If you want to add more sliding/drifting it might be better to go with a vector based approach for movement and forces.

2 Likes

#10

Okay brilliant, thank you very much for your help :blush:

0 Likes