Corona – Game Loops part 3

Following up on my previous two posts, this discussion will continue with the game loop topic. Here I’ll create a couple game objects, or actor objects, that will work with the game loop.

As previously discussed, actors work need to interface with the game loop by implementing the update(deltaTime) method. This interface is just a function that each actor object must posses. How the actors implement this function is up to the actor.

In this example I’ll create two types of objects. One object will start at the top of the screen and move down the screen. I’ll call these objects rocks.

The second object will move to the location of a touch on the screen. I’ll call this a ship.

Object when created will need to add themselves to the game_loop. To make this easy we’ll use the singleton nature of Lua modules to help. Every file that uses require(“game_loop”) will be getting a reference to the same programming object. Any module that require game loop will be talking to the same game loop.

The rock objects will remove themselves from the display when they reach the bottom of the screen. This means, rocks will also have to remove themselves from the game loop at the time they remove themselves from the display. To make this easy we’ll make use of the singleton nature of the game_loop module again.

rocks.lua –
I made a file named rocks.lua. This file contains the code that will produce “rock” objects. The rocks will fall down the and remove themselves when they get past the bottom edge of the screen.

The rocks module have the following methods.

make() rock – This function returns a rock.

This module requires game_loop.

The rocks module acts as factory that produces rock objects. Each rock is is a Corona shape object, a rectangle. Corona display objects are essentially tables. Each rock has two methods.

rock:remove() – removes the rock from game_loop, and then from display.
rock:update( deltaTime ) – updates the position of the rock.


--------------------------------------------------------------------
--
-- rocks.lua 
-- 
--------------------------------------------------------------------
local M = {}
--------------------------------------------------------------------

local game_loop = require("game_loop")

local xMax = display.contentWidth
local xMin = 0
local yMax = display.contentHeight + 40
local yMin = 0

local function make()
	local rock = display.newRect( 0, 0, 40, 40 )
	rock:setFillColor( 0, 1, 0 )
	rock.x = math.random( xMin, xMax )
	rock.y = yMin - 40
	rock.speed = math.random() * 3 
	
	function rock:remove()
		game_loop.remove( self )
		display.remove( self ) 
	end
	
	function rock:update( dt ) 				-- receive dt here as a parameter. 
		self.y = self.y + self.speed * dt 	-- Use dt, multiply by pixels per frame (speed)
		if self.y > yMax then 
			
			self:remove()
		end 
		return self
	end
	
	game_loop.add( rock )
	 
	return rock
end 
M.make = make

--------------------------------------------------------------------
return M

ship.lua –
The ship.lua module is very similar to the rocks module. This module acts as factory that produces ship objects. The ship module has a single method.

make() ship – The make method returns a a ship object.

The ship module requires the game_loop module. Each ship created is added to game_loop.

Ship objects have three methods.

ship:move_to( x, y ) – starts the ship moving towards the x, and y.
ship:remove() – Removes the ship from game_loop and from the display.
ship:update( deltaTime ) – Updates the position of the ship.


-----------------------------------------------
--
-- ship.lua
-- 
-----------------------------------------------
local M = {}
-----------------------------------------------
local game_loop = require( "game_loop" )
-----------------------------------------------

local function make()
	local ship = display.newRect( display.contentCenterX, display.contentHeight - 100, 20, 40 )
	
	ship.target_x = ship.x
	ship.target_y = ship.y
	
	function ship:move_to( x, y )
		self.target_x = x
		self.target_y = y
	end 
	
	function ship:remove()
		game_loop.remove( self )
		display.remove( self )
	end 
	
	function ship:update( dt )
		ship.x = ship.x - (ship.x - ship.target_x) * 0.1
		ship.y = ship.y - (ship.y - ship.target_y) * 0.1
	end 
	
	game_loop.add( ship )
	
	return ship
end 
M.make = make

-----------------------------------------------
return M 

Here’s a simple program to test out the modules defined above.


-----------------------------------------------------
-- Import the game loop module 
local game_loop = require("game_loop")
game_loop:run()
-----------------------------------------------------

-- Make a player
local ship = require( "ship" ) 
local player = ship.make()

local function move_ship( x, y )
	player:move_to( x, y )
end 

