How Do I Create A Virtual Controller With Corona?

Oh, i see…im using this one, can you tell me if its a separated module and i call it from for example the level1.lua or i can paste it in the same file ??

And with what  instruction do i move the character ??

Excuse me,  im really lost with this feature =(

module(…, package.seeall);

function joystick:create(group, imgJoystick, joyWidth, joyHeight, imgBgJoystick, bgWidth, bgHeight)
    local stage = display.getCurrentStage();
    local mMin = math.min;
    local mCos = math.cos;
    local mSin = math.sin;
    local mAtan2 = math.atan2;
    local mSqrt = math.sqrt;
    local mFloor = math.floor;
    local mPi = math.pi;
    
    local joyGroup = display.newGroup();
    group:insert(joyGroup);
    local bgJoystick = display.newImageRect(joyGroup, imgBgJoystick, bgWidth, bgHeight );
    bgJoystick.x, bgJoystick.y = 0, 0;
    local radius = bgJoystick.contentWidth/4;
    joyGroup.radius = radius;
    local radToDeg = 180/mPi;
    local degToRad = mPi/180;
    local joystick = display.newImageRect(joyGroup, imgJoystick, joyWidth, joyHeight );
    
    function joystick:touch(event)
        local phase = event.phase;
        if phase == “moved” then
            if self.isFocus then
                local parent = self.parent;
                local posX, posY = parent:contentToLocal(event.x, event.y);
                local angle = (mAtan2( posX, posY )*radToDeg)-90;
                if angle < 0 then angle = 360 + angle end;
                local distance = mSqrt((posX*posX)+(posY*posY));
                if distance >= radius then
                    local radAngle = angle*degToRad;
                    distance = radius;
                    self.x, self.y = distance*mCos(radAngle), -distance*mSin(radAngle)
                else
                    self.x, self.y = posX, posY;
                end
                parent.angle = angle;
                parent.distance = distance;
            else
                stage:setFocus(event.target, event.id);
                self.isFocus = true;
                self.parent.state = true;
                self.alpha = 0.5;    
            end
        elseif phase == “began” then
            stage:setFocus(event.target, event.id);
            self.isFocus = true;
            self.parent.state = true;
            self.alpha = 0.5;
            local parent = self.parent;
            local posX, posY = parent:contentToLocal(event.x, event.y);
            self.x, self.y = posX, posY;
            local angle = (mAtan2( posX, posY )*radToDeg)-90;
            if angle < 0 then angle = 360 + angle end;
            local distance = mSqrt((posX*posX)+(posY*posY));
            if distance >= radius then
                local radAngle = angle*degToRad;
                distance = radius;
                self.x, self.y = distance*mCos(radAngle), -distance*mSin(radAngle)
            else
                self.x, self.y = posX, posY;
            end
            parent.angle = angle;
            parent.distance = distance;
        else
            self.isFocus = false;
            self.parent.state = false;
            self.x, self.y = 0, 0;
            self.parent.distance = 0;
            self.parent.angle = 0;
            stage:setFocus(nil, event.id);
            self.alpha = 1;
        end
        return true;
    end
    
    joyGroup.activate = function()
        joyGroup[1]:addEventListener(“touch”, joyGroup[2]);
        joyGroup.angle, joyGroup.distance = 0, 0;
    end
    joyGroup.deactivate = function()
        joyGroup[1]:removeEventListener(“touch”, joyGroup[2]);
        joyGroup.angle, joyGroup.distance = 0, 0;
    end
    joyGroup.x, joyGroup.y = joyGroup.contentWidth*0.5, display.contentHeight-joyGroup.contentHeight*0.5;
    return (joyGroup);
end

Here’s a simpler version of Rob’s original code (no images required, removed some nice-ities but it still works):

-- simpleJoystick.lua local Joystick = {} function Joystick.new( innerRadius, outerRadius ) local stage = display.getCurrentStage() local joyGroup = display.newGroup() local bgJoystick = display.newCircle( joyGroup, 0,0, outerRadius ) bgJoystick:setFillColor( .2,.2,.2 ) local radToDeg = 180/math.pi local degToRad = math.pi/180 local joystick = display.newCircle( joyGroup, 0,0, innerRadius ) joystick:setFillColor( .8,.8,.8 ) -- for easy reference later: joyGroup.joystick = joystick -- where should joystick motion be stopped? local stopRadius = outerRadius - innerRadius -- return a direction identifier, angle, distance local directionId = 0 local angle = 0 local distance = 0 function joyGroup.getDirection() return directionId end function joyGroup:getAngle() return angle end function joyGroup:getDistance() return distance/stopRadius end function joystick:touch(event) local phase = event.phase if( (phase=='began') or (phase=="moved") ) then if( phase == 'began' ) then stage:setFocus(event.target, event.id) end local parent = self.parent local posX, posY = parent:contentToLocal(event.x, event.y) angle = (math.atan2( posX, posY )\*radToDeg)-90 if( angle \< 0 ) then angle = 360 + angle end -- could expand to include more directions (e.g. 45-deg) if( (angle\>=45) and (angle\<135) ) then directionId = 2 elseif( (angle\>=135) and (angle\<225) ) then directionId = 3 elseif( (angle\>=225) and (angle\<315) ) then directionId = 4 else directionId = 1 end -- could emit "direction" events here --Runtime:dispatchEvent( {name='direction',directionId=directionId } ) distance = math.sqrt((posX\*posX)+(posY\*posY)) if( distance \>= stopRadius ) then distance = stopRadius local radAngle = angle\*degToRad self.x = distance\*math.cos(radAngle) self.y = -distance\*math.sin(radAngle) else self.x = posX self.y = posY end else self.x = 0 self.y = 0 stage:setFocus(nil, event.id) directionId = 0 angle = 0 distance = 0 end return true end function joyGroup:activate() self:addEventListener("touch", self.joystick ) self.directionId = 0 self.angle = 0 self.distance = 0 end function joyGroup:deactivate() self:removeEventListener("touch", self.joystick ) self.directionId = 0 self.angle = 0 self.distance = 0 end return( joyGroup ) end return Joystick

And:

-- main.lua local jslib = require( "simpleJoystick" ) local js = jslib.new( 100, 200 ) js.x = display.contentWidth/2 js.y = display.contentHeight/2 function catchTimer( e ) print( " joystick info: " .. " dir=" .. js:getDirection() .. " angle=" .. js:getAngle() .. " dist="..js:getDistance() ) return true end js:activate() timer.performWithDelay( 500, catchTimer, -1 )

Would someone be so kind as to put that code up on Github or a GIST and post it to the new code exchange?

http://code.coronalabs.com/

Thanks

Rob

WIll do … or  http://code.coronalabs.com/code/simple-joystick   (links to github)

jbp1 you can´t imagine how much i thank you bro

One last question. When im going to move my character ( called “ship” ) im doin it here :

            if( (angle>=45) and (angle<135) ) then
                ship.x=ship.x +10
            elseif( (angle>=135) and (angle<225) ) then
                ship.x=xhip.x-10
            elseif( (angle>=225) and (angle<315) ) then
                ship.x=xhip.y+10
            else
                ship.x=xhip.y-10
            end

But i get a nil value error, what can i do ?

Ahh … now it depends on what exactly you want to do in your code.  RIght now, the loop is triggering every 500 msec (per the timer).  If you’re doing a FPS or action game, you might just want to read the joystick:getDirection() inside of enterFrame (and do your ship movements there).  Or if you’re doing less of an action game, maybe dispatch events every so often (maybe 500 msec is good?)

Re: the nil error … my guess is it can’t find the ship object  (or the xhip object, possible typo in 3 of the lines?)

jajaja the “xhip” was a paste error but the nil it´s for something else =P  , im gonna check.

Jbp1 again thanks a lot, your´e the best man.

There´s no way to give you stars or calificate here ??  =)