Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Creating/Limiting the number of shapes — Gideros Forum

Creating/Limiting the number of shapes

AxlFlameAxlFlame Member
edited July 2012 in General questions
Ok, i'll do my best to explain my problem, i'd really apreciate any help!

I'm trying to create a shape at class X using a gestures module. The idea is: I have this game class and by using some values given by another class (Gestures) i wanted to create a shape at my game when the user draws a line.

Here is my code so far (this is written at the init function on the game class):

--Shape for gestures scope
local areaGestures = Shape.new()
areaGestures:setFillStyle(Shape.SOLID, 0xC0C0C0, 0.5)
areaGestures:beginPath(Shape.NON_ZERO)
areaGestures:moveTo(0, 190)
areaGestures:lineTo(application:getContentWidth(), 190)
areaGestures:lineTo(application:getContentWidth(), 220)
areaGestures:lineTo(0, 220)
areaGestures:lineTo(0, 190)
areaGestures:endPath()
self:addChild(areaGestures)

local font = TTFont.new("Fontes/tahoma.ttf", 20)

local myText = TextField.new(font, "Result: ")
myText:setPosition(50,50)
self:addChild(myText)

local function callback(name)
myText:setText(name)
end


local gest = Gestures.new({
debug = true,
draw = true,
drawColor = 0xff0000,
drawWidth = 5,
autoTrack = true,
scope = areaGestos,
allowRotation = true,
inverseShape = true,
points = 33
})

gest:addGesture("Line", {
{x = 0, y = 0},
{x = 0, y = 100}
}, callback)



gest:addGesture("ZigZag", {
{x = 0, y = 0},
{x = 50, y = 87},
{x = 100, y = 0},
{x = 150, y = 87},
}, callback)

local x = 0
local y = -100
local circle = {}
local totalPoints = 72
local step = (math.pi*2)/totalPoints

for angle = 1, totalPoints do
local newX = x*math.cos(angle*step)-y*math.sin(angle*step)
local newY = y*math.cos(angle*step)+x*math.sin(angle*step)
local point = {x = newX, y = newY}
table.insert(circle, point)
end

gest:addGesture("Circle", circle, callback)
--------------

In the Gestures class the values i need are the first and last points from the drawing made by the user that are stored in the self.points table.
The Gestures class i'm using is the one found at AppcodingEasy.com with some modifications that follows:

