Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Using mousejoints in a class — Gideros Forum

Using mousejoints in a class

DikkesnoekDikkesnoek Member
edited August 2012 in General questions
Hi,

It's not really clear to me how to use classes in a proper way. Also the use of self is sometimes difficult. I think that I need good documentation how variables and methods are in focus (local, global, within the class, etc.) in specific code parts (main, classes, etc.). I am trying to add physics to my Block classes (inherited sprite object) and functionalty to move the created blocks on the screen. In the first place I'll used the x and y properties of the block object in the onMouse events. Now I like to use the mousejoint for moving the blocks. In block.lua I tried:
-- MAIN.LUA part
 
-- Create multiple blocks.
for i = 1, 6 do
 
	-- The block image.
	local blockImage = Bitmap.new(Texture.new("Graphics/3D_Block3.png"))
	blockImage:setAnchorPoint(0.5, 0.5)
 
	-- The block value (later also + - : x)
	local blockValue = math.random(1000)
 
	local posX = (i * 150) + 32
	local posY = 540
 
	blockBody = physicsWorld:createBody{type = b2.DYNAMIC_BODY, position = {x = posX, y = posY}}
	local shape = b2.EdgeShape.new(0, 0, 144, 80)
	blockBody:createFixture{shape = shape, density = 0.1, restitution = 0.2, friction = 0.3}
 
	-- Create new block.
	block = Block.new(blockImage, blockValue, blockFont, physicsWorld, blockBody, blockReleased)	
	block:setPosition(posX, posY)
	stage:addChild(block)
 
	-- Add new sprite to the array.
	actors[blockBody] = block
end
 
--BLOCK.LUA part
 
Block = Core.class(Sprite)
 
function Block:init(image, value, font, world, body, released)
	-- Get the world.
	self.world = world
 
	-- Pass the the block body from main.
	self.body = body
 
	-- Joint with dummy body.
	self.mouseJoint = nil
 
	-- Create empty Box2D body for touches and mouse.
	self.dummyBody = self.world:createBody({})
 
	self.released = released
 
	self:addEventListener(Event.MOUSE_DOWN, self.onMouseDown, self)
	self:addEventListener(Event.MOUSE_MOVE, self.onMouseMove, self)
	self:addEventListener(Event.MOUSE_UP, self.onMouseUp, self)
 
	--self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
 
	-- Add a label.
	label = TextField.new(font, value)
 
	-- Center the label on parent image.
	label:setPosition(image:getWidth()  / 2 - label:getWidth()  / 2 - 5, 
					  image:getHeight() / 2 + label:getHeight() / 2 + 15)
 
	-- Add label to the parent image.
	image:addChild(label)
	--image:setAnchorPoint(0.5, 0.5)
 
	-- Self is me, the sprite.
	self:addChild(image)
 
	return self
end
 
function Block:onMouseDown(event)
	if self:hitTestPoint(event.x, event.y) then
		local jointDef = b2.createMouseJointDef(self.dummyBody, self.body, event.x, event.y, 100000)
		self.mouseJoint = self.world:createJoint(jointDef)
		print("MOUSE_DOWN")
 
		--self.focus = true
		--self.x0 = event.x
		--self.y0 = event.y
		--event:stopPropagation()
	end
end
 
function Block:onMouseMove(event)
	if mouseJoint ~= nil then
		self.mouseJoint:setTarget(event.x, event.y)
		print("MOUSE_MOVE")
	end
 
	--if self.focus then
		--local dx = event.x - self.x0
		--local dy = event.y - self.y0
 
		--self:setX(self:getX() + dx)
		--self:setY(self:getY() + dy)
 
		--self.x0 = event.x
		--self.y0 = event.y
 
		--event:stopPropagation()
	--end
end
 
function Block:onMouseUp(event)
	if mouseJoint ~= nil then
		self.world:destroyJoint(mouseJoint)
		self.mouseJoint = nil	
		print("MOUSE_UP")
	end
 
	--if self.focus then
		--self.focus = false
		--event:stopPropagation()
	--end
