Jump to content

Designing JS Game


Nohana

Recommended Posts

Hello,I figured I might still find some annoying problems with my JS game, and because I'll be designing a second game soon, I decided to make this thread to put all my "Game-related" questions here, instead of creating a multitude of random threads that deal with specific problems. Hope this is okay. 'ω'I have the following function but it won't run properly because of the way I'm trying to get to modify the element events. Just how do I do it? I assume there's something before the event type, like: document.getElementById().Event.eventType, but I'm not sure. I googled for an answer but found none. Any help is greatly appreciated. :)

function Dig(id){	alert("Digging...");	document.getElementBy(id).onmousedown = "";	document.getElementBy(id).onmouseup = "";	document.getElementBy(id).onmouseout = "";	COUNTER_digs++;	alert("You dug here!");

Link to comment
Share on other sites

Hi. If you want to use document.getElementById() properly you should put the proper id's that you want inside the parantheses. It could look like document.getElementById(digspot1).onclick. If you wanted all of those id's to be the same, then use a variable like this:

var digspot = document.getElementById(digspot1);digspot.onmousedown = function newfunction {}

I would put a function in there whether it is a function you have already created or a function you design there.

Link to comment
Share on other sites

Is digspot.onmousedown = function newfunction {} (Empty function is that right?) any different from document.getElementById("disgpot1").onmousedown? Anyway tried both:

function Dig(id){	alert("Digging...");	var tile = document.getElementBy(id);	tile.onmousedown = function EmptyFunction() {};	tile.onmouseup = function EmptyFunction() {};	tile.onmouseout = function EmptyFunction() {};	COUNTER_digs++;	alert("You dug here!");

function Dig(id){	alert("Digging...");	var tile = document.getElementBy(id);	tile.onmousedown = "";	tile.onmouseup = "";	tile.onmouseout = "";	COUNTER_digs++;	alert("You dug here!");

Doesn't work. >_<It's definitely the way to access the event attribute that's wrong. I just don't know how to do it.

Link to comment
Share on other sites

No first of all. getElementById(someid) ... don't put (id) in parantheses.secondly, the empty function you have is what is going to happen when you click the thing. So if it is empty nothing is happening.Perhaps you could explain to me what you what to happen on each of these events when the function is called? I may then be able to show you a code that would do that.

Link to comment
Share on other sites

Thanks. Fixed the problem. Now I got a new one, haha. Making JS games is such a pain. :)

function getTrace( x,y ) {	var i,  ,yd;	var good = false;	var bad = false;	for ( i = 1; i <= 4; i++ )	{		if( good == true && bad = false ) return ("g"+i+".gif");		if( good == false && bad = true ) return ("b"+i+".gif");		if( good == true && bad = true ) return ("n"+i+".gif");	}	return ("0.gif");}

Okay, code won't run. I know the buggy part is with the for block... If I turn the if's into a comment, the code goes smoothly. :/(Never mind... figured it. I really, really, really hate JS) >_<

Link to comment
Share on other sites

		txt = txt.replace(/onmousedown=\"VoidFunction()\"/g, "onmousedown=\"PressButton(id)\"");

This piece of code doesn't work... Can anyone help me out? :)Strangely, when I switch from /onmousedown=\"VoidFunction()\"/g to "onmousedown=\"VoidFunction()\"" the code works, but only for the first match it finds. I want it to do a global search and replace all instances of "onmousedown=\"VoidFunction()\"" . How can I do that? No iteration please, that's running away from the problem lol.(Additional note)I just tried

txt = txt.replace(/src="button1.png"/g, "src=\"g_bullion.gif\"");

And it works like charm.

txt = txt.replace(/onmousedown="VoidFunction()"/g, "onmousedown=\"PressButton(id)\"");

However doesn't work at all. Both codes look the same except for their content... Any ideas? :/

Link to comment
Share on other sites

Parentheses define a group in regular expressions. You might try changing your expression from this:

/onmousedown="VoidFunction()"/g

to this:

/onmousedown="VoidFunction\(\)"/g

Link to comment
Share on other sites

Thanks. Haha. I figured it had something to do with the parentheses. :)Now I have a small second problem...

function setButtonState( state ) {	if ( state == "disable" )	{		var txt;		txt = document.getElementById("map").innerHTML;		txt.replace(/onmousedown="PressButton\(id\)"/g, "onmousedown=\"VoidFunction()\"" );		txt.replace(/onmouseup="Dig\(id\)"/g, "onmouseup=\"VoidFunction()\"" );		txt.replace(/onmouseout="UnpressButton\(id\)"/g, "onmouseout=\"VoidFunction()\"" );		txt.replace(/cursor: pointer/g, "cursor: default" );		document.getElementById("map").innerHTML = txt;		alert("OFF");	} else if (state == "enable" )	{		var txt;		txt = document.getElementById("map").innerHTML;		txt = txt.replace(/onmousedown="VoidFunction\(\)"/g, "onmousedown=\"PressButton(id)\"");		txt = txt.replace(/onmouseup="VoidFunction\(\)"/g, "onmouseup=\"Dig(id)\"" );		txt = txt.replace(/onmouseout="VoidFunction\(\)"/g, "onmouseout=\"UnpressButton(id)\"" );		txt = txt.replace(/cursor: default/g, "cursor: pointer" ); 		document.getElementById("map").innerHTML = txt;		alert("ON");	} }

This is my function. It works fine for if( state == "enable" ), however for if(state == "disable" ) it gets really buggy and I can't even imagine why. This code is supposed to assign all onmousedown, onmouseup, onmouseup to a specific function when the state is "enable" and assign VoidFunction() when the state is "disable". Basically speaking, the first if block is just the opposite of the second block. They do opposite things. I've checked this code over several times, I've tried to remove the parentheses in VoidFunction all over my JS file to see if it helps, trying to catch where the problem is occuring but all in vain. The damn code just won't run as intended and I have no clue why. Any help/advice is greatly appreciated. :/Note: I'm not sure if this helps, but I figured any bit of information would come in handy. The specific bug that I get is that my elements in txt (which are images used as a button) which should be updated with the setButtonState(state) function don't change at all when I switch from "enable" to "disable". On the contrary, the updated images (buttons) start to change their src when I hover my mouse over them, the cursor remains the same, and they still respond to onmousedown/onmouseup events when they shouldn't, and god knows why. I hope you can safely ignore this part if it's too complicated. lol :)

