DIALOG 3D WITH 2D

Imagine that you are creating a little game for your space (Croquet is not a game engine but it's viable for the creation of simple minigames).

In the game, a "shooter" try to kill many "monsters" (HalfLife3?). And you would like to create an score, showing how many "monsters" are dead.

TIP: There are more "serious" applications for this convergence 3D-2D, like, by example: a virtual galery of sculptures. When the avatar is near (use of "distance") an sculpture, appears a description about it. Different ambient sounds for each sculpture... Etc. Etc. Use your imagination!

In this lessons you will learn how to do it.

IMPORTANT: I hope that you understood all the concepts of the "Basic Tutorial for Beginners because they are pre-requirements for these lessons.

Until now we have created "instances variable" of a Class. But for our application we need to create a: Class variable.

When we change the value of a Class variable in any instance of the Class, this value will be changed at all the instances .

We will do an exercice using some of the resources we have created at previous lessons. So, the new definition of the Class Private will be:

 
TeapotMorph subclass: #Private
	instanceVariableNames: 'tframe cworld sceneObjects floor world space contacts prevTime
         rnd  wD12x7x1a wD12x7x1abody ahead   cL4x6x4a cL4x6x4abody on 
          cL4x6x4afly  lG shot bulletInitT bulletInitO shotS expS recS  '
	classVariableNames: 'Score' 
	poolDictionaries: 'OpenGLConstants '
	category: 'MyCroquet' 

A Class variable is always "capitalized" (first letter in upper case).

Like Smalltalk doesn't have the usual concept of properties (like Java, C++ etc.) we need to create 2 new methods to access this Class variable. To "read" and "write":

score

^  Score.

And to "write":

score:aScore.

Score:= aScore.

In the initializeDefaultSpace method we initialize the variable with: zero (in red).

 
initializeDefaultSpace
	 
| base|
 on:=0. 
cL4x6x4afly:=0.
shot:=0.

 Score := 0.

"Loading the sound files" 
shotS:=StreamingMP3Sound onFileNamed:  
 (FileDirectory pathFrom:
           {FileDirectory default pathName.  'Content'. 'legoicMGunODE' .'gunshot2.mp3'}) . 
expS:=StreamingMP3Sound onFileNamed:  
 (FileDirectory pathFrom:
           {FileDirectory default pathName.  'Content'. 'legoicMGunODE' .'explosion2.mp3'}) . 
recS:=StreamingMP3Sound onFileNamed:  
 (FileDirectory pathFrom:
           {FileDirectory default pathName.  'Content'. 'legoicMGunODE' .'gunrecharging.mp3'}) . 

cworld := TSpace new.
self makeLight: cworld.
	 
base :=BasePlateA70x3x70 new.
base translationX: 0 y: -6.3  z: 0.
cworld addChild: base.
 
prevTime := Time millisecondClockValue.
world := ODEWorld new.
space := ODESpace new.
world add: (contacts := ODEContactGroup new).
sceneObjects := Dictionary new.
rnd := Random new.
	
lG := LegoicMGunODE  new. 
lG translationX: 0 y: -2  z: 0.
cworld addChild: lG.
world add: (lG body).
space add: (lG geom).
sceneObjects at:lG body id put: {lG. lG body.  lG geom}.

bulletInitT:= lG bullet translation.
bulletInitO:= lG bullet orientation. 

self addCube.  "required"
self transferCam: lG.
^ cworld 

Our exercice will be very simple. At this lesson we will create a Text-border and to do an script glued to it, where we will create an instance of the Class Private, whose name will be: pr. Look the figure:

IMPORTANT: If you are not understanding nothing that you are seeing it's because you need to read again the: "Basic Tutorial for Beginners.

The code of the script1 is:

 
| pr |
pr:=Private new.
self setCharacters: pr score.

This script will run when the user "mouseEnter" the Text-border, actualizing the value of the score.

We would like that: when the shooter do a "good shot" against the column, the score is increased by 1.

We need to code this (in red) at the stepAt method:

stepAt: currentTime

| dur nCollision|
super step.

 cL4x6x4a ifNotNil:[
 cL4x6x4a logo addRotationAroundY: 1.
 (cL4x6x4afly=1)ifTrue:[
   cL4x6x4abody linearVel:  5@ 5@ -5.
   cL4x6x4abody angularVel:  5@ 0.5@ -5. 
 ]
]. 
	
 wD12x7x1a ifNotNil:[
 wD12x7x1abody  position:28.0@0.50@-26.0.
 wD12x7x1abody rotationAroundZ:0.
]. 

 (shot=1) ifTrue:[
 lG  bullet translation: lG  bullet translation + (lG  bullet localTransform column3*-2). " A good velocity..."

 ((lG bullet distanceTo: lG)>20) ifTrue:[
   lG bullet translation: bulletInitT .
   lG bullet orientation: bulletInitO.
   recS play.
   shot:=0.
  ].
  (cL4x6x4a)ifNotNil:[
   ((lG bullet distanceTo: cL4x6x4a)<4) ifTrue:[ "What to do in the collision"
     cL4x6x4abody linearVel:  5@ 5@ -5.
     cL4x6x4abody angularVel:  5@ 0.5@ -5. 
     expS play.
     Score := Score+1. 
     lG bullet translation: bulletInitT .
     lG bullet orientation: bulletInitO.
     recS play.
     shot:=0.
   ].
  ].
].	
 	
 
space ifNil: [^self  ].
world connect.
space connect.
dur := ((currentTime asFloat) - (prevTime asFloat)) / 1000.
prevTime := currentTime.
sceneObjects do:[:id|
  | each body |
  each := id at:1. 
  body := id at:2.
  each isStepping not ifTrue:[
  each localTransform: body transform transposed.
 ]
 ifFalse:[ 
  body linearVel:  each globalPosition - (body position) * 10.	
  body position: each globalPosition.
  body quaternion: (each quaternion)
 ]
].
space collideDo: [:geom1 :geom2 |  
 nCollision := contacts
 addContact: geom1
 with: geom2
 bounce: 0.1 
 bounceVel: 0.1
 softCFM: 0.1.
 nCollision > 0 ifTrue: [
  wD12x7x1a ifNotNil:[ 
  
  self verifycL4x6x4a. 
 
  (ahead=true & on=0 ) ifTrue:[
   lG translationX: 0 y: -2  z: 0.
  ].
  (ahead=false & on=0 ) ifTrue:[
    lG translationX: 0 y: -2  z: 0.
   ].	
  (ahead=true  & on=1) ifTrue:[
    lG  translation:lG translation + (lG localTransform column3*0.5). 
  ].
  (ahead=false  & on=1 ) ifTrue:[
    lG  translation: lG translation - (lG localTransform column3*0.5). 
  ]. 	 
 
]].
].

world quickStep: dur.  
contacts empty.

Only this... Very easy.




PREVIOUS LESSON NEXT LESSON
T. CONTENTS HOMEPAGE

DISCLAIMER: This material can be translated for any language, and reproduced total or partially by anybody using any type of media. But, please, don't put your name like author. And let me know if it was useful (americo@dmu.com).The use of any code, 3D model or technique published is free and doesn't need to have any reference about this source.The author is not responsible for any damage that the material can cause to your professional or sexual life.