Adobe Director Online
 
Sridevi Aishwariya

Lavanya G S
Director Developer

Simple Shooting Game using 3D with Director 11

 
Download the Source here
 

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

  1. Implementing “mega offers” in the game like if a cylinder appears and if user clicks on it, score increases by 10
  2. Random change in colours for the models
  3. 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

 
spacer image
This is not an official site from Adobe. If you need any clarifications, please mail me at info@adobedirectoronline.com