Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
Extending Gideros - Page 4 - Gideros Forum

Extending Gideros



  • @ar2rasween Was just taking a look at it myself but that was quick. Thanks, I can confirm that works.

    Also, whilst I've been playing with it, I thought it might be an idea to split things up into logical parts. I don't need most of the stuff in the library and I'd like to be able to just keep the parts I do want up to date when changes are made, e.g. just the Sprite stuff for example. It seems a bit of an overhead to load everything in.

    What are the plans for this going forwards? It's getting quite large.
  • @moopf, and @ar2rsawseen, I did suggest a way of splitting the file up in my post to this thread on Oct 6th. I don't think we should split it into lots of different sections though, since that will just be more for the beginner to think about.

    best regards
  • @bowerandy ah yes, I've read that fully now. I don't think lots of different sections would work, you're right, it would end up being more hassle than it's worth. I actually quite like your proposed idea for splitting it up.
  • ar2rsawseenar2rsawseen Maintainer
    edited October 2012
    I also agree with @bowerandy and will try to come up with a list of all functionalities and then divide them in two groups and present here for public approval and modifications before implementing ;)

    But just for clarification, what bothers you more? used up space, or stack of virtual function calls?

    If it's the first, then functionalities probably should be divided in two different files, if it's the second, I might try to provide some kind of configuration options, on what to enable or not?
  • Hi @ar2rsawseen I'm not really bothered per-se, it's more just the general overhead of a lot of stuff I don't really need and I'm not sure adds much (I'm not keen on the chaining, for instance).

    There are things in this library that are absolutely crucial - such as the changes to objects for anchor points - and then there are convenience facilities that aren't really about extending the functionality, more about creating a layer between the Gideros core and the user for easier use which, whilst some may be useful, serve a slightly different purpose to extending functionality.

    Also, I had to remove the mouse/touch cross-compatibility in order to get my app running again after including the library - there shouldn't be any need for this now, should there?

    To be honest I need to delve into the other facilities offered by the library a bit more - I really picked it up and put it in my app to get the anchor point stuff quickly first of all :)

    Likes: bowerandy

    +1 -1 (+1 / -0 ) Share on Facebook
  • bowerandybowerandy Guru
    edited October 2012
    Hi @ar2rsawseen, I agree with what @moopf says above. It isn't the size of the library particularly, more the feeling of a loss of control should something go wrong. This is all going to be core stuff that absolutely must be rock solid and, without some sort of regression tests, will give an uneasy feeling each time a new Gideros release comes out.

    This feeling would be eased somewhat if the library were smaller and simpler. As @moopf says, there are things in there that are really crucial but others not so. Tricky thing is deciding what is important to some people and what is to others.

    One problem I have found, (and I don't think there's a way around it), is that of errors. Currently, if you make a programming mistake that causes an error in one of the built-in Lua functions you will get an error message that directly pertains to your code. However now, especially since the init library overrides a large number of built-in functions, the error will occur in init.lua and sometimes a couple of calls down.

    Yes, mostly you still have the backtrace so you can find the line in your code that caused it but by now the error message is not relevant to this point. It's made worse by the fact that, if the error causes the program to exit, you won't have the stack trace at all. For example:
    -- if bottle1 should be bottle
    self.world:createRectangle(bottle1, {type="dynamic", draggable=true, resitution=0.5})
    I get:
    init.lua:1651: attempt to index local 'object' (a nil value)
    stack traceback:
    	init.lua:1651: in function 'createRectangle'
    	SoftHands.lua:32: in function 'addBottle'
    	SoftHands.lua:49: in function 'init'
    	[string "property.lua"]:31: in function 'new'
    	SoftHands.lua:57: in main chunk
    This is not too bad but I do need to be able to understand the createRectangle() function to find out what is going on. Some of the meta functions (not this one) might be a bit hard for folks (including me) to understand.

    Worse is:
    -- Bg1.png does not exist
    local bg=Bitmap.new("Images/Bg1.png")
    init.lua:1020: Images/Bg1.png: No such file or directory.
    stack traceback:
    Unfortunately, I have no idea from this where in the my code the problem occurred.

    As far as I can see, the only way to get around this problem is to minimize the number of built-in functions that are overridden and to make the functions that are present easy to understand. I guess this is why I'm not keen on stuff like the chaining and the named coordinates ("centre" etc). These features need to override a lot of built-in functions and can be tricky to understand.

    Please don't take this as criticism. I'm using this library all the time now, I just think it needs a bit of thinking through.

    best regards
  • Oh, I don't mind criticism @bowerandy.
    I've also been thinking about this problem and wondered if the error problem could be solved by increasing the error level

    error (message [, level])
    The level argument specifies how to get the error position. With level 1 (the default), the error position is where the error function was called. Level 2 points the error to where the function that called error was called; and so on.
  • ar2rsawseenar2rsawseen Maintainer
    edited October 2012
    And here's a list of all enhancements and dependencies, so how should we divide it?
    Take into consideration, that if both features override same methods, then it can be combined in one method override and not two, if they are put together. :)

    Global Additions
    • print_r - recursive print of tables
    • math.round - rounding numbers to provided percision or full number
    • chaining - each non-returning functions returns self for chaining
    • AnchorPoints - setting anchorpoint of Sprite and all Sprite inherited objects. Adds two more methods for setting/getting anchor points, overrides set, get, setRotaiton, setScale, setScaleX, setScaleY, setPosition, setX, setY, getPosition, getX, getY
    • Absolute positioning - allows setting position of sprite ignoring automatic scaling. Adds three more methods, setAbsoluteX, setAbsoluteY, setAbsolutePosition, which accept named positions as "top", "bottom", "left", "right", "center" or numbers (dimensions ignored by scaling can be obtained using Application:getAbsoluteWidth and Application:getAbsoluteHeight, but basically I think that absolute dimensions are useless without named positions). Overrides set method.
    • Z-index control - controlling z-index of sprite. Adds 9 methods: bringToFront, sendToBack, setIndex, getIndex, addChildAtBack, addChildBefore, addChildAfter, replaceChild
    • Sprite collision - detects collision between untransformed bounding boxes. Adds 1 method: collidesWith
    • Ignore inputs - ignore touches on sprites. Adds 3 methods: ignoreTouchHandler, ignoreMouseHandler, ignoreTouches
    • Sprite dimensions - setting dimensions of sprites based on scaling. Adds 2 methods: setWidth, setHeight
    • Sprite transformations - some additions to transformations. Adds 5 methods: setSkew, setSkewX, setSkewY, flipHorizontal, flipVertical. Overrides: set method
    • Sprite visibility - Hides sprite from touches. Adds 4 methods: hide, isHidden, show, isVisibleDeeply
    • Shorthand for texture pack - Allows to create TexturePacks as TexturePack.new("packname"). Overrides: TexturePack.new

    • Shorthand for Bitmap - Allows to create Bitmap without texture, as Bitmap.new("myimage.png"). Overrides Bitmap.new
    • Fix for anchor point - allows providing only when anchorpoint when setting same for both x and y. Overrides: setAnchorPoint
    • Retrieving texture - returns texture of Bitmap. Adds 1 method: getTexture
    • Baseline fix - fixes positions of TextField. Overrides: TextField.new
    • Text Shadows - create shadows for texts. Adds 1 method: setShadow(offX, offY, color). Overrides: TextField.new, setText
    • Drawing abstraction: different drawing abstraction methods. Adds 8 methods: drawPoly, drawRectangle, quadraticCurveTo, bezierCurveTo, drawRoundRectangle, drawEllipse, drawArc, drawCircle. Overrides: Shape.new, moveTo, lineTo
    • Getting shape points - returns points of current shape. Adds 1 method: getPoints. Overrides: Shape.new, moveTo, lineTo, clear
    • Fix content dimension - returns devices dimensions when logical dimensions are not set, taking orientation into account. Overrides: getContentWidth, getContentHeight
    • Provide absolute dimensions - retrieves absolute dimensions for absolute positioning (ignoring scaling). Adds 2 methods: getAbsoluteWidth, getAbsoluteHeight
    • Controlling app sound volume - way to control global volume of app (can be applied only to global application instance). Adds 2 methods: setVolume, getVolume. Overrides: Sound:play
    • Controlling texture filtering - way to control texture filtering globally(can be applied only to global application instance). Adds 3 methods: enableFiltering, disableFiltering, isFilteringEnabled. Overrides: Font.new, TTFont.new, Texture.new
    • App exit fix - app should exit only on Android system
    • Loop sounds - loops provided sound. Adds 1 method: loop
    • Is Playing - check if sound is playing. Adds 1 method: isPlaying. Overrides: Sound.new, SondChannel.stop
    • Matrix transformations - provides abstraction for matrix transformations. Adds 14 methods.
    Named colors
    • Provides a way to set colors using color names - Overrides: TextField,:setTextColor, Application:setBackgroundColor, Shape:setFillStyle, Shape:setLineStyle
    Box2d enhancements
    • Box2d object creation - methods for creating box2d objects from Sprite object. Adds 5 methods: b2.World:createRectangle, b2.World:createCircle, b2.World:createTerrain, b2.World:removeBody, b2.World:update
    • Vector object - provide some vector calculations. It's own object, no extensions or dependencies.
    • Local collisions - provide callbacks for collisions between two objects. Adds 2 methods: addBeginContact, addEndContact. Overrides: World.new
    • Drag'n'drop - draggin for physical objects. Adds 2 methods: b2.World:makeDraggable, b2.World:undoDraggable
    • Easy debug - wrapper for debug, Adds 1 method: getDebug
    • Merging sprite and body concept: overrides all body and fixture methods, by making them accessible from sprite object, and overrides sprite set, to control body together with sprite.
  • I haven't played with this at all (which I should have done, really, before asking), but wondered if, when you say things override existing methods, does that rule out the existing methods altogether? For instance, under shape you list 8 abstraction methods and then say that they override Shape.new, moveTo and lineTo. Does that mean that you won't be able to use Shape.new, moveTo or lineTo or does it mean that you have the new methods alongside the existing ones?
    Thanks, Pete
  • ar2rsawseenar2rsawseen Maintainer
    edited October 2012
    @petec no not at all. All existing functions are still provided. Basically when loading this lib, your previous application should work as before, except some cases, for example, position of TextField might be slightly different, because of the baseline fix. (Which I just got an idea, can be fixed, by providing a was to set baseline of TextField to top, middle and bottom).

    Overrides basically means that it adds something to existing functions, by maintaining its main purpose. Overrides are mentioned to state the dependencies of features, so they could be combined in groups more efficiently.

    BTW. the heaviest override is probably for chaining, but actually I really like it, as it makes code shorter and cleaner. But I guess that chaining should definitely be optional. (Better of course if @atilim implements it natively :) )

    And PPS.
    If I forgot something anyone suggested to add before and I didn't do it, please, remind me. ;)
  • It's interesting how different developers have different ideas of what makes cleaner code. Personally I find chaining less clean, forsaking clarity for brevity. Although Objective-C goes way too far (in my opinion) in the other direction, you cannot fault the clarity it provides in my opinion (although it's tedious to develop in because it's so verbose).
  • @ar2rsawseen Thanks for clarifying that for me. It was the word override that was making me unsure. One of the things I found frustrating about Gideros when first switching from Corona was that some processes seemed quite long winded. I now find that I actually quite like that long windedness as it feels like I am more in control of what's going on and have more options of what will happen. That's why I was worried that existing functions/methods would be overridden completely. There's lots in your extension that looks as if I would use it, so I will give it a go sometime soon.
  • I think by cleaner code, they were just referring to less code for the end user using this extension which is aimed at an easier entry point for beginners if I'm not mistaken. I've always seen it as there is two types of clean when dealing with code, readability and efficiency, both are very important.
  • ar2rsawseenar2rsawseen Maintainer
    edited October 2012
    Well it must be because I come from a javascript background (have used too much jquery), but aren't you just in love when you see something as beautiful as this? :x
    local text = TextField.new(font, "Some text")
    	:setAnchorPoint(0.5, 0.5)
    	:setShadow(3, 3, "gray")
    local shape = Shape.new()
    	:setFillStyle(Shape.SOLID, "red")
    	:drawCircle(100, 100, 100)
    	:addEventListener(Event.TOUCHES_BEGIN, function(e)
    • in ten lines it saves you about 40 symbols of typing
    • you can easily rename variable later, without renaming it in every line
    • it makes you structure your code accordingly, that firstly you set up your object and only then use it somewhere
    +1 -1 (+3 / -0 ) Share on Facebook
  • More easy! I like!
  • Hi @ars2rsawseen - Ah jQuery, something I don't like using :) I'm not sure why, I've always presumed it's because I've been a developer in C and C-like languages for so long (20+ years) that I find it completely backwards. Old dogs and new tricks etc.

    I have to use jQuery quite a bit for my web development work and I've never enjoyed it! I much prefer writing js directly.
  • @moopf, for leisure so am I. I'm writing plain JS

    But for work, with limited time and resources, you can't say no to jquery and all it's plugins :)
  • bowerandybowerandy Guru
    edited October 2012
    @ar2rsawseen, I had an idea for another function to add to the library. I do find a need to use this sort of thing occasionally. It's a postToInputQueue() feature as detailed in this thread.
    If you do decide to add it, it should probably be a member function of the stage and not a global function as I have there.

    UPDATE: another example of where it can be used is to replace some dodgy calls to Timer.delayedClass(). Take a look at line 63 in this demo of my snapshot screen to png file demo. One can't snapshot the screen until everything has been painted on it. I use a delay, but a better solution would be to wait until the next frame is ready.

    best regards
  • @arthurs, that is like the
    with object
     .someAttr = someValue
    end with
    that is definitely something that will be nice to chain them.

    In either case, it is not used, so for those that want to use it traditionally, they can continue to use it, and those that want to chain them can.

    I personally think that this is going to be a big help, it is just it will take time to proliferate into mainstream development.

    Likes: ar2rsawseen

    twitter: @ozapps | http://www.oz-apps.com | http://howto.oz-apps.com | http://reviewme.oz-apps.com
    Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
    Cool Vizify Profile at https://www.vizify.com/oz-apps
    +1 -1 (+1 / -0 ) Share on Facebook
  • @ar2rsawseen Your jQuery like example is a thing of pure beauty. Lol I too have used jQuery a bit too much and often miss that kind of chaining. It's just so easy.. :)
    ThumbHurt Games / FB: ThumbHurt Games / FB: Eli/Teranth | Skype: teranth37
  • Hey guys, I am not sure if this has already been answered someplace, but is this GiderosInit code MIT licensed or something to that extent?

    I don't see a license notice in the main file but I figured it probably was since most of Gideros Examples/Libraries seem to be. I figured I better ask anyway since I like to know where I stand with code before I use it in apps :)

    Looks to be a very helpful little library. Thanks guys.
    ThumbHurt Games / FB: ThumbHurt Games / FB: Eli/Teranth | Skype: teranth37
  • @Teranth that's actually pretty good question, because lot's of functions are simply collection of hacks found around the forum combined in one place. But probably the license should be as limitless as possible, so yes, you can count it MIT. ;)

    Likes: Teranth

    +1 -1 (+1 / -0 ) Share on Facebook
  • TeranthTeranth Member
    edited October 2012
    @ar2rsawseen Great to hear, I will certainly be making use of this library, and of course if I have posted anything that would be a useful add to the library feel free to include it as well for everyone :)

    I've been missing a little while, seems like you guys have come up with a lot of cool things since I last dropped by. :)
    ThumbHurt Games / FB: ThumbHurt Games / FB: Eli/Teranth | Skype: teranth37
  • Refactored a project a bit.
    Basically change it's name, thus the change of repo link:

    Since init.lua may be used also for other purposes, copied everything into separate lua file which can now be implemented by disabling execution for it and requiring it inside init.lua file. Example shown in the commited project.

    And separated chaining, you can find chaining related stuff between
    --[[ CHAINING STARTS ]]--
    --[[ CHAINING ENDS ]]--
    And if you don't want to use it you can simply remove it, everything should work fine without it.

    Of course other implemented and overridden methods will probably return self, but that does not create much overhead and does not interfere if you are not using chaining.


    Likes: bowerandy

    +1 -1 (+1 / -0 ) Share on Facebook
  • @ar2rswaseen, FAB! I'll try it out as soon as I can.

    best regards
  • Very cool, I will download and test things out asap. :)
    ThumbHurt Games / FB: ThumbHurt Games / FB: Eli/Teranth | Skype: teranth37
  • MellsMells Guru
    edited December 2012
    What do you think about adding alignAxisToVect in this lib?
    @atilim has provided a solution.

    For example that would allow to :
    • align object's X axis to the stage's Y axis
    • align turret's cannon X axis to enemy's direction
    • align character's Y axis to the normal of the object/polygon that he is walking on
      • send ray (rayCast(to, from, distance, property, face, xray)) from the character to the platform he is walking on
      • get the normal at the hit's position
    • Align the character's y axis to the normal
    This is how it's been implemented in Blender's Game Engine :


    <strong>alignAxisToVect(vect, axis, fac)</strong>
    Aligns a Game Object axis to a World vector.
    vect:    Uses the World axis as it's base reference.
    Type:  3D Vector
       [ 1.0, 0.0, 0.0] = World X-axis
       [ 0.0, 1.0, 0.0] = World Y-axis
       [ 0.0, 0.0, 1.0] = World Z-axis
    axis:   Game Object axis
    Type:  integer
      0 = Game Object x-axis
      1 = Game Object y-axis
      2 = Game Object z-axis
    fac:   Determines the "speed" of the alignment over multiple frames.
    Type:  float
    Range:  0.0 to 1.0
         0.0 = no movement
         1.0 = instantly
    and also


    Returns the alignment of the Game Object's x-axis and y-axis and z-axis to a World vector.
    Return type:   List [   cosine of the angle of object x-axis to a world vector, 
    cosine of the angle of object y-axis to a world vector,
    cosine of the angle of object z-axis to a world vector   ]
         Type:  List [ worldX, worldY, worldZ]
         A world vector pointing in the direction of the World X axis: [1.0, 0.0, 0.0]
         A world vector pointing in the direction of the World Y axis: [0.0, 1.0, 0.0]
         A world vector pointing in the direction of the World Z axis: [0.0, 0.0, 1.0]

    but also having access to rayCast (without Box2D) would be great :


    <strong>rayCast(to, from, distance, property, face, xray, poly)</strong>
    Casts a ray from one object/point to another object/point.  Returns the first object hit that has the correct property.  
    Returns the game object, the hit point and hit normal (poly = 0)
    Returns the game object, the hit point, hit normal and polygon (poly = 1)
    Method Parameters
              Type:  KX_GameObject
                 Position  [ x, y, z ]  World coordinates. 
              Type:  KX_GameObject
                Position  [ x, y, z ]  World coordinates.
              Type:  float
              distance can be negative 
                   look behind the object rayCast is attached to.
              distance = 0.0 
              ray stretches all the way to the other object center or position.
              Property on an object that triggers the ray.
              property = ""
                   all properties trigger ray
              Type:  int
                 1 = return face normal
                 0 = normal is oriented towards origin
              Type:  int
                 1 = x-ray on.  Check behind objects that don't have property
                 0 = x-ray off.  Only check first object hit.
              Type:  int
                 1 = return polygon (KX_PolyProxy)
                 0 = don't return polygon (KX_PolyProxy)
    Return type: 
         poly = 0
              list [ GameObject, hit, normal]
                  Returns [ None, None, None] if nothing was hit.
         poly = 1
              list [ GameObject, hit, normal, polygon]
                  Returns [ None, None, None, None] if nothing was hit.
    Return Parameters
         GameObject:  The game object that triggered the ray.
                   Type:  a KX_GameObject
         hit:   The position of the hit.  (The distance from the starting position of the ray.)
                   Type:  List [ x, y, z]
         normal:  The normal of the surface that the ray hit.  (The angle of the hit.)
                   Type: list [ x vector, y vector, z vector]
                   Type:  KX_PolyProxy
         The ray detects ghost objects.
         The ray ignores objects with Object type: No collision
         The ray ignores faces that don't have the collision flag enabled.


    <strong>rayCastTo(other, disance, property)</strong>
    Returns the KX_GameObject that trips rayCastTo. (Acts like a laser beam trip wire between one object and an object/position.)
    Method Parameters
                 Type:  KX_GameObject (object center)
                 a position  ( [x, y, z])  float values.
                   Type:  float
                   distance can be negative 
                        look behind the object rayCast is attached to.
                   distance = 0.0 
                        ray stretches all the way to the other object center or position.
              Property on an object that triggers the ray.
              property = ""
                   all properties trigger ray
              Return Type:  KX_GameObject
              Returns None if it doesn't find anything.

    Likes: Teranth

    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
    +1 -1 (+1 / -0 ) Share on Facebook
  • This is not adding any code, but a simple observation, (positive of course). Like many developers prior to Gideros I too came from C*SDK. I had created a couple of libraries and then had to take them off for various reasons. The point or the observation is that here everyone is working towards creating a single source, a common library or set of functions unlike on C*SDK where the focus (even today) is to have a small snippet and call it a library. There are so many libraries created to manage saving data to a file, I believe it would be better to have a single source which could be collaborated on rather than everyone trying to be a cowboy and bask in their own glories.

    So kudos guys, come on in share the love and the code.

    The only issue that I have seen sometimes with some sample code is people using absolute paths (i.e their own setup paths) and expecting the presence of certain dependent files which renders the code not runnable. If that could be avoided, then it would be so wonderful.

    Likes: gorkem, Mells

    twitter: @ozapps | http://www.oz-apps.com | http://howto.oz-apps.com | http://reviewme.oz-apps.com
    Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
    Cool Vizify Profile at https://www.vizify.com/oz-apps
    +1 -1 (+2 / -0 ) Share on Facebook
  • @ar2rsawseen: I have just noticed a small error in GiderosCodingEasy.lua. In the function Textfield:setShadow, there is a reference to a variable alpha on line 727 in the color code
    	if color then
    		if alpha then
    but there is no alpha passed to the function. I think you missed it from the function definition
    function TextField:setShadow(offX, offY, color)
    should be
    function TextField:setShadow(offX, offY, color, alpha)
  • There's some strange weirdness when using anchor points on BMFont sprites - GiderosCodingEasy will add the anchor point facilities to BMFont correctly but, if you change the text, you need to ensure that you re-call setAnchorPoint otherwise when the changed text first displays it's in the wrong position. Probably only really noticeable if you're using a non 0,0 anchor point, but thought I'd post about it here in case other people were encountering the same problem.
Sign In or Register to comment.