vendredi 24 juin 2016

deleting entity vplay gives nonetype error

I am new to VPlay and QT and I am working through the VPlay tutorials. I am currently wrapping up the box-stacking game making tutorial up to the point where I create boxes and then need to delete all of the box entities when a box has reached the top. However, when I get a box reaching the top, then my application crashes. I took a look through the debugger (and I am not very familiar with it since I am a beginner) but I did see that an object with "No value"/"nonetype"/something along those lines, and I do not know how to fix this/debug this. [I found this problem by dragging a box to the top of the screen, where it hits the top wall, which makes the EntityManager delete every box that there is (or hopefully,so)]. If anyone could please explain to me not just what the error is, but how to detect such errors in the future (since I am a newbie to this debugger- having previously used xcode), that would be great. My code is as following [please assume that all images, sound effects, and particle effects are in the right directory and are good files. I can post these files here, if you want]. My code is here: (Main.qml) import VPlay 2.0 import QtQuick 2.0 GameWindow { id: gameWindow //start physics once the splash screen has disappeared, else the box would fall out of the screen onSplashScreenFinished: physicsWorld.running = true EntityManager { id: entityManager entityContainer: scene } Scene { id: scene //gets increased when a new box is created, and reset to 0 when a new game is started //start with 1 because initially 1 Box is created property int createdBoxes: 0 //display the amount of stacked boxes Text { text: "Boxes: " + scene.createdBoxes color: "white" z: 1 //put on top of everything else in the Scene } Timer { id: timer interval: Math.random()*3000 + 2000 running: true //start running from the beginning, when the scene is loaded repeat: true //otherwise restart won't work onTriggered: { var newEntityProperties = { //safetyZoneHorizontal = box.width*SQRT(2)/2+LeftWall.width -> which is ~ 50 //vary x between [safetyZoneHorizontal ... scene.width-safetyZoneHorizontal] x: Math.random() * (scene.width-2*50) + 50, y: 50, //position on top of the scene or at least below the top wall rotation: Math.random()*360 } entityManager.createEntityFromUrlWithProperties(Qt.resolvedUrl("Box.qml"), newEntityProperties); //increase the createdBoxes number scene.createdBoxes++ //recalculate new interval between 2000 and 5000 ms interval = Math.random() * 3000 + 2000 //restart the timer timer.restart() } } Component { id: mouseJoint MouseJoint { //make this high enough so the box with its density is moved quickly maxForce: 1000000 //the damping ratio. 0= no damping, 1= critical damping. default is 0.7 dampingRatio: 1 //the response speed. default is 5 frequencyHz: 2 } } //when the user presses a box, move it towards the touch position MouseArea { anchors.fill: parent property Body selectedBody: null property MouseJoint mouseJointWhileDragging: null onPressed: { selectedBody = physicsWorld.bodyAt(Qt.point(mouseX,mouseY)); console.debug("selected body at position",mouseX,mouseY,":",selectedBody); //if the user selected a body, this if-check is true if (selectedBody) { //create a new mouseJoint mouseJointWhileDragging = mouseJoint.createObject(physicsWorld) //set the target position to the current touch position (initial position) mouseJointWhileDragging.target = Qt.point(mouseX,mouseY) //connect the joint with the body mouseJointWhileDragging.bodyB = selectedBody } } onPositionChanged: { //this check is also necessary because the user might also drag when no initial body was selected if (mouseJointWhileDragging) mouseJointWhileDragging.target = Qt.point(mouseX,mouseY) } onReleased: { //if a user pressed a body initially, remove the created MouseJoint if (selectedBody) { selectedBody = null if (mouseJointWhileDragging) mouseJointWhileDragging.destroy() } } } Rectangle { //the game's background id:background anchors.fill: scene.gameWindowAnchorItem color: "black" } PhysicsWorld { id: physicsWorld //physics is disabled initially and enabled after the splash is finished running: false gravity.y: 9.81 z: 10 //draw the debugDraw on top of the entities //these are the perfomance settings to avoid boxes colliding too far together //set them as low as possible so that it still looks good updatesPerSecondForPhysics: 60 velocityIterations: 5 positionIterations: 5 //set this to true to see the debug draw of the physics system //this displays all bodies, joints, and forces, which is great for debugging debugDrawVisible: false } Box { x: scene.width/2 y: 50 } Wall { height: 20 anchors { bottom: scene.bottom left: scene.left right: scene.right } } //adding the walls to the screen Wall { //bottom wall height: 20 anchors { bottom: scene.bottom left: scene.left right: scene.right } } Wall { //left wall width: 20 height: scene.height anchors { left: scene.left } } Wall { //right wall width: 20 height: scene.height anchors { right: scene.right } } Wall { //top wall height: 20 width: scene.width anchors { top: scene.top } color: "red" //make top wall red onCollidedWithBox: { console.debug("DEBUG: in onColliededWithBox"); //gets called when the wall collides with a box and the game should restart //remove all entities of type "box" but not the walls entityManager.removeAllEntities(); console.debug("removed all boxes"); //reset the createdBoxes amount scene.createdBoxes = 0; console.debug("Set createdBoxes to 0 and left function"); } } }} and then Box.qml: import QtQuick 2.0 import VPlay 2.0 EntityBase { id: box entityType: "box" //the origin (the 0/0 position of the entity) of this entity is in the center //thus we cannot use an anchors.fill: parent in Image and BoxCollider, //otherwise it would use the top left corner as the origin width: 32 height: 32 //the 0/0 of the entity should be the center of the collider and image //this is required when a width & height are set to the entity! //in that case, the rotation should be applied around the center (which is top-left, //not the width/2, height/2 Item.center, which is the default value transformOrigin: Item.TopLeft Image { id: boxImage source: "../assets/box.png" //set the size of the image to one of the box collider and not vice versa because //the physics properties depend on the collider size anchors.fill: boxCollider } BoxCollider { id: boxCollider //the size affects the physics settings (the bigger the heaver) //this is set automatically in any collider- the default size is the one of the parent! //width: parent.width //height: parent.height //the collider should have its origin at the x/y of the entity (so the center is in the TopLeft) x: -width/2 y: -height/2 friction: 1.6 restitution: 0 //restitution is bounciness- a wooden box does not bounce density: 0.1 //makes the box more heavy fixture.onBeginContact: { //when colliding with another entity, play the sound and start particle effect collisionSound.play(); collisionParticleEffect.start(); } } //the soundEffect is played at a collision SoundEffectVPlay { id: collisionSound source: "../assets/boxCollision.wav" } //the Particle effect is started at a collision ParticleVPlay { id: collisionParticleEffect fileName: "../assets/SmokeParticleCpy.json" } } and then Wall.qml: import QtQuick 2.0 import VPlay 2.0 //for accessing the Body.static type EntityBase { entityType: "wall" //this gets used by the top wall to detect when the game is over signal collidedWithBox //this allows setting the color property or the Rectangle from outside, //to use another color for the top wall property alias color: rectangle.color property alias collider: collider preventFromRemovalFromEntityManager: true Rectangle { id: rectangle color: "blue" anchors.fill: parent } BoxCollider { id: collider anchors.fill: parent bodyType: Body.Static //the body should not move fixture.onBeginContact: collidedWithBox() }} and then the Main.cpp file that runs all of this stuff is: #include <QApplication> #include <VPApplication> #include <QQmlApplicationEngine> int main(int argc, char *argv[]) { QApplication app(argc, argv); VPApplication vplay; // QQmlApplicationEngine is the preferred way to start qml projects since Qt 5.2 // if you have older projects using Qt App wizards from previous QtCreator versions than 3.1, please change them to QQmlApplicationEngine QQmlApplicationEngine engine; vplay.initialize(&engine); // use this during development // for PUBLISHING, use the entry point below vplay.setMainQmlFileName(QStringLiteral("qml/Main.qml")); // use this instead of the above call to avoid deployment of the qml files and compile them into the binary with qt's resource system qrc // this is the preferred deployment option for publishing games to the app stores, because then your qml files and js files are protected // to avoid deployment of your qml files and images, also comment the DEPLOYMENTFOLDERS command in the .pro file // also see the .pro file for more details // vplay.setMainQmlFileName(QStringLiteral("qrc:/qml/Main.qml")); engine.load(QUrl(vplay.mainQmlFileName())); return app.exec(); } And the error thread is: eERROR: Lldb stderr: Exception in thread Thread-1: eTraceback (most recent call last): e File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner e self.run() e File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run e self.__target(*self.__args, **self.__kwargs) e File "/Users/Nata/vplay/Qt Creator.app/Contents/Resources/debugger/lldbbridge.py", line 769, in loop e self.handleEvent(event) e File "/Users/Nata/vplay/Qt Creator.app/Contents/Resources/debugger/lldbbridge.py", line 1409, in handleEvent e % self.hexencode(msg)) e File "/Users/Nata/vplay/Qt Creator.app/Contents/Resources/debugger/dumper.py", line 479, in hexencode e return s.encode("hex") eAttributeError: 'NoneType' object has no attribute 'encode'

Aucun commentaire:

Enregistrer un commentaire