Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Get values from child sprite? — Gideros Forum

Get values from child sprite?

rio8rio8 Member
edited April 2014 in General questions
Hi everyone, I've been using Gideros for a few days and I'm trying to add support for collision masks into a simple collision function but I'm having some trouble

I have a class, RedSquare, and I want to add a child, maskSprite, so I'm doing it like this
RedSquare = Core.class(Sprite)
 
local maskSprite
 
function RedSquare:init()
	local bmp = Bitmap.new(Texture.new("redsquare.png"))
	bmp:setAnchorPoint(0.5, 0.5)
	self:addChild(bmp)
 
	local mask = Bitmap.new(Texture.new("redsquare_mask.png"))
	mask:setAnchorPoint(0.5, 0.5)
	maskSprite = Sprite.new()
	maskSprite:addChild(mask)
 
	self:addChild(maskSprite)
end
When I run the project, it seems to work fine and the mask follows the main object wherever it moves

The problem is, when I want to get the X value of the mask in RedSquare's update function (so I can pass it to the collision function)

If I do this:
print(maskSprite:getX())
It just prints 0.... But I can see that the mask is definitely not at 0

I'm sure I'm setting up the sprite the wrong way somehow but I can't figure it out, can anyone help?

Thank you

- 'Rio

Comments

  • hgvyas123hgvyas123 Guru
    edited April 2014 Accepted Answer
    actually maskSprite is a child of RedSquare and it is at the position of 0,0 in redsquare now if you move the redsquare masksprite will also move as redsquare is parent but still it is at 0,0 in redsquare so you will always get 0 for the print(maskSprite:getX()) .

    you should try localToGlobal or local x,y,width,height = masksprite:getBounds(stage) to get the position of masksprite in actual screen or simply use the position parent sprite

    :)
  • rio8rio8 Member
    actually maskSprite is a child of RedSquare and it is at the position of 0,0 in redsquare now if you move the redsquare masksprite will also move as redsquare is parent but still it is at 0,0 in redsquare so you will always get 0 for the print(maskSprite:getX()) .

    you should try localToGlobal or local x,y,width,height = masksprite:getBounds(stage) to get the position of masksprite in actual screen or simply use the position parent sprite

    :)
    I got it working perfectly with localToGlobal, thank you!
  • Hello!
    I'm having the same issue but in my case I tried all the way possible and nothing happens. I have a sprite that starts with initial positions, but on mouse event I can change its position to whatever I want. This sprite is initiated on level class. Later, enemy is initiated, and I've set the sprite as parameter to get the values but indepently what I do, my enemy sprite receives always the sprite initial positions, never update its value... I have no idea of what this might be... If anyone has any life is appreciated.
  • @Paulo777 your description of the issue is not really descriptive.. could be anything from here :) if you post some code it may help to help
  • Paulo777Paulo777 Member
    edited February 2018
    On my ship class I have:
    Ship = Core.class(Sprite)
     
    function Ship:init()
     
    self:setPosition(230, 200)
     
    self:addEventListener(Event.TOUCHES_MOVE, self.events, self)
     
    end
     
    function.onMouseMove(self, event)
     
        if self:hitTestPoint(event.x, event.y)
            self.x = event.touch.x - self:getWidth()/2
            self.y = event.touch.y - self:getHeight()/2
        end
            self:setPosition(self.x, self.y)
    end
    On my enemy class I have:
    Enemy = Core.class(Sprite)
     
    function Enemy:init(sprite)
     
        self:setPosition(0, 0)
     
        self.x = sprite:getX()
        self.y = sprite:getY()
     
    end
    And on level code I have:
     
    Level = Core.class(Sprite)
    local ship
     
    function Level:init()
     
        self:setPosition(0, 0)
        ship = Ship.new()
        self:addChild(ship)
        self.counter = 1
     
        self:addEventListener(Event.ENTER_FRAME, self.events, self)
     
    end
    In the function events I have:
     
    function Level:events(event)
     
        self.counter += 1
     
        if self.counter >= 400 then
            local enemy = Enemy.new(ship)
        end
    I tried everything and nothing... I even tried to create custom event, but also nothing... everything I get is the ship initial positions.... never get it to update... never updates...
  • Paulo777Paulo777 Member
    edited February 2018
    I want to know why this happens and why I am doing wrong
  • minimally i'd change the order of lines:
    Enemy = Core.class(Sprite)
     
    function Enemy:init(sprite)
     
        self.x = sprite:getX()
        self.y = sprite:getY()
     
        self:setPosition(self.x, self.y)
    end

    Likes: Paulo777

    +1 -1 (+1 / -0 )Share on Facebook
  • keszegh said:

    minimally i'd change the order of lines:

    Enemy = Core.class(Sprite)
     
    function Enemy:init(sprite)
     
        self.x = sprite:getX()
        self.y = sprite:getY()
     
        self:setPosition(self.x, self.y)
    end
    Hello! Thank you for your return, but by what I've got the enemy would set its position to the sprite position.. but what I want is: every time I move my "ship" sprite, is for the enemy to get this curren sprite position... that is what's not doing... firstly, it does... but when I move the sprite, the sprite on the screen updates... but on enemy doesn't... and doesn't matter what I do it never changes...
  • keszeghkeszegh Member
    edited February 2018
    well, the ship does not know about these enemies, so no surprise there.
    either you should add the enemies to the ship instead of to the stage as child. that's simplest.

    alternatively, which could be better in some use cases, you should make an empty table inside the ship init function, like self.enemies. and then every time you create a new enemy you should add it to this table as well (you can have a function Ship.addEnemy(enemy) e.g. for this and then call this function).
    finally, in the ship event function you should update along with
    self:setPosition(self.x, self.y) also the position of every enemy in the table like
    for i=1,#self.enemies do
    self.enemies[i]:setPosition(self.x,self.y)
    self.enemies[i].x=self.x
    self.enemies[i].y=self.y
    end
    btw having properties self.x and self.y are pretty unnecessary as you could simply get the coordinates by calling self.getX() and self.getY() and then there is no issue about updating self.x and self.y.

    Likes: Paulo777

    +1 -1 (+1 / -0 )Share on Facebook
  • olegoleg Member
    edited February 2018
    function Level:events(event)
     
        self.counter += 1
     
        if self.counter >= 400 then
     
            local enemy = Enemy.new()
            ship:addChild(enemy )
        end

    Likes: Paulo777

    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
    +1 -1 (+1 / -0 )Share on Facebook
  • Omg!! How I didn't think about that before!! I'll have to redo my logic about that... This actually makes sense... Really thank you for your answer... Getting home I'll do it!
  • Paulo777Paulo777 Member
    edited February 2018
    Really thanks for this light! I will try all of the suggestions. If I choose one, surelly I'll use the another for other projects. Thanks @oleg and @keszegh
    It really makes sense when we think about objected oriented... about relationships between them... At first I'm thinking about "level", and what happens to the level, but I must take into consideration the relation between objects...

    By the way, do you know where I can find sprite hierarchy explanation or material? If anyone knows anything or some link about I'd be very glad.

    Likes: keszegh

    +1 -1 (+1 / -0 )Share on Facebook
  • Paulo777Paulo777 Member
    edited February 2018
    uhaaaaaaaau!! Exactly what I need! Thanks so much!!!
  • Paulo777Paulo777 Member
    edited February 2018
    oleg said:

    function Level:events(event)
     
        self.counter += 1
     
        if self.counter >= 400 then
     
            local enemy = Enemy.new()
            ship:addChild(enemy )
        end
    Hello! I tried that but now I'm getting an ... unpleasant behaviour... the enemy is added "glued" with the ship... is there a way to specify its position to the stage?
  • "but what I want is: every time I move my "ship" sprite, is for the enemy to get this curren sprite position." - you wrote and then
    "unpleasant behaviour... the enemy is added "glued" with the ship"
    these seem to be contradicting each other, so i'm not sure what you want to achieve. try to clarify.
  • what I want is just the enemy to "take" ship position dinamically, whereas enemy position keeps intact, having its own movement to be coded thereafter
  • keszeghkeszegh Member
    edited February 2018
    it's still not clear for me, so when the enemy is spawned, it should be at the same place as the ship, but later it moves independently, just you need the position of the ship for other purposes (like where the enemy shoots)? if yes, then in the
    Enemy init add:

    self.ship=sprite

    and then any time the enemy can get the current position of its mothership by querying

    self.ship:getPosition()
  • Paulo777Paulo777 Member
    edited February 2018
    keszegh said:

    it's still not clear for me, so when the enemy is spawned, it should be at the same place as the ship, but later it moves independently, just you need the position of the ship for other purposes (like where the enemy shoots)? if yes, then in the
    Enemy init add:

    self.ship=sprite

    and then any time the enemy can get the current position of its mothership by querying

    self.ship:getPosition()

    Exactly! For that purpose that I want to know ship position, for wherever the ship changes its position, the enemy will target the fire, the fire class I did to shoot wherever I want and from wherever sprite that I want it to shoot... and maybe for other purposes also

    Likes: Paulo777

    +1 -1 (+1 / -0 )Share on Facebook
  • OOOMG!!!! Worked like a charm!! So simple... really thank you!! I see that I have to much to learn with this...

    Likes: keszegh, antix

    +1 -1 (+2 / -0 )Share on Facebook
  • @keszegh can you explain me how this way works and what's the behaviour behind both sprites?
  • keszeghkeszegh Member
    edited February 2018
    i'm not sure what you need. guessing i'd say you may confuse
    sprite1.mySprite=sprite2
    and sprite hierarchy when you add a child to another like
    sprite1:addChild(sprite2).

    the first (sprite1.mySprite=sprite2) just creates a reference for sprite2 so sprite1.mySprite points to the same object as sprite2, and that's it, there is no other connection between them.
    in the example self.ship=sprite, self refers to the sprite whose function we are inside currently (an object from the class Enemy), and self.ship is just a way to store sprite in the scope of this enemy.

    the second example on the other hand ties sprite2 to sprite1 in the visual hierarchy, so whenever sprite1 moves/scales/is added or removed from stage/made invisible etc. then the same happens with sprite2.
    sprite2:getParent() will still get you sprite1, so there is a way to get it (like in the first way), but the connection is now much stronger as i said, they basically move together.

    to understand the first, probably you should read through a lua manual, the basics are short. for the second, the ultimate guide for gideros is a good place to learn about sprite hierarchy etc. but this concept is quite common, as actionscript works the same way.


    Likes: Paulo777

    +1 -1 (+1 / -0 )Share on Facebook
  • If I understood correctly, then you do need to create an AI for the enemy's behavior ??

    Likes: Paulo777

    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
    +1 -1 (+1 / -0 )Share on Facebook
  • Paulo777Paulo777 Member
    edited February 2018
    thanks @keszegh for the introduction.
    @oleg not quite. But from now just simple behaviors like moving and shooting, as it is a side scrolling, more of them are in my plans to add in the level :)
Sign In or Register to comment.