Open itsOgden opened 10 years ago
Hi @itsOgden,
yes you could do that within the handleInput
of your game method and iterate through inputPoints = ig.input.getInputPoints(['tapped'], [true]);
like it does in the original method:
https://github.com/collinhover/impactplusplus/blob/dev/lib/plusplus/core/game.js#L2210
So this console.log()
won't show up for you?
javascript
handleInput: function(){
this.parent();
if (ig.input.released('tap')) {
console.log('I should show up in the console :O');
}
}
@Pattentrick, Unfortunately, it does not, which is extremely weird! As of right now, the only way I've been able to get touch input to work is by an entity extending from UIButton
using activateComplete()
or by using update()
. In the case of the update I've had trouble registering the proper inputPoints
. It's been rather frustrating.
I've been able to get around it up until now, but I've reach a point where I need to be able to hold & tap and it can't be on UI elements.
That's strange! Could you provide a small demo of your project and upload it to GitHub, or to another place? I am AFK for the next few hours, but once I am back I could look at your code and we may figure out together what's going on.
That would be very helpful! A demo of what I currently have can be found here: http://itsogden.com/kcdevtemp/. I uploaded the project to github so you can look at it here: https://github.com/itsOgden/KillerColors
Demo controls: Move through "blob" queue with WASD, hold SHIFT and move with WASD to mix "blob" colors. Click on the grid to throw "blobs".
Don't judge, it still has a long way to go :)
Have you tried adding the following to your clickable entities?
...
targetable: true,
initTypes: function() {
this.parent();
_ut.addType(ig.EntityExtended, this, 'type', "INTERACTIVE");
},
...
Also, your demo project on github has the ImpactJS source code in it. You should delete the github repo and upload it without the source code.
Thanks @collinhover, I completely forgot about that. I've never put a project up in any way so I didn't even think about it. Good catch.
Unfortunately, no dice on your addition. Even with that, it still will only work with the update.
@itsOgden I get an 404 error when I am trying to get a local copy of your game running in my browser. The file that is missing is named lib/impact/gaPooling.js
. Is this a plugin, or part of an older ImpactJS release? By the way, I am using version 1.23.
@collinhover What is the story behind INTERACTIVE
in additon to targetable
? Does this result in calling the activate
method of the entitiy once it get's tapped/clicked?
Offtopic:
That really not belongs here, but I found a special piece of code yesterday that I have to share.
[2,3,4][+true]
Will return 3
by the way. Good cryptic way to retrieve an item from an array xD
Woops! It's a plugin that I forgot not to delete. I added it back and it should be good to go now.
On the off topic: How exactly does that work? I'm trying to figure it out and I'm stumped lol
@itsOgden Great, works now! I will have a closer look at your code in a few hours. I am more into pixelart for myself, but i really love the smooth animation of your player. Also I kind of like the idea to select certain colors to defeat a specific monster. This has potential and is quite good for a first demo.
About the cryptic code: since JS is loosely typed, the interpreter will try to convert other values, that are not a number, to a number if you want to calculate with them. For example, true will be converted to 1, and false to 0. So true + true + 3
will be 5
. And + true
becomes 1.
So the [2,3,4][+true]
is a very "creative" way to do this:
javascript
var arr = [2,3,4];
arr[1] // gets the second item of arr
Haha that's fantastic. Does it have any practical applications?
And thanks for the compliments!
@itsOgden
I think i solved your problem. When you call the parent method of the handleInput method, you won't be able to use the same inputPoint inside the child method. I think this is because of this part:
https://github.com/collinhover/impactplusplus/blob/master/lib/plusplus/core/game.js#L2236
But this is more like a wild guess, than a real explanation, very unsure about that one. Maybe @collinhover could clear that up for us. Fortunately we can work around that, just overwrite the handleInput method at your main.js like that:
javascript
handleInput: function(){
var i, il;
var j, jl;
var inputPoints;
var inputPoint;
var targets;
var target;
if (ig.input.released('tap')) {
// find all inputs that are tapping
inputPoints = ig.input.getInputPoints(['tapped'], [true]);
for (i = 0, il = inputPoints.length; i < il; i++) {
inputPoint = inputPoints[i];
targets = inputPoint.targets;
if (targets.length > 0) {
// check input targets
for (j = 0, jl = targets.length; j < jl; j++) {
target = targets[j];
// toggle activation
target.toggleActivate();
}
}
}
}
}
Also make sure to add a type to your interactive entities and set the target property to true, like @collinhover has stated in the comment above:
``` javascript```
targetable: true,
initTypes: function() {
this.parent();
_ut.addType(ig.EntityExtended, this, 'type', "INTERACTIVE");
}
After that you should add an activate method to all of your interactive entities:
activate: function(){
// Do stuff here ...
}
For actions based on hold just use the specific event. Hope this helps you.
Thanks @Pattentrick. I would love to have an explanation behind it, but I'll see if I can get it to work this way in the mean time!
@Pattentrick you rock man! As far as the interactive type and targetable go, they are both there because targetable is intended for entities that can be targeted with something like an ability, while interactive type is more for mouse interaction. I think. To be fair, the current mouse handling system is not so good and is far too confusing :(
This is the first area I've had a real problem with. A few other things required some extensive researching to figure out, but all were understandable once that was taken care of. I still don't have a very firm grasp on what exactly is happening here.
I have tapping working now with the changes that you guys suggested, but I assumed that the following would solve my problem for holding and to no avail. The code for 'tapped'
is all over the place, but no where is the same thing used for holding
so I am kinda winging it:
handleInput: function(){
var i, il;
var j, jl;
var inputPoints;
var inputPoint;
var targets;
var target;
if (ig.input.released('tap') || ig.input.released('hold')) {
inputPoints = ig.input.getInputPoints(['tapped'], [true]) || ig.input.getInputPoints(['holding'], [true]);
for (i = 0, il = inputPoints.length; i < il; i++) {
inputPoint = inputPoints[i];
targets = inputPoint.targets;
if (targets.length > 0) {
// check input targets
for (j = 0, jl = targets.length; j < jl; j++) {
target = targets[j];
// toggle activation
target.toggleActivate();
}
}
}
}
},
That doesn't work, but I would have thought it should. Thoughts?
@itsOgden
Just to be clear, what do you expect to happen with your touch events? This for example will work inside your handleInput
method at your demo for me:
javascript
if ( ig.input.released('tap') || ig.input.state('hold') )
If you tap, the player will throw a color balloon. If you hold, the player will throw color balloons as long as you hold, without any kind of delay. Is this what you want, or do you have something other in mind?
About the explanation, which part is confusing for you? The `handleInput` code may look confusing at first, but basically you have just two loops. The first one will look through all inputPoints and checks if there is a target, and if so the second tries to interact with them. Like calling the `toggleActivate` method of the target in the code above.
@collinhover
Thanks man! I do my very best ;-)
Thank you for explaining the target and interactive stuff. I noticed that once the parent method in the `handleInput` method registered a event, you can't use that event/inputPoint any more in the child method. Is this because of this?
https://github.com/collinhover/impactplusplus/blob/master/lib/plusplus/core/game.js#L2232
https://github.com/collinhover/impactplusplus/blob/master/lib/plusplus/core/game.js#L2236
And if yes, what does that code?
Also I am quite new to bitwise operators, but ++ is using them in some places. Is that because of performance improvements? And is this a proper way to check for a type with them?
``` javascript```
// entity is a reference to an entity
entity.type & ig.EntityExtended.TYPE.INTERACTIVE
A better mouse handling system would be cool. I'll keep that in mind. But the next thing that I personally would love to do, if I had the time, is to integrate pixi.js into ++. This is a hot topic. Not an easy task I think. I know you had the same idea a few months ago and dropped it. But I can't stop thinking about that. I'll come back to that topic once i finished my customer acquisition and have a project to pay my bills ;-)
@Pattentrick, the desire is that it will throw the balloon once the player releases. With just tap, if the player presses down on the lane and then decides he wants to move it to a slightly different place, it no longer recognizes as a tap because now he is holding. So, in that case, when they let go nothing happens. I would like it to throw on the hold release as well as on tap.
@itsOgden Then you could use the touch event like that:
javascript
if ( ig.input.released('touch') )
And that event will be triggered once you release the touch, no matter if you just tapped or used a hold. But for whatever reason I can't get an inputPoint with that, if I release the event on a slightly different place, or after a few seconds.
I will have a closer look at the `input.js` of ++ and may figure out why that happens.
@Pattentrick to answer your question, it is a very simple method of not allowing clicks to activate multiple targets. Usually you want the target in front to intercept the click. The game's handleInput method is more of an out of the box click handler and example. Calling parent is unnecessary, usually you want to just override it.
You compare bitwise operators using a single & and combine them using a single |. The ops are very fast, and you can check for a single type in many with only one check.
@itsOgden @Pattentrick I think you can also use ig.input.released("hold")
You can also change some input properties in the config, check out CONFIG.INPUT
@collinhover I tried using ig.input.released('hold')
and it didn't seem to do anything. I also can't find anything in the config for input; am I somehow missing it?
I think @collinhover actually meant CONFIG.GESTURE
;-)
@Pattentrick is right, sorry! It does look like hold doesn't get a release, it is only a state, my bad. Does released touch as @Pattentrick suggested work?
@collinhover Nope, in the handleInput method code above the inputPoints won't have a target on release. But I almost have a solution. Just give me a little bit more time ;-)
And thanks for the explanation related to bitwise operators and the handleInput method!
@itsOgden @collinhover Okay … I have a solution that works “most of the time”. And yes, using the words “most of time” gives me the creeps when I code something.
So every idea on this one is highly appreciated ;-)
First of the handleInput
method in the main.js
:
javascript
handleInput: function(){
var inputPoints;
var targets;
var target;
if ( ig.input.released('touch') ) {
inputPoints = ig.input.inputPoints;
for ( var i = 0, il = inputPoints.length; i < il; i++ ) {
targets = inputPoints[i].targets;
if( targets.length > 0 ){
for( var j = 0, jl = targets.length; j < jl; j++ ){
target = targets[j];
target.activate();
}
}
}
}
}
Also in the `lane.js` change this:
``` javascript```
var inputPoints = ig.input.getInputPoints(['tapped'], [true]);
To this:
javascript
var inputPoints = ig.input.inputPoints;
I also noticed a `,` in the `blobShadowSettings` variable that not belongs there (the last one before the closing curly bracket). That has nothing to do with our problem, but the code may break in IE, because of that.
Here comes the “most of the time part”. Sometimes after refreshing the game the inputPoint won't have a target, no matter what. And after a few clicks or seconds everything works as expected. Thats creepy, no idea why that happens :-/
Well, as of right now, I haven't had the issue you were referring to. I have no idea what the difference could be, but for now I'm going to pretend the bug is just on your end :D Thanks so much @Pattentrick and @collinhover! You guys are the best.
It is really all @Pattentrick, he is the man!
@Pattentrick your solution might be affected by something external, it looks like it should work every time.
@itsOgden Haha - okay then it's just me. Let's pretend that I have never written something about a bug. Glad to hear that everything is working now as it should. Keep us up to date with your progress on your game, looks quite cool.
@collinhover Awwww - thanks for the compliment man! I am just using the stuff that you have created in the first place ;-)
@Pattentrick Haha, I'm sure you've never written anything with bugs in it. Never.
The only thing in this vein that I still need to figure out is how to keep clicking one entity from clicking through to the next (example: picking up ammo that is on top of the lane). When they were UI entities they did that naturally, but I haven't been able to replicate the function yet. Still working on it though!
@itsOgden take a look at how it is done in the parent call: https://github.com/collinhover/impactplusplus/blob/master/lib/plusplus/core/game.js#L2228
@collinhover Exactly what I needed. Thanks!
You guys up for another issue based on the same issue? I need 1 entity to respond only to a hold release and another to respond to a hold state. Since handleInput()
is in main.js
, how would I go about customizing these?
I feel so needy these days....
@itsOgden Haha - that's okay. I remember my first Impact++ project a few months ago. I spammed new issues all over the place ;-)
You could place the logic for that in the updateChanges
method of the related entity after calling this.parent()
. That leaves the problem of the handleInput still triggering that entity in your main.js
. You could add a check to that method, maybe looking for a custom name
to work around that:
javascript
// in the second for loop of the handleInput
if( target.name !== 'mySpecialEntity' ){
target.activate();
}
So.... I now have your 0 inputPoint issue happening. I reverted all changes back just to make sure my new stuff wasn't screwing it up, but I think I just didn't notice it before.
If I hold/fire before ever tap/firing, the targets.length is 0. If I tap/fire first, the targets.length is always after that 1+. Super trippy!
I also recently discovered that if I hold and then drag the cursor outside the lanes entity and let go, it will fire out into no-man's land and cause quite a stir lol
@itsOgden right now there isn't an automated way to handle filtering responses. You need to set up how and when you call the entity's activate method. Doing something like @Pattentrick suggests is fine, but if you have multiple entities and can't use the name, just do an instanceof or type comparison.
As for the other issue, that looks like a bug. Just so I understand you, if you hold before ever tapping, the targets found is always zero?
Specifically the targets.length
is always equal to zero. I would have thought it would be identical to tapping.
My current method:
handleInput: function(){
var inputPoints;
var targets;
var target;
var il;
if ( ig.input.released('touch') ) {
inputPoints = ig.input.inputPoints;
for ( var i = 0, il = inputPoints.length; i < il; i++ ) {
targets = inputPoints[i].targets;
if( targets.length > 0 ){
for( var j = 0, jl = targets.length; j < jl; j++ ){
target = targets[j];
if (target.type && ig.EntityExtended.TYPE.INTERACTIVE) {
// toggle activation
target.toggleActivate();
if (il === 1) {
ig.input.delayedKeyup.tap = false;
}
break;
}
}
}
}
}
}
@itsOgden Related to the firing into no-man's land: Does this already happens if you leave the lane, but stay inside the actual game? I can reproduce this behavior only, if I leave the canvas with the mouse. If I do understand it right, ++ will trigger a mouseleave/mouseout event if you leave the canvas, which is causing that behavior.
Quick idea for a fix: You could add a check and look if the current mouse/touch position is still inside the canvas. No idea about the other bug though. Let's see what @collinhover has to say about that once he finds the time for debugging.
@collinhover Let me now if you are too busy for this right now. I could try to fix this at the upcoming weekend. I am pretty clueless about the input system in ++ to be honest. This could be a good way to change that ;-)
@Pattentrick If I hold down inside the lane, then move the mouse to no-man's land and let go, the reticle spawns there, and the blob and blob shadow kinda go off and do their own thing. It is very similar to the behavior of going off-canvas, but still happens even in-canvas.
@itsOgden To be clear, with no-man's land you mean places like the wall, the area where the player is located, the inventory and so on? That means you just want to throw at things that are inside the lane? If yes, only execute the throwing if the mouse position is inside that lane.
Sorry guys, been in a crunch so I've no time atm. I'll try to get back to this and fix the bug soon. Otherwise, I agree with @Pattentrick on checking if the mouse is inside the bounds of the lane before spawning anything.
Never updated you guys after all of this. So sorry about that! I did end up just checking the mouse position vs the entity position/size. I'm also working around the bug so it hasn't been a problem.
Hey guys,
Just trying to clarify the question I posted on the ImpactJS forums. I don't think I explained my issue very well so I'm going to try again :)
I'm wanting to (on any type of entity) get the inputPoint and do a few actions when it is tapped OR held. Do I do this with the handleInput method? I thought that is how I would do it, but I can't seem to get it to even register a console log when I hold.