I am all new to defold and would need some help.
I am working on an top shooter and wants my ship to follow my mouse/touch but it don’t works as i want. I was trying to cap the movement so it wouldn’t go outside the screen but my if wont work. And my other problem is that if i touch somewhere on the screen the ship jumps to that position i want it to move from where it is. Hope you understand=)
function init(self)
msg.post(".", "acquire_input_focus")
self.pos = go.get_position()
end
function update(self, dt)
end
function on_input(self, action_id, action)
if action_id == hash("touch") and action.dx then
local pos
if action.dx > 0 or action.dx < 640 then
pos = vmath.vector3(action.x, 150, 0)
end
if pos ~= nil then
go.set_position(pos)
end
end
end
There’s some confusion in your script between the self.pos you set in init() and the local pos you modify in on_input(). I would suggest that you keep track of a direction of movement in a script variable, update it in on_input() based on user input and then move and clamp position in update(). Like this (untested):
function init(self)
msg.post(".", "acquire_input_focus")
-- speed in pixels/second
self.speed = 200
-- direction of movement
self.direction = vmath.vector3()
end
function update(self, dt)
-- get current position
local pos = go.get_position()
-- move
pos = pos + self.direction * self.speed * dt
-- clamp to between 0 and 640
if pos.x < 0 then pos.x = 0 end
if pos.x > 640 then pos.x = 640 end
-- update position
go.set_position(pos)
end
function on_input(self, action_id, action)
if action_id == hash("touch") then
if action.released then
self.direction.x = 0
else
self.direction.x = action.dx
end
end
end
I am not sure if its okey to reply on an solved question but i faced some problems. In the emulator everything worked good with controlling the ship but when i tried to run it on my Oneplus one 3T it don’t behave as i want. If i press in the middle the ship jumps to the right, is this because i have numbers in the script? Should i use % or something like that? In my game.project i have the resolution of 640 x 1136 and my phone has the dimensions 1080 x 1920.
Have you made any changes, or created your own, render script?
I took a quick look at the code Björn posted above and it looks like it should behave like you initially expected… It will position the ship/gameobject using the relative movement of the touch/mouse. You should also be able to debug it on your computer by just resizing the window to “simulate” a different resolution.
Could you share the part of your script that controls the ship movement?
I have changed to fixed_fit_projection i dont really know which projection that works best for mobile games but i felt that one made more sence.
Here is the code that controls the ship:
function init(self)
msg.post(".", "acquire_input_focus")
self.speed = 50
self.direction = vmath.vector3()
end
function update(self, dt)
local pos = go.get_position()
pos = pos + self.direction * self.speed * dt
if pos.x < 0 then pos.x = 0 end
if pos.x > 640 then pos.x = 640 end
go.set_position(pos)
end
function on_input(self, action_id, action)
if action_id == hash("touch") then
if action.released then
self.direction.x = 0
else
self.direction.x = action.dx
end
end
end
I am also wondering how i gets the width of the ship so i can get the ship to stop at the edge of the ship sprite, now it ends in the middle of the ships sprite.
I dont know if my problem is a bug but if i test my game on the emulator everything works goods, but when i try it on my device several strange things happen, first i get this error:
ERROR:SCRIPT: /main/main.script:5: attempt to index global 'delay' (a nil value)
stack traceback:
/main/main.script:5: in function </main/main.script:1>
The code it’s pointing to is:
function init(self)
msg.post(".", "acquire_input_focus")
self.spawnSpeed = 10
local id = delay.repeating(1.5, function(self, id)
local enemyId = math.random(1, 3)
local enemyType = "enemies#asteroidfactory"
if enemyId == 1 then
enemyType = "enemies#asteroidfactory"
elseif enemyId == 2 then
enemyType = "enemies#bombfactory"
elseif enemyId == 3 then
enemyType = "enemies#ufofactory"
end
print(enemyType)
pos = vmath.vector3()
pos.x = math.random(160, 480)
pos.y = 1300
factory.create(enemyType, pos)
end)
end
I have the url to the timer set in my game.project.
And the next strange thing that happens is that the ship wont follow my touch, if i touch in the middle the ship jumps to the right and if i touch different places in the x-axis the ship start to jump to different places however not to the position i have touched. It always is on the + side of my touch.
it have worked earlier but suddenly it started to give me that error.
However the touch functionality still misbehaves. If i press one place on the x.axis the ship jumps to another place in the x.axis. If i run it in the emulator in only moves when i am dragging it don’t jumps if just touch.
function on_input(self, action_id, action)
if action_id == hash("touch") then
if action.released then
self.direction.x = 0
-- ignore first touch since dx&dy will be huge
elseif not action.pressed then
self.direction.x = action.dx
end
end
end