by Timothy Martin, CEO and Editor-in-Chief read it

What aspect of the Web 3D Industry needs more coverage?
interface design

Send your url for review in the VirtuPortal!

Give us your email for regular news & updates

about us
Basic Game Programming in VRML by Steve Guynup
Web 3D artist and guru, Steve Guynup lays out principles and techniques for building games in VRML. Steve shows details about how to use his game PROTOs to create fun, shoot-em up 3D applications for the web.

Shoot’em up type games use the collision between objects to creategame play. The gamer fires a projectile at a target object and upon collision with the target an event is generated. Unfortunately, VRML and most Web3D formats allow for collision and other forms of detection to occur only with the gamer’s avatar. Java is commonly used to fill this void.

Contrary to popular belief, you can trick VRML to appear to have this object collision functionality. The concept is simple: the targets secretly fire back at you when you fire at them. Since you need to properly position or aim yourself at the targets, you fundamentally have the power to re-route that act of positioning so that a secret object does collide with you as your projectile collides with the target. This rule is applicable under wide range of circumstances.

In the 3D Invaders game engine that follows, we have a grey cone, the users firebase. It uses a TouchSensor to follow the movement of the mouse and from it a yellow missile is fired on the touchTime. The target PROTO consists of a red box and a ProximitySensor is positioned higher and forward. Esstentially the sensor is positioned directly above the viewers position. So when the viewer fires up at the red box target, the sensor is fired down at the viewer. Both the red box and the sensor are animated with the same positionInterloper and they move unified manner. The key is that we route the same TouchSensor data that moves the grey cone to the PromixitySensor via a separate Transform node. This node has a rotational value of 0 1 0 3.14. This value inverts it and makes the incoming TouchSensor data move the PromixitySensor in reverse. In the beginning, the unmoving sensor was positioned above the viewer, this reverse action compensates for that change of position. When the grey cone is positioned under the red box, the PromixitySensor is positioned directly above the viewer. Firing activates both the yellow missile upwards animation and the PromixitySensor downwards animation.

About the Code

The game code that follows is a single complete .wrl file. It has all the elements mentioned above. The code has been formatted to minimize its size, unneed spaces and Tabs have been removed. Printed, it runs about three pages. The reader may note seemingly the extra levels of Tranform nodes. These appear because the multiple animative forces are applied at different levels.

An example of a slightly upgrading the game with sound, multiple targets and a game board is linked to at the end of this article. A third example with "proxy shapes" which show the position of the Avatar and ProximitySensor(s) is also linked at the end.

The Proto

Every VRML world begins with the following Header

#VRML V2.0 utf8

The PROTO's first eventIn, set_fireTime, represents the act of firing the missile. (A TouchSensor is the trigger.) The proxyTranslation values are created by moving the firebase via the TouchSensor. This sensor appears later, in the Body Code.

eventIn SFTime set_fireTime
eventIn SFVec3f set_proxyTranslation

The primary animation or behavior is routed to TARGET_ANIMATION01

translation 0 3.5 0

The object you shoot at is defined below as TARGET. Here it is a simple red box, but any conceiveable shape or form could be inlined into the file at this point. Note that the size of the box is one meter cubed, 1 1 1. The ProximitySensor (listed next) is also one meter cubed. A change in the object’s size means that the ProximitySensor size should change accordingly. Multiple sensors could be used to produce more complicated events. Also the animation triggered by a hit is routed here.

