Regarding a JavaScript mouse event anomaly I'm having trouble with - javascript

I'm in the process of designing a small RPG-like interface where the user will be given the freedom to create the items and weapons they use. Rest assured, that particular system is thought deeply through and is not the cause of my concern. : )
No, it is something related to the mechanism I have set up for the actual drawing of the user's items. I could try to put the design in words, but it would probably be most beneficial if I just took you there, so click here before continuing.
Not bad, eh? It works practically without flaw in everything but IE (haven't coded for it in years), except for one minor issue; it is, in fact, so minor, that I'm quite certain almost all players would use the interface without ever paying it any attention. I, however, am something of a nitpicker with my own designs, and toiling over this one for hours has, alas, led me here.
So, Stack Overflow JavaScript gurus, a bit of help regarding this issue:
At the moment, there are two ways by which you can inject color into the canvas; you can just click squares individually, or you can drag the mouse and fill in tiles as you go along. Well, give that second option a go. Now, did you notice that, while the dragging most definitely occured, your drag didn't actually initiate until you'd moved out of the square you began in.
Sure, no big deal, just go back and single-click the spot that got missed. And that is definitely something that I wouldn't mind settling with; at this point, though, it's just a matter of understanding why it is the code isn't working exactly as it should. Any help would be greatly appreciated.
Also, a run-down of the algorithm if you aren't able to decipher my code:
global variable md (mouse down) set to 0 at start
document.onmousedown sets md to 1; conversely, onmouseup puts it back at 0
user's currently selected color is stored as an index in cur_color
palette of user's colors stored in palette array
palette[cur_color] references the user's currently selected color
upon moving over a tile, if the mouse is being held down, toggle() function initiates
toggle() compares the backgroundColor of the tile in question with the user's cur_color
if they are different, cur_color overwrites, effectively "painting" that portion of the canvas
this continues until the user has let go of their mouse button
Overall a pretty basic method, but that whole mouse-being-pressed-not-registering-until-one-square-late thing is killing me. Again, assistance with getting to the bottom of this matter would most definitely be appreciated.

It's because you don't call tile_over when mousing down initially. Reading through the steps above you can see that.
Here's a fix, add this to the onmousedown function:
var target = e.target || e.srcElement;
if (target.tagName == 'DIV' && target.className == 'tile') {
tile_over(target);
}
Obviously having a framework to handle getting the targets of mouse events and so forth would make this easier.
You'll need to remove the toggle that occurs when you mouseup without having triggered a mouseover, I didn't bother tracking that down as it should be obvious.

Related

Is there a way to prevent click input from bots?

I have a javascript canvas game with pixi.js that requires a player to press a certain combination of buttons to complete a level. They basically have to press the button that matches a certain color.
It turns out that players are writing bots in python to do this task and they are getting the maxium score each time. The game is already live and users enjoy playing it so I can't really change anything gameplay wise.
So I thought about a few possible solutions but I have some concerns
Captcha between each level
Check the speed of the input
Check how consistent the input is
The captcha will hurt user experience, and there are tons of video's how to bypass it. 2 and 3 will fail after the creators of the bots understand what is happening. So I am really stuck on what I could do.
I would consider a random grace period before allowing the buttons to be clicked. this may stump some bots, but is circumventable.
Besides that, I would profile the timing of the clicks/interactions. Every time next level is requested, compare to the profile, and if they are consistently the same introduce a randomized button id, button shape (circle, oval, square, etc.), button placement (swap buttons) to avoid easy scripting. Also the font and the actual text could be varied.
I would also change the input element to <input type="image"> since it will give you the exact coordinates (if possible - I'm not familiar with pixi.js) and this will aid in the profiling.
You could also implement some sort of mouse position tracker, but people on touchscreens will not produce data for this. You could supplement with additional check if the user input is touch, but a bot would easily be able to circumvent it.
EDIT
I don't know if some library to detect other JavaScript imports and thereby detecting potential bots would be applicable. Might be one avenue to consider.
Doing something like this: Check whether user has a Chrome extension installed to verify that you are running in a browser and not in a python environment could be another avenue. It would mean that you restrict your users to certain browsers, and as a lot of other code, could be circumvented. Cost/benefit should be kept in mind here.
If everything is being run though the actual browser with some sort of headless interface it is not going to be useful at all.
EDIT 2
A quick googling of python automate browser game brings up a tutorial of how to automate browser games with python. based on a cursory glance, making your buttons move around and changing font would be effective, and even resizing the playing area "randomly" (even if you have a full screen function) may be a viable defense. Again, following the tutorial and trying to automate it using that, and seeing how to block it would be a good exercise.
You could also consider asking some students for help. This could be a good project idea for many computer studies courses that offer project based courses. It could also be a student job type deal - if you want to ensure that you get a result and a "report".
I think your approach is valid. It seems a bit excessive to add Capcha between each level, perhaps add it before the game starts.
It might be a good idea to check interval between individual clicks, and define some threshold when you can safely assume that it was a bot who clicked the button.
Another approach you could take is to make it more complicated to look up the correct buttons. Approaches like randomizing the element IDs, not rendering the label inside the buttons but as separate elements (I assume it is a game with some fixed window size and you don't care about mobile that much).
I am not familiar with Pixi.js, but that could be an approach to consider.
----------------------- Edit -----------------------
What if you run your game in an iframe ?

Createjs: Adding mouseover to containers slowsdown FPS

Link 1 - http://horebmultimedia.com/Sam3/
Link 2 - http://horebmultimedia.com/Sam5/
In the above links, i have added a set of numbers added in separate containers in each file and u can find the FPS on the top right. The issue is when i mouse over in this Link 1 and click any numbers, as u see the FPS is getting slower & slower, making the world to rotate slower on the left side.
While on this link, Link 2, I added only one mouse over and 5 mouse over, but there is not much difference in FPS, why it lags so much when i have 37 containers. I can give my code if u need to resolve.
I had a rough look at your code, but digging through an entire project is not a fantastic way to debug an optimization problem.
The first thing to consider is if you have mouseOver enabled on your stage, I would recommend a liberal use of mouseChildren=false on interactive elements, and mouseEnabled=mouseChildren=false on anything not interactive. The rollover could be a big cause, as it requires everything to be drawn 20 times per second (in your usage). Text and vectors can be expensive to redraw.
// Non-interactive elements (block all mouse interactions)
element.mouseEnabled = element.mouseChildren = false;
// Interactive elements (reduce mouse-checking children individually)
element.mouseChildren = false;
If they don't change, you might consider caching text elements, or button graphics. I think I saw some caching in the source - but its generally a good thing to consider.
--
With that said, debugging optimization can be tough.. If removing all the buttons brings your performance up, consider how your buttons are being constructed, and what their cost is.
* Mouse over is expensive
* Vectors and text can be expensive
* Caching can help when used right, but can be expensive if it happens too often.
* Review what is happening on tick(). Sometimes, code is running constantly, which doesn't need to.
--
A few other notes:
This does not do what you think: _oButton.off("mousedown"); -- You need to pass the result of the on() call. If you are just cleaning up, call _oButton.removeAllEventListeners().
You don't need to set the cursor on mouseover. The cursor will only change when it rolls over -- so just set it once, and then get rid of your buttonover stuff.
It might make sense to just extend EventDispatcher for your custom classes, which gives you things like the on() method, which supports a data param. I might recommend this in place of your addEventListener stuff in CTextButton
Note that RAF does not support a framerate property (it just uses the browser's RAF rate, which is usually 60fps). Use createjs.Ticker.timingMode instead of the deprecated useRAF.
Hope that helps a little.

Animation of features in OpenLayers3

I was curious about the possibilities of animating features in OpenLayers3.
I'm very aware of the examples presented here
http://openlayers.org/en/v3.0.0/examples/animation.html and here
https://gis.stackexchange.com/questions/26546/openlayers-animation-examples-and-algorithms
However, the official examples for OL3 don't quite fit my needs.
Let's assume that I have a layer (geojson for instance) that has a "time" column with lots and lots of time values.
I'd like to implement something like a slider that adds/removes features (or changes their style) depending on the user's actions.
The thing is that there are some APIs that might be able to do that, but they seem to be outdated (code examples were still working with ol2).
Do you have any suggestions on how to build a simple animation slider with OL3?
EDIT: It doesn't necessarily have to be proper animation. A possibility that came to my mind is changing the style of a layer whenever the slider is moved. Still no clue though on how to realise that.
This image illustrates what I have in mind:
EDIT: My current approach is to have a slider, that triggers code everytime it is moved. I somehow try do change the layer style dynamically, but I still haven't gotten a viable result.
Ok. I've come up with a solution myself. It's not really a full-fledged animation, but it works for me.
Basically what I do is that I load a wfs-layer to my map.
Now, here is the trick:
When I do that, I simply sort the time-values of the features one by one and add every feature with the time value of 1 to one layer, every feature with a time value of 2 to another and so and so forth.
This basically does the trick. The rest is simple.
Next step is that I implement a slider that ranges from 1 (the lowest time value) to whatever the highest time value is. Everytime the slider is moved it triggers an event that finds out to which time value the slider is set to and then adds/removes the corresponding layers.
So, if the slider is set to 5. It will add every layer from 1 to 5 to the map and remove every other layer. Again, this is not really an animation, but it does work in my case.
If anyone comes up with another possible solution, please post it here. I'd appreciate it.
(Btw, this is what my solution looks like in action:)
EDIT: I can now also confirm that it is possible to build "proper" animations with this approach. I simply built a js-function that includes multiple "setTimeout"s to time when a layer is added and added a play button that triggers this function. This amounts to an animation that visualises the growth from t=1 to tmax.

About Crafty - Isometric and gravity; also fourway

I have two questions about Crafty (I've also asked in their google group community, but it seems very few people look at that).
I've followed this tutorial http://buildnewgames.com/introduction-to-crafty/ and also took a look at the "isometric" demo in crafty's website of a bunch of blocks (http://craftyjs.com/demos/isometric/). And I've been trying some stuff by combining what I've learned in both.
(Q1) When I use the fourway component (used in the tutorial a lot), if I hold the left arrow key for example and CTRL-TAB out the current tab while holding left, and then go back (not necessarily holding left anymore), then the my character seems to get stuck in moving to the "left" direction. It also happens for the other 3 directions. Is that a known issue? Is there anyway to fix it without changing crafty?
It happens here with firefox 29 and chrome 34. My code is pretty much the one in the final version presented at the tutorial's end (it's not the same, but even when it was the same I already had this issue).
By the way, when this happens, if I CTRL-TAB out and back again holding that left key, things go back to normal (the movement stops).
(Q2) The isometric-ish features interprets Z as being height, and the gravity component uses Y for height. Isn't this a problem? Can I, maybe, for example, tell gravity to use something else, other than y, for height?
Regarding (Q1), the movement is managed by keydown and keyup events. If you change the tab when the start of a movement was triggered, the fourway component never gets any keyup event to stop again. You could use a workaround like the following:
Crafty.settings.modify("autoPause", true);
Enabling autoPause (somewhere in your init function) will pause your game when the browser tab crafty is running in is inactive. You can then react to this event by triggering keyup events or preventing the player component to move like this:
player.bind('Pause', function() {
this.disableControl();
});
player.bind('Unpause', function() {
this.enableControl();
});
You might want to stop animation there too if you handle that in your player component..

Is processing.js a good option to implement this idea?

I've been gathering ideas for my personal project in CSS/JavaScript/XHTML.
The idea is to replicate this:
And so far I have this (I know it's far away from what I need, but just playing around)
http://jsfiddle.net/dburelax/XY8CA/9/
I was wondering if http:// processingjs.org/exhibition/ is my best choice to get this done in javascript? Thanks
P.S: I have no idea how to make the character move within the tiles any suggestions are welcome :)
I'd say light years away. But don't take it as sarcasm; let me explain.
What I see when I look at the gif is an engine that supports block "primitives".
Because, you see, every time he hovers a tile with the pointer it gets decorated with a white border.
In your case, you just have two images:
A map background
A gif of sprites for the character (without his back or sideway, but let's just forget that for now).
With these two in order to achieve the block highlighting you should always calculate offset, and apply image filters on the background with the border decoration (and shadows and what not). Then, when moving outside the box remove decoration the last window.
After that what do you do if you change box size? Recalibrate all offsets? What if you have boxes/bocks (I'll call them interchangeably now) in mixed sizes?
In game engines particularly you have primitives such as boxes, where you can detect collisions and either allow passage or not from the colliding box (a character is a box as well). Think how this would be practical if you for example had "fog of war" and allowed vision only in adjacent boxes.
It's not just about processing.js, which may or may not be helpful to you, but there are key bindings, character movement, character orientation to be thought about first.
I don't know about you, but I wouldn't be able to encode all that information in Javascript objects and still have it performant. Not with current Javascript engines, at least.
While your hobby project is a fun idea, there is much much more you have to learn first to be able to pull this off.
In the case I have offended, take but this and all is mended -- The Goblin
If this is in the scope of learning programming, while having a project to keep you motivated; then go for it (use the path I've deemed hard), learn first how to move images on the HTML5 canvas and when having actual code problems come back.

Categories