Link to comment
Share on other sites

A more standardized way of doing what you are doing would be something along the lines of the following:

function setButtonState(enabled){	var el = document.getElementById("map");		if(enabled)	{		el.onmousedown = function() { PressButton(this); }		el.onmouseup = function() { Dig(this); }		el.onmouseout = function() { UnpressButton(this); }		el.style.cursor = "pointer";		alert("ON");	}	else	{		el.onmousedown = VoidFunction;		el.onmouseup = VoidFunction;		el.onmouseout = VoidFunction;		el.style.cursor = "default";		alert("OFF");	}}

Then, rather than passing "enable" and "disable", you'd pass true for enabled and false for disabled. Also, in the case of the PressButton(id), Dig(id), and UnpressButton(id) functions, rather than pass the id, pass the this keyword and modify your functions like so:

function Dig(tile){	...}

rather than:

function Dig(id){	var tile = document.getElementById(id);	...}

Link to comment
Share on other sites

I think you might be misunderstanding what I want to do. I'm not trying to change the event attributes for a single element, what I want is to replace specific sections that occur multiple times within a very large string. If you look at my code, the variable txt stores innerHTML of "map", that is, I'm not interested in "map" itself, I want its content only. I don't know if it helps but I'll post below a small portion of string txt to give a better idea of what I want:

