Forums

OverviewV-Play 1 Support › Gravity in Space

Tagged: , ,

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #6142

    AKroell

    Hello,

    I am currently working on a space-themed physics game. Basicly a scene consists of a spaceship (the player) and various other objects. There is no gravity in the gameworld per se but each object should have it’s own “gravitational pull” on the player.

    So my question is if there is a way to give entities a gravity property or another easy way to solve this problem with the physics engine of if i should rather use a movement vector for the spaceship and calculate it’s direction and size every frame based on the distance to each object on the screen?

    thanks in advance,

    AK

    #6149

    Alex
    V-Play Team

    Hi,

    I am not aware of any super easy solution to this. However, I prepared a small example which you maybe can take as a starting point to achieve your desired behavior.

    Player.qml

    import VPlay 1.0
    import QtQuick 1.1
    
    EntityBase {
      id: player
      entityType: "player"
    
      width: 25
      height: 25
    
      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
      }
    
      function getPosition() {
        return collider.body.getWorldCenter()
      }
    }
    

    Object.qml

    import VPlay 1.0
    import QtQuick 1.1
    
    EntityBase {
      id: object
      entityType: "object"
    
      width: 4
      height: 4
    
      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 applyGravityImpuls(forward) {
        collider.applyLinearImpulse(forward,getPosition())
      }
    }
    

    GravityLogic.js

    var player
    var objects = new Array
    var force
    
    function addObject(entityId) {
      objects.push(entityManager.getEntityById(entityId))
    }
    
    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 = force*Math.cos(angle)
        var impulseY = force*Math.sin(angle)
        object.applyGravityImpuls(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
        }
    
        Timer {
          id: gravityTimer
          interval: 100
          repeat: true
          running: false
          onTriggered: {
            Gravity.applyGravity()
          }
        }
    
        Component.onCompleted: {
          Gravity.player = player
          Gravity.force = 0.5
          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()
        }
      }
    }

    Is this what you were looking for?

    Cheers,
    Alex

    #6198

    AKroell

    Hello Alex,

    thank you very much! It helped us a lot!

     

    For some reason

     bodyType: Body.Static

    didn’t work the first time i tried it, but now it does.

     

    regards,

    AK

    #6200

    OutOfBounds

    Hello Alex,

    as I’m currently working on a project with AKroell, we tried the code above and changed the collider type to a circleCollider, because we want to display planets on screen.

    We now have a problem with setting the bodyType to Body.Static.

    If we don’t set the bodyType the circleCollider is working, but the planets are moving around in space.

    We want to achieve, that the planets have a fixed position and don’t move.

    For solving this problem we need to set the bodyType of the circleCollider to static, but this does not work properly.

     

    Maybe these pictures help understanding our problem: http://imgur.com/a/SR59l

     

    Thanks in advance

    AG

    #6201

    Alex
    V-Play Team

    Hi,

    I’m sorry, I don’t quite understand your problem. In my demo, we have 1 player that is static and all objects move towards him. What is your exact setup?

    Is what you call a planet the same thing as the player in my demo? Do you have more then one “players” then?

    From your screenshots i can only see that the objects obviously collide with the planet in the first picture and they do not collide in the second one, but I don’t know if that is the problem you are talking about!?

    Cheers,
    Alex

    #6202

    OutOfBounds

    Hi,

     

    That’s what I call a planet is the same as the Player in you demo. We have multiple static planets per level.

    The problem is, that if we set the bodyType of the collider of the planet to “static”, they don’t collide with the planets.

    If we don’t set the bodyType, the objects do collide with the planets, but the planets are moving around.

     

    It’s quite hard to explain the problem, i hope you understand it now.

     

    BR

    Alex

    #6203

    Alex
    V-Play Team

    I tried something similar without any troubles, so it is definitely possible to do, you can download the source code here. You should be able to track down your problem by comparing the code I think.

    If you have no success, feel free to send me your source to support@v-play.net and I will have a quick look if i can solve it. I fear i can’t help you out any further without the source code though.

    One thing worth mentioning: You have to be aware that large numbers of objects in combination with several planets will have a huge impact on the performance.

    Cheers,
    Alex

    #6204

    AKroell

    Thank you very much Alex, I will compare the two today.

    We are aware of the performance issues with a lot of objects (like in the picture) we just used so many for testing purposes. In the final version there will only be one object affected be multiple planets.

    BR,

    AK

Viewing 8 posts - 1 through 8 (of 8 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