Topic: [BGE] Python collision callback op object; collision eind detectie  (gelezen 6831 keer)


Offline jvp

  • Member
  • *
  • Berichten: 1
    • Bekijk profiel
« Gepost op: 16 juli 2016, 21:11:20 pm »
Ik ben op zoek naar een manier om in Python te detecteren dat een collision begint, én wanneer deze eindigt.

Op het moment doe ik dit:

class Sensor(bge.types.KX_GameObject):
    def __init__(self, gameobj):
        # gameobj is automatically used to populate this object
        self.collisionCallbacks.append(self.onCollisionPulse)

    def onCollisionPulse(self, other):
        if "is_block" in other:
            print(self, "collided with", other)

Ik ben alleen geinteresseerd in de objecten die de is_block property hebben, maar ik wil ook graag weten wanneer de collision eindigt.

Het lijkt erop dat dit op het moment niet kan met deze callbacks, en dat ik toch naar de Collision Sensor logic bricks terug moet vallen.

Heeft iemand het verlossende antwoord?
« Laatst bewerkt op: 16 juli 2016, 21:14:49 pm door jvp »

Offline IJp

  • *
  • Berichten: 4,387
    • Bekijk profiel
    • IJpart
« Reactie #1 Gepost op: 17 juli 2016, 09:59:19 am »
Ik niet,  zo slim ben ik niet.  :-[  ;-)

Maar PKHG is hier ook wel eens op het forum en zover ik weet kan hij wel met Python overweg, dus die kan je wellicht helpen.
Zaph was ik vergeten en ik zie dat hij ook met Python overweg kan dus het zal we goed komen  ;)
« Laatst bewerkt op: 17 juli 2016, 15:04:56 pm door ijp »

Offline koos2

  • Member
  • *
  • Berichten: 2,053
    • Bekijk profiel
« Reactie #2 Gepost op: 17 juli 2016, 12:45:35 pm »
Helaas, ik ben niet bekend met Python.

Offline koos2

  • Member
  • *
  • Berichten: 2,053
    • Bekijk profiel
« Reactie #3 Gepost op: 17 juli 2016, 13:48:00 pm »
Is het niet zo dat zo'n collision detect een true of falls teruggeven?! Dan eindigt de collision als hij na de true een falls geeft. een 1 true een 0 flass of iets dergelijks.

Offline Zaph

  • Member
  • *
  • Berichten: 540
    • Bekijk profiel
    • Zaph webdevelopment
« Reactie #4 Gepost op: 17 juli 2016, 14:54:05 pm »
Nee, een collision is als een event, vergelijkbaar met een muisklik - je operating system detecteert een klik, en geeft dat door aan het programma waarop dat plaatsvindt. Het ontbreken ergens van is geen event, en het OS is dan ook niet continu aan het doorgeven - anders zou er (heel overdreven) non-stop moeten worden doorgegeven dat er niet geklikt is op x=0&y=0, x=1&y=0, etcetera, en dat ook niet de toetsen 'a', 'b', 'c', etcetera ingedrukt zijn.

Offline Zaph

  • Member
  • *
  • Berichten: 540
    • Bekijk profiel
    • Zaph webdevelopment
« Reactie #5 Gepost op: 17 juli 2016, 15:05:09 pm »
Het lijkt erop dat dit op het moment niet kan met deze callbacks, en dat ik toch naar de Collision Sensor logic bricks terug moet vallen.
Je kunt in je callbackfunctie een array vullen met objecten die gebotst zijn, en een property als "frameCount" toevoegen met waarde 0. Daarnaast zou je een functie moeten hebben die elke frame (of hoe het dan ook werkt in BGE) die waarde met 1 ophoogt. Als dan die waarde boven een bepaalde waarde, bijvoorbeeld 10, uitkomt weet je dat dat object al 10 frames lang niet gebotst heeft, en kun je dat moment als 'einde collision' beschouwen.

Offline Zaph

  • Member
  • *
  • Berichten: 540
    • Bekijk profiel
    • Zaph webdevelopment
« Reactie #6 Gepost op: 17 juli 2016, 15:24:41 pm »
Zoiets, bijvoorbeeld:

class Sensor(bge.types.KX_GameObject):
    def __init__(self, gameobj):
        # gameobj is automatically used to populate this object
self.collidedObjects = []
        bpy.app.handlers.frame_change_pre.append(self.onFrame) # weet niet of dit werkt
        self.collisionCallbacks.append(self.onCollisionPulse)

    def onCollisionPulse(self, other):
        if "is_block" in other:
            print(self, "collided with", other)
            # het object wordt gebruikt als index in het array, de waarde is de framecount
            self.collidedObjects[other] = 0

    def onFrame():
        # er van uitgaand dat 'self' hier bereikbaar is...
        for obj, frameCount in self.collidedObjects:
            # het object is de index in het array, frameCount de waarde
            if frameCount == 10:
                # 'einde collision' event
                self.collidedObjects.remove(obj);
            else:
                self.collidedObjects[obj]++;

Offline Zaph

  • Member
  • *
  • Berichten: 540
    • Bekijk profiel
    • Zaph webdevelopment
« Reactie #7 Gepost op: 20 juli 2016, 16:26:10 pm »
Heerlijk - dingen uit gaan zoeken en zelfs een stukje voorbeeldcode in elkaar hannesen voor iemand die even een vraagje dropt en niet meer terugkomt om te kijken of 'ie antwoord heeft gekregen...doe ik dus ook niet weer.  :-\