“Tipsy Tower” HTML5 prototype made with Defold

Read all posts about "" game
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
And now we also have a Defold version of Tipsy Tower, with realistic physics and zooming camera, as well as a scoring system. To get the entire project, check the official GitHub page.

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

215 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stairs
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers