Here’s my die code, for the record.
-- DieCraft
function setup(
displayMode(FULLSCREEN)
local dieimg = image(600,100)
setContext(dieimg)
background(255, 255, 255, 255)
noFill()
stroke(0, 0, 0, 255)
strokeWidth(10)
noSmooth()
for k=1,6 do
rect(100*(k-1)-5,-5,110,110)
end
noStroke()
fill(0, 0, 0, 255)
for k=0,5 do
for j=0,3 do
rect(100*k+90*math.floor(j/2),90*(j%2),10,10)
end
end
fill(255, 255, 255, 255)
ellipseMode(RADIUS)
for k=0,5 do
for j=0,3 do
ellipse(100*k+10+80*math.floor(j/2),10+80*(j%2),6)
end
end
fill(0, 0, 0, 255)
ellipseMode(CENTER)
noStroke()
fill(255, 0, 0, 255)
ellipse(100*(5-1)+50,50,15)
fill(0, 0, 0, 255)
for k=1,2 do
ellipse(100*(k-1)+50,50,15)
end
for _,k in ipairs({1,2,3,4,6}) do
fill(255, 0, 0, 255)
ellipse(100*(k-1)+25,25,15)
fill(0, 0, 0, 255)
ellipse(100*(k-1)+75,75,15)
end
for _,k in ipairs({1,4,6}) do
ellipse(100*(k-1)+75,25,15)
ellipse(100*(k-1)+25,75,15)
end
ellipse(525,50,15)
ellipse(575,50,15)
setContext()
scene = craft.scene()
scene.camera.z = -15
die = scene:entity()
die.model = craft.model("Primitives:RoundedCube")
local uvs = {}
local p,u,x,y,z
for k=1,die.model.vertexCount do
p = vec3(die.model:position(k))
u = vec2(die.model:uv(k))
u.x = u.x / 6
x = math.abs(p.x)
y = math.abs(p.y)
z = math.abs(p.z)
if x > y and x > z then
if p.x > 0 then
else
u.x = u.x + 2/6
end
elseif y > z then
if p.y > 0 then
u.x = u.x + 1/6
else
u.x = u.x + 3/6
end
else
if p.z > 0 then
u.x = u.x + 4/6
else
u.x = u.x + 5/6
end
end
table.insert(uvs,u)
end
die.model.uvs = uvs
die.material = craft.material("Materials:Specular")
die.material.map = dieimg
die:add(Spinner)
end
function draw()
background(72, 55, 55, 255)
scene:update(DeltaTime)
scene:draw()
sprite(dieimg,WIDTH/2,50)
end
function touched(t)
if t.state == ENDED then
if t.tapCount == 2 then
if state == 3 then
state = 2
else
state = 3
end
else
if state == 1 then
die:get(Spinner):setRoll()
state = 2
elseif state == 2 then
die:get(Spinner).rolling = true
state = 1
end
end
end
end
local sides
Spinner = class()
function Spinner:init(e)
self.entity = e
self.target = quat(1,0,0,0)
self:setRotation()
self.rolling = true
sides = sides or {
quat.fromToRotation(vec3(1,0,0),vec3(0,0,1)),
quat(1,0,0,0),
quat.fromToRotation(vec3(0,-1,0),vec3(0,0,1)),
quat.fromToRotation(vec3(0,1,0),vec3(0,0,1)),
quat.fromToRotation(vec3(0,0,-1),vec3(0,0,1)),
quat.fromToRotation(vec3(-1,0,0),vec3(0,0,1))
}
end
function Spinner:setRotation()
self.start = self.target
self.target = quat.random()
self.life = self.start:sdist(self.target)
self.time = 0
self.rotation = self.start:make_slerp(self.target)
end
function Spinner:setRoll()
self.start = self.entity.rotation
self.value = math.random(1,6)
self.target = sides[self.value]
self.life = self.start:sdist(self.target)
self.time = 0
self.rotation = self.start:make_slerp(self.target)
self.rolling = false
end
function Spinner:update(dt)
dt = dt or DeltaTime
self.time = self.time + dt
local t = self.time/self.life
t = math.min(1,math.max(0,t))
self.entity.rotation = self.rotation(t)
if t == 1 and self.rolling then
self:setRotation()
end
end
It uses my extension of the quat
userdata which adds some extra functions such as choosing a quat at random. You can get that from github at https://github.com/loopspace/Codea-Library-Maths