I’ve been scouring the internet looking for some clarification on rotating images. Basically my game is just clicking falling balls so they bounce up to keep them from going off the bottom of the screen. I have the basic functionality of the game working, but I can’t get the rotation to work properly. I want the balls to rotate in a direction and speed based on how far from the center they are clicked. I also want the rotation speed and direction to adjust when hitting the side walls due to friction. I feel like this is a pretty simple thing to accomplish, but I’m unable to find a solution.
Tagged: BoxCollider, circlecollider, colliderbase, Image, Rotation
-
AuthorPosts
-
September 26, 2016 at 22:23 #14933
Bill
September 27, 2016 at 11:28 #14934
GüntherFelgo TeamHi Bill,
It’s hard to give hints without seeing the actual code, as there might be several solutions. Can you put together a minimum code-sample with some explanations and send it to support@felgo.com?
In general, the Box2D physics implementation that we use allows to set up density, friction and restitution for e.g. BoxCollider of your balls and walls to define the behavior when the ball bounces off the wall or ground. You can also only use the colliders for collision detection by setting collisionTestingOnlyMode to true. This will allow you to manually change or apply forces or rotate the ball.
Best,
GüntherSeptember 27, 2016 at 11:34 #14935
AlexFelgo TeamHi Bill,
make sure to give the collider a density, Box2D requires this for the rotation. Then you can use applyTorque for rotation, you will have to calculate the force depending on the point where you clicked the ball.
I am pretty sure collisionTestingOnlyMode does NOT allow you to apply forces to a collider, it turns the collider into a sensor that is not affected by any physical forces, but emits signals upon collision with other colliders. You would need to use animations to move the balls then.
Cheers,
AlexSeptember 27, 2016 at 20:09 #14939
Bill
Thank you for your responses. Adding density worked. I ran into another problem that I’ve spent most of today trying to fix. I have health bars that show up when the balls are clicked. They are now rotating with the balls. I took a lot at the squaby demo and made the health bars into their own item. I got the rotating to stop, but the bars are still moving in a circle when the balls rotate. I can’t seem to get the bars to stay in one position.
HealthBar.qml
import Felgo 3.0 import QtQuick 2.0 Item { id: healthBar property real percent: 1.0 property bool ignoreParentRotation: true Binding { target: healthBar property: "rotation" value: -healthBar.parent.rotation when: ignoreParentRotation && visible } property alias absoluteX: nonRotatedItem.x property alias absoluteY: nonRotatedItem.y transformOrigin: Item.TopLeft Item { id: nonRotatedItem width: healthBar.width height: healthBar.height Rectangle { width: healthBar.width * healthBar.percent height: healthBar.height color: "#08dc05" opacity: 1 radius: 1 } Rectangle { width: healthBar.width height: healthBar.height color: "red" opacity: 1 radius: 1 anchors.right: parent.right } } }
Ball.qml
import Felgo 3.0 import QtQuick 2.0 import "../scenes" import "../entities" EntityBase { id: ball entityType: "ball" width: 55 height: 55 z: 1 property int hp: 100 property int spriteWidth: 55 property int spriteHeight: 55 property int cat: Circle.Category1 property real gScale: 1 property real lScale: 1 property string ballPic: "greenBall" property alias healthBar: healthBar CircleCollider { id: collider radius: spriteWidth / 2 gravityScale: gScale linearDamping: lScale categories: cat bodyType: Body.Dynamic fixture.density: 1/3025 fixture.restitution: 1 collidesWith: Box.Category2 | Box.Category3 } Image { id: sprite source: "../../assets/img/" + ballPic + ".png" anchors.fill: collider } MouseArea { id: mouse anchors.centerIn: collider onPressed: { bounce(player.power) } } HealthBar { id: healthBar absoluteX: -width absoluteY: -height width: sprite.width height: 5 percent: hp / totalHp visible: true } ... }
September 28, 2016 at 08:30 #14942
GüntherFelgo TeamHi Bill!
If the Health Bar rotation is stopped but it still moves in a circle, the issue is most likely a different rotation origin point.
For example: When the ball is rotated, the HealthBar also rotates, but not around itself. It rotates around the same axis/point as the ball to maintain its position even when rotated.
You can modify the HealthBar item to reverse the rotation but also take the origin point into account:
Item { id: healthBar property real percent: 1.0 property bool ignoreParentRotation: true // we take the center of the ball and map it to the coordinate system of the HealthBar item property point ballCenter: mapFromItem(parent, healthBar.parent.width * 0.5, healthBar.parent.height * 0.5) // we define the reverse rotation with the ballCenter as the origin point Rotation { id: reverseRotation; origin.x: ballCenter.x; origin.y: ballCenter.y; angle: -healthBar.parent.rotation } // when ignoreParentRotation is set, we apply the defined rotation transform: ignoreParentRotation ? reverseRotation : null property alias absoluteX: nonRotatedItem.x property alias absoluteY: nonRotatedItem.y // ... }
As we now use the ball center as the origin point to reverse the rotation, the position of the HealthBar will stay the same (if the ball is rotated around its center).
Best,
GüntherSeptember 28, 2016 at 20:27 #14950
Bill
Thank you for the response. That totally worked. I got my bars and other info that pops up above the balls to stop rotating. However I ran into another issue that I’m having trouble figuring out. I’m using a the following function to “bounce” the balls that gets called when the mouse area is clicked. My problem is the direction that the balls bounce depends on how the collider is rotated. So, if the collider is rotated 180 degrees the ball will bounce down instead of up.
function moveBall() { collider.body.linearVelocity = Qt.point(0,0) var localForwardVector = collider.body.toWorldVector(Qt.point(0, 100); collider.body.applyLinearImpulse(localForwardVector, collider.body.getWorldCenter()); }
September 28, 2016 at 21:24 #14951
Bill
After gaining a little more of an understanding of the function and what some of the body functions are doing. I stopped converting the Qt.point(0, 100) to a world vector and just added them to the applyLinearImpulse function. This is giving me the desired results. Thanks again for all the help.
function moveBall() { collider.body.linearVelocity = Qt.point(0,0) var localForwardVector = Qt.point(0, 100); collider.body.applyLinearImpulse(localForwardVector, collider.body.getWorldCenter()); }
You must be logged in to reply to this topic.