Created
October 15, 2017 02:17
-
-
Save DolenzSong/24c33f889f06f98ac2af98b31ddc19b3 to your computer and use it in GitHub Desktop.
A simplified version of the "Learn Craft" project included with Codea
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--# Scene | |
-- Craft Scenes | |
function setup() | |
-- Create a new craft scene | |
yourScene = craft.scene() | |
-- Activate sidebar controls | |
setParameters() | |
end | |
-- Called automatically by Codea | |
function draw() | |
-- No need to clear the background, a scene does that for you | |
-- Update the scene | |
yourScene:update(DeltaTime) | |
-- Draw the scene | |
yourScene:draw() | |
-- Do any 2D drawing last | |
drawStepName("Scene 🎬") | |
end | |
function setParameters() | |
-- Define this scene's individual sidebar controls | |
Note = "There are six lessons. You may need to scroll down to see them all." | |
parameter.watch("Note") | |
end | |
function PrintExplanation() | |
output.clear() | |
print("Where is everything?") | |
print("This is a blank scene right now, but it can hold amazing things.") | |
print("It just takes 3 steps to start one.") | |
print("Create it using craft.scene(), then with it call update(DeltaTime) and draw() inside the draw function.") | |
end | |
function cleanup() | |
if viewer then | |
touches.removeHandler(viewer) | |
viewer = nil | |
end | |
yourScene = nil | |
collectgarbage() | |
end | |
--# Entities | |
-- Craft Entities | |
function setup() | |
-- Create a new craft scene | |
yourScene = craft.scene() | |
-- Use that scene to create a new entity | |
cube = yourScene:entity() | |
-- Define a size for the entity | |
size = vec3(1,1,1) | |
-- Use that size to make the entity a cube | |
cube.model = craft.model.cube(size) | |
-- Give the entity a material, which lets it have an image | |
cube.material = craft.material("Materials:Standard") | |
-- Assign it an image or "skin" using material.map | |
cube.material.map = readImage("Blocks:Dirt") | |
-- Position it (these values are also set in the sidebar controls) | |
cube.x = 0 | |
cube.y = 0 | |
cube.z = 4 | |
cube.eulerAngles = vec3(200,180,0) | |
-- Activate sidebar controls | |
setParameters() | |
end | |
-- Called automatically by Codea | |
function draw() | |
-- For convenience you can give scene updates their own function | |
updateScene() | |
-- Draw the scene | |
yourScene:draw() | |
-- Do 2D drawing last | |
drawStepName("Entities 👻") | |
end | |
function updateScene() | |
-- Update entity position based on sidebar controls | |
cube.x = x | |
cube.y = y | |
cube.z = z | |
cube.eulerAngles = vec3(eulerAnglesX, eulerAnglesY, eulerAnglesZ) | |
-- Update skin setting based on sidebar controls | |
if cube.material.map and not skin then | |
cube.material.map = nil | |
elseif not cube.material.map and skin then | |
cube.material.map = readImage("Blocks:Dirt") | |
end | |
-- Update the scene (physics, transforms etc) | |
yourScene:update(DeltaTime) | |
end | |
function setParameters() | |
-- Define this scene's individual sidebar controls | |
DontPanic = "The lesson buttons are still here! Just scroll down to see them." | |
parameter.watch("DontPanic") | |
parameter.boolean("skin", true) | |
parameter.number("x", -2, 2, 0) | |
parameter.number("y", -2, 2, 0) | |
parameter.number("z", 0, 8, 4) | |
parameter.number("eulerAnglesX", 0, 360, 180) | |
parameter.number("eulerAnglesY", 0, 360, 200) | |
parameter.number("eulerAnglesZ", 0, 360, 180) | |
end | |
function PrintExplanation() | |
output.clear() | |
print("Entities are flexible objects used for displaying 3D models, simulating physics, and more.") | |
print("Create an entity inside a scene using yourScene:entity().") | |
print("To see it, give it a model (and a material or \"skin\" to jazz it up).") | |
print("Its x, y, z, and eulerAngles properties are just a few of the ways to position it onscreen.") | |
end | |
--# Models | |
-- Craft Models | |
function setup() | |
-- All the code from the previous lessons (cube's position adjusted) | |
yourScene = craft.scene() | |
cube = yourScene:entity() | |
size = vec3(1,1,1) | |
cube.model = craft.model.cube(size) | |
cube.material = craft.material("Materials:Standard") | |
cube.material.map = readImage("Blocks:Dirt") | |
cube.x = 0 | |
cube.y = -8.4 | |
cube.z = 41 | |
cube.scale = vec3(35,0.6,34) | |
-- Make the cube's texture smaller and repeated (looks a bit nicer) | |
cube.material.offsetRepeat = vec4(0,0,5,5) | |
-- Make a new entity and give it the robot model | |
robot = yourScene:entity() | |
robot.model = craft.model("Blocky Characters:Robot") | |
-- Position the robot | |
robot.y = -8.2 | |
robot.z = 41 | |
-- Set the robot's eulerAngles (these are also set in the sidebar) | |
-- Basically we're just turning it to face us. | |
robot.eulerAngles = vec3(0, 180, 0) | |
-- Activate sidebar controls | |
setParameters() | |
end | |
-- Called automatically by Codea | |
function draw() | |
-- For convenience scene updates can be a separate function | |
updateScene() | |
-- Draw the scene | |
yourScene:draw() | |
-- 2D drawing goes here | |
drawStepName("Models 🤖") | |
end | |
function updateScene() | |
-- Update Robot eulerAngles based on sidebar controls | |
robot.eulerAngles = vec3(RobotEulerX, RobotEulerY, RobotEulerZ) | |
-- Update the scene (physics, transforms etc) | |
yourScene:update(DeltaTime) | |
end | |
function setParameters() | |
-- Define this scene's individual sidebar controls | |
DontPanic = "The lesson buttons are still here! Just scroll down to see them." | |
parameter.watch("DontPanic") | |
parameter.number("RobotEulerX", 0, 360, 0) | |
parameter.number("RobotEulerY", 0, 360, 180) | |
parameter.number("RobotEulerZ", 0, 360, 0) | |
end | |
function PrintExplanation() | |
output.clear() | |
print("The last lesson showed a cube model, but models can be much more complex than that.") | |
print("This entity uses a built-in Codea model called \"Blocky Characters:Robot\".") | |
print("The ground is actually the same cube from the last scene, just flattened out.") | |
end | |
--# Cameras | |
-- Craft Camera | |
function setup() | |
-- All the code from the previous lessons | |
yourScene = craft.scene() | |
cube = yourScene:entity() | |
size = vec3(1,1,1) | |
cube.model = craft.model.cube(size) | |
cube.material = craft.material("Materials:Standard") | |
cube.material.map = readImage("Blocks:Dirt") | |
cube.y = -8.4 | |
cube.z = 41 | |
cube.scale = vec3(35,0.6,34) | |
cube.material.offsetRepeat = vec4(0,0,5,5) | |
robot = yourScene:entity() | |
robot.model = craft.model("Blocky Characters:Robot") | |
robot.y = -8.2 | |
robot.z = 41 | |
robot.eulerAngles = vec3(0, 180, 0) | |
-- Set the position of the scene's built-in camera (also set in the sidebar) | |
yourScene.camera.eulerAngles = vec3(0, 0, 0) | |
yourScene.camera.position = vec3(0, 0, 0) | |
-- The camera component lots of other camera settings, like fieldOfView | |
cameraSettings = yourScene.camera:get(craft.camera) | |
-- fieldOfView is similar to zoom (this value is also set in the sidebar) | |
cameraSettings.fieldOfView = 60 | |
-- Activate sidebar controls | |
setParameters() | |
end | |
function setParameters() | |
-- Define this scene's individual sidebar controls | |
DontPanic = "The lesson buttons are still here! Just scroll down to see them." | |
parameter.watch("DontPanic") | |
parameter.number("CameraX", -20, 20, 0) | |
parameter.number("CameraY", -20, 20, 0) | |
parameter.number("CameraZ", -20, 20, 0) | |
parameter.number("CameraEulerX", 0, 360, 0) | |
parameter.number("CameraEulerY", 0, 360, 0) | |
parameter.number("CameraEulerZ", 0, 360, 0) | |
parameter.number("FieldOfView", 20, 90, 55) | |
end | |
function updateScene() | |
-- Set the camera position based on sidebar controls | |
yourScene.camera.eulerAngles = vec3(CameraEulerX, CameraEulerY, CameraEulerZ) | |
yourScene.camera.position = vec3(CameraX, CameraY, CameraZ) | |
-- Set the field of view based on sidebar controls | |
cameraSettings.fieldOfView = FieldOfView | |
-- Update the scene (physics, transforms etc) | |
yourScene:update(DeltaTime) | |
end | |
-- Called automatically by Codea | |
function draw() | |
-- For convenience scene updates can be a separate function | |
updateScene() | |
-- Draw the scene | |
yourScene:draw() | |
-- Do any 2D drawing last | |
drawStepName("Cameras 🎥") | |
end | |
function PrintExplanation() | |
output.clear() | |
print("Each scene contains a built-in camera that you can move around") | |
print("It's part of an entity, so you can position it like any other entity") | |
print("Cameras also have settings like fieldOfView (basically a zoom)") | |
print("Access these on the camera component directly by calling camera:get(craft.camera) from your scene") | |
end | |
--# Viewers | |
-- Craft Viewers | |
function setup() | |
-- The code from the previous lessons, save Cameras (replaced below) | |
-- Some positions and sizes have been adjusted | |
yourScene = craft.scene() | |
cube = yourScene:entity() | |
size = vec3(1,1,1) | |
cube.model = craft.model.cube(size) | |
cube.material = craft.material("Materials:Standard") | |
cube.material.map = readImage("Blocks:Dirt") | |
cube.position = vec3(-3.03,-8.4,81.39) | |
cube.scale = vec3(136.13,0.6, 128.27) | |
cube.material.offsetRepeat = vec4(0,0,10,10) | |
robot = yourScene:entity() | |
robot.model = craft.model("Blocky Characters:Robot") | |
robot.position = vec3(4.55,-8.0,36.80) | |
robot.eulerAngles = vec3(0, 180, 0) | |
-- Hey let's add a trebuchet! Trebuchets are cool. | |
trebuchet = yourScene:entity() | |
trebuchet.model = craft.model("CastleKit:siegeTrebuchet") | |
trebuchet.eulerAngles = vec3(0, 180, 0) | |
trebuchet.position = vec3(-15.15,-8.66,100) | |
trebuchet.scale = vec3(1,1,1)*4.22 | |
-- An OrbitViewer from Cameras (a dependency added via the + button) | |
-- parameters: (viewer type, target, distance, min dist, max dist) | |
local target = trebuchet.model.bounds.center | |
viewer = yourScene.camera:add(OrbitViewer, target, 30, 20, 100) | |
-- Activate sidebar controls | |
setParameters() | |
end | |
function updateScene() | |
-- Update the scene (physics, transforms etc) | |
yourScene:update(DeltaTime) | |
end | |
-- Called automatically by Codea | |
function draw() | |
-- For convenience scene updates can be a separate function | |
updateScene() | |
-- Draw the scene | |
yourScene:draw() | |
-- Do any 2D drawing last | |
drawStepName("Viewers 👀") | |
end | |
function setParameters() | |
-- Define this scene's individual sidebar controls | |
parameter.watch("Note") | |
Note = "You may need to scroll down to see all the lessons." | |
end | |
function PrintExplanation() | |
output.clear() | |
print("To simplify camera setup, Codea offers a couple pre-configured cameras or \"Viewers\"") | |
print("This scene uses OrbitViewer, which lets you control the camera with gestures. Try it!") | |
print("To use Viewers set the Cameras project as a dependency") | |
print("Also, because everyone needs a trebuchet, we added a trebuchet") | |
end | |
--# Sky | |
-- Craft Sky | |
function setup() | |
-- All the code from the previous lessons, adjusted here and there | |
yourScene = craft.scene() | |
cube = yourScene:entity() | |
size = vec3(1,1,1) | |
cube.model = craft.model.cube(size) | |
cube.material = craft.material("Materials:Standard") | |
cube.material.map = readImage("Blocks:Dirt") | |
cube.position = vec3(-3.03,-8.4,81.39) | |
cube.scale = vec3(136.13,0.6, 128.27) | |
cube.material.offsetRepeat = vec4(0,0,10,10) | |
robot = yourScene:entity() | |
robot.model = craft.model("Blocky Characters:Robot") | |
robot.position = vec3(31.42,-8.0,36.80) | |
robot.eulerAngles = vec3(0, 180, 0) | |
trebuchet = yourScene:entity() | |
trebuchet.model = craft.model("CastleKit:siegeTrebuchet") | |
trebuchet.eulerAngles = vec3(0, 180, 0) | |
trebuchet.position = vec3(-15.15,-8.66,100) | |
trebuchet.scale = vec3(1,1,1)*4.22 | |
-- A wall made with a preset texture, just for the heck of it | |
wall = yourScene:entity() | |
wall.model = craft.model.cube(vec3(2,2,2)) | |
wall.material = craft.material.preset("Surfaces:Basic Bricks") | |
wall.material.normalScale = vec2(-1,-1) | |
wall.material.offsetRepeat = vec4(4,4,3,3) | |
wall.eulerAngles = vec3(0, 180, 0) | |
wall.scale = vec3(68.71,13.09,6) | |
wall.position = vec3(-3,4.96,145.45) | |
-- A kludge used for having the viewer start in a nonstandard place | |
viewerKludge = yourScene:entity() | |
viewerKludge.position = vec3(42.513,-5.765,2.033) | |
viewer = yourScene.camera:add(OrbitViewer, viewerKludge.position, 0.005, 0.0005, 10000) | |
-- Viewer eulerAngles are set with .rx, .ry, .rz | |
viewer.rx = -10.75 | |
viewer.ry = -24.125 | |
-- Activate sidebar controls | |
setParameters() | |
end | |
function updateScene() | |
-- Update the scene (physics, transforms etc) | |
yourScene:update(DeltaTime) | |
end | |
-- Called automatically by Codea | |
function draw() | |
-- For convenience scene updates can be a separate function | |
updateScene() | |
-- Draw the scene | |
yourScene:draw() | |
-- 2D drawing goes here | |
drawStepName("Sky ☁️") | |
end | |
function setParameters() | |
-- Define this scene's individual sidebar controls | |
parameter.watch("DontPanic") | |
DontPanic = "The lesson buttons are still here! Just scroll down to see them." | |
parameter.boolean("SkyActive", true, function(b) | |
yourScene.sky.active = b | |
end) | |
parameter.color("SkyColor", | |
color(70, 151, 234, 255), | |
function(c) | |
yourScene.sky.material.sky = c | |
end) | |
parameter.color("Horizon", | |
color(152, 204, 223, 255), | |
function(c) | |
yourScene.sky.material.horizon = c | |
end) | |
parameter.color("Ground", | |
color(37, 37, 37, 255), | |
function(c) | |
yourScene.sky.material.ground = c | |
end) | |
local sunny = readText("Environments:Night") | |
local env = craft.cubeTexture(json.decode(sunny)) | |
parameter.boolean("EnvMap", false, function(b) | |
if b then | |
yourScene.sky.material.envMap = env | |
else | |
yourScene.sky.material.envMap = nil | |
end | |
end) | |
parameter.color("CameraClearColor", | |
color(0, 0, 0, 255), | |
function(c) | |
-- Get the camera component to change camera settings | |
yourScene.camera:get(craft.camera).clearColor = c | |
end) | |
end | |
function PrintExplanation() | |
output.clear() | |
print("A custom sky is a powerful way to set the stage for a scene") | |
print("Craft's built-in sky is highly customizable on its own, and can also display pre-rendered images") | |
print("Play with the parameters above to see it in action") | |
print("If you've been through all the lessons, now you know the basics of Codea Craft!") | |
end | |
--# Main | |
----------------------------------------- | |
-- Learn Craft | |
-- Written by John Millard | |
-- Special thanks to Ignatz for the MultiStep project template | |
----------------------------------------- | |
-- Description: | |
----------------------------------------- | |
supportedOrientations(ANY) | |
displayMode(STANDARD) | |
function setup() | |
startTab("Scene") | |
setButtons() | |
end | |
function drawStepName(name) | |
fill(255, 255, 255, 255) | |
font("Inconsolata") | |
fontSize(40) | |
textAlign(LEFT) | |
textMode(CORNER) | |
text(name, 30, HEIGHT - 60) | |
end | |
function setButtons() | |
parameter.action("Scene 🎬", function () startTab("Scene") end) | |
parameter.action("Entities 👻", function () startTab("Entities") end) | |
parameter.action("Models 🤖", function () startTab("Models") end) | |
parameter.action("Cameras 🎥", function () startTab("Cameras") end) | |
parameter.action("Viewers 👀", function () startTab("Viewers") end) | |
parameter.action("Sky ☁️", function () startTab("Sky") end) | |
end | |
function startTab(tabName) | |
if cleanup then cleanup() end | |
parameter.clear() | |
loadstring(readProjectTab(tabName))() | |
if PrintExplanation then PrintExplanation() end | |
setup() | |
setButtons() | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment