Invisible blocks halting character movement?

Hi. I am a student who is very new to coding and defold as a whole. I’m currently making a game project for my coursework however I have encountered an error that is hard to explain. My character keeps being stopped from moving by these ‘invisible blocks’. If I jump over the ‘invisible blocks’, I can move back and forth through them like normal, as if jumping over them makes them disappear? Thing is, it doesn’t happen every time I build my game. The blocks seem to spawn randomly in a select amount of places on my tilemap, and I have no idea what to do. It may be something to do with my collisions? I have a collision box on my main character and I have set the ground tiles on my tileset with a collision group called ‘ground’. I have attached my character script below, I followed a tutorial to make it because I don’t know a lot of Lua. I hope I explained my issue well enough! Thank you :slight_smile:

-- player.script

local move_acceleration = 1000
local air_acceleration_factor = 0.5
local max_speed = 100
local gravity = -1000
local jump_takeoff_speed = 500
local touch_jump_timeout = 0.2

local msg_contact_point_response = hash("contact_point_response")
local msg_animation_done = hash("animation_done")
local group_obstacle = hash("ground")
local input_left = hash("left")
local input_right = hash("right")
local input_jump = hash("jump")
local input_touch = hash("touch")
local anim_run = hash("idle")
local anim_idle = hash("idle")
local anim_jump = hash("idle")
local anim_fall = hash("idle")

function init(self)
	msg.post(".", "acquire_input_focus")

	self.velocity = vmath.vector3(0, 0, 0)
	self.correction = vmath.vector3()
	self.ground_contact = false
	self.move_input = 0
	self.anim = nil
	self.touch_jump_timer = 0
end

local function play_animation(self, anim)
	if self.anim ~= anim then
		sprite.play_flipbook("#player", anim)
		self.anim = anim
	end
end

local function update_animations(self)
	sprite.set_hflip("#player", self.move_input < 0)
	if self.ground_contact then
		if self.velocity.x == 0 then
			play_animation(self, anim_idle)
		else
			play_animation(self, anim_run)
		end
	else
		if self.velocity.y > 0 then
			play_animation(self, anim_jump)
		else
			play_animation(self, anim_fall)
		end
	end
end

function update(self, dt)
	local target_speed = self.move_input * max_speed
	local speed_diff = target_speed - self.velocity.x
	local acceleration = vmath.vector3(0, gravity, 0)
	if speed_diff ~= 0 then
		if speed_diff < 0 then
			acceleration.x = -move_acceleration
		else
			acceleration.x = move_acceleration
		end
		if not self.ground_contact then
			acceleration.x = air_acceleration_factor * acceleration.x
		end
	end
	local dv = acceleration * dt
	if math.abs(dv.x) > math.abs(speed_diff) then
		dv.x = speed_diff
	end
	local v0 = self.velocity
	self.velocity = self.velocity + dv
	local dp = (v0 + self.velocity) * dt * 0.5
	go.set_position(go.get_position() + dp)

	if self.touch_jump_timer > 0 then
		self.touch_jump_timer = self.touch_jump_timer - dt
	end

	update_animations(self)

	self.correction = vmath.vector3()
	self.move_input = 0
	self.ground_contact = false

end

local function handle_obstacle_contact(self, normal, distance)
	local proj = vmath.dot(self.correction, normal)
	local comp = (distance - proj) * normal
	self.correction = self.correction + comp
	go.set_position(go.get_position() + comp)
	if normal.y > 0.7 then
		self.ground_contact = true
	end
	proj = vmath.dot(self.velocity, normal)
	if proj < 0 then
		self.velocity = self.velocity - proj * normal
	end
end

function on_message(self, message_id, message, sender)
	if message_id == msg_contact_point_response then
		if message.group == group_obstacle then
			handle_obstacle_contact(self, message.normal, message.distance)
		end
	end
end

local function jump(self)
	if self.ground_contact then
		self.velocity.y = jump_takeoff_speed
		play_animation(self, anim_jump)
	end
end

local function abort_jump(self)
	if self.velocity.y > 0 then
		self.velocity.y = self.velocity.y * 0.5
	end
end

function on_input(self, action_id, action)
	if action_id == input_left then
		self.move_input = -action.value
	elseif action_id == input_right then
		self.move_input = action.value
	elseif action_id == input_jump then
		if action.pressed then
			jump(self)
		elseif action.released then
			abort_jump(self)
		end
	elseif action_id == input_touch then
		local diff = action.x - go.get_position().x
		if math.abs(diff) > 10 then
			self.move_input = diff / 100
			self.move_input = math.min(1, math.max(-1, self.move_input))
		end
		if action.released then
			self.touch_jump_timer = touch_jump_timeout
		elseif action.pressed then
			if self.touch_jump_timer > 0 then
				jump(self)
			end
		end
	end
end

I think your first step is to visualize the physics objects:

1 Like

This question is probably the most commonly asked of all (bumping against the sides of tiles while sliding against them). Maybe it would be worth it to make a “Commonly asked questions” thread? @Mathias_Westerdahl @britzl Any thoughts? I think answering it over and over is probably not the way to go.

It might be worth a shot.

Something to check. If you seem to be getting random blocks then it might be that you are running out of collision objects.

Use the debugger so you can see the collision boxes *See the post on Debugging in Defold.
If you see that there are randomly disappearing blocks - check the number of MAX COLLISIONS in the project settings. I made this mistake on my current project. I have a very large tileset with a lot of moving objects 400+, so I simply ran out of collision objects. Setting this to a bigger number 1000 fixed the problem for me.