<img id="1" class="button" src="button1.png" onmousedown="VoidFunction()" onmouseup="VoidFunction()" onmouseout="VoidFunction()" style="left: 0px; top: 0px; cursor: default" /><img id="2" class="button" src="button1.png" onmousedown="VoidFunction()" onmouseup="VoidFunction()" onmouseout="VoidFunction()" style="left: 16px; top: 0px; cursor: default" /><img id="3" class="button" src="button1.png" onmousedown="VoidFunction()" onmouseup="VoidFunction()" onmouseout="VoidFunction()" style="left: 32px; top: 0px; cursor: default" /><img id="4" class="button" src="button1.png" onmousedown="VoidFunction()" onmouseup="VoidFunction()" onmouseout="VoidFunction()" style="left: 48px; top: 0px; cursor: default" /><img id="5" class="button" src="button1.png" onmousedown="VoidFunction()" onmouseup="VoidFunction()" onmouseout="VoidFunction()" style="left: 64px; top: 0px; cursor: default" /><img id="6" class="button" src="button1.png" onmousedown="VoidFunction()" onmouseup="VoidFunction()" onmouseout="VoidFunction()" style="left: 80px; top: 0px; cursor: default" /><img id="7" class="button" src="button1.png" onmousedown="VoidFunction()" onmouseup="VoidFunction()" onmouseout="VoidFunction()" style="left: 96px; top: 0px; cursor: default" />

This is but a tiny part of my string stored in txt, it goes all the way up to 144. On your given example you're directly modifying an html element, however, in my case I can't afford this option since it takes way longer than just modifying a string, not to mention its heavy toll on the browser, plus, I have 144 objects, if I were to modify them one by one it would take ages for the code to complete its task. The setButtonState() function is supposed to be called several times while the game is running, and I definitely don't want it to take more than half a second to update the image elements I have in txt.My code is okay in theory.... It should work fine for what I want. Like I said, the if( state == "enable" ) works perfectly. The problem is with the if(state=="false") block, which for some reason doesn't replace the events properly, which is leading to faulty results. When I look at both blocks, they look identical... I'm falling to grasp what's wrong with the first one though. That's where I need some help or maybe a simpler alternative that would produce the same result at same cost.Btw, I did replace the ( state == "enable" ) with ( state == true ). Yeah, it's better this way indeed. :)(update)This is what I'm getting from the if( state == false) block:

<img id="1" class="button" src="button1.png" onmousedown="PressButton(id)" onmouseup="Dig(id)" onmouseout="UnpressButton(id)" style="left: 0px; top: 0px; cursor: pointer;">

There's this fishy ";" at the end... but I doubt it's what's causing such a ruckus.

Link to comment
Share on other sites

Update:After analyzing the string txt, I have finally reached the ultimate problem in my code. It has nothing to do with the if true/false blocks as I previously thought, in fact it has to do with Javascript itself.To keep the problem brief and simple I will stick to the basics. I have the following element which appears several time within my <div> (for simplicity's sake, you can assume there's only one <img> inside <div>):

<img id="1" class="button" src="button1.png" onmousedown="VoidFunction()" onmouseup="VoidFunction()" onmouseout="VoidFunction()" style="left: 0px; top: 0px; cursor: default" />

As you can see, this <img> element doesn't produce any particular results when you click on it, and in fact it's not supposed to at all. So far, so good.When the user (player) clicks the "Start game" button, the previous <img> element changes to:

<img id="1" class="button" src="button1.png" onmousedown="PressButton(id)" onmouseup="Dig(id)" onmouseout="UnpressButton(id)" style="left: 0px; top: 0px; cursor: pointer;">

Now the user is able to click the <img> element which behaves more or less like a button.After the user clicks on <img>, it calls the function Dig(id) which should turn the <img> into this:

<img id="1" class="button" src="item.png" onmousedown="VoidFunction()" onmouseup="VoidFunction()" onmouseout="VoidFunction()" style="left: 0px; top: 0px; cursor: default" />

(This is where the headache begins...)Now the user shouldn't be able to click on <img> anymore. So far all works well, the problem is with my Dig(id) function:

