How to reactivate contact between two physicsBody's - ios

I'm trying to get two physicsBody, that are already in contact with each other (in fact they overlap because physicBody.collisionCategory = 0; for both physicsBody's), to restart/re-register/re-trigger their contact, on command. I've been unable to do this even though I tried to get body1 to move by one pixel within body2 to re-trigger the contact. I've also deleted one of the physicsBody's & re-instantiated it several seconds after that to re-trigger the contact. But nothing works. Is there some sort of method or technique to restart the contact process while both bodies are already in contact?
So, to make things a little clearer:
1) SpriteHuman walks onto SpritePanel.
2) -(void)didBeginContact:(SKPhysicsContact *)contact registers the contact.
3) I call a method that starts step 2 again, while SpriteHuman doesn't move and is still contacting SpritePanel.

You can set a BOOL property to YES for your player object if it contacts a certain object. This will allow you to continuously run whatever code you need to run. Just remember to do also set the BOOL back to NO when contact is lost.

Related

DJI Waypoint mission listeners

I need to create/upload/start waypoint mission on one button. When user press button drone should move up for certain number of point based on current position. User can stop mission and again start new one. My logic here is next:
I initialize mission with points
Load mission
Add Listeners to mission operator
Upload mission
Mission starts on listener
missionOperator.addListener(toUploadEvent: self, with: DispatchQueue.main) { (event) in
if event.currentState == .readyToExecute {
self.startMission()
}
}
I'm reading documentation for days and trying to understand how this thing work, but I'm missing something obviously. Listeners are created on waypoint mission operator, but if I create listeners before loading mission they are not called. If I create listeners every time I load mission, startMission() is called multiple times (first time is called ones, but after one mission is stopped or finished, next time startMission() gets called two times)
So, I guess that my questions would be:
What is right moment to add listeners and to remove them since I'm calling startMission() from listeners? Actually what is appropriate way to init/upload/start mission on one button, and be able to do that multiple times?
You need to remove the upload listener when the the upload succeeded and the event state is readyToExecute. Also when the event contains an error, or the state is readytoupload/notsupported/disconnected. Pretty much in every case except when it's still in the state 'uploading'.
When you start the mission, add a listener for execution events, and one for finished. Remove those again when the mission is stopped/cancelled, has an error, or finishes successfully.
Even though you use Swift, I suggest looking at the more complete Objective C sample code, which includes examples of several different types of missions.

How to optimize performance of Results change listeners in Realm (Swift) with a deep hierarchy?

We're using Realm (Swift binding currently in version 3.12.0) from the earliest days in our project. In some early versions before 1.0 Realm provided change listeners for Results without actually giving changeSets.
We used this a lot in order to find out if a specific Results list changed.
Later the guys at Realm exchanged this API with changeSet providing methods. We had to switch and are now mistreating this API just in order to find out if anything in a specific List changed (inserts, deletions, modifications).
Together with RxSwift we wrote our own implementation of Results change listening which looks like this:
public var observable: Observable<Base> {
return Observable.create { observer in
let token = self.base.observe { changes in
if case .update = changes {
observer.onNext(self.base)
}
}
observer.onNext(self.base)
return Disposables.create(with: {
observer.onCompleted()
token.invalidate()
})
}
}
When we now want to have consecutive updates on a list we subscribe like so:
someRealm.objects(SomeObject.self).filter(<some filter>).rx.observable
.subscribe(<subscription code that gets called on every update>)
//dispose code missing
We wrote the extension on RealmCollection so that we can subscribe to List type as well.
The concept is equal to RxRealm's approach.
So now in our App we have a lot of filtered lists/results that we are subscribing to.
When data gets more and more we notice significant performance losses when it comes to seeing a change visually after writing something into the DB.
For example:
Let's say we have a Car Realm Object class with some properties and some 1-to-n and some 1-to-1 relationships. One of the properties is a Bool, namely isDriving.
Now we have a lot of cars stored in the DB and bunch of change listeners with different filters listing to changes of the cars collection (collection observers listening for changeSets in order to find out if the list was changed).
If I take one car of some list and set the property of isDriving from false to true (important: we do writes in the background) ideally the change listener fires fast and I have the nearly immediate correct response to my write on the main thread.
Added with edit on 2019-06-19:
Let's make the scenario still a little more real:
Let's change something down the hierarchy, let's say the tires manufacturer's name. Let's say a Car has a List<Tire>, a Tire has a Manufacturer and a Manufacturer has aname.
Now we're still listing toResultscollection changes with some more or less complex filters applied.
Then we're changing the name of aManufacturer` which is connected to one of the tires which are connected to one of the cars which is in that filtered list.
Can this still be fast?
Obviously when the length of results/lists where change listeners are attached to gets longer Realm's internal change listener takes longer to calculate the differences and fires later.
So after a write we see the changes - in worst case - much later.
In our case this is not acceptable. So we are thinking through different scenarios.
One scenario would be to not use .observe on lists/results anymore and switch to Realm.observe which fires every time anything did change in the realm, which is not ideal, but it is fast because the change calculation process is skipped.
My question is: What can I do to solve this whole dilemma and make our app fast again?
The crucial thing is the threading stuff. We're always writing in the background due to our design. So the writes itself should be very fast, but then that stuff needs to synchronize to the other threads where Realms are open.
In my understanding that happens after the change detection for all Results has run through, is that right?
So when I read on another thread, the data is only fresh after the thread sync, which happens after all notifications were sent out. But I am not sure currently if the sync happens before, that would be more awesome, did not test it by now.

