Aarhus Universitets segl

Workshop: App udvikling på smartphones F13

Med udgangspunkt i rapid prototyping af smartphone app´s vil workshoppen fokusere på IDE´s udviklet til dette, cross-platform deliverance og koblingen ml. kode og integerede sensorer i smartphones. Workshoppen dækker altså både iOS og Android. Workshoppen henvender sig til studerende der er interesserede i at få et hurtigt indblik I, hvad det indebærer at lave smartphone app´s der integrerer sensor stimuli. Underviserne lover at ved afslutning af workshoppen vil alle deltagere med en smartphone, gå hjem med en ny app i lommen!

  • Niveau: Programmering – let-øvede
  • Timer ialt: 15 timer
  • Tidspunkter: Lørdag d. 20 april, kl. 10:30-18:00 / Søndag d. 21 april, kl. 10:30-18:00
  • Sted: DD Lab, Wienerbygningen 026-032, Helsingforsgade 14, Katrinebjerg
  • Undervisere: Kasper Skov og Steffan Poulsen (DD kandidat-studerende samt ansat som lab-assistenter i DD Lab)

Ressourcer til app udvikling

Som en del af DD Labs mobile app udviklingsworkshop, er her en liste over nyttige ressourcer til udvikling med Corona SDK.

Link til Steffan og Kaspers dropbox ressourcer:
https://www.dropbox.com/sh/6y30ypl6okfx6za/zIT5DHSPZQ

Tonsvis af Corona SDK tutorials!
http://learningcorona.com/

Guide til at arbejde med DisplayObjects i Corona:
http://developer.coronalabs.com/content/application-programming-guide-graphics-and-drawing

Opsætning af app-ikoner (iOS + Android)
https://docs.coronalabs.com/guide/distribution/buildSettings/index.html#appicons

Opsætning til Mac OS X:
https://docs.coronalabs.com/guide/start/installMac/index.html

Opsætning på Windows:
https://docs.coronalabs.com/guide/start/installWin/index.html

Basal introduktion til Lua programmering:
https://docs.coronalabs.com/guide/start/introLua/index.html

Corona SDK API (dokumentation):
https://docs.coronalabs.com/api/index.html

Opsætning af Android eller iOS enheder (signing, building og distribution)
https://docs.coronalabs.com/guide/index.html#building-and-distribution

Gratis, royalty free lyde til brug i fx. spil:
http://www.soundbible.com/

Søgemaskine til at søge i materialer med en creative commons licens (igen royalty free!)
http://search.creativecommons.org/

Corona showcases
https://coronalabs.com/halloffame

1. Displaying objects

Her følger løsningen på opgave 1:

-- Live coding 1: Display objects

local background = display.newImage("images/background.png")

display.setStatusBar(display.HiddenStatusBar);

_W = display.contentWidth
_H = display.contentHeight

local ball = display.newCircle(_W/2, _H/2, 25)
ball:setFillColor(255,0,0)

local leftWall = display.newRect(0, 0, 10, _W)

-- Opg 1:

local rightWall = display.newRect(_W-10, 0, 10, _W)
local topWall = display.newRect(0, 0, _W, 10)
local bottomWall = display.newRect(0, _H-10, _W, 10)

-- Live coding 2: Physics library

local physics = require("physics")
physics.start()
physics.setGravity( 0.0, 9.82)

physics.addBody(ball, "dynamic", {density=0.1, friction=0.0, bounce=1.0, radius=25});
physics.addBody(bottomWall, "static", {bounce = 1.0})
ball:applyForce(math.random(-100,100), math.random(-100,100), ball.x, ball.y)

-- Opg 2:

physics.addBody(leftWall, "static", {bounce = 1.0})
physics.addBody(rightWall, "static", {bounce = 1.0})
physics.addBody(topWall, "static", {bounce = 1.0})
physics.setGravity( 0.0, 0.0)

2. Physics library

Her følger løsningen på opgave 2!

-- Live coding 1: Display objects

local background = display.newImage("images/background.png")

display.setStatusBar(display.HiddenStatusBar);

_W = display.contentWidth
_H = display.contentHeight

local ball = display.newCircle(_W/2, _H/2, 25)
ball:setFillColor(255,0,0)

local leftWall = display.newRect(0, 0, 10, _W)