--Update
if match.name == "Line" then
local xIni = points[1].x;
local xFim = points[#points].x;
local yIni, yFim = 191, 220;
--local width = xFim - xIni;
--local height = yFim - yIni;
as = {}
as[i] = Shape.new()
as[i]:setFillStyle(Shape.SOLID, 00000000, 0.5)
as[i]:beginPath(Shape.NON_ZERO)
as[i]:moveTo(points[1].x, yIni)
as[i]:lineTo(points[#points].x, yIni)
as[i]:lineTo(points[#points].x, yFim)
as[i]:lineTo(points[1].x, yFim)
as[i]:lineTo(points[1].x, yIni)
as[i]:endPath()
stage:addChild(as[i])
i = i +1
floorcnt = floorcnt +1
print (floorcnt)
print (i)
if floorcnt > 1 then
stage:removeChild(as[i-1])
floorcnt = 0;
end
end

As you can see, i couldn't find a better way so i created the shape inside the Gestures class. But it just feels wrong.. The right thing would be to create the shape inside the game class, right?

So my question is, how can i access those values from another class and create shape using them? Also, would it be possible to limit the number of shapes on screen? Like, you can only have one at a time and if you draw another one the last one vanishes.

I'm sorry for the long post, i'm new to Gideros and i'm currently having a lot of problems to learn it.

Thank you for the attention!

Yuri

Likes: mefisto

+1 -1 (+1 / -0 )Share on Facebook

Comments

  • ar2rsawseenar2rsawseen Maintainer
    Hello,

    glad you found your way into the forum. ;)

    It will be much easier to communicate this way.

    So first you have a shape, where user can draw gestures. Right?

    What does the second shape do, which is created inside Gestures class?
  • Thanks. Hope I can count on you guys and the other way around too.

    About the code, the second shape actually is gonna be a Physical body, the idea is to create a bridge where the player's character can walk.

    I'm trying to use eventDispatcher to "transfer" the points[1].x and points[#points].x from the Gestures.lua to my game class, so i can create the shape inside my game class but it isn't working...
  • ar2rsawseenar2rsawseen Maintainer
    Well outside the Gesture class it should look like (put it inside function as callback for drawing Line):
    function lineCallback()
    	--Update
    	local xIni = gest.points[1].x;
    	local xFim = gest.points[#gest.points].x;
    	local yIni, yFim = 191, 220;
    	--local width = xFim - xIni;
    	--local height = yFim - yIni;
    	as = {}
    	as[i] = Shape.new()
    	as[i]:setFillStyle(Shape.SOLID, 00000000, 0.5) 
    	as[i]:beginPath(Shape.NON_ZERO)
    	as[i]:moveTo(gest.points[1].x, yIni)
    	as[i]:lineTo(gest.points[#gest.points].x, yIni)
    	as[i]:lineTo(gest.points[#gest.points].x, yFim)
    	as[i]:lineTo(gest.points[1].x, yFim)
    	as[i]:lineTo(gest.points[1].x, yIni)
    	as[i]:endPath()
    	stage:addChild(as[i])
    	i = i +1
    	floorcnt = floorcnt +1
    	print (floorcnt)
    	print (i)
    	if floorcnt > 1 then
    		stage:removeChild(as[i-1])
    		floorcnt = 0;
    	end 
    end
  • AxlFlameAxlFlame Member
    edited July 2012
    You mean placing that code inside the callback function for the Line?
    I tried that and this happens: "attempt to index global 'gest' (a nil value)"

    Why he can't find the gest?

    local gest = Gestures.new({
    debug = true,
    draw = true,
    drawColor = 0xff0000,
    drawWidth = 5,
    autoTrack = true,
    scope = areaGestos,
    allowRotation = true,
    inverseShape = true,
    points = 33
    })

    gest:addGesture("Line", {
    {x = 0, y = 0},
    {x = 0, y = 100}
    }, callback)

    And the callback function:

    local function callback(name)
    myText:setText(name)
    --Update
    local xIni = gest.points[1].x;
    local xFim = gest.points[#gest.points].x;
    local yIni, yFim = 191, 220;
    --local width = xFim - xIni;
    --local height = yFim - yIni;
    as = {}
    as[i] = Shape.new()
    as[i]:setFillStyle(Shape.SOLID, 00000000, 0.5)
    as[i]:beginPath(Shape.NON_ZERO)
    as[i]:moveTo(gest.points[1].x, yIni)
    as[i]:lineTo(gest.points[#gest.points].x, yIni)
    as[i]:lineTo(gest.points[#gest.points].x, yFim)
    as[i]:lineTo(gest.points[1].x, yFim)
    as[i]:lineTo(gest.points[1].x, yIni)
    as[i]:endPath()
    stage:addChild(as[i])
    i = i +1
    floorcnt = floorcnt +1
    print (floorcnt)
    print (i)
    if floorcnt > 1 then
    stage:removeChild(as[i-1])
    floorcnt = 0;
    end
    end


    Btw, how can i post my code like you do? Mine is so ugly and unorganized.

    Thanks.
  • ar2rsawseenar2rsawseen Maintainer
    About code posting:
    http://www.giderosmobile.com/DevCenter/index.php/Forum_FAQ#How_can_I_highlight_my_Lua_code_in_the_forum_post.3F

    About undefined gest, well it all depends on your code structure. The should be in the same upper scope. And gest definition should be before callback function. And probably some other circumstances I'm not aware of to make it happen. :)

    Solution:
    If you are using it inside the class, then make gest a class property:
    self.gest = Gestures.new({
     debug = true,
     draw = true,
     drawColor = 0xff0000,
     drawWidth = 5,
     autoTrack = true,
     scope = areaGestos,
     allowRotation = true,
     inverseShape = true,
     points = 33
    })
    and then access it anywhere else inside the class by using self.gest

    If you are not inside any class, then try removing local before definition of gest, to make it global (I know, a dirty hack).
  • Nice, it worked, at least no more sintax erros... The problem now is that apparently the callback function isn't being called at all. I tried moving it and placing the () but still it won't work...

    Here is what looks like so far:

    Relevant stuff inside the game class (this is all inside the init function on the game class)
    The area for drawing:
    local areaGestos = Shape.new()
    		areaGestos:setFillStyle(Shape.SOLID, 0xC0C0C0, 0.5)   
    		areaGestos:beginPath(Shape.NON_ZERO)
    		areaGestos:moveTo(0, 190)
    		areaGestos:lineTo(application:getContentWidth(), 190)
    		areaGestos:lineTo(application:getContentWidth(), 220)
    		areaGestos:lineTo(0, 220)
    		areaGestos:lineTo(0, 190)
    		areaGestos:endPath()
    		self:addChild(areaGestos)
    Declaration for gest and adding the line:
    self.gest = Gestures.new({
    	debug = true,
    	draw = true,
    	drawColor = 0xff0000,
    	drawWidth = 5,
    	autoTrack = true,
    	scope = areaGestos,
    	allowRotation = true,
    	inverseShape = true,
    	points = 33
    })
     
    self.gest:addGesture("Line", {
    	{x = 0, y = 0},
    	{x = 0, y = 100}
    }, callback)
    The callback function, inside the game class. I tried to print those 2 values just to see if it was at least being called:
    local function callback(name)
    	myText:setText(name)
    	print (floorcnt)
    	print (i)
    	--Update
    	local xIni = self.gest.points[1].x;
    	local xFim = self.gest.points[#self.gest.points].x;
    	local yIni, yFim = 191, 220;
    	--local width = xFim - xIni;
    	--local height = yFim - yIni;
    	as = {}
    	as[i] = Shape.new()
    	as[i]:setFillStyle(Shape.SOLID, 00000000, 0.5) 
    	as[i]:beginPath(Shape.NON_ZERO)
    	as[i]:moveTo(self.gest.points[1].x, yIni)
    	as[i]:lineTo(self.gest.points[#self.gest.points].x, yIni)
    	as[i]:lineTo(self.gest.points[#self.gest.points].x, yFim)
    	as[i]:lineTo(self.gest.points[1].x, yFim)
    	as[i]:lineTo(self.gest.points[1].x, yIni)
    	as[i]:endPath()
    	stage:addChild(as[i])
     
    end
  • ar2rsawseenar2rsawseen Maintainer
    callback function should be declared before using it when adding line. And you can try making same approach, by turning callback function to class property:
    --self or whatever your class name is
    self.callback = function(name)
    	--all contents here
    end
     
    self.gest:addGesture("Line", {
    	{x = 0, y = 0},
    	{x = 0, y = 100}
    }, self.callback)
  • It is now declared right affer the gestures.new() and before the addGesture.
    But this is happening:

    "attempt to index field '?' (a nil value)"

    This is reffering to this line:
    local xIni = self.gest.points[1].x;
    So that means it is not fiding the points table? Why?
  • ar2rsawseenar2rsawseen Maintainer
    hard to tell what it can't find

    try putting this before accessing points:
    print(self)
    print(self.gest)
    print(self.gest.points)
    print(self.gest.points[1])
    print(self.gest.points[1].x)
    And you'll see which is nil, which can not be found
  • I did that and turns out its .x that cannot be found.
    self.gest.points[1].x
    All the others returned a table value: self
    self.gest
    self.gest.points

    I don't understand, that x value should exist, why is it going like nil to the game class?
  • ar2rsawseenar2rsawseen Maintainer
    Yes, checked the Gestures code and it is because internal points are reset when proper gesture is found, so it would be empty when there is an attempt for another gesture.

    You can see it at:
    function Gestures:resolve(points)
    	if(#points>1) then
    		self:reset()
    If you remove self:reset(), then points won't be removed, but you would have to manually reset them inside callback function using gest:reset(), or you can simply move self:reset() to the end of resolve function.
  • It worked! The problem was indeed with the self:reset on the Gestures class. I was starting to think i would have to appeal to black magic to get this done... Thanks a lot Arturs!
    About the second part of this post... limiting the number of shapes on screen.

    I'm trying to only allow 1 shape per time drawn on screen. Meaning if the player draws another shape, the first one should be removed or anything like that.

    For this i thought the solution would be creating an array of shapes and a counter, so i can control how much is on screen.

    I declared these 2 before the init function to serve as controllers.
    local floorcnt = 0
    local i = 0
    Then inside the callback function its like this:
    self.callback = function(name)
    	myText:setText(name)
    	print (floorcnt)
    	print (i)
    	--Update
    	local xIni = self.gest.points[1].x;
    	local xFim = self.gest.points[#self.gest.points].x;
    	local yIni, yFim = 191, 220;
    	--local width = xFim - xIni;
    	--local height = yFim - yIni;
    	as = {}
    	as[i] = Shape.new()
    	as[i]:setFillStyle(Shape.SOLID, 00000000, 0.5) 
    	as[i]:beginPath(Shape.NON_ZERO)
    	as[i]:moveTo(self.gest.points[1].x, yIni)
    	as[i]:lineTo(self.gest.points[#self.gest.points].x, yIni)
    	as[i]:lineTo(self.gest.points[#self.gest.points].x, yFim)
    	as[i]:lineTo(self.gest.points[1].x, yFim)
    	as[i]:lineTo(self.gest.points[1].x, yIni)
    	as[i]:endPath()
    	if floorcnt >= 1 then
    		self:removeChild(as[i-1])
    		self:addChild(as[i])
    	else
    		self:addChild(as[i])
    	end
    	i = i + 1
    	floorcnt = floorcnt + 1	
    end
    But, for some reason i keep getting this error:
    "bad argument #1 to 'removeChild' (Sprite expected, got nil)"

    What is bugging me is that i can add the child but can't remove it... what is going on?

    Thanks!
  • If you need to limit only to one shape, then it's easy, you simply have one property to store shape in it and that's all:
    local someShape = Shape.new()
    self.callback = function(name)
    	myText:setText(name)
    	--Update
    	local xIni = self.gest.points[1].x;
    	local xFim = self.gest.points[#self.gest.points].x;
    	local yIni, yFim = 191, 220;
    	--local width = xFim - xIni;
    	--local height = yFim - yIni;
    	--clear previous shape
    	someShape:clear()
    	--draw new shape
    	:setFillStyle(Shape.SOLID, 00000000, 0.5) 
    	someShape:beginPath(Shape.NON_ZERO)
    	someShape:moveTo(self.gest.points[1].x, yIni)
    	someShape:lineTo(self.gest.points[#self.gest.points].x, yIni)
    	someShape:lineTo(self.gest.points[#self.gest.points].x, yFim)
    	someShape:lineTo(self.gest.points[1].x, yFim)
    	someShape:lineTo(self.gest.points[1].x, yIni)
    	someShape:endPath()	
    end
    That would be the best way to do it, because you are reusing existing shape.

    As to why your code is not working I really can't tell from the first sight, without deeper debugging :)
  • AxlFlameAxlFlame Member
    edited August 2012
    Ok, but what if you were to add an physical body to that shape? Something for the player's character to walk above it. Would something like this work?

    My idea was to create a physical body just the size of the bridge shape i currently have.
    Still... it isn't creating the body, the fixture at least, as the character just passes through the shape and fall.

    Up there, before the init function i declared a b2World to use:
    local b2World
    My callback function:
    self.callback = function(name)
    	myText:setText(name)
    	--Update
    	local xIni = self.gest.points[1].x;
    	local xFim = self.gest.points[#self.gest.points].x;
    	local yIni, yFim = 196, 225;
    	--Clear all
    	bridge:clear()
    	if bridge.body then
    		b2World:destroyBody(bridge.body)
    	end
    	--Creating new shape
    	bridge:setFillStyle(Shape.SOLID, 00000000, 0.5) 
    	bridge:beginPath(Shape.NON_ZERO)
    	bridge:moveTo(self.gest.points[1].x, yIni)
    	bridge:lineTo(self.gest.points[#self.gest.points].x, yIni)
    	bridge:lineTo(self.gest.points[#self.gest.points].x, yFim)
    	bridge:lineTo(self.gest.points[1].x, yFim)
    	bridge:lineTo(self.gest.points[1].x, yIni)
    	bridge:endPath()
     
    	areaGestos:addChild(bridge)
     
    	--Physical body
    	bridge.body = b2World:createBody{type = b2STATIC_BODY, 
    				position = {x = bridge:getX(), y = bridge:getY()},
    				};
    	bridge.body.name = "bridge";	
    	local bridgeShape = b2.PolygonShape.new()
    	local bridgeWidth = bridge:getWidth()
    	local bridgeHeight = bridge:getHeight()
    	bridgeShape:set(-bridgeWidth, -bridgeHeight,
    			-bridgeWidth+bridgeWidth*currentPathLen, -bridgeHeight,
    			-bridgeWidth+bridgeWidth*currentPathLen, bridgeHeight,
    			-bridgeWidth, bridgeHeight);	
    	bridge.body:createFixture{shape = bridgeShape,
    						friction = 0,
    						restitution = 0,
    						density = 10,
    						isSensor = false
    						};	
    end
    EDIT:

    Ok, i actually got it, just switched the 'bridge:getX()' and 'bridge:getY()' for 'self.gest.points[1].x' and 'yFim' respectively. That way it gets the right position for the body!
  • So, I got myself a new problem... It's regarding the bridge shape/physical body, thus i thought it would be ok to use this topic again.

    Here's the deal: I created the shape/physical body for the bridge and both are working fine, but the game class has an parallax effect so it feels like an 2d side-scroller, moving the background always to the left.

    How can i create the same effect for my bridge so it goes left with my background?

    This is my callback function:
    self.callback = function(name)
    	myText:setText(name)
    	--Update
    	local xIni = self.gest.points[1].x;
    	local xFim = self.gest.points[#self.gest.points].x;
    	local yIni, yFim = 196, 225;
    	--Erase
    	bridge:clear()
    	if bridge.body then
    		b2World:destroyBody(bridge.body)
    	end
    	--New shape
    	bridge:setFillStyle(Shape.SOLID, 00000000, 0.5) 
    	bridge:beginPath(Shape.NON_ZERO)
    	bridge:moveTo(self.gest.points[1].x, yIni)
    	bridge:lineTo(self.gest.points[#self.gest.points].x, yIni)
    	bridge:lineTo(self.gest.points[#self.gest.points].x, yFim)
    	bridge:lineTo(self.gest.points[1].x, yFim)
    	bridge:lineTo(self.gest.points[1].x, yIni)
    	bridge:endPath()
    	areaGestos:addChild(bridge)
     
    	--Physical body for the bridge
    	bridge.body = b2World:createBody{type = b2STATIC_BODY, 
    							position = {x = self.gest.points[1].x, y = yFim-4},
    							};
    	bridge.body.name = "bridge";	
    	local bridgeShape = b2.PolygonShape.new()
    	local bridgeWidth = bridge:getWidth()
    	local bridgeHeight = bridge:getHeight()
    	bridgeShape:set(-bridgeWidth, -bridgeHeight,
    					-bridgeWidth+bridgeWidth*currentPathLen, -bridgeHeight,
    					-bridgeWidth+bridgeWidth*currentPathLen, bridgeHeight,
    					-bridgeWidth, bridgeHeight);	
    	bridge.body:createFixture{shape = bridgeShape,
    						friction = 0,
    						restitution = 0,
    						density = 10,
    						isSensor = false
    						};	
    	print (bridge.x)
    And here i tried to make it move using the layer1Speed, already declared:
    	function bridge:onEnterFrame()
    		self:setX(self:getX()-layer1Speed);
    		if self:getX() < screenWidth then
    			bridge:clear()
    			bridge:removeListeners()
    		end
    	end	
    	function bridge:removeListeners()
    		bridge:removeEventListener(Event.ENTER_FRAME, bridge.onEnterFrame, bridge);
    	end
    	function bridge:addListeners()
    	  bridge:addEventListener(Event.ENTER_FRAME, bridge.onEnterFrame, bridge);
    	end	
    	bridge:addEventListener(Event.ENTER_FRAME, bridge.onEnterFrame, bridge);
    With this code 2 things happened:

    1- The shape did move to the left, but its body stayed still.

    2- The shape sometimes isn't even drawn, but the body is there.

    And one last thing: I tried printing the X for the bridge but somehow it returns a nil to me, even though the shape/body are created on scene, what could be causing it?
  • ar2rsawseenar2rsawseen Maintainer
    edited August 2012
    Well, the problem is, that you are moving Shape object, which is attached to box2d physical object, which is not moving, because it should not move by definition of box2d world :)

    Basically solution should be to move box2d object, which you have referenced inside bridge.body
    function bridge:onEnterFrame()
    	self.body:setPosition(self:getX()-layer1Speed, self:getY());
    	if self:getX() < screenWidth then
    		self:clear()
    		self:removeListeners()
    	end
    end
    And the Shape will folow ;)
  • Well, i think i understand, but now the problem is inverse. The shape is being drawn but the physical body isn't there.
    And when i try to print the bridge x up there, it still returns a nil to me.

    Is it related, somehow?
  • Then it means that body is moving and shape is not? :)

    Inside on enter frame do you have something like:
    -- edit the step values if required. These are good defaults!
    	self.world:step(1/60, 8, 3)
    	--iterate through all child sprites
    	for i = 1, self:getNumChildren() do
    		--get specific sprite
    		local sprite = self:getChildAt(i)
    		-- check if sprite HAS a body (ie, physical object reference we added)
    		if sprite.body then
    			--update position to match box2d world object's position
    			--get physical body reference
    			local body = sprite.body
    			--get body coordinates
    			local bodyX, bodyY = body:getPosition()
    			--apply coordinates to sprite
    			sprite:setPosition(bodyX, bodyY)
    			--apply rotation to sprite
    			sprite:setRotation(body:getAngle() * 180 / math.pi)
    		end
    	end
    to move visual objects along with physical bodies?
  • Actually no it's not. Something weird is happening and i can't tell why.
    Using this code on the bridge on enter frame:
    function bridge:onEnterFrame()
    	self.body:setPosition(self:getX()-layer1Speed, self:getY());
    	if self:getX() < screenWidth then
    		self:clear()
    		self:removeListeners()
    	end
    end
    I tried to debugdraw and i saw that the shape is not being drawn and the position of the physical body is on the top of the screen, it's like its not getting the bridge X at all.
    But the shape should have an X and Y, right?
    It would be best if i just used an bitmap to create the bridge instead of the shape?
    When i try to print the bridge X it just returns nil to me...

    I'm still using the exact callback function that i pasted here before.

    You mean inside the bridge:onEnterFrame or the game class enter frame?
    I have that code inside my gameclass on enter frame, inside the bridge one i just have that portion of the code i pasted on the last post.

    This is my game class onEnterFrame:
    function gameClass:onEnterFrame() 
    	--get screen dimensions
    	local screenW = application:getContentWidth()
    	local screenH = application:getContentHeight()
     
    	--Scores
    	currentScore = currentScore+layer1Speed;
    	objScore:setScore(currentScore);
     
    	--define offsets
    	local offsetX = 0;
    	local offsetY = 0;
     
    	--here we need to update the physics world, and the score.
    	b2World:step(worldStep, 8, 3);
    	--currentScore = currentScore+layer1Speed;
    	--objScore:setScore(currentScore);
    	--iterate through all child sprites
    	for i = 1, self:getNumChildren() do
    		--get specific sprite
    		local sprite = self:getChildAt(i)
    		-- check if sprite HAS a body (ie, physical object reference we added)
    		if sprite.body then
    			--update position to match box2d world object's position
    			--get physical body reference
    			local body = sprite.body
    			--get body coordinates
    			local bodyX, bodyY = body:getPosition()
    			--apply coordinates to sprite
    			sprite:setPosition(bodyX, bodyY)
    			--apply rotation to sprite
    			sprite:setRotation(body:getAngle() * 180 / math.pi)
    		end
    	end
    end
  • Yes, the code in your post is what moves physical bodies and the sprites along them.

    And there are two things to keep in mind, for a shape to properly position with physical body, it need to have 0,0 coordinates in center, so it should be drawn like:
    --just example values
    local width, height = 20, 100
    bridge:beginPath(Shape.NON_ZERO)
    bridge:moveTo(-width, -height)
    bridge:lineTo(width, -height)
    bridge:lineTo(width, height)
    bridge:lineTo(-width, height)
    bridge:lineTo(-width, -height)
    bridge:endPath()
    and then position bridge at according positions where you want it to be

    And second thing, is a bridge (Which is a Shape object) a direct child of game class?
  • AxlFlameAxlFlame Member
    edited August 2012
    I see, but my bridge code creates the shape based on the player's drawing. Meaning its width would be always different as it gets the first and last points from the line drawn by the player. How could i solve that?
    	bridge:setFillStyle(Shape.SOLID, 00000000, 0.5) 
    	bridge:beginPath(Shape.NON_ZERO)
    	bridge:moveTo(self.gest.points[1].x, yIni)
    	bridge:lineTo(self.gest.points[#self.gest.points].x, yIni)
    	bridge:lineTo(self.gest.points[#self.gest.points].x, yFim)
    	bridge:lineTo(self.gest.points[1].x, yFim)
    	bridge:lineTo(self.gest.points[1].x, yIni)
    	bridge:endPath()
    	areaGestos:addChild(bridge)
    And the bridge is not a child of the game class, i was creating it as a child of my drawable area so it doesn't get in front of other objects on screen. For that reason, i created that onEnterFrame function just for the bridge, which is created/called inside the callback function. Is it a problem?

    My callback function so far:
    self.callback = function(name)
    	myText:setText(name)
    	--Update
    	local xIni = self.gest.points[1].x;
    	local xFim = self.gest.points[#self.gest.points].x;
    	local yIni, yFim = 196, 225;
    	--Erase
    	bridge:clear()
    	if bridge.body then
    		b2World:destroyBody(bridge.body)
    	end
    	--New shape
    	bridge:setFillStyle(Shape.SOLID, 00000000, 0.5) 
    	bridge:beginPath(Shape.NON_ZERO)
    	bridge:moveTo(self.gest.points[1].x, yIni)
    	bridge:lineTo(self.gest.points[#self.gest.points].x, yIni)
    	bridge:lineTo(self.gest.points[#self.gest.points].x, yFim)
    	bridge:lineTo(self.gest.points[1].x, yFim)
    	bridge:lineTo(self.gest.points[1].x, yIni)
    	bridge:endPath()
    	areaGestos:addChild(bridge)
     
    	--Physical body
    	bridge.body = b2World:createBody{type = b2STATIC_BODY, 
    					position = {x = self.gest.points[1].x, y = yFim-4},
    					};
    	bridge.body.name = "bridge";	
    	local bridgeShape = b2.PolygonShape.new()
    	local bridgeWidth = bridge:getWidth()
    	local bridgeHeight = bridge:getHeight()
    	bridgeShape:set(-bridgeWidth, -bridgeHeight,
    					-bridgeWidth+bridgeWidth*currentPathLen, -bridgeHeight,
    					-bridgeWidth+bridgeWidth*currentPathLen, bridgeHeight,
    					-bridgeWidth, bridgeHeight);	
    	bridge.body:createFixture{shape = bridgeShape,
    						friction = 0,
    						restitution = 0,
    						density = 10,
    						isSensor = false
    						};	
    	print (bridge.x)
    	--Trying to move the bridge with the background
    	function bridge:onEnterFrame()
    		self.body:setPosition(self:getX()-layer1Speed, self:getY());
    		if self:getX() < screenWidth then
    			self:clear()
    			self:removeListeners()
    		end
    	end
    	function bridge:removeListeners()
    		bridge:removeEventListener(Event.ENTER_FRAME, bridge.onEnterFrame, bridge);
    	end
    	function bridge:addListeners()
    	  bridge:addEventListener(Event.ENTER_FRAME, bridge.onEnterFrame, bridge);
    	end	
    	bridge:addEventListener(Event.ENTER_FRAME, bridge.onEnterFrame, bridge);
    end
    One last thing, when i try to print bridge:getX() it returns me an 0....
    That wasn't supposed to happen, right?
  • Oh ok, so I probably misunderstood where you were going with this.

    So about the shape it's easy, you simple get difference between first point and last point to get height and width and divide by 2 to take half width, like:
    local width = math.abs(self.gest.points[1].x - self.gest.points[#self.gest.points].x)/2
    local height = math.abs(yIni - yFim)/2
    Why it returns 0 or nil, maybe it's a scope problem, can't tell.

    But I tell you, it's hard to get my head around on this :D Maybe if you want you can share simple project where you are now, so I could experiment and make it work. Or if you don't want to share it here, you can email it to me to my username at gmail.com
  • Ok, your email is ar2rsawseen@gmail.com right?
    I just sent you my project, hope you can give it some light. I'm sorry for all the trouble!
    I managed to make the bridge body have the right size, but still only the shape moves...
    Hope you can help me with that! Thanks!
  • Sure, will look at it today on the lunch break ;)
  • So, i'm trying some new things here but not with a lot of success... did you received the email with the project? Turns out the project was a little bigger than i expected so i'm not sure that it was sent as it should.
  • @AxlFlame yes, sorry, I've received your project, it was just so large, with so many features, that it was too hard to navigate at first and is taking me definitely more than a lunch break to figure it out. But I'll get there eventually and will notify you via email asap ;)
Sign In or Register to comment.