you cannot create signal handlers dynamically, instead implement the handler in our EntityBase, and you can toggle if it shall be used or not for example with a property that you define.
the handling is to be done be logic within the level?
The real example I face is that a Key (in this instance) knows when it has hit a Platform (both dynamically created instances). This is detected in the Key’s collider’s onBeginContact.
But the Key has no idea what is supposed to happen when it hits the Platform. Only the level knows this. One example of what might have to happen is a new Key drops in from the ceiling (this is in fact the case in the current level I am working on).
This reply was modified 8 years, 4 months ago by GreenAsJade.
This reply was modified 8 years, 4 months ago by GreenAsJade.
I’ve readjusted my “game story” to not have to have level responses to dynamically created entity interaction, for now.
I wonder if one workaround to get that interaction is to create the entities statically in QML with signal handlers as pooled entities, then remove them, so that later when they are grabbed from the pool on creation they have the handler?
This brings up a “worrying” topic about pooled entities: it seems that their “state” is not reset upon reactivation. For example, I had a pooled entitiy go to opacity 0 before removal … when it was “reused” it came back at opacity 0!
the deactivation and reactivation needs to be handled in the onMovedToPool and onUsedFromPool signal handlers of the entity.
Regarding your entities, I’m not quite sure how your exact game logic looks like, but maybe something like this could help you:
As you said, the key detects the collision, so the key obviously knows all the actions that can happen to him, so what i like to do in this cases is having a distinct game logic object that can be accessed from the entities, with functions to handle those actions. This could look like this:
GameLogic {
function keyCollided(key,collidedWith) {
// do something like this
entityManager.removeEntityById(key.entityId)
}
}
Scene {
id: gameScene
property alias gameLogic: gameLogic
GameLogic {
id: gameLogic
}
}
EntitiyBase {
id: entitiy
// ...
BoxCollider {
// ...
fixture.onBeginContact: {
// actually physical bodies collide, to get the entity we have to navigate <body>.<fixture>.<collider>.<entity>
var collidedEntity = other.parent.parent.owningEntity
gameScene.gameLogic.keyCollided(entity,collidedEntity)
}
}
}
If the key collides with something, it tells the gameLogic that a collision happened, and passes a reference to himself and the collided entity. Now the gameLogic can access all items that participated in the action. If the actions are different in every level, consider moving the gameLogic to the different levels then.
Thanks for the suggestion – I made the problem “go away” for a while, so I only just got back to this. I need to deal with it now.
I hope you will understand what I mean when I observe that while this obviously works, its not “good” in the sense of “clean design”.
signals exist to provide a clean interface between entities. This solution breaks that: it requires that the scene instantiating the entity have a fixed name, and have a logic block with a fixed name as well.
What if I need to use the entity in more than one “game scene”? Maybe I want to make little display in my credits scene, for example? Then the entity will not have a “gameScene” to refer to.
I’ve worked out that I can actually achieve what I’m trying to do by using function-properties instead of signals:
In my Grunt.qml:
EntityBase {
id: grunt
entityType: "grunt"
property var kickedNinja: function() {console.log("grunt kicked ninja - no further action")}
fixture.onBeginContact: {
# ... blah blah
if (collidedEntityType == "ninja") {
var ninja = collidedEntity
if (ninja.kickState == "idle") {
console.log("Hah! (grunt kicks ninja)")
ninjaKicked.play()
kickedNinja()
Where a change is needed statically (in QML) of a level:
And where it needs to be added to a dynamically created entity:
// make a new grunt
var newGruntProperties = {
y: gruntEntryY,
x: gruntEntryX,
kickedNinja: newKickedNinja
}
entityManager.createEntityFromUrlWithProperties(
Qt.resolvedUrl("../entities/Grunt.qml"),
newGruntProperties);
where newKickedNinja is of course a function pointer passed into this routine by the level that wants to do something different.
It’s kind of do-it-yourself signals ….
This reply was modified 8 years, 4 months ago by GreenAsJade.
This reply was modified 8 years, 4 months ago by GreenAsJade.
wow that’s an extremely nice workaround. I think this looks even cleaner than this approach: http://doc.qt.io/qt-5/qtqml-syntax-signals.html as you don’t even need the JavaScript code lines to connect, did you try that too?
Especially the line relay.messageReceived.connect(sendToPost)
could be what you needed.
Cheers,
Alex
This reply was modified 8 years, 4 months ago by Alex.
By signing up, you consent to Felgo processing your data & contacting you to fulfill your request. For more information on how we are committed to protecting & respecting your privacy, please review our privacy policy.
Want to find out if Felgo is a good fit for your company?
As part of the free Business evaluation, we offer a free welcome call for companies, to talk about your requirements, and how the Felgo SDK & Services can help you. Just sign up and schedule your call.
Sign up now to start your free Business evaluation: