This code draws a 3d dice that can be rolled and feedback the number it lands on. Feel free to use the code.
--# Main
-- main
function setup()
b=Die(0,0,0,200)
end
function draw()
background(255, 0, 0, 255)
b:draw()
fill(0)
fontSize(50)
if b.rolling then
text("rolling...",300,100)
else
text("The dice is on face "..b.face,300,100)
end
end
function touched(touch)
if touch.state==BEGAN then
b:roll()
end
end
--# Die
Die = class()
function Die:init(x,y,z,s)
local one=image(s,s)
local two=image(s,s)
local three=image(s,s)
local four=image(s,s)
local five=image(s,s)
local six=image(s,s)
local spotsize=s/4.5
fill(0)
noStroke()
setContext(one)
ellipse(s/2,s/2,spotsize)
setContext(two)
ellipse(s/3,s/3,spotsize)
ellipse(s/3*2,s/3*2,spotsize)
setContext(three)
ellipse(s/4,s/4,spotsize)
ellipse(s/4*2,s/4*2,spotsize)
ellipse(s/4*3,s/4*3,spotsize)
setContext(four)
ellipse(s/3,s/3,spotsize)
ellipse(s/3*2,s/3,spotsize)
ellipse(s/3*2,s/3*2,spotsize)
ellipse(s/3,s/3*2,spotsize)
setContext(five)
ellipse(s/4,s/4,spotsize)
ellipse(s/4*2,s/4*2,spotsize)
ellipse(s/4*3,s/4*3,spotsize)
ellipse(s/4,s/4*3,spotsize)
ellipse(s/4*3,s/4,spotsize)
setContext(six)
ellipse(s/4,s/3,spotsize)
ellipse(s/4*2,s/3,spotsize)
ellipse(s/4*3,s/3,spotsize)
ellipse(s/4,s/3*2,spotsize)
ellipse(s/4*2,s/3*2,spotsize)
ellipse(s/4*3,s/3*2,spotsize)
local img=image(s*6,s)
local spotpos={1,2,6,5,3,4}
setContext(img)
stroke(0)
strokeWidth(10)
rectMode(CORNER)
spriteMode(CORNER)
for i=1,6 do
fill(255)
rect((i-1)*s-5,0-5,s+10,s+10)
fill(0)
fontSize(30)
font("AmericanTypewriter-Bold")
if spotpos[i]==1 then
sprite(one,(i-1)*s,0)
elseif spotpos[i]==2 then
sprite(two,(i-1)*s,0)
elseif spotpos[i]==3 then
sprite(three,(i-1)*s,0)
elseif spotpos[i]==4 then
sprite(four,(i-1)*s,0)
elseif spotpos[i]==5 then
sprite(five,(i-1)*s,0)
elseif spotpos[i]==6 then
sprite(six,(i-1)*s,0)
end
end
setContext()
self.x = x
self.y = y
self.z = z
self.width = s/4 -- width
self.height = s/4 -- height
self.depth = s/4 -- depth
self.texture = img
self.texR = {0,0,1/6,1, 1/6,0,2/6,1, 2/6,0,3/6,1, 3/6,0,4/6,1, 4/6,0,5/6,1, 5/6,0,6/6,1}
self.mesh = self:createDie()
self.angle={x=0,y=0,z=0}
self.rolling=false
self.face=6
self.faceangle=
{vec2(2,4),vec2(1,3),vec2(2,1),vec2(4,1),vec2(3,2),vec2(0,0)}
end
function Die:createDie()
local w,h,d = self.width,self.height,self.depth
-- right = +
-- up = +
-- front = +
--table of the verticies of a cube
--x ,y, z
local v =
{
vec3(-0.5*w +self.x,-0.5*h +self.y,0.5*d +self.z), -- left bottom front --+
vec3(0.5*w +self.x,-0.5*h +self.y,0.5*d +self.z), -- right bottom front +-+
vec3(0.5*w +self.x,0.5*h +self.y,0.5*d +self.z), -- right top front +++
vec3(-0.5*w +self.x,0.5*h +self.y,0.5*d +self.z), -- left top front -++
vec3(-0.5*w +self.x,-0.5*h +self.y,-0.5*d +self.z), --left bottom back ---
vec3(0.5*w +self.x,-0.5*h +self.y,-0.5*d +self.z), -- right bottom back +--
vec3(0.5*w +self.x,0.5*h +self.y,-0.5*d +self.z), -- right top back ++-
vec3(-0.5*w +self.x,0.5*h +self.y,-0.5*d +self.z), -- left top back -+-
}
local cubeverts =
{
-- front face
v[1], v[2], v[3], v[1], v[3], v[4],
-- right face
v[2], v[6], v[7], v[2], v[7], v[3],
-- back face
v[6], v[5], v[8], v[6], v[8], v[7],
-- left face
v[5], v[1], v[4], v[5], v[4], v[8],
-- top face
v[4], v[3], v[7], v[4], v[7], v[8],
-- bottom face
v[5], v[6], v[2], v[5], v[2], v[1],
}
local cubetexCoords = {}
for f=1,6 do
local p=(f-1)*4
local BL=vec2(self.texR[1+p],self.texR[2+p]) --bottom left
local BR=vec2(self.texR[3+p],self.texR[2+p]) --bottom right
local TR=vec2(self.texR[3+p],self.texR[4+p]) --top right
local TL=vec2(self.texR[1+p],self.texR[4+p]) --top left
table.insert(cubetexCoords,BL)
table.insert(cubetexCoords,BR)
table.insert(cubetexCoords,TR)
table.insert(cubetexCoords,BL)
table.insert(cubetexCoords,TR)
table.insert(cubetexCoords,TL)
end
local ms = mesh()
ms.vertices = cubeverts
ms.texture = self.texture
ms.texCoords = cubetexCoords
ms:setColors(255,255,255,255)
return ms
end
function Die:draw()
pushMatrix()
perspective(45,WIDTH/HEIGHT)
camera(0,0,-300,0,0,0,0,1,0)
rotate(self.angle.x,0,1,0)
rotate(self.angle.y,1,0,0)
self.mesh:draw()
popMatrix()
ortho()
viewMatrix(matrix())
end
function Die:roll()
if not self.rolling then
local Xroll=0
while Xroll==0 do Xroll=math.random(-1,1) end
local Yroll=0
while Yroll==0 do Yroll=math.random(-1,1) end
self.newface=math.random(1,6)
self.rolling=true
local rotateX=self.faceangle[self.newface].x*90-self.angle.x+Xroll*360
local rotateY=self.faceangle[self.newface].y*90-self.angle.y+Yroll*360
tween(1.5,self.angle,
{x=self.angle.x+rotateX,
y=self.angle.y+rotateY},
tween.easing.quadInOut,
function()
self.rolling=false
self.face=self.newface
end)
end
end
This script can only make a dice on center of screen. How can I make a few dices and place it at other location?
To change a dice’s position, a quick solution is to use translate:
pushMatrix()
translate(-WIDTH/2+yourX,-HEIGHT/2+yourY) -- replace yourX and yourY with the dice position you want to use
d:draw() -- draw the dice
popMatrix()
@olzenkhaw Replace the functions with what I have below.
EDIT: Changed code a little.
supportedOrientations(LANDSCAPE_ANY)
function setup()
b=Die(0,0,0,100)
c=Die(0,0,0,100)
end
function draw()
background(255, 0, 0, 255)
translate(25,0)
b:draw()
translate(-50,0)
c:draw()
fill(0)
fontSize(50)
if b.rolling then
text("rolling...",300,100)
else
text("The dice is on face "..b.face,300,200)
text("The dice is on face "..c.face,300,100)
end
end
function touched(touch)
if touch.state==BEGAN then
b:roll()
c:roll()
end
end
Thank you. However, the 2 dices when see in 2D are different because of the camera view. How can I show the 2 dices exactly 100% same in 2D?
@olzenkhaw One way to do it would be to show the dice spinning in 3D, but just as they stop, draw the face of the dice in 2D.
@olzenkhaw If you’re after simple 2D dice, then here’s a small program to get you started. You can modify this to what you want. Tap the screen to roll the dice.
function setup()
rectMode(CENTER)
d1=dice(200,400)
d2=dice(300,400)
end
function draw()
background(40, 40, 50)
d1:draw()
d2:draw()
end
function touched(t)
if t.state==BEGAN then
d1:touched(t)
d2:touched(t)
end
end
dice=class()
function dice:init(x,y)
self.x=x
self.y=y
self.cnt1=0
self.cnt2=0
self.p=math.random(6)
self.rolls=false
end
function dice:draw()
fill(255)
rect(self.x,self.y,80)
fill(0)
if self.p==1 or self.p==3 or self.p==5 then
ellipse(self.x,self.y,20)
end
if self.p==2 or self.p==3 then
ellipse(self.x-20,self.y-20,20)
ellipse(self.x+20,self.y+20,20)
end
if self.p==4 or self.p==5 or self.p==6 then
ellipse(self.x-20,self.y-20,20)
ellipse(self.x+20,self.y+20,20)
ellipse(self.x-20,self.y+20,20)
ellipse(self.x+20,self.y-20,20)
end
if self.p==6 then
ellipse(self.x-20,self.y,20)
ellipse(self.x+20,self.y,20)
end
if self.rolls then
if self.cnt1>math.random(10,20) then
self.rolls=false
end
self.cnt2=self.cnt2+1
if self.cnt2>math.random(5,10) then
self.cnt2=0
self.cnt1=self.cnt1+1
self.p=math.random(6)
end
end
end
function dice:touched(t)
if t.state==BEGAN then
self.cnt1=0
self.cnt2=0
self.rolls=true
end
end
Nice!