How to listen the number of touches? - kotlin

I thought it's easy. Like always
//somewhere inside constructor
overlay.addOnTouchListener(this)
//...
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
event?:return false
if (event.actionMasked == MotionEvent.ACTION_DOWN || event.actionMasked == MotionEvent.ACTION_POINTER_DOWN) {
//start drag
moving=true
} else if (event.actionMasked == MotionEvent.ACTION_MOVE) {
if (!moving) return true
//do drag
} else if (event.actionMasked == MotionEvent.ACTION_UP) {
//stop drag
println("touch:up(${event.pointerCount})")
}
return true
}
I was expecting MotionEvent.ACTION_UP will fire up on release of each finger.But looks like it only fires once for the last finger.
Is there way catch moment when user releases one finger but keep's moving another one?

You can use two methods getPointerCount(x) and/or getPointerId(x).
getPointerCount gets the number of pointers of data contained in an event. This is always >= 1.
While getPointerId() returns the pointer identifier associated with a particular pointer data index in an event. The identifier tells you the actual pointer number associated with the data, accounting for individual pointers going up and down since the start of the current gesture.
So in your case, if you want to capture the pointer that was not removed from the screen, you can use getPointerCount to check if there has been a pointer removed and then use getPointerId to assign some sort of function when the last pointer has been released.

The initial statement is incorrect. Actualy android notifies all touch ups with events MotionEvent.ACTION_UP/MotionEvent.ACTION_POINTER_UP

Related

How can I force shell to push an object after self destroying with delay (Unity3D)

I have an object inside a boundary and I shoot into the object (to understand my code see this lesson: https://unity3d.com/learn/tutorials/projects/space-shooter/creating-hazards?playlist=17147). Shell (bullet) should be destroyed after collision with object, but not instantly - after some delay (i.e. they collides and after some amount of seconds shell disappears). Shell's collider should be with a trigger, but because of it she flies through the object. Shell should disappear after it affected the object. I made the delay in order to have time for affecting. But if there a way it can disappear instantly then that's great. I just wanted give time to shell to apply a force.
void OnTriggerEnter(Collider other) {
if (other.tag == "Boundary")
{
return;
}
//Destroy (gameObject);
StartCoroutine(WaitAndDestroy());
}
IEnumerator WaitAndDestroy() {
yield return new WaitForSeconds(2);
Destroy (gameObject);
}
Try to move StartCoroutine(WaitAndDestroy()); above the return statement.
It is nesessary to use OnCollisionEnter(Collision other), and put Destroy(other.gameObject) into it. And colliders should be without triggers - on both interacting objects.

Is the return statement and the end if the method required if the method return value is void?

If I have for example this piece of code:
- (void)doSomething
{
// do whatever the method has to do
return;
}
I know that the return is not required for the app to keep running. It seems to be smart enough to know that the method has finished. My question is: Does the absence of the return have negative side effects? (e.g. a memory leak)
Of course not, return has no meaning in void methods except if you wanna return early based on condition or failure to stop execution rest of method.

Observe every item in RACSequence

I have a method on ParentViewModel which returns an RACSequence of ViewModel objects like so:
- (RACSequence *) viewModels
{
return [self.models.rac_sequence map:^id(Model *model) {
return [[ViewModel alloc] initWithModel: model];
}];
}
Each of the ViewModels has a state property on which is an enum and has 3 states: NotStarted, InProgress and Completed. When all the ViewModels in my sequence have the state Completed I know ParentViewModel is valid. I have a validSignal on the ParentViewModel which I want to derive the fact that is valid from the viewModels sequence. At the moment I have this code:
BOOL valid = [[self viewModels] all:^BOOL(ViewModel *vm) {
return vm.state == Completed;
}];
Which gives me an indicator if all ViewModels in the sequence are valid. How can I then turn this into a RACSignal which will update every time the state property on one of the ViewModels changes?
You need first to turn state into a RACSignal, and then everything is easy from that point.
The final code will be something like the following:
RACSignal *valid = [[RACSignal combineLatest:
[[self viewModels] map:^id(ViewModel *viewModel) {
return RACAbleWithStart(viewModel, state);
}]
]
map:^(RACTuple *states) {
return #([states.rac_sequence all:^BOOL(NSNumber *state) {
return state.unsignedIntegerValue == Completed;
}]);
}
];
The first block maps each of your view models into a signal that observes the state property (with the starting value as first value of the signal).
combineLatest: will take a collection of RACSignals and will create a new signal that fires everytime one of the underlaying signals changes, and sends a RACTuple with the value of each signal.
That RACTuple is then converted into a RACSequence, and we can generate a value of #YES or #NO depending if all the values are Completed or not.
I think the result is the signal you were looking for.
(Disclaimer: I’m new to ReactiveCocoa, so there may be an easier way).

Getting the code of released key