function Dig(id){	document.getElementById(id).onmousedown = VoidFunction;	document.getElementById(id).onmouseup = VoidFunction;	document.getElementById(id).onmouseout = VoidFunction;	document.getElementById(id).style.cursor = "default";	COUNTER_digs++;

From my experience with JS, I'd naturally thought that document.getElementById(id).onmousedown = VoidFunction; would explicitly change the element's event attribute, and thus the content of my <div>'s innerHTML, much like calling its src explicitly changes the source of the element, that it is, should I call innerHTML of my <div> after assigning my element a new src, I'll get a different string. But this doesn't happen at all with document.getElementById(id).onmousedown = VoidFunction; (god knows why)! The damn thing changes but only implicitly, that is, I can't click on <img> anymore, as intended, but when I retrieve my <div>'s innerHTML, I get:

<img id="1" class="button" src="item.png" onmousedown="PressButton(id)" onmouseup="Dig(id)" onmouseout="UnpressButton(id)" style="left: 0px; top: 0px; cursor: default;">

(What are those three stupid functions doing here??? I erased them didn't I?)When I SHOULD get:

<img id="1" class="button" src="item.png" onmousedown="VoidFunction()" onmouseup="VoidFunction()" onmouseout="VoidFunction()" style="left: 0px; top: 0px; cursor: default;">

Note the the cursor display changes as expected, but the problem is with the event attributes.Just how can I change them so the change is reflected inside my <div>'s innerHTML? I hope this is not too confusing. :/

Link to comment
Share on other sites

To further my example of how to do this in a more standardized way, you could do something like this:

function setButtonState(enabled){	var el = document.getElementById("map");	var images = el.getElementsByTagName("img");	for(var i = 0; i < images.length; i++)	{		if(enabled)		{			images[i].onmousedown = function() { PressButton(this); }			images[i].onmouseup = function() { Dig(this); }			images[i].onmouseout = function() { UnpressButton(this); }			images[i].style.cursor = "pointer";			alert("ON");		}		else		{			images[i].onmousedown = VoidFunction;			images[i].onmouseup = VoidFunction;			images[i].onmouseout = VoidFunction;			images[i].style.cursor = "default";			alert("OFF");		}	}}

However, to help you with your specific problem, I believe you want to do something like this:

<img id="1" class="button" src="button1.png" onmousedown="PressButton(this.id)" onmouseup="Dig(this.id)" onmouseout="UnpressButton(this.id)" style="left: 0px; top: 0px; cursor: pointer;">

The problem, it seems to me, is that "id" isn't defined as anything. "this.id", however, is the id of the image element that would be passed to your functions.

Link to comment
Share on other sites

But that's resorting to an iteration. In addition to that, you're directly accessing many elements at a time which I want to avoid. And noting what I said in my 2nd post. The problem is with the function Dig(id). It does modify the event attributes of my elements, but only "behind the scenes", I can't see the change when I call my <div>'s innerHTML.Is there another way of accessing event attributes and modifying them other than document.getElementById("").event? Or even better, is there a way to access all attributes of an element with just one go? For example, when you can getElementById().innerHTML, you get the element's content, but I want its attributes, everything that goes between the brackets (id, class, width, src, etc). This way I'd be sure to be modifying its events and getting the result in my <div>'s content (which I want as a string).

Link to comment
Share on other sites

1. Changing an element's attributes, like an onmousedown handler, does not necessarily update the element's innerHTML. As a javascript object, the element's attributes have in fact changed. But there is no reason the innerHTML has to reflect this. The DOM will reflect the change, and that's all that matters.2. About this VoidFunction I keep reading about -- do you actually have such a function? All you really need is something like onmousedown = null

Link to comment
Share on other sites

1. So there's no way to get this change to appear on my innerHTML, correct? I take the only way to do this would be for me pass the innerHTML as a string to some variable then edit it as a string and repass it back to the containing element. Anyways, I've managed to rid myself of the problem with the innerHTML and event handler. Though it's not perfect, it satisfies its purpose in my game. 2. Haha, yeah sometimes I do silly things. I didn't think of using 'null'. Would changing this make any impact on my code? I'm not sure if I want to go through the trouble taking out all the calls to VoidFunction(), but if that gives some advantage, I will do so. :/Lastly, as I'm done with this project of mine, I need to just get through with one last problem.Is it possible for me to both use JS script from a file and include separate JS blocks within the <body> part of my html file?I'm trying to have a small script turn a <div> invisible when the user's finished loading the document, but whenever I add a JS block in my <body> section, all CSS styles seem to be overlooked and everything goes out of place.I also did some experiment with the following code and the first JS block in <body> is ignored altogether:

<html><script type="text/javascript" src="file.js"></ script><body><p>Some text...</p><script type="text/javascript">alert("hello world!");</script><p>Some more text</p><script type="text/javascript">document.body.bgColor = "red";</script></body></html>

So, is it impossible to have both script from a file and have separate blocks?

Link to comment
Share on other sites

Sure. Now, you're not going to believe this, but depending on your browser, the little space in your closing script tag may screw up your whole page. It certainly does in Firefox 3. I mean this one:

</ script>  ^delete this space

Also, if you want to mess with background colors and stuff, use the correct javascript interface with CSS. EG, not this:document.body.bgColor = "red";but this:document.body.style.backgroundColor = "red";The old way could lose support without warning.

Link to comment
Share on other sites

Last problem I think... I have a certain function within another function and I need it to be run every 100 ms when ClearGameTextEffect() is called.

function ClearGameTextEffect(){	var counter = 0;	colors();			function colors()	{		document.getElementById("scoreText").innerHTML = counter;		counter++;		t2 = setTimeout( "colors()", 100 );	}	}

The code stops at t2 = setTimeout( "colors()", 100 );. I suppose you cannot or perhaps this is not the right way to call a function that is inside another function. Just how can I get this to work? :)Thanks again for all the help, guys. Really appreciate it. :)