DEF TARGET Transform {
translation 0 3.5 0
Shape {
appearance Appearance {
material Material { diffuseColor 1 0 0 } }
geometry Box { size 1 1 1 } }


This is the parent level of the ProximitySensor, TARGET_HITTER. The same animation that moves TARGET_ANIMATION01 also moves TARGET_HIT_ME_MOVER. In addition, the animation triggered by a hit is routed here.

translation 0 0 0
children [

The TARGET_INITIAL_POSITIONER uses the proxyTranslation values brought by the eventIn of the PROTO. The parent Transform has the rotation value of 0 1 0 3.14, and inverts the child TARGET_INITIAL_POSITIONER so that the motion is applied in reverse

Transform {
rotation 0 1 0 3.14
translation 0 4 12
children [

set_translation IS set_proxyTranslation
children [

When the firing mechanism is activated the animation which secretly moves the sensor down torward the viewer is routed to TARGET_HIT_ME

translation 0 0 0
children [

{ size 1 1 1 },


This first set of Clock and PositionInterpolater moves the ProximitySensor when the fire mechanism is activated. The fireTime eventIn is used.

DEF Clock2 TimeSensor {
set_startTime IS set_fireTime
cycleInterval .5
loop FALSE

DEF TARGET_HIT_ME_BLAST_SHAPE PositionInterpolator {
key [ 0.0, 1.0 ]
keyValue [ 0 8 0, 0 -1 0]

Primary animation clock and path

DEF TARGETSPEED TimeSensor { cycleInterval 4 loop TRUE }

DEF TARGETPATH PositionInterpolator {
key [ 0, .5, 1, ]
keyValue [ 3 0 0, -3 0 0, 3 0 0, ]

Animation clock and path activated by TARGET being hit

DEF TARGET_DIE_CLOCK TimeSensor { cycleInterval 5 loop FALSE }

DEF TARGET_DIE_PATH PositionInterpolator {
key [ 0.00, 0.04, 0.11, .96, .9999, 1 ]
keyValue [ 0 3.5 0, 0 7 0, 0 -20 0, 0 0 500, 0 -2.5 -10 0 3.5 0 ]

Routes for all the PROTO’s animations and behaviors

ROUTE Clock2.fraction_changed TO TARGET_HIT_ME_BLAST_SHAPE.set_fraction

ROUTE TARGET_HIT_ME_BLAST_SHAPE.value_changed TO TARGET_HIT_ME.set_translation

ROUTE TARGETSPEED.fraction_changed TO TARGETPATH.set_fraction

ROUTE TARGETPATH.value_changed TO TARGET_ANIMATION01.set_translation

ROUTE TARGETPATH.value_changed TO TARGET_HIT_ME_MOVER.set_translation


ROUTE TARGET_DIE_CLOCK.fraction_changed TO TARGET_DIE_PATH.set_fraction

ROUTE TARGET_DIE_PATH.value_changed TO TARGET_HIT_ME_MOVER.set_translation

ROUTE TARGET_DIE_PATH.value_changed TO TARGET.set_translation


This ends the PROTO target code.

The Body

We start this section with NavigationInfo set to type NONE. The ProximitySensor is positioned relative to the Viewpoint below and if the user moves, the ProximitySensor will miss.

NavigationInfo { type NONE }

DirectionalLight { direction 1.0 -1.5 1}

Viewpoint {
position 0 8 12 orientation 1 0 0 -.45 description "overview"

Use the PROTO. For multiple targets repeat the code using MY_TARGET02, MY_TARGET03 etc. Remember to add additional ROUTEs as well.


WEAPON_SHAPE is the form you weapon takes. At present, a grey cone is used. A child of this Transform is LASERBLAST_SHAPE. This is the missile that is fired upwards an appears to collide with the TARGET. Because it is a child, it is moved as the WEAPON_SHAPE is moved.

children [
Shape {
appearance Appearance {
material Material { diffuseColor .6 .6 .6 }}
geometry Cone { bottomRadius 1 height .9 }}

children [
Shape {
appearance Appearance {
material Material { diffuseColor 1 1 0 }}
geometry Cone { bottomRadius .10 height .6 }}


The code that follows is for the TOUCH TouchSensor. This is the sensor that determines; the movement of the WEAPON_SHAPE, the movement of the ProximitySensor(s) in the PROTO, and is the firing mechanism for the LASERBLAST_SHAPE as well as the ProximitySensor(s) in the PROTO.

The sensor is attached to transparent box that is 10 .1 10 in size. Change the transparency value to .5 to see the range of motion it allows. If you have a gameboard I suggest you inline it here and be careful to position it beneath the TouchSensor box.

Transform {
translation 0 .5 2
children [
Shape {
appearance Appearance {
material Material { transparency 1 }}
geometry Box { size 10 .1 10 }}

DEF TOUCH TouchSensor { },


Animation clock and path for LASERBLAST_SHAPE

DEF Clock2 TimeSensor {
cycleInterval .5
loop FALSE

DEF LASERBLAST PositionInterpolator {
key [ 0, .9999, 1 ]
keyValue [ 0 -.5 0, 0 8 0, 0 16 0 ]

The information from the TOUCH TouchSensor is ROUTED to; WEAPON_SHAPE, LASERBLAST_SHAPE and the MY_TARGET01 PROTO. Further PROTOs will require additional ROUTES

ROUTE TOUCH.touchTime TO Clock2.set_startTime

ROUTE TOUCH.touchTime TO MY_TARGET01.set_fireTime

ROUTE TOUCH.hitPoint_changed TO MY_TARGET01.set_proxyTranslation

ROUTE Clock2.fraction_changed TO LASERBLAST.set_fraction

ROUTE LASERBLAST.value_changed TO LASERBLAST_SHAPE.set_translation

ROUTE TOUCH.hitPoint_changed TO WEAPON_SHAPE.set_translation

End Game

The code presented is only a beginning. More elements and functionality can be added without much difficulty. So enjoy, the code is free.

To play some examples of the game above try:

The Basic Engine ( the code the same as what presented here )

The Advanced Version ( watch for updates )

The Example Version ( proxy shapes added to show the action)

Copyright © 2000 by Steve Guynup TSG ( That Steve Guy ).

Edited by Jean Tam

All rights reserved.

Lastly, this and all my other work is done 100% on a Macintosh G3.

Current features
* Core Web3D Book

* Spazz3D: Authoring-tool
* Game Programming in VRML

Previous Features
* State of the Industry
* The X3D Initiative
* Alphabet Soup: Our glossary of technical acronyms

What do you think of this tutorial?
Not so hot 

What did we miss?

Questions, Comments, and Suggestions about this site can be emailed to: [webmaster]
VirtuWorlds, VirtuWorld, VirtuPortal, and 3DEZine are Trademarks of VIRTUWORLDS LLC.
No unauthorized uses are permitted.
© VirtuWorlds 1999, 2000