Jump to content
  • Advertisement
Sign in to follow this  
JimPrice

[web] Javascript : binding parameters to functions and general practices

This topic is 4803 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all, two questions for you today, one technical and one practical. Sorry for the length. I am playing with a browser-based game, and am currently writing a vehicle designer. The vehicle design is simple, and works as follows:
  • Every vehicle starts with a chassis.
  • Each chassis has a number of spaces.
  • Each space can take a certain kind of component, of a certain maximum size.
For example, a "light chassis" may have 2 spaces; a 1-slot engine space, and a 1-slot weapon space. So it can carry a "light engine", which only occupies 1-slot, but not a "medium engine", which is too big at 2-slots. It also can't carrry a "short-range radar", which is only 1-slot, but is of type "system". The design page looks something as follows:

(1)
Chassis : [selection box here]

(2)                                    (3)
Engine : [selection box here]          Light engine; takes 1 slot, provides speed 10
Weapon : [selection box here]





There are 3 main components here; the chassis selection box (1), the list of available spaces (and options) (2), and a description of component currently being examined (3). The chassis selection box is responsible for dictating what spaces appear in (2). When a different chassis is selected, area (2) updates with the information for that chassis. The information in area (3) depends upon the last selected option (from any select box) from area (2). So, if a player chooses the "light chassis" above, he might get a list of 2 available engines, and 4 available weapons. If he then chooses an engine from the engine select box, detailed information appears in (3). If he then chooses a weapon from the weapon selection box, the information in area (3) is updated with that weapons information. Still with me? So, let's look at some code:
// This div contains the chassis select box
// When the value changes, the options in id=chassisSpaces change
// In practice, this is all done dynamically through PHP and SQL
<div id = "chassisSelect">
 Chassis : 
 <select onchange = "UpdateComponentSlots(document.getElementById("chassisSpaces"));">
  <option value = "1">Chassis 1</select>
  <option value = "2">Chassis 2</select>
 </select>

</div>

// This div is a set of select boxes; actual boxes change depending upon chassis selected above
<div id = "chassisSpaces">
 
</div>


// At any given time, one select box is in focus, with one item selected - this is a description of that item
<div id = "description">
 
</div>



This is fairly obviously the basic HTML structure for the page as described above. In order to make it come alive, we need to add the required javascript functions, as follows:
// General purpose node-clearing - is there a more elegant way to do this?
function clearNode(node)
{
 var kids = node.childNodes;
 var numKids = kids.length;

 for(var i = numKids - [[[1]]]; i >= [[[0]]]; --i)
 { 
  node.removeChild(kids);
 }
}


function UpdateComponentSlots(node)
{
// First clear out the current text in componentSlot
 clearNode(node);

// Loop over each of the spaces of this chassis - in practice this is all picked up with PHP and SQL
// Just assume we have picked up the chassis type, and any unreferenced variables have their natural interpretation
 for(var loopOverSpaces = [[[0]]]; loopOverSpaces < totalSpaces; ++loopOverSpaces)
 {

// A bit of text to describe the space type - again, dummy code
  var newText = document.createTextNode("SpaceType : ");
  node.appendChild(newText);

// Set up our selection box
  var selectBox = document.createElement("select");

//
// THESE [[[2]]] LINES DIRECTLY RELATE TO THE QUESTION
//
  selectBox.setAttribute("id", "selectSpace" + loopOverSpaces);
  selectBox.onchange = GetComponentInfo;

// Identify the required component type - again, this is a slightly fudged line, but you should get the idea
// please ignore the references to this; that's what happens when you change code to make it simpler for a question on gamedev - hopefully the intent is clear!
  var thisSpace = this.GetSpace();

// Now find everything that will fit in that space - this.componentsList_ is just a list of every possible component
// Yes there are better containers for this job :)
// Note also I'm ignoring the type requirements here as well
  for(var i = [[[0]]]; i < this.ComponentsList_.length; ++i)
  {
   if(this.componentsList_.slots_ <= thisSpace.slots_)
   {
    var optionText = new Option(this.componentsList_.name_, this.componentsList_.techid_);
    selectBox.add(optionText);
   }
  }

// Finally add it to the form
  node.appendChild(selectBox);
 }
}



(Finally) we get to the crux of the question. Buried in the previous function is a call to GetComponentInfo. This function does the following:
  • Clears out the id=description box
  • Fills it again with a description of the component currently being played with, which will be one of the select boxes in id = chassisSelect
The component being described depends upon which select box the function was called from in UpdateComponentSlots. When I wrote my initial dummy code I did this simply by calling the function with a parameter; so something like:
function GetComponentInfo(which)
{ 
 clearNode(document.getElementById("description"));

 var whichBox = document.getElementById("space" + which);
// Now loop through the options of this container and print a description of the one selected
}



However, binding a parameter to the function using the code above is where my problem lies. I can't use: selectBox.onchange = GetComponentInfo(loopOverSpaces) as this doesn't bind the function to the onchange handler. The only option I can see is to loop through all the child nodes of div container id=chassisSelect, find which is in focus, and then work from there. Is there a better way? Second question: As my web-programming gets more complex, I find I as using a mix of HTML, PHP, javascript and SQL. This can get moderately confusing at times (different syntaxes, grrr). My approach has been to write a simple HTML script that approximates what I want to start with, then add the javascript that gives the required effect, then add the PHP and SQL as a final step. Does anyone have any suggested working practices for working on complex scripts? Hope some of that's clear :) Jim. [Edited by - JimPrice on September 14, 2005 11:07:07 AM]

Share this post


Link to post
Share on other sites
Advertisement

Example code to nuke all the child nodes:

while (board.firstChild) {
board.removeChild(board.firstChild);
}

Example code to loop over all the 'computed' styles, meaning all styles whether set locally or inherited from a parent:

var style = document.defaultView.getComputedstyle(document.getElementsByTagName("body")[0], '');
var dont = { 'left' : true, 'top' : true, 'width' : true, 'height' : true }
for (var i = 0; i < style.length; ++i) {
var s = style.item(i);
if (!(s in dont)) iframe.body.style[s] = style[s];
}

Cheers!
Roy
http://www.p2pmud.com

Share this post


Link to post
Share on other sites
Check out these two libraries:

Prototype.js
http://prototype.conio.net/
http://www.sergiopereira.com/articles/prototype.js.html - good docs for it

Behavior.js
http://bennolan.com/behaviour/

Behavior needs the Prototype library to function (which is an awesome library on its own as well) and it allows you to do all sorts of cool behavior bindings and they both function well cross-browser.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!