Forums

OverviewV-Play 2 Support (Qt 5) › Rotating a 2d circle on collision

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #14933

    Bill

    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.

    #14934

    Günther
    V-Play Team

    Hi 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@v-play.net?

    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ünther

    #14935

    Alex
    V-Play Team

    Hi 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,
    Alex

    #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 VPlay 2.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 VPlay 2.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
        }
        ...
    }  

     

    #14942

    Günther
    V-Play Team

    Hi 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ünther

     

     

    #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());
        }

     

    #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());
        }

     

Viewing 7 posts - 1 through 7 (of 7 total)

RSS feed for this thread

You must be logged in to reply to this topic.

Voted #1 for:

  • Easiest to learn
  • Most time saving
  • Best support

Develop Cross-Platform Apps and Games 50% Faster!

  • Voted the best supported, most time-saving and easiest to learn cross-platform development tool
  • Based on the Qt framework, with native performance and appearance on all platforms including iOS and Android
  • Offers a variety of plugins to monetize, analyze and engage users
FREE!
create apps
create games
cross platform
native performance
3rd party services
game network
multiplayer
level editor
easiest to learn
biggest time saving
best support