Link to comment
Share on other sites

I don't think putting the function inside the other one is going to work well. What's the disadvantage of putting it outside? A function won't run until it's called. And you'll have to make the counter variable global.Another thing: The code will be more efficient if you don't force the setTimeout to evaluate en expression. Since the function has no parameters just call it like this: setTimeout(colors,100)

var counter;function colors(){	document.getElementById("scoreText").innerHTML = counter;	counter++;	t2 = setTimeout( colors, 100 );}	function ClearGameTextEffect(){	counter = 0;	colors();}

Link to comment
Share on other sites

For me the only disadvantage would be I'd have to rename some variables... It's not obvious maybe, but I just replaced the actual content of my function with this counter thing, the actual function does something a little more complicated using some dozen of variables, thus why I'd prefer to keep the variables in the scope of a function rather than having global variables which I will only need for this particular code. :)I thought already of putting the function outside, though I'm wondering, is there no way to use a function from within a function? This is possible in Java, so I thought it'd work in JS as well. It's not a big deal in any case, I can place it outside if it ain't worth the hassle working with functions within functions. Also, thanks for the input on the parameter part. I didn't know this was possible at all, haha. :)(small update)Second Question: Is it possible to capture specific key presses (from keyboard) with javascript? For instance is it possible for me to set an event to occur whenever some x key is pressed?

Link to comment
Share on other sites

I managed to get things to work as intended regarding the inside function.

function ClearGameTextEffect(){	//do something		colors();			function colors()	{		//do something		t2 = setTimeout( colors, 10 );	}	}

What I did was replace the parameter "colors()" (a string) in setTimeout with colors as shown above. But I'm still failing to grasp why it works one way but not another. Can anyone shed some light onto this? I'd feel safer after understanding the difference between directly passing function calls and passing them as a string. :)And my second question stands (lol). I did some googling and found some interesting results, but I'd appreciate some advice on the best way to handle key presses.

Link to comment
Share on other sites

Most likely because it's being called locally. If you call "colors()" as a string you're calling the function from the top level of the program rater than from inside the function.I'm not exactly sure how you would call it from outside, but I think it would be something like this:

ClearGameTextEffect.colors();

I don't know for sure, because I've never called a function that was inside a function before.By the way, I'm not sure if it was given in an example or something, but you don't need to add //do something in all your functions. That's just a comment.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...