1

I've been trying to create a game in strictly HTML5 and JavaScript and have run into an issue that I can't seem to wrap my head around. In an attempt to try and avoid using third party classes/libraries, I'm creating my own class for handling custom buttons within the HTML5 canvas element. I almost got them to work and then had to re-write most of the script after realizing that my event listeners kept adding on top of each other every time the canvas redrew (I was using an anonymous function in the mouseDown event listener before, but have since switched to a different method).

First of all, my event listeners now use a function which holds a reference to whichever button I'm trying to use. My prototype's mouseDownFunc is then called, it checks the boundary of the button instance's dimensions, and then finally calls a referenced onPress() (which is actually an overridden method that every button uses, so each button has a custom set of instructions when pressed).

So, if you're still following along (I know, it's a bit confusing without seeing the full script), the problem is that because my event listeners are using the same function, they're overwriting the previous event listener, so only the last button added functions correctly. To sum this all up, how can I add multiple event listeners to the canvas element, which all use the same function without erasing the previous event listeners. Note that I'm trying to do this without the use of jQuery or other third-party extensions.

If more information is needed in regards to my code so that it's easier to understand, let me know. Thanks in advance for any type of feedback.


Edit: Perhaps this might help. Note that this isn't the complete code, but contains the main points:

Adding a button:

this.test_button = new CreateButton(this, 'test_button');
this.test_button.onPress = function() {
    alert('Blue button works!');
};
this.test_button.create(200, 50, 30, 200, 'text');

When using create() on a button, variables are checked and stored, as well as an array that holds onto all current buttons (so they can be referenced at any point). Then this is run: this.that.custom_canvas.addEventListener('mousedown', this.create.prototype.mouseDownFunc, false);

When mouseDownFunc is called, this takes place:

CreateButton.prototype.create.prototype.mouseDownFunc = function(e) {
    var mouse_x = e.clientX-this.offsetLeft;
    var mouse_y = e.clientY-this.offsetTop;

    // Check if the mini-button button was actually clicked
    if(mouse_x >= test2.x && mouse_y >= test2.y && mouse_x <= (test2.x + test2.width) && mouse_y <= (test2.y + test2.height)){
        alert('clicked and working!');
        test2.onPress(); // A reference to the saved function
    }
};

Currently, my test2 is a reference to any given object -- it's a global var, but after I get these other issues fixed, I'll deal with getting rid of the global var (I know, I know - it was just a temporary quick-fix).

2
  • Fair enough; I updated my post. Commented Mar 3, 2011 at 17:59
  • Your explicit references of the prototype looks suspicious. "this.create.prototype.mouseDownFunc" as an explicit callback and the "CreateButton.prototype.create.prototype.mouseDownFunc" declaration doesn't make much sense. I suspect you may be overriding the prototype function on each button instance. That is why "last one wins" is a bug. Commented Mar 3, 2011 at 18:19

2 Answers 2

2

Maybe instead of an event listener for each and every possible button, and checking box size within the function, you could create a single event that calls a routing function to check where on the element the event occurred, and then delegate to another function

Sign up to request clarification or add additional context in comments.

2 Comments

Hmmm, perhaps this might be the best answer. I thought about this before, but I thought there were some drawbacks to this method -- however, I can't think of any right now, so perhaps I'll give it a go.
This answer I gave to someone else the other type may be similar to your issue: stackoverflow.com/questions/5139093/…
0

You need to design something to handle the event dispatch in your program. You seem to have components that have their listeners all disorganized. You could build a tree data structure (https://en.wikipedia.org/wiki/Tree_%28data_structure%29) that is a hierarchy for the event dispatch in your components ( such as buttons, text areas etc.). The idea is that when the tree is traversed the events will be handled in an ordered fashion. The tree would be reorganized based on how the user interacts with your program. For a simple example, to start this tree could perhaps prioritize the most recently drawn component (out of some structure that holds a list of everything to be drawn) as the event listener to receive event handling first. Then, if a component is blocked by another component the blocked component (like a button covering the button) it's event handling could either be disabled or scheduled to happen later depending on your implementation. Of course your implementation may be more complex, but you need to keep track the event handling. Java uses a component heirarchy data structure to handle a wide variety of GUI events that you can learn more about here http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.