Learn what Felgo offers to help your business succeed. Start your free evaluation today! Felgo for Your Business

Forums

OverviewFelgo 1 Support › BoxCollider Movement

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #6400

    Fahmy

    In our game, we have an multiple Entities that will walk toward the center of screen with constant speed. When we use PathMovement it work perfectly like we want, but the collider will not work (the entity maybe on top of each other).

    From documentation, it is wrote that we need to use BoxCollider force to move the entity rather than PathMovement if we want the collider to working. But rather than the Entities look like walking to center, it will look like there are throwing to center (speed is not constant and sometime it too fast). And also, PathMovement will automatically rotate the Enitities toward target but not BoxCollider.

    So, how and what is the proper way to do it?

    #6401

    Alex
    Felgo Team

    Hi,

    I wrote a demo project upon a developer request in the forums a while ago, which matches your requirements pretty much. I changed the code a bit for you now, hopefully this gives you an idea of how to achieve it. It was about a gravitational pull towards the player, the major difference now is the applyGravityImpulse() function of the object, which now applies a constant velocity instead of an impulse (i didn’t change the old names of functions etc). So here’s the code:

    Player.qml

    import VPlay 1.0
    import QtQuick 1.1
    
    EntityBase {
      id: player
      entityType: "player"
    
      width: 25
      height: 25
    
      signal collidedWithObject(variant object)
    
      Rectangle {
        width: player.width
        height: player.height
        x: -player.width/2
        y: -player.height/2
        color: "blue"
      }
    
      BoxCollider {
        id: collider
        width: player.width
        height: player.height
        x: -player.width/2
        y: -player.height/2
        bodyType: Body.Static
        fixture.onBeginContact: {
          var collidedColliderComponent = other.parent.parent;
          var collidedEntity = collidedColliderComponent.parent;
          var collidedEntityType = collidedEntity.entityType;
          if(collidedEntityType === "object")
            collidedWithObject(collidedEntity)
        }
      }
    
      function getPosition() {
        return collider.body.getWorldCenter()
      }
    }
    

    Object.qml

    
    import VPlay 1.0
    import QtQuick 1.1
    
    EntityBase {
      id: object
      entityType: "object"
    
      width: 10
      height: 10
    
      Rectangle {
        width: object.width
        height: object.height
        x: -object.width/2
        y: -object.height/2
        color: "red"
      }
    
      BoxCollider {
        id: collider
        width: object.width
        height: object.height
        x: -object.width/2
        y: -object.height/2
      }
    
      function getPosition() {
        return collider.body.getWorldCenter()
      }
    
      function applyGravityImpulse(forward) {
        collider.linearVelocity.x = forward.x
        collider.linearVelocity.y = forward.y
      }
    }
    

    GravityLogic.js

    var player
    var objects = new Array
    var speed
    
    function addObject(entityId) {
      objects.push(entityManager.getEntityById(entityId))
    }
    
    function removeObject(entityId) {
      for(var i=0; i<objects.length; i++) {
        if(objects[i].entityId === entityId) {
          objects.splice(i,1)
          return
        }
      }
    }
    
    function applyGravity() {
      for(var i = 0; i < objects.length; i++) {
        var object = objects[i]
        var objectPosition = object.getPosition()
        var playerPosition = player.getPosition()
        // the distance could be useful if you want to apply the gravity only within a radius around the player
        var distance = Math.sqrt(Math.pow(Math.abs(objectPosition.x-playerPosition.x),2)+Math.pow(Math.abs(objectPosition.y-playerPosition.y),2))
        var atanY = playerPosition.y - objectPosition.y;
        var atanX = playerPosition.x - objectPosition.x;
        var angle = Math.atan2(atanY, atanX);
        var impulseX = speed*Math.cos(angle)
        var impulseY = speed*Math.sin(angle)
        object.applyGravityImpulse(Qt.point(impulseX,impulseY))
      }
    }
    

    main.qml

    import VPlay 1.0
    import QtQuick 1.1
    import "GravityLogic.js" as Gravity
    
    GameWindow {
      EntityManager {
        id: entityManager
        entityContainer: scene
      }
      Scene {
        id: scene
        property alias player: player
    
        PhysicsWorld {
          id: world
        }
    
        Player {
          id: player
          x: scene.width/2
          y: scene.height/2
          onCollidedWithObject: {
            Gravity.removeObject(object.entityId)
            object.removeEntity()
          }
        }
    
        Timer {
          id: gravityTimer
          interval: 300
          repeat: true
          running: false
          onTriggered: {
            Gravity.applyGravity()
          }
        }
    
        Component.onCompleted: {
          Gravity.player = player
          Gravity.speed = 20
          for(var i = 0; i <50; i++) {
            var entityId = entityManager.createEntityFromUrlWithProperties(Qt.resolvedUrl("Object.qml"),{"x":Math.random()*scene.width, "y":Math.random()*scene.height})
            Gravity.addObject(entityId)
          }
          gravityTimer.start()
        }
      }
    }
    

    If you have any questions about the code, feel free to ask 🙂

    Cheers,
    Alex

     

     

     

     

    #6433

    Fahmy

    Hi, thanks for the answer. I’ll try it and give feedback..thanks again!

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

RSS feed for this thread

You must be logged in to reply to this topic.

Qt_Technology_Partner_RGB_475 Qt_Service_Partner_RGB_475_padded