How to actually start a GKTurnBasedMatch so that I can send an exchange?

I'm trying to send an exchange to another player in a GKTurnBasedMatch. When I send it, my completion handler gets a big error message, with these descriptions:
The requested operation could not be completed because the session is in an invalid state.
Game is not active, session state is Matching
I want the match to start when there are just two players, but to allow a total of 16 players. So naturally I'm setting maxPlayers = 16 and minPlayers = 2. I'd thought that would automatically start the match once two players were seated, but it's not so.
I've tried to do this once the match has two players, :
if match.participants?.count == 2 {
match.status = GKTurnBasedMatchStatus.open
}
But then I'm told that status is read-only. I can't manually set it.
Now, with a regular GKMatch, I officially start the match by calling:
GKMatchmaker.shared().finishMatchmaking(for: match)
But there doesn't seem to be a similar thingy for GKTurnBasedMatch.
How do I actually get the match started, so I can send an exchange between the two players?
Man, the documentation on GKTurnBasedMatch is sparse.
Here's the thing: you don't actually start a GKTurnBasedMatch explicitly. You only end it explicilty.
During gameplay, you just pass the turn from one active player to another active player. The game technically starts as soon as the first player is seated.
The problem I was having is that I had passed the turn when there was no other active player. So I accidentally told Game Center to assign the turn to an empty seat. So when the error message told me
Game is not active, session state is Matching
It meant that the current seat was empty and still looking for a player to fill it. The game apparently goes out of active status any time the current player's status is Matching (which denotes an empty seat).
Why on earth this would affect sending exchanges, whose whole purpose is to enable communication between any players, no matter who the current player is, is beyond me. But there you go.
The solution: make sure that the current turn is held by an actual person, and is not an empty seat. Then you can send exchanges. Otherwise you can't.

ABAddressBook detect contact record changes

Is there a way to detect which contact records have changed ?
I understand there are 2 options to detect change:
kABDatabaseChangedNotification and
kABDatabaseChangedExternallyNotification
ABAddressBookRegisterExternalChangeCallback
I would like to detect each contact that has been changed. How would I be able to do this ?
I suppose there is no way to detect the individual changes.
Couple of points to keep in mind:
You need to use `ABAddressBookRegisterExternalChangeCallback1 to
specify the callback function
When the callback function is called reload all the contacts from address book.
Use NSOperation and ensure isCancelled is handled.

Deleting the proper CCSprite from an array in a schedule

Before I explain my issue, I made this very not neat illustration of how my project works -
My issue is - when the time that I want to check damage is up, I want to delete that object from the array! I have tried deleting it in the checkForDamage, but as this gets called with ccTimeit just deletes every object (when I use removeObjectAtIndex:0 to get rid of the first one). I can't put it in the stopCheckDamagebecause while the damage on the first one is being checked, the player might as well have put another bomb down.
The checkForDamageworks just fine when the user gets hit, I break; it and calls stopCheckDamage. My problem is when the user does NOT get hit, because then the nonexisting sprite stays in the array and just messes stuff up. I have been thinking about every way I know of and I can't seem to find a way to delete a specific object after three seconds delay if the player doesn't get hit.
I also made a pastebin for the relevant code, which you can find here
This is just an idea,
You have an array of all of the objects. You just need to know which one to delete.
So, why not give each object a tag that gets added into the array. When you go to delete that object test its tag and delete it.
//Say your array has 10 objects in it,
//There will be 10 objects each with a tag 1-10.
//When you want to delete an object,
EDIT
//Before you add each object to the array, use a `for` loop
for (int i = 0; i < theMaxNumberOfTagsYouWant; i++)
{
self.myObject.tag = i;
[self.myArray addObject:self.myObject];
//This will loop thru as many times as you want, specify using the
//maxNumberOfTagsYouWant variable. and it will give it a tag, which'll be the value of `i`
//which gets increased for each object you insert into the array, Then when you want to
//remove the object, use the below code to remove the object using it's tag.
}
-(void)deleteObjectFromArray{
[self.myArray removeObjectAtIndex:myObject.tag];
}
Hope this helps a bit. :)

Resources