Talking about Tipsy Tower game, Defold, Game development, HTML5 and Users contributions.
Believe me, I have some other tutorial series about new games on their ways, but it seems Tipsy Tower tutorial series is getting more and more interest, with readers asking me to add features and showing their prototypes. Björn Ritzl is a die hard Defold user who already ported my versions of Mike Dangers and zNumbers on Defold, and now hes’ back with the Defold version of Tipsy Tower. A brief recap about Defold, it’s the “free forever” 2D engine used by King to develop some of their games. Back to Tipsy Tower, here is Defold version, with nice sprites taken from the platformer pack graphics made by Kenney. Click to drop a crate. It uses LUA as programming language, and it’s quite easy to unserstand:
go.property("timer", 0)
go.property("zoom_factor", 1)
local camera = require "orthographic.camera"
local BOX_HEIGHT = 70
local PROJECTOR = hash("ZOOMOUT")
local CAMERA = hash("/camera")
local BOX = hash("/box")
local function wait(duration, cb)
go.animate("#", "timer", go.PLAYBACK_ONCE_FORWARD, 0, go.EASING_LINEAR, duration, 0, cb)
end
--- Calculate max height of boxes
local function max_height(self)
local ground = go.get_position("ground").y
local max = ground
for id,_ in pairs(self.boxes) do
local y = go.get_position(id).y
max = math.max(max, y)
end
return math.floor(max - ground) / BOX_HEIGHT
end
local function drop_box(self, id)
-- spawn a box and add it to the lookup table
local id = factory.create("#boxfactory", go.get_position(BOX))
self.boxes[id] = true
-- release input focus and hide moving box
msg.post(".", "release_input_focus")
msg.post(msg.url(nil, BOX, "sprite"), "disable")
-- wait 2 seconds, then zoom, show moving box and update score
wait(2, function()
local height = max_height(self)
local zoom_to = 1 - height * 0.05
go.animate("#", "zoom_factor", go.PLAYBACK_ONCE_FORWARD, zoom_to, go.EASING_LINEAR, 1, 0, function()
msg.post(msg.url(nil, BOX, "sprite"), "enable")
msg.post(".", "acquire_input_focus")
msg.post("#hud", "update_score", { score = math.ceil(height * 100) })
end)
end)
end
-- Delete a box and remove it from the lookup table
local function remove_box(self, id)
self.boxes[id] = nil
go.delete(id)
end
function init(self)
math.randomseed(os.time())
self.boxes = {}
msg.post("@render:", "clear_color", { color = vmath.vector4(0.2, 0.3, 0.7, 1.0) })
msg.post(".", "acquire_input_focus")
-- animate the moving box left and right in an inifinite loop
go.animate(BOX, "position.x", go.PLAYBACK_LOOP_PINGPONG, 140, go.EASING_LINEAR, 2)
-- create and use a camera projection that will always zoom according to current
-- zoom factor
camera.add_projector(PROJECTOR, function(camera_id, near_z, far_z)
local window_width, window_height = camera.get_window_size()
local display_width, display_height = camera.get_display_size()
local projected_width = window_width / self.zoom_factor
local projected_height = window_height / self.zoom_factor
local xoffset = -(projected_width - display_width) / 2
local yoffset = -(projected_height - display_height) / 2
return vmath.matrix4_orthographic(xoffset, xoffset + projected_width, yoffset, yoffset + projected_height, near_z, far_z)
end)
camera.use_projector(CAMERA, PROJECTOR)
end
function update(self, dt)
-- keep camera at bottom of screen
local bounds = camera.screen_to_world_bounds(CAMERA)
local camera_pos = go.get_position(CAMERA)
camera_pos.y = (bounds.y - bounds.w) / 2
go.set_position(camera_pos, CAMERA)
-- keep box at same vertical distance from top of screen
local box_pos = go.get_position(BOX)
box_pos.y = bounds.y - 120
go.set_position(box_pos, BOX)
end
function on_message(self, message_id, message, sender)
-- the box has fallen off the platform - delete it
if message_id == hash("collision_response") and message.group == hash("box") then
remove_box(self, message.other_id)
end
end
function on_input(self, action_id, action)
if action_id == hash("touch") and action.released then
drop_box(self)
end
end
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.