end
 
function Block:onEnterFrame (event)
	--physicsWorld:step(1/60, 8, 3)	
 
       self:setPosition(self.body:getPosition())
end
This is not working. If I use the --commented parts then it will work. Also, do you need to use "self" the way I did in the init. Or can you use: mouseJoint = nil instead of self.mouseJoint = nil. This is what is still not clear to me. Can you use a global variable in a class or do you need to create a instance like variable with self.xxx?

Thanks in advance,

Marc

Dislikes: r033rt

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

Comments

  • You want to use self to add variables to the instance of the class being made yes. (Incidentally I don't think you need to have any sort of return in your init function, Gideros must handle that under the hood when you call .new())

    You should be able to reference global variables, but that means than managing which order the code is executed. The larger the project that may be harder to manage, so keep that in mind.

    In your onMouseUp and onMouseMove function you also need to do self.mouseJoint instead of just mouseJoint. Also, you may still want to have event:stopPropagation in your calls unless you want one mouse click/move to affect multiple objects.
  • Thanks again. Still learning.

    Regards,

    Marc
  • Same here, so hope it helped! :)
  • DikkesnoekDikkesnoek Member
    edited August 2012
    I tried some things. It seems that the mouseJoint stays nil.
    It is not clear why you cant use this within the class itself.
    I also tried to create all the the bodies inside the class like
    this:
    function Block:init(image, value, font, world, released, x, y)
    	-- Get the world.
    	self.world = world
     
    	self.x = x
    	self.y = y
     
    	-- Create the block body.
    	self.blockBody = self.world:createBody{type = b2.DYNAMIC_BODY, position = 
                                                 {x = self.x, y = self.y}}
    	local shape = b2.EdgeShape.new(0, 0, 144, 80)
    	self.blockBody:createFixture{shape = shape, density = 0.1, 
                                                 restitution = 0.2, friction = 0.3}
     
    	-- Joint to couple block body with dummy body.
    	self.mouseJoint = nil
     
    	-- Create empty Box2D body for touches and mouse.
    	self.dummyBody = self.world:createBody({})
     
            --
    It gives the same results.

    Marc
  • DikkesnoekDikkesnoek Member
    edited August 2012
    I found a small issue. The "if mouseJoint ~= nil" test must be
    "if self.mouseJoint ~= nil", sorry for that. The block object
    will still not move.

    Marc
  • ar2rsawseenar2rsawseen Maintainer
    edited August 2012
    @Dikkesnoek
    have you checked this example:
    http://appcodingeasy.com/Gideros-Mobile/Dragging-Box2d-object-in-Gideros-Mobile

    Basically you need to perform a step in box2d world to make objects move, which is physicsWorld:step(1/60, 8, 3)
  • self.world:step(1/60, 8, 3)

    What exactly does this do? In Corona SDK, we have "Position Iterations" which define how accurate physics calculations are. Is this the same thing?

    What is each number 1/60, 8, 3?

    1/60 is something like 1 60th of a second, and 8 is and 3 is?

    :)

    ng
  • DikkesnoekDikkesnoek Member
    edited September 2012
    Thank you all. ar2rsawseen, I've checked that example. In this example, the mouse handling is not handled in a different class. I think that I found a solution to a part of the problem. Indeed I forgot to re-enable the physicsWorld:step(1/60, 8, 3) call. I also forgot that mouse joints are box2D related. I also set the gravity to zero so now I can move my object through the screen.

    Regards,

    Marc
  • @Dikkesnoek
    about 1/60, 8, 3
    From box2d manual
    http://www.box2d.org/manual.html#_Toc258082976

    First is a time step to move world forward
    float32 timeStep = 1.0f / 60.f;

    Second is a quantity of velocity steps
    int32 velocityIterations = 10;

    Third is a quantity of position steps
    int32 positionIterations = 8;
Sign In or Register to comment.