-- Opg 1:

local rightWall = display.newRect(_W-10, 0, 10, _W)
local topWall = display.newRect(0, 0, _W, 10)
local bottomWall = display.newRect(0, _H-10, _W, 10)

-- Live coding 2: Physics library

local physics = require("physics")
physics.start()
physics.setGravity( 0.0, 9.82)

physics.addBody(ball, "dynamic", {density=0.1, friction=0.0, bounce=1.0, radius=25});
physics.addBody(bottomWall, "static", {bounce = 1.0})
ball:applyForce(math.random(-100,100), math.random(-100,100), ball.x, ball.y)

-- Opg 2:

physics.addBody(leftWall, "static", {bounce = 1.0})
physics.addBody(rightWall, "static", {bounce = 1.0})
physics.addBody(topWall, "static", {bounce = 1.0})
physics.setGravity( 0.0, 0.0)

3. Collision events

Her følger løsningen på opgave 3!


-- Live coding 1: Display objects

local background = display.newImage("images/background.png")

display.setStatusBar(display.HiddenStatusBar);

_W = display.contentWidth
_H = display.contentHeight

local ball = display.newCircle(_W/2, _H/2, 25)
ball:setFillColor(255,0,0)

local leftWall = display.newRect(0, 0, 10, _W)

-- Opg 1:

local rightWall = display.newRect(_W-10, 0, 10, _W)
local topWall = display.newRect(0, 0, _W, 10)
local bottomWall = display.newRect(0, _H-10, _W, 10)

-- Live coding 2: Physics library

local physics = require("physics")
physics.start()
physics.setGravity( 0.0, 9.82)

physics.addBody(ball, "dynamic", {density=0.1, friction=0.0, bounce=1.0, radius=25});
physics.addBody(bottomWall, "static", {bounce = 1.0})
ball:applyForce(math.random(-100,100), math.random(-100,100), ball.x, ball.y)

-- Opg 2:

physics.addBody(leftWall, "static", {bounce = 1.0})
physics.addBody(rightWall, "static", {bounce = 1.0})
physics.addBody(topWall, "static", {bounce = 1.0})
physics.setGravity( 0.0, 0.0)

-- Live coding 3: Collision events

  -- Opg 3:
  local bounce = audio.loadSound("sounds/bounce.mp3")
  topWall.myName = "wall"
  leftWall.myName = "wall"
  rightWall.myName = "wall"

bottomWall.myName = "wall"

local function onCollision(self, event)
  if (event.phase == "began" and event.other.myName ~= nil) then
    --Opg 3:
    if (event.other.myName == "wall") then
      audio.play(bounce)
    end

  end
end

ball.collision = onCollision
ball:addEventListener("collision", ball)

4. Accelerometer + tekst

Her følger løsningen på opgave 4!

-- Live coding 1: Display objects

local background = display.newImage("images/background.png")

display.setStatusBar(display.HiddenStatusBar);

_W = display.contentWidth
_H = display.contentHeight

local ball = display.newCircle(_W/2, _H/2, 25)
ball:setFillColor(255,0,0)

local leftWall = display.newRect(0, 0, 10, _W)

-- Opg 1:

local rightWall = display.newRect(_W-10, 0, 10, _W)
local topWall = display.newRect(0, 0, _W, 10)
local bottomWall = display.newRect(0, _H-10, _W, 10)

-- Live coding 2: Physics library

local physics = require("physics")
physics.start()
physics.setGravity( 0.0, 9.82)

physics.addBody(ball, "dynamic", {density=0.1, friction=0.0, bounce=1.0, radius=25});
physics.addBody(bottomWall, "static", {bounce = 1.0})
ball:applyForce(math.random(-100,100), math.random(-100,100), ball.x, ball.y)

-- Opg 2:

physics.addBody(leftWall, "static", {bounce = 1.0})
physics.addBody(rightWall, "static", {bounce = 1.0})
physics.addBody(topWall, "static", {bounce = 1.0})
physics.setGravity( 0.0, 0.0)

-- Live coding 3: Collision events

  -- Opg 3:
  local bounce = audio.loadSound("sounds/bounce.mp3")
  topWall.myName = "wall"
  leftWall.myName = "wall"
  rightWall.myName = "wall"