local function on_touch( event )
	if event.phase == "began" then 
		move_ship( event.x, event.y )
	elseif event.phase == "moved" then 
		move_ship( event.x, event.y )
	end
end 
Runtime:addEventListener( "touch", on_touch )
-----------------------------------------------------

-- A function to make rocks
local rocks = require( "rocks" )

local function make_rock()
	local rock = rocks.make()
end 

-- Use a timer to make rocks periodically
local rock_timer = timer.performWithDelay( 900, make_rock, 0 )
-----------------------------------------------------

Let’s take a look at each part. The first two lines load up the game_loop module, and start it running.


local game_loop = require("game_loop")
game_loop:run()

Next we make a player object. The player object will be made from a ship object. To move the ship I’m calling on the ship objects move_to( x, y ) method. Here I made a touch event that calls on move_to() with the event.x and event.y. Which tells the player/ship to move to the position of the touch event.

The event calls move_ship() during both the began and moved phases. The effect is that the ship will start moving to the position of the point your finger makes contact with the screen, and updates position as you drag your finger across the screen.


local ship = require( "ship" ) 
local player = ship.make()

local function move_ship( x, y )
	player:move_to( x, y )
end 

local function on_touch( event )
	if event.phase == "began" then 
		move_ship( event.x, event.y )
	elseif event.phase == "moved" then 
		move_ship( event.x, event.y )
	end
end 
Runtime:addEventListener( "touch", on_touch )

Lest create a timer to create a new rock every 900 milliseconds.


local rocks = require( "rocks" )

local function make_rock()
	local rock = rocks.make()
end 

-- Use a timer to make rocks periodically
local rock_timer = timer.performWithDelay( 900, make_rock, 0 )

Here’s a few ideas to try on your own.

Make a new object type that moves differently from the two examples here.
Add some new features to the one or both of the objects here. For example make the rocks rotate as they move down the screen.
Use images, or better yet sprites, in place of the rectangles I used.

Apple HIG – Branding

I see many apps that look like web sites. These often feel the need to brand themselves with a logo and company name in the title bar. Or they present the company logo in a splash screen.

An app is not a web site. Apps are small focussed pieces of software. They live on a mobile device, and in that environment they act in a more personal and intimate role. The icon alone should brand the app. Making the conscious decision to launch an app you know what you are looking at.

Here’s a quote from the HIG:

Incorporate a brand’s assets in a refined, unobtrusive way. People use your app to get things done or be entertained; they don’t want to feel as if they’re being forced to watch an advertisement. For the best user experience, you want to quietly remind users of the brand identity through your choice of font, color, and imagery.

Human Interface Design Guidelines

Apple published a book called the Human Interface Design Guidelines. This covers everything about how to design computer interfaces. I had a print copy some years ago. You can now read it online. It covers everything from color to working with text in different languages.

Apple has also written an IOS version. Here is a great quote from it.

Deference. The user interface helps users understand and interact with the content, but never competes with it.
Clarity. Text is legible at every size, icons are precise and lucid, adornments are subtle and appropriate, and a sharpened focus on functionality motivates the design.
Depth. Visual layers and realistic motion impart vitality and heighten users’ delight and understanding.

Corona – Game Loop part 2

Here’s a follow up to the previous post on game loops. The game loop works with actor objects. Actors are stored in an array. The game loop sends it’s actors an update message each frame, and passes the delta time.

Here I have created a Lua module to handle the game and appropriately named it: game_loop. Using a module gives us three advantages.

First, the code is easily portable. You can copy this Lua file/Module into another project and use the game there.

Second, the code is isolated. This makes it easier to edit the game loop if necessary.

Last, Lua modules are only loaded once. If we load this file with require() in file A, and then load it again with require() in file B, file B sees the same game_loop with the same variable values. It doesn’t load a new unique instance. In effect Lua modules act like singleton objects. For the game loop this is perfect. We will only need one game loop, and many other modules will want to access it.

Here’s the game_loop module. Move all of the code here into a file named game_loop.lua.


---------------------------------------------------
--
-- game_loop.lua
--
---------------------------------------------------
local M = {}
---------------------------------------------------

local MSPF = 1000 / display.fps
local actors_array = {}
local last_ms = 0
local isRunning = false


