Creating a space shooter in defold

Hello everyone.
After having played with defold for nearly a month, I thought that I should move onwards to creating a complete game in Defold, for it is the journey that will teach me what playing around won’t.
So after thinking on it for a while, I finally decided to start with a space shooter, much like Star Pirates, I have been working on it for about 3 days and have definitely progressed about making asteroids, a malfunctioning player and thanks to @britzl 's swarm ai, enemies. But along this , there is problem which I am unable to solve.

This is currently my player controller:

go.property("MAX_SPEED", 300)



local UP = hash("up")
local DOWN = hash("down")
local LEFT = hash("left")
local RIGHT = hash("right")
local FIRE = hash("fire")

local MIN_SPEED = 50
local ROTATION_ACCELERATION = math.rad(380)
local MAX_ROTATION_SPEED = math.rad(300)
local TURN_DECELERATION = 50
local DECELERATION = 250
local ACCELERATION = 175
local DT = 0

local RATE_OF_FIRE = 0.15
local MAX_BULLET_SPEED = 300
local MIN_SPEED = 50

local UNITVECTOR_Z = vmath.vector3(0, 0, 1)
local UNITVECTOR_UP = vmath.vector3(0, 1, 0)

local function dampen(value, amount, dt)
	local diff = math.abs(value)-math.abs(value*amount)
	if value<0 then
		return math.min(0, value+(diff*dt))
	else
		return math.max(0, value-(diff*dt))
	end
end

function init(self)
	-- Add initialization code here
	-- Remove this function if not needed
	self.speed = self.MAX_SPEED
	msg.post(".", "acquire_input_focus")
	self.direction = self.MAX_SPEED
	self.rotation_speed = 0
	self.acceleartion = 0
	self.fire_timeout = 0
end

function final(self)
	-- Add finalization code here
	-- Remove this function if not needed
	msg.post(".", "release_input_focus")
end

function update(self, dt)
	-- Add update code here
	-- Remove this function if not needed
	DT = dt

	local q = vmath.quat_axis_angle(UNITVECTOR_Z, self.rotation_speed * dt)
	go.set_rotation(go.get_rotation() * q)

	-- move forward and limit horizontally
	local pos = go.get_position()
	local distance = self.speed * dt
	local direction = vmath.rotate(go.get_rotation(), UNITVECTOR_UP) * distance
	pos = pos + direction
	go.set_position(pos)
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)
	-- Add input-handling code here
	-- Remove this function if not needed
	if action_id == UP  then
		self.speed = math.min(self.speed + ACCELERATION * DT, self.MAX_SPEED)
	else 
		self.speed = math.max(self.speed - DECELERATION * DT, MIN_SPEED)
	end
	
	if action_id == LEFT then
		if self.rotation_speed < 0 then
			self.rotation_speed = -self.rotation_speed * 0.8
		end
		self.rotation_speed = math.min(self.rotation_speed + ROTATION_ACCELERATION * DT, MAX_ROTATION_SPEED)
		self.speed = math.max(self.speed - TURN_DECELERATION * DT, MIN_SPEED)
		print("left")
	elseif action_id == RIGHT then
		if self.rotation_speed > 0 then
			self.rotation_speed = -self.rotation_speed * 0.8
		end
		self.rotation_speed = math.max(self.rotation_speed - ROTATION_ACCELERATION * DT, -MAX_ROTATION_SPEED)
		self.speed = math.max(self.speed - TURN_DECELERATION * DT, MIN_SPEED)
	else
		self.rotation_speed = self.rotation_speed * 0.9
	end

	if action_id == FIRE and action.pressed then
		self.fire_timeout = self.fire_timeout - DT
		if self.fire_timeout <= 0 then
			factory.create("#factory", go.get_world_position(), go.get_rotation(), { speed = MAX_BULLET_SPEED })
			self.fire_timeout = RATE_OF_FIRE
		end
	else
		self.fire_timeout = 0
	end
	
end

function on_reload(self)
	-- Add reload-handling code here
	-- Remove this function if not needed
end

This is mostly based on masterpiece GBRausers and works equally as well, but when I release left or the right key, the plane continues to turn instead of stopping. How can I cure this?

1 Like

You never reset self.rotation_speed, which means that the rotation speed continues to be whatever the last input set it to. You’ll be wanting to reset it to 0 after using it, so that whenever there is no input, it stays at 0.

I tried replacing

else 
self.rotation_speed = self.rotation_speed *0.9
end

To

else 
self.rotation_speed = 0
end

But it did not help

That won’t work. Remember that on_input will only be called when a key is pressed, held down and released. It will not be called every frame. This means that the else statement will only be called when some key other than LEFT and RIGHT is pressed or released.

You mention that you base the movement code on GBRausers. In my player.script I keep track of which keys are pressed in on_input() and then I use this information every frame in update() to accelerate/decelerate and turn left/right or to stop turning:

3 Likes

I could not find input mapper .In GBrausers it was under ludobits but when I imported ludobits from Github it was not there. Is it moved somewhere else?

Oh, yeah, it’s been moved. You should be able to download the version used by GBRausers though: https://github.com/britzl/ludobits/archive/1.1.1.zip

1 Like

It works now, and in a good way too. Thanks a lot for your valuable help and of course, projects.
Any suggestions you can give on how to add virtual joysticks to it. I found your virtual joysticks repo, but I think they won’t be useful here.
So maybe a couple of suggestions on how will it be easy to make this…

1 Like

You need to look into multi touch and how that is handled by the engine (similar to normal touch). Exactly how would you like your virtual joystick layout to work?

Is there some documentation on this?

Since you know how GBRausers player controller was like, I thought it could be like this
[It is a large game, so watching this might help.]
So basically what i want is to create something similar to its input method.

Multi touch is just another input action that gives you a list of touch events instead of a single touch. There’s an example here: https://github.com/britzl/publicexamples/tree/master/examples/virtual_gamepad

3 Likes

Thanks. I will look into it and try to understand it. Thanks for your valuable help again…

1 Like