bottomWall.myName = "wall"

local function onCollision(self, event)
  if (event.phase == "began" and event.other.myName ~= nil) then
    --Opg 3:
    if (event.other.myName == "wall") then
      audio.play(bounce)
    end

  end
end

ball.collision = onCollision
ball:addEventListener("collision", ball)

-- Live coding 4: Accelerometer + tekst

  -- Opg 4:
  local debugText = display.newText("", _W/2, _H/2, native.systemFont, 32)

local function debug(tekst)
  print(tekst)
  -- Opg 4:
  debugText.text = tekst
end

local function onAccelerometer(event)
  debug(event.yGravity)
end

Runtime:addEventListener("accelerometer", onAccelerometer)

5. Interaktion!

Her følger løsningen på opgave 5!

-- Generalle indstillinger
display.setStatusBar(display.HiddenStatusBar);
local physics = require("physics")
physics.start()
physics.setGravity( 0.0, 0.0)

-- Accelerometer
system.setAccelerometerInterval(60)

-- Variabler
local _W = display.pixelHeight
local _H = display.pixelWidth
local speed = 50
local figurRadius = 50

-- Initialize Funktioner
local debug
local onCollision
local onAccelerometer
local addBall

-- Objekter
local background = display.newImageRect("images/background.png", _W, _H)
local touchObject = display.newCircle(_W/2, _H/2, 25)
local figur = display.newImage("images/hippo.png")
local leftWall = display.newRect(0, 0, 10, _W)
local rightWall = display.newRect(_W-10, 0, 10, _W)
local topWall = display.newRect(0, 0, _W, 10)
local bottomWall = display.newRect(0, _H-10, _W, 10)
local debugText = display.newText("", _W/2, _H/2, native.systemFont, 32)

-- Objekt indstillinger
touchObject.alpha = 0.5
touchObject:setFillColor(255,255,255)
figur.x = _W/2
figur:scale(0.7,0.7)
figur.myName = "figur"
background.x = _W/2
background.y = _H/2
topWall.myName = "wall"
bottomWall.myName = "wall"
leftWall.myName = "wall"
rightWall.myName = "wall"

-- Physics
physics.addBody(figur, "static", { radius = figurRadius })
physics.addBody(bottomWall, "static", {bounce = 1.0})
physics.addBody(leftWall, "static", {bounce = 1.0})
physics.addBody(rightWall, "static", {bounce = 1.0})
physics.addBody(topWall, "static", {bounce = 1.0})

-- Physics draw mode | "normal" | "debug" | "hybrid"
physics.setDrawMode("normal")

-- Lyde
local bounce = audio.loadSound("sounds/bounce.mp3")

-- Funktioner
function debug(tekst)
  debugText.text = tekst
end  

function addBall()
  local ball = display.newCircle(_W/2, _H/2, 25)
  ball:setFillColor(255,0,0)
  physics.addBody(ball, "dynamic", {density=0.1, friction=0.0, bounce=1.0, radius=25});
  local randomX = math.random(math.random(-100,-50),math.random(50,100))
  local randomY = math.random(math.random(-100,-50),math.random(50,100))
  ball:applyForce(randomX, randomY , ball.x, ball.y)

  ball.collision = onCollision
  ball:addEventListener("collision", ball)
end

function onCollision(self, event)
  if (event.phase == "began" and event.other.myName ~= nil) then
    if (event.other.myName == "wall") then
      audio.play(bounce)
    elseif (event.other.myName == "figur") then
      --debug("haps!")
      self:removeSelf()
      timer.performWithDelay(100, addBall, 1)
    end
  end
end

function onAccelerometer(event)
  debug(event.yGravity)
  figur.x = figur.x + ((event.yGravity * -1) * speed)
  if (figur.x < 0 + figurRadius) then
    figur.x = 0 + figurRadius
  elseif (figur.x > _W - figurRadius) then
    figur.x = _W - figurRadius
  end
end

local function onBackgroundTouch(event)
  --if (event.phase == "ended") then
    touchObject.x = event.x
    touchObject.y = event.y
    debug(event.numTaps)  
  --end
end

addBall()

-- Listeners
background:addEventListener("tap", onBackgroundTouch)
Runtime:addEventListener("accelerometer", onAccelerometer)