function add( obj ) 
	if table.indexOf( actors_array, obj ) == nil then 
		actors_array[#actors_array+1] = obj
	end 
end 
M.add = add
	
function remove( obj )
	local index = table.indexOf( actors_array, obj )
	if index ~= nil then 
		table.remove( actors_array, index )
	end  
end 
M.remove = remove
	
function enterFrame( event )
	local ms = event.time
	local dt = MSPF / ( ms - last_ms )
	last_ms = ms
	
	for i = #actors_array, 1, -1 do 
		local actor = actors_array[i]
		actor:update( dt )
	end 
end 

	
function run()
	if isRunning == false then 
		Runtime:addEventListener( "enterFrame", enterFrame )
		isRunning = true
	end 
end 
M.run = run	


function pause()
	if isRunning then 
		Runtime:removeEventListener( "enterFrame", enterFrame )
		isRunning = false
	end 
end 
M.pause = pause
---------------------------------------------------
return M

Load game_loop.lua with require(“game_loop”). When using require() do not include the .lua file extension.

The game_loop object/table has four methods.

game_loop.add( obj ) — Adds obj to the game loop, obj must implement
the update(dt) method.

game_loop.remove( obj ) — Removes obj from the game loop.

game_loop.run() — Starts the game loop by adding an enterFrame listener.

game_loop.pause() — pauses the game loop by removing the enterFrame listener.

A game_loop keeps track of objects, we’ll refer to these as actors, in an array/table. Each frame game_loop sends each of the actors an update() message and passes the delta time (dt).

To use this in a game all actor objects must implement the update() method.
Actors are added to the game_loop using game_loop.add( actor ). When an actor
is to be removed from the display it should also be removed from the game_loop using

game_loop.remove( actor )

The game_loop can be stopped and started with:

game_loop.run() 
game_loop:pause()

To test this you can add the following code to main.lua in a new project. The code below first creates a new game loop. Touching the screen creates a new box. Boxes are added to the game loop that sends them update messages each frame. Touching a box removes it from the game loop, and then from the screen.

At the bottom I created two buttons to to run and pause the game loop.

-- Import the game loop module 
local game_loop = require("game_loop")
-- Start the game loop 
game_loop.run()

-- make green boxes
local function make_green_box()
	local box = display.newRect( 0, 0, 40, 40 )
	box:setFillColor( 0, 1, 0 )
	box.x = 0
	box.y = math.random( 0, 480)
	box.speed = math.random() * 3 
	
	function box:update( dt ) -- receive dt here as a parameter. 
		self.x = self.x + self.speed * dt -- Use dt, multiply by pixels per frame (speed)
		if self.x > 320 then 
			self.x = 0
		end 
	end 
	return box
end 




-- Tap a box to remove a box
local function remove_box( event )
	if event.phase == "began" then 
		-- Remove the box from the loop
		local box = event.target
		game_loop.remove( box )		-- Remove box from loop
		display.remove( box )	-- Remove box from display
	end 
	return true
end 


-- Tap the screen to add a box
local function add_box( event )
	if event.phase == "began" then
		local box = make_green_box() -- Make a new box
	
		box.x = event.x	-- Position box
		box.y = event.y
	
		box:addEventListener( "touch", remove_box ) -- Add a touch event 
	
		game_loop.add( box )	-- Add box to the game loop 
	end 
	return true
end 

Runtime:addEventListener( "touch", add_box )





local run_button = display.newRect( 31, 21, 60, 40 )
run_button:setFillColor( 0, 200/255, 0 )

local pause_button = display.newRect( 92, 21, 60, 40 )
pause_button:setFillColor( 200/255, 0, 0 )

local function touch_run( event )
	if event.phase == "began" then 
		game_loop.run()
	end 
	return true 
end 

local function touch_pause( event )
	if event.phase == "began" then 
		game_loop.pause()
	end 
	return true
end 

run_button:addEventListener( "touch", touch_run )
pause_button:addEventListener( "touch", touch_pause )

To expand on what’s here, you could imagine every actor in the actor_array as a table. These
actor tables could contain properties describing how the game_loop should treat each
actor. A simple idea might be to give each a type, and active property. As is the game
loop can be paused and run. Using this idea you could pause or run actors in groups.

Corona – Game Loop

The Game Loop is a system that organizes all of your game actions under a common timer. Imagine the heart of your game system sending out a message to all of it’s actor objects once each “tick”. Imagine a tick is a short time span between actions.

Corona, like many other software frameworks, redraws the screen at a fixed frame rate. Typically Corona projects run at 30 or 60 FPS. In other words, Corona redraws everything on the screen 60 times each second, if the frame rate is set to 60 FPS.

Corona provides an event to notify you of these updates. This event, named “enterFrame”, is fired just before each redraw. This is a perfect opportunity for your program to move objects on the screen. Imagine increasing the x property of an object by 1 each frame. The object would appear to move to the right, 60 pixels each second. The enterFrame event acts like a game loop to some extent.

The timer can also be used to create a game loop. The transition.to(), and related methods, can also be used to create animation. In this article I will focus on enterFrame.

The best way to learn is by doing. I encourage everyone to follow create these examples for themselves.

Below are a series of examples you can try for yourself.

Make a box and move it across the screen. Here we make a box. Position it on the right of the screen, about half way from the top. An enterFrame handler moves the box 1 pixel to the right each frame.


local box = display.newRect( 0, 0, 40, 40 )
box.x = 0
box.y = 200

local function on_frame( event )
	box.x = box.x + 1 
end 

Runtime:addEventListener( "enterFrame", on_frame )

make 10 boxes and move them across the screen.
This time we use a for loop to create 10 boxes.
Each box is added to an array. The enterFrame handler, on_frame,
loops through all of the boxes in box_array and moves each.


local box_array = {}

for i = 1, 10 do 
	local box = display.newRect( 0, 0, 40, 40 )
	box.x = 0
	box.y = math.random( 0, 480)
	box_array[#box_array+1] = box
end 

local function on_frame( event )
	for i = 1, #box_array do 
		local box = box_array[i]
		box.x = box.x + 1
	end
end 

Runtime:addEventListener( "enterFrame", on_frame )

This time make the boxes loop. Here we’ll check the position of each box and
move it to x = 0 when it’s x is greater than (>) 320.


local box_array = {}

for i = 1, 10 do 
	local box = display.newRect( 0, 0, 40, 40 )
	box.x = 0
	box.y = math.random( 0, 480)
	box_array[#box_array+1] = box
end 

local function on_frame( event )
	for i = 1, #box_array do 
		local box = box_array[i]
		box.x = box.x + 1
		if box.x > 320 then 
			box.x = 0
		end 
	end
end 

Runtime:addEventListener( "enterFrame", on_frame )

Give each box a different speed. Since display objects are tables new properties
can be added. Here each box is assigned a new property speed, and the speed of each
is assigned a random value between 1 and 3.
As the boxes are moved each box applies it’s own speed to it’s x so each moves
at a different rate.


local box_array = {}

for i = 1, 10 do 
	local box = display.newRect( 0, 0, 40, 40 )
	box.x = 0
	box.y = math.random( 0, 480)
	box.speed = math.random() * 3
	box_array[#box_array+1] = box
end 

local function on_frame( event )
	for i = 1, #box_array do 
		local box = box_array[i]
		box.x = box.x + box.speed
		if box.x > 320 then 
			box.x = 0
		end 
	end
end 

Runtime:addEventListener( "enterFrame", on_frame )

Give each box an update function. Here we’ve assigned each box a function
named update(). The enterFrame handler now calls the update on each box.
Notice the self reference. As we call update() on each box. The function
has a reference to the current box in self. This allows each box to set it’s
own x with it’s own speed.

Note that speed in this case is represented as pixels per frame. That is the object
will move the number of pixels as the value of speed each frame.


local box_array = {}

for i = 1, 10 do 
	local box = display.newRect( 0, 0, 40, 40 )
	box.x = 0
	box.y = math.random( 0, 480)
	box.speed = math.random() * 3
	
	function box:update()
		self.x = self.x + self.speed
		if self.x > 320 then 
			self.x = 0
		end 
	end 
	
	box_array[#box_array+1] = box
end 

local function on_frame( event )
	for i = 1, #box_array do 
		local box = box_array[i]
		box:update()
	end
end 

Runtime:addEventListener( "enterFrame", on_frame )

Make different kinds of boxes. Better to have a function to create a box of type.
Here both boxes implement the update() method.
Being able to make different types of objects that move in different ways is
very difficult using the earlier frame loop. Here it is easy since each box
implements that same method: update(). The frame loop itself doesn’t need to know
anything about the box or how it moves. The frame loop only needs to call the
object’s update(). Each object can implement update() to suit it’s needs. This
a programming concept called polymorphism.

 
local box_array = {}

-- make green boxes
local function make_green_box()
	local box = display.newRect( 0, 0, 40, 40 )
	box:setFillColor( 0, 1, 0 )
	box.x = 0
	box.y = math.random( 0, 480)
	box.speed = math.random() * 3
	
	function box:update()
		self.x = self.x + self.speed
		if self.x > 320 then 
			self.x = 0
		end 
	end 
	return box
end 

-- make red boxes
local function make_red_box()
	local box = display.newRect( 0, 0, 10, 20 )
	box:setFillColor( 1, 0, 0 )
	box.x = math.random( 0, 320 )
	box.y = 0
	box.speed = math.random() * 3 + 3
	
	function box:update()
		self.y = self.y + self.speed
		if self.y > 480 then 
			self.y = 0
		end 
	end 
	return box
end 

-- Make 10 green boxes
for i = 1, 10 do 
	box_array[#box_array+1] = make_green_box()
end 

-- Make 15 red boxes
for i = 1, 15 do 
	box_array[#box_array+1] = make_red_box()
end

local function on_frame( event )
	for i = 1, #box_array do 
		local box = box_array[i]
		box:update()
	end
end 

Runtime:addEventListener( "enterFrame", on_frame )

Using enterFrame to move objects across the screen, creates fairly smooth motion.
But it is not perfect. Imagine a scenario where the system is slowed by another
process. In a perfect world a frame rate of 30 fps would have 33.33 ms between
enterFrame events. The frame sometimes sped up or slowed down the time between
frames might go higher than this number at times. In those moments objects on the
screen would appear to move more slowly.
Prevent this type of slow down we can vary the speed of objects over time based on
the time between frames. Think about speed of objects become pixels per ms rather
pixels per frame.
The enterFrame event objects has a time property that holds the number of ms
since the app was started. Here’s a sample:

event.time

2014-05-04 20:21:58.234 Corona Simulator[359:507] 84.183
2014-05-04 20:21:58.264 Corona Simulator[359:507] 114.168
2014-05-04 20:21:58.296 Corona Simulator[359:507] 146.563
2014-05-04 20:21:58.330 Corona Simulator[359:507] 180.306
2014-05-04 20:21:58.363 Corona Simulator[359:507] 212.987

About 32ms each frame. 1000ms / 30fps = 33mspf

To find the number of ms for each frame subtract the event.time of the last frame
from event.time of the current frame. Delta is a word that describes an amount
of change. Here’s another sample:

dt

2014-05-04 20:29:10.910 Corona Simulator[359:507] 84.915 84.915
2014-05-04 20:29:10.938 Corona Simulator[359:507] 113.071 28.156
2014-05-04 20:29:10.972 Corona Simulator[359:507] 146.972 33.901
2014-05-04 20:29:11.005 Corona Simulator[359:507] 179.935 32.963
2014-05-04 20:29:11.039 Corona Simulator[359:507] 213.002 33.067

About 33 ms per frame.

The second number is the delta time. You can see the first frame was lot longer
than the other frames, starting the app probably has some overhead. The second frame
is shorter than it should be. After this the other frames settle in very close to
33 ms. This app doesn’t have much going on. If there was more happening we might see
longer frames appear every so often. In other words objects on the screen would
slow down or speed up.

To calculate delta as a function of the frame rate divide the difference by the
frame rate. Then multiply this number by the pixels per frame your object wants to move.

Think about it this way. If the frame rate of the project is 30, the number of ms per
frame is 1000 / 30 or 33 (really it’s 33.333)

If the delta time for a frame is 33,

33/33=1

Multiply this by the number of pixels per frame your object should move. If your
object was supposed to move 10 pixels per frame then 1 * 10ppf = 10 pixels.

Now a imagine a long frame where the computer has slowed for some reason, delta time
might be 40ms.

40/33 = 1.2

Multiply by the same 10 pixels per frame and you get 12. This frame the object moved
a little further to compensate for game lag.

We can incorporate this system by passing the delta time divided by the frame rate to
to each object as a parameter of update(). Now each object can use this value to handle
it own move in any way it chooses.

Note: This system is still imperfect! In extreme situations you might pass a large
number that might move an a larger distance. Imagine if delta passed 2, 5 or 10! Your
object might 20, 50 or 100 pixels in one frame. This can move an object through other
objects causing your game to miss a collision. Delta time should probably have a cap
to set a maximum value. In these cases the game will slow by the system won’t break.


local box_array = {}

-- make green boxes
local function make_green_box()
	local box = display.newRect( 0, 0, 40, 40 )
	box:setFillColor( 0, 1, 0 )
	box.x = 0
	box.y = math.random( 0, 480)
	box.speed = math.random() * 3 
	
	function box:update( dt ) -- receive dt here as a parameter. 
		self.x = self.x + self.speed * dt -- Use dt, multiply by pixels per frame (speed)
		if self.x > 320 then 
			self.x = 0
		end 
	end 
	return box
end 

-- Make 10 green boxes
for i = 1, 10 do 
	box_array[#box_array+1] = make_green_box()
end 


local last_ms = 0				-- Last time in ms
local mspf = 1000 / display.fps	-- milliseconds per frame
local function on_frame( event )
	-- 
	local ms = event.time
	local dt = ms - last_ms
	last_ms = ms
	
	-- print( event.time, dt )
	
	dt = dt / mspf -- divide by frame rate
	
	for i = 1, #box_array do 
		local box = box_array[i]
		box:update( dt )	-- Pass the delta time to update
	end
end 

Runtime:addEventListener( "enterFrame", on_frame )

WordPress – jQuery

WordPress will load jQuery automatically without you having to add the files yourself. I’ve seen a different methods, some of which do not always work. Here’s the method I use that seems to work reliably.

The following would be added to your functions.php file. If you don’t have a functions.php yet, create one, in your theme folder.

 

<?php 
function theme_init() {
	if (!is_admin()) {
		wp_enqueue_script('jquery');
	}
}
add_action('init', 'theme_init');

 

Note! There can be no characters, this include spaces, or extra lines, in front of the tag. This is good practice. Extra characters outside of the php tag will cause the server to create HTTP header and send it to the browser before WordPress is ready.

If you already have a funtions.php file in your theme, you can add the snippet above, without the <?php.

WordPress loads jQuery in “No Conflict” mode. This means that jQuery will be accessed through the variable jQuery rather than the $. To work with this easily, set up your document ready actions like this:

jQuery(function($){ // Notice the $ here!
	$("#box>div>div").eq(0).siblings().hide();
	$("#box>ul>li.slide-thumb").click(function(event){
		var index = $(this).index();
		$("#box>div>div.slides").fadeOut(400).eq(index).fadeIn(400)
	});
});

Notice here, that jQuery (note the uppercase Q!) replaces the $ outisde the ready function. While inside the function I’ve used the $. This is possible by including the $ as a parameter to the function inside jQuery(function($){}). Placing this variable here allows jQuery to assign itself to this name, so inside of the function you can use that variable in place of jQuery.

Famo.us

Famo.us is a new JS library that is a very cool and inspiring. From my cursory investigation I’ll present my thoughts on Famo.us.

The goal of Famo.us is to create a graphical engine that renders elements to the browser more efficiently than current techniques. At the present time browsers are designed to render documents, rather than graphical elements, this presents a lot of bottle necks. Famo.us converts the typical HTML document type content into graphical elements, and renders them to the browser using canvas and webGL. This evolves the process of creating web apps from an experience of wrestling with HTML/CSS/JS to make something that mimics an app-like appearance. To, something more akin to making real apps.

There is something very different and distinct about using Famo.us. Rather than creating a web page with it’s DOM, and styles, and relying on the browser to position content based on a long list of arcane (and, should I add twisted) rules, is very different from freely placing things on the screen using x, y, and z coordinates. With Famo.us you are creating graphical elements that live in a 3 dimensional space on the screen. These elements can be freely translated and transformed.

The bigger promise of Famo.us is to create templates for apps that anyone can apply to their content. Much in the way that themes are applied to WordPress content. Realizing this goal would create an explosion of HTML5 apps, and make good on real the promise of HTML5, which at the current time has not lived up to it’s hype. All of these templates would be using the Famo.us system to position, and animate elements close to native rendering speed.

Here are a few basic concepts. To display things with Famo.us you need a Context and a renderable. A context is an area where one or more renderables can be drawn. A renderable maps to a display element in your page. A page can contain more than one context, or the context can take up the entire page.

The basic renderable is called a Surface. A Surface can contain HTML content, and is styled with CSS rules. You can set styles via JS when creating a new surface. Surfaces then become the basic view elements containing your content that are rendered to a Context. Imagine buttons, text boxes, and images all as Surfaces moving around a 3d environment in the browser window. Neat!

Famo.us looks pretty cool. I’m going to call it a second generation JS tool kit. Like AngularJS, it moves beyond the previous tools and sets new paradigms and increases the performance of web apps. If you were a Flash developer, and long for the days when you could do all of the things people were doing with Flash in the browser, I feel that this is the tool that will get you excited again. I can definitely see showcase web sites, like FWA, popping up to show Famo.us work.

All of that’s pretty rosy so I’ll end with a word of caution. Browser based apps are still hampered by downloads. Every file asset must be downloaded and cached. Ever been browsing a page when the style sheet did not load? Browser based apps built with Famo.us will still be prone to these issues. On desktops with a fast connection, the issues are minor. On mobile devices with slower connections these issues will be more apparent.

Native or HTML5?

Native or HTML5?

Starting a new project, you’re likely to explore what would be the correct platform as a first step. Javascript has a lot of buzz right now. There seems to be a movement to do everything in the Javascript language. At the moment you can Write your app with JS, script your server with Node.js, query your data base in JS using MongoDB. Wow, sounds like you can do it all in JS! This is neat but, I feel it’s important to not lose sight of the forest through the trees. In any project it’s really about choosing the right tool for the job.

If we’re doing everything in JS does that mean the browser is the new OS? I don’t think so. There’s a bit of the emperors new clothes in this type of thinking. The thing about JS and apps in the browser is they just don’t live up the promise in many cases. Or, maybe I should say that there is to much promise. JS has a lot of hiccups and performance issues. Writing a program across HTML, CSS, and JS has a lack of elegance, and feels crude and verbose at times. Just because you can do something doesn’t mean you should. Again it’s about choosing the right tool. The big draw of JS for everything is that it leverages a common tool set, on a common platform. This can save time and money which is good, but if you are making an inferior product is it worth it?

I don’t want to sound like I have some axe to grind. I’ve had a lot of fun with JS, and if it’s the right tool for the job I’m more than happy to use it. My point is HTML5 has so much hype people are treating it like it can do no wrong, like its the wunderkind that can do anything. I just want to get real here. JS can do anything, and I suppose that’s a really a great thing. But, just like people, JS is good at somethings and not good at other things. I’m a firm believer that anyone can do anything if they put their mind to it, I’m not saying that everyone can break world records.

There’s a lot to like about writing code in one place using a common set of tools and deploying to every platform. But if the app provides weak and compromised user experience do you want to put your name on it? Look at Facebook. They had an HTML5 app, and the user experience and performance was weak. The way I see it, they essentially shoehorned a web site into an “app”. They obviously bought into the promise of HTML5.

“The biggest mistake we’ve made as a company was betting on HTML5 over native”

M Zuckerberg

It’s fun to think you can recreate all of the nifty transitions and animation of a native app with JS in a browser. But, you’re not really doing your job unless you apply a critical eye and are willing to say that something is falling short of expectation. Kudos to Facebook for owning up to a problem that was theirs.

Is the browser the new OS? Computers are getting faster, and JS can do more in the browser than ever before. But I don’t think this makes JS the be all end all. There will always be something you can do native that will be out of reach from the browser. Either for security, performance or other reasons. The world may spend more time in a browser than all other apps combined but, I don’t want to edit images in Safari, and I don’t think this is where the world is going.

 

 

AngularJS – intro

AngularJS is a Javascript framework from Google. It’s goal is to display data in a web page based on the MVC, and related paradigms. It was built with the idea of being able to make the connections between, data and UI, apparent and easy to manage.

I just began with it a day ago, so take everything here with a grain of salt. I’m sure I’ll cringe at this a month from now. I’m just writing this all down to try and get it all straight in my own head.

Directives

Directives are attributes, that act as hooks for AngularJS. Assigning a Directive to a tag creates link to that tag and it’s contents to AngularJS.

AngularJS defines many built in Directives. These all begin with ng-. For example, ng-app, and ng-model. These can, optionally, be prepended with data- for validation if you like. For example: data-ng-app, and data-ng-model.

You can also write your own Directives.

Here area  few Directives.

The ng-app directive tells Angular which part of the page it should manage. It could be placed in the html tag to manage the entire page, or on the body or div tag to manage a smaller realm.

Where this tag is placed determines the document root for Angular. Placing the ng-app directive on a tag other than the <html> tag will limit the scope of the Angular app to that region of the page.

Include an optional module name as a value to this attribute. For example: ng-app=”moduleName”.

The ng-init Directive initializes data. Usually you’ll want to handle this with a Controller.

The ng-controller directive attaches a controller to DOM element. A controller is a Javascript object that will manage data displayed in that region.

The ng-repeat directive tells Angular to copy the elements within the repeat element a number of times. It will populate this “template” element with data from the model.

Loop with ng-repeat

  • {{name}}

Within ng-repeat Angular defines $index, $first, $middle, and $last. $index holds the the index of the repeated element. While $first, $middle and $last are booleans, true when the element is the first, middle or last element.

{{expression}}

The {{}} defines a template expression. The {{ and }} can thought of as defining the area where Angular will write data. The expression inside can be thought of as modifying or defining how the data is written.

The ng-model attribute allows you to define connection from the DOM to model data. In the case of an input field modifying the input modifies the model data directly.

{{item.price | currency}}

The | defines a filter to be applied to the content of a {{}} template. There are several built in templates, and you can define your own. The example above formats item.price as currency.

The ng-click directive sets up a click action that will call on JS we define. The handler function should be part of the $scope of the controller that contains this ng-click.

Note that $index is a variable defined by ng-repeat.

{{greeting}}

The ng-bind attribute can be used to bind a view element to a model value. This works the same as use the {{}} template syntax. Where the {{}} syntax will show the {{}} for a moment when the page initially loads the ng-bind directive will not. Making this good for elements that will show initially.

Use ng-change to call a function defined in the $scope of the elements controller when a form element changes.

Use ng-submit to call a function when a form is submitted.


some text

Images and Anchors are special cases and have their own specific directives.

MVC – Model View Controller

MVC is a software design pattern that breaks functionality into three areas: Model, View, and Controller. This pattern is particularly suited to software that handles and manipulates data via user interface. Which makes it a good fit for Web apps. AngularJS turns HTML, CSS, and Javascript into a surprisingly good fit for this pattern.

Models

Angular uses the MVC, or Model, View, Controller, paradigm. Where the Model represents data used by your program. For example, a list of user names, or a list of products with their price and description. The View is where data is displayed and represents the visual end of your program. The controller is the business side of your program. It contains the logic that manages data and facilitates translating data so it can be displayed by the View.

A Model can be as simple as a variable containing the number of times a button has been clicked. More often model data will be an array or object containing a list of values and properties.

A Controller might contain functions that controls the how a number is displayed. It might round the value off or format it any number of ways. More often the Controller will load an array of data and sort and filter before sending it to the View.

Views in Angular, are HTML. The view is essentially written in HTML and CSS, along with Angular’s templating system. Controllers are tied to views directly in the HTML as attribute names. This is a key feature of Angular that makes it unique.

Controllers

Controllers handle processing model data.

Views

The display data held by the model. Views in AngularJS are templates defined as snippets of HTML. These can be external files loaded into the app, or defined within the same file tags. Templates can all be defined as strings as part of a controller, directive or other module.

Modules

Model data should be defined in a “modules”. Use Angular’s module method to create a new module.

Services

Services are singleton objects that provide global functionality to an app. Built in services begin with the $, such as $routeProvider, and $http.

Bootstrapping

Here’s the outline for an Angular page: