Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Extending a Codea class, in this case physics.body

edited November 2012 in General Posts: 25

As I'm not familiar with extending classes in LUA/Codea, somebody may help me out. I tried to use the physics.body property .info to store additional data e.g. an unique name, which I can use for the selection of certain bodies going through the bodies table. The .info property was not functioning in the way I thought. But can I extend the body class with properties like .name, .color and so on? How to do that?
Advice very appreciated, thanks in advance!

Comments

  • Jmv38Jmv38 Mod
    Posts: 3,295

    I'm not an expert, so you'll probably get a better advice than mine, but just in case here is how i did it for the mesh class: i create a class that include the object:

    MyMesh = class()
    function MyMesh:init(name)
       self.ms = mesh()
       self.name = name
    end
    

    then i access the mesh properties via myvar.ms and my property xxx via myvar.xxx

    the great point with lua is you can add properties on the fly, without initial declaration!

  • JohnJohn Admin Mod
    Posts: 564

    What was the info property doing that you weren't expecting? I think an issue people have run into with body.info is that they try to set properties on it directly like body.info.myTable = {}, whereas what you need to do is body.info = myTable. I think it might be best to put an empty table in body.info by default so people stop running into this issue.

  • edited November 2012 Posts: 580

    .@John To me the confusing thing is that body.info initially seems to point at _G, which I don't understand. At first I disliked your suggestion for putting an empty table in body.info by default, because I thought it would be wasteful in case you didn't need it, but now that I think about it more I can't think of a time I've ever *not* needed it (though I've not used Codea's physics library much, I've used c++ Box2D in other projects, and usually you would assign the actor that "owns" the body to the 'userdata' property, which is what body.info seems to be emulating). So honestly that seems like a pretty good idea.

    I think it would be a good idea though if Codea could enforce that you could only assign tables to body.info, because it seems like it's just like any other property on a table. Also, would it be possible to lazily create a table and assign it to body.info if you attempt to do a read access on it (e.g. body.info.whatever) and a table has not been assigned to it yet? That would be the best of both worlds: it would just work the way people expect, and it wouldn't waste memory creating a table by default it the programmer never used the body.info property.

    EDIT: pretty much re-wrote this entire post a couple of times.

  • JohnJohn Admin Mod
    Posts: 564

    The lazy table creation seems like the best way to go. I haven't heard of it pointing to _G initially, that must be a bug due to it being uninitialised.

  • JohnJohn Admin Mod
    Posts: 564

    I did some experiments and decided to add generic table access to body and most of Codea data types. This means that you'll be able to set whatever key you like aside from built-in properties to whatever value you want. body.info will still work, as will any other named key that isn't being used for something.

    For example:

    local circle == physics.body(CIRCLE, 30)
    circle.myData = {key1=value1, key2=value2}
    circle.name = "henry"
    circle.magicNumber = 42
    -- this will cause an error because radius expects a number and cannot be overridden
    circle.radius = "foo"
    
  • edited November 2012 Posts: 25

    Thanks for your replies.
    What I tried to do some time ago and it didn't work was something like that

    in Main ...
    
    function createMouse(x,y,r)
        mouse = physics.body(CIRCLE, r)
        mouse.fixedRotation = true
        mouse.interpolate = true
        mouse.x = x
        mouse.y = y
        mouse.restitution = 0.05
        mouse.sleepingAllowed = false
        mouse.friction = 0.00001
        mouse.info = "mouse"
        PhysicsDraw:addBody(mouse)
        return mouse
    end
    
    in Physics.Draw ...
    
    for i,body in ipairs(self.bodies) do 
     if body.info == "mouse" do ...
      else ...
     end
    end
    
    

    It failed and I stored it in my memory as "does not work". It also failed with integers.

  • JohnJohn Admin Mod
    Posts: 564

    To get it to work at the moment you have to set body.info to a new table and then you can set properties on it instead. In the upcoming release of Codea built-in types like body will function like tables as I described above.

  • Posts: 25

    Thanks, John - now I remember, that tables are the basic data type in LUA. I should have thought about it when the manual says "... to store arbitrary data".
    Thanks again, that helped a lot!

  • Posts: 489

    Now implemented in Codea version 1.5:

    --
    -- myBody.myCustomField
    -- in Codea 1.5
    --
    
    function setup()
        myBody = physics.body(CIRCLE, 10)
        print(type(myBody)) -- Output: userdata
        myBody.myCustomField = "myData"
        print(myBody.myCustomField) -- Output: myData
    end
    
    function draw() background(0) end
    
Sign In or Register to comment.