I'm trying to make a simple platformer using action script 2.0 but I have a problem with getting input from keyboard. I have two function "myKeyDown" and "myKeyUp" that get called whenever a key is pressed down/released.
keyListener.onKeyDown = function(){
myKeyDown();
}
keyListener.onKeyUp = function(){
myKeyUp();
}
The functions check which key was pressed by using Key.getCode() method. It works for myKeyDown but it's buggy for myKeyUp. The bug happens if (for example) I first press A (to move left), then W (to jump), then release W and then release A. The player won't stop moving (even though that's what should happen when you release A)
I understand the problem here. Key.getcode return the code of the last pressed key and what I want is the code for the last released key. I've been searching for hours for a function like this but I haven't found anything.
Here's the code for both myKeyDown and myKeyUp functions
function myKeyDown(){
//A
if(Key.getCode() == 65){
velX=-3;
}else
//D
if(Key.getCode() == 68){
velX=3;
}else
//W
if(Key.getCode() == 87){
if(isInAir == false){
jump();
}
}
}
function myKeyUp(){
//A
if(Key.getCode() == 65){
if(velX==-3){
velX=0;
}
}else
//D
if(Key.getCode() == 68){
if(velX==3){
velX=0;
}
}
}
for cases like this, when you need to hold/release multiple keys a little bit different approach would be better for key handling.
what you can do is use onEnterFrame event listener to check for the pressed keys in case of events when something has to be continuous.
an example
var my_keys:Array = new Array();
my_keys["jump"]=false;
my_keys["right"]=false;
my_keys["left"]=false;
//keydown sets the variables to true
keyListener.onKeyDown = function(){
code=Key.getCode();
if(code==65){
my_keys["left"]=true;
}
if(code==68){
my_keys["right"]=true;
}
if(code==87){
my_keys["jump"]=true;
}
//etc, etc, anything else you wish
//of course, this doesn't prevent you from calling additional one-time events from the keydown!
}
//keyup unsets the button variables
keyListener.onKeyUp = function(){
code=Key.getCode();
if(code==65){
my_keys["left"]=false;
}
if(code==68){
my_keys["right"]=false;
}
if(code==87){
my_keys["jump"]=false;
}
}
now at every point of your game you have a set of keys that are pressed stored in the my_keys array. of course you could use a more generic function inside the keyDown/keyUp and pass the Key.getCode itself directly into the array as indexes instead of the captioned array (like my_keys[Key.getCode()]=true;), it would be even shorter to write. however, i found this to be more illustrative as an example, feel free to modify the code as you need
what you want now is a function that would handle the behavior based on what keys are pressed.
in your case this could, for example, be:
this.onEnterFrame=function(){ //you don't have to use "this" movieclip reference if you have other enterframe events in the movieclip. just don't forget to modify the objcet paths
if(my_keys["left"]){
velX=-3;
}
if(my_keys["right"]){
velX=+3;
}
if((my_keys["jump"])&&(!isInAir)){ //note that i added !isInAir instead of (isInAir==false). this is an equivalent expression, it's just shorter and nicer
jump();
}
}

Use ScaleGestureDetector with GestureDetector?

In my Android app I have an ImageView where I'd like the user to be able to fling it left/right/up/down to change the image (static maps) to the adjacent one. But in addition, I'd like pinch-zoom abilities and a map itself.
I can get either flinging OR pinch-zooming to work, but not together. I'm using GestureDetector (with a SimpleOnGestureListener) for the flinging. And I'm using ScaleGestureDetector (from Making Sense of Multitouch) for the scaling.
The difficulty is to determine which gesture listener to invoke upon a touch action. This is less a coding issue, but logic issue. Upon a single finger touch action, is it a fling or scale? Even when a pinch-zoom is used, the initial MotionEvent is ACTION_DOWN. I've been trying to use the image size (intrinsic or scaled?) as a decision point. But the initial scaling operation (when image size is intrinsic and I want to zoom on it) with ACTION_DOWN seems to escape me.
Has anyone tackled this successfully previously?
You can pass the events on to both gesture detectors.
Check http://developer.android.com/training/gestures/scale.html under "More complex scaling example":
public boolean onTouchEvent(MotionEvent event) {
boolean retVal = mScaleGestureDetector.onTouchEvent(event);
retVal = mGestureDetector.onTouchEvent(event) || retVal;
return retVal || super.onTouchEvent(event);
}
Of course given the bug Ratatat is referencing, super.onTouchEvent will never be called in the above example, which may or may not be fine, depending on your use case.
The idea of Ratatat's answer is OK but we should still pass events to the gestureDetector even if we don't want to scroll, or it will be messed up.
I ended up with something like this:
scaleDetector = new ScaleGestureDetector( ... );
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (scaleDetector.isInProgress()) {
// don't allow scrolling while scaling
return false;
}
// handle scrolling
return true;
}
}
And then onTouchEvent's implementation should be like in aij's answer:
boolean result = scaleDetector.onTouchEvent(event);
result = gestureDetector.onTouchEvent(event) || result;
return result || super.onTouchEvent(event);
Finally found the answer on a link:
http://code.google.com/p/android/issues/detail?id=42591
#Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = mScaleGestureDetector.onTouchEvent(event);
// result is always true here, so I need another way to check for a detected scaling gesture
boolean isScaling = result = mScaleGestureDetector.isInProgress();
if (!isScaling) {
// if no scaling is performed check for other gestures (fling, long tab, etc.)
result = mCommonGestureDetector.onTouchEvent(event);
}
// some irrelevant checks...
return result ? result : super.onTouchEvent(event);
}