The game explained here demonstrates the creation of various 3d models and how to make them targets, for purposes like shooting. Also we can learn about collision detection
To begin with, we need to initialize 3d cast member and a physics cast member. Using Window > Shockwave 3d , we can create a 3d cast member , which I name as “3dScene”. Now using Insert > Media Element > Physics, I initialize a physics cast member.I name it as DirPhyz. Physics is used here to make use of RigidBody concepts and make collision detection easier.
To initiate physics,
----INITIALIZE THE PHYSICS CAST
MEMBER--------
DirPhyz = member(4)
DirPhyz.Init( member(1), vector(1,1,1),#equal, 0.0167, 5 )
DirPhyz.friction=0
DirPhyz.restitution=1
DirPhyz.contacttolerance=0.025
member("DirPhyz").gravity = vector(0,-9.81,0)
-----INITIALIZE THE 3D
CAST MEMBER---------------
my3d = member("3dScene")
member("3dScene").resetWorld()
Spheres and boxes need to be created continuously. If user targets the sphere and then clicks on it, the sphere disappears. The score increases by 1.If user clicks on box, we reduce the score by 1. If the score reaches -5, game over. If it reaches 25, user wins. As more and more models are created , the game becomes slower. Hence its necessary to define the winning and losing criteria. Sooner the user loses, better for us J
In my game, I choose to call my sphere as egg J
To create the plane (this plane is the one on which all our models are placed)
------CREATION
OF PLANE RESOURCE AND MODEL---
planeResource = my3d.newModelResource("myplane",#plane)
planeResource.length = 160
planeResource.width = 200
myPlane = my3d.newModel("myPlane" , planeResource)
---PLACE THE PLANE AT REQUIRED
POSITION----------
myplane.transform.position = vector(0,0,-20)
For sphere, I create the modelResource once in my startMovie script.
-----SPHERE MODEL
RESOURCE CREATION----
eggRes = member("3dScene").newModelResource("myegg", #sphere)
eggRes.radius = 5
This is because director doesn’t allow us to create multiple resources for the same model. Anyways multiple models for the same resource can be created, of course with different model names.
Now, I need 3 boxes to the left, right and bottom of the plane to enable collision detection.So I choose to create them in my startMovie script
-----BOX CREATION AT THE BOTTOM OF THE
PLANE FOR COLLISION DETECTION---
PlaneResource_base = member("3dScene").newModelResource("GroundPlane", #box)
PlaneResource_base.width = 600
PlaneResource_base.length =600
PlaneResource_base.height = 10
base_plane = member("3dScene").newModel("Ground", PlaneResource_base)
base_plane.transform.position=vector(0,-70,0)
base_plane.addmodifier(#meshdeform)
rb_basePlane = member(4).createRigidBody("Ground","Ground",#box,#static)
Since “exitFrame” script is executed each time the corresponding frame is exited, I call my “CreateEggs()” function in “exitFrame”
on createEggs
choose_color = random(1000)
i=random(2000)
--CREATE MODEL FOR
SPHERE , EACH WITH UNIQUE NAME--
myEgg = member(1).newModel("myegg" & eggcount,eggRes)
myEgg.addmodifier(#meshdeform)
myEgg.transform.position=vector(-20+random(10),100+random(10),0)
rb = member(4).createRigidBody(myEgg.name,myEgg.name,#sphere,#dynamic)
member("DirPhyz").gravity = vector(0,-9.81,0)
rb.linearvelocity=vector(10,0,10)
eggcount=eggcount+1
str_to_delete = rb.name
list1.add(str_to_delete)
--SHADER FOR EACH
SPHERE CREATED ----
egg_texture_red= member("3dScene").newTexture("egg_texture_red" & choose_color &i
, #fromCastmember, member("red"))
egg_shader_name.texture = egg_texture_red
myEgg.shader =
egg_shader_name
executed = executed + 1
--FOR EVERY 5 SPHERES,
A BOX IS CREATED----
if(executed=5) then
createBox()
executed = 0
end if
End
In CreateBox() we create a box with the dimensions of our own. We increment the boxcount by 1 each time the method is called. We append the “boxcount” to our box model so that the model created will be unique.
on CreateBox()
boxResource.length = 9
boxResource.width = 9
boxResource.height = 9
--MODEL CREATION FOR
BOX
mybox = member("3dScene").newModel("mybox" & boxcount, boxResource)
mybox.addmodifier(#meshdeform)
--APPLY SHADER FOR
CREATED BOX---
mybox.shaderlist[1] = box_shader_name
mybox.shaderlist[2] = box_shader_name
mybox.shaderlist[3] = box_shader_name
mybox.shaderlist[4] = box_shader_name
mybox.shaderlist[5] = box_shader_name
mybox.shaderlist[6] = box_shader_name
mybox.transform.position=vector(-70+random(10),-20+random(10),0)
rb_box = member(4).createRigidBody(mybox.name,mybox.name,#box,#dynamic)
--DEFINE ITS VELOCITY
AND INCREMENT BOX COUNT--
rb_box.linearvelocity=vector(45,-30,10)
boxcount=boxcount+1
end
The main part of our game is implementing the mouseUp function which is called when we click on a sphere or anywhere in our 3dScene
on mouseUp
---GET THE POINT WHERE
THE USER CLICKS
pt = the mouseLoc - point(sprite("3dsprite").left, sprite("3dsprite").top)
--GET ALL THE MODELS
AT THE POINT WHERE USER CLICKS
m = sprite("3dsprite").camera.modelsUnderLoc(pt, #detailed)
--CHECK IF MODEL IS A
SPHERE. IF SO, DELETE IT---
repeat with k = 1 to m.count
modelName = m[k].model.name
if (modelName contains "myegg") then
member(4).deleteRigidbody(modelName)
member("3dScene").deleteModel(modelName)
final_result=final_result+1
else if(modelName contains "mybox") then
final_result=final_result-1
end if
--FINAL_RESULT
INDICATED THE SCORE---
member("result").text=string(final_result)
if(final_result=-6) then
alert("
Game Over ")
halt
else if(final_result=25) then
alert("U
win")
end if
end repeat
end
As our models go on increasing , we need to get out a way to delete them when they are out of scene. For this we need to use collision detection concept. Once the model(sphere or box) collides with the box which is at the base of the 3d Scene, we delete it.
The below code shows the way we register for collision detection
--COLLISION CALLBACK
FOR RIGID BODIES
pDirPhyz.registercollisioncallback(#collisionCallback, me)
pDirPhyz.enablecollisioncallback()
We need to pass the parameter ‘me’ because the code for collision detection is written in ‘exitFrame’ script.
--USING COLLISION REPORT TO DELETE
UNWANTED MODELS--
on collisionCallback me,colReport
repeat with k = 1 to colReport.count
rb1 = colReport[k].ObjectA
rb2 = colReport[k].ObjectB
if ((rb1.name
contains "ground") and ( rb2.name contains "mybox")) then
---------------DELETE
MODEL----------------
list_for_basePlane.add(rb2.name)
else if ((rb1.name contains "mybox") and ( rb2.name contains "ground")) then
list_for_basePlane.add(rb1.name)
else if ((rb1.name contains "ground") and ( rb2.name contains "myegg")) then
list_for_basePlane.add(rb2.name)
else if ((rb1.name contains "myegg") and ( rb2.name contains "ground")) then
list_for_basePlane.add(rb1.name)
end if
end repeat
if (list_for_basePlane.count > 0) then
put list_for_basePlane
repeat with n=1 to list_for_basePlane.count
if member(4).getrigidbody(list_for_basePlane[n])
<> VOID then
member(4).deleterigidbody(list_for_basePlane[n])
member(1).deletemodel(list_for_basePlane[n])
end if
end repeat
end if
list_for_basePlane=[]
end
Finally
we need to empty our list so that the models appended to the list are deleted.
on stopmovie me
if list1.count > 0 then
repeat with i=1 to list1.count
if member(4).getrigidbody(list1[i])
<> VOID then
member(4).deleterigidbody(list1[i])
member(1).deletemodel(list1[i])
end if
end repeat
end if
halt
end
Many of us might want to few enhancements for this game. Some of my suggestions go here
- Implementing “mega offers” in the game like if a cylinder appears and if user clicks on it, score increases by 10
- Random change in colours for the models
- Introducing the levels in the game
I am sure there are many other ideas are awaiting to be implementedJ . Get going !
Feedback:
If you have any questions or comments concerning this
article, please send a message to lavanya_gss@yahoo.com
|