Шукати в цьому блозі

Віртуальний джойстик



-- VirtualRelativeJoystick for Gideros
--
-- Onscreen joystick that only appears when lower left quadrant
-- of screen is touched
--
 
VirtualRelativeJoystick = Core.class(Sprite)
 
function VirtualRelativeJoystick:init(options)
  -- default options
  self.= 100
  self.= 100
  self.outerRadius = 100
  self.padColor = 0xaaaadd
  self.knobColor = 0xaaddaa
  self.onPressed = nil
  self.onDragged = nil
  self.onReleased = nil
 
  self.left = false
 
  self.xpos = 0
  self.ypos = 0
  self.strength = 0
  self.angle = 0
 
  self.enabled = false
 
  -- set user supplied options
  if options then
    for key, value in pairs(options) do
      self[key]= value
    end
  end
 
  self.outerCircle = self:getNewCircle(self.outerRadius, self.padColor, false)
  self:addChild(self.outerCircle)
 
  self.innerNubbin = self:getNewCircle(self.outerRadius * .5, self.knobColor, true)
  self:addChild(self.innerNubbin)
 
  self:setPosition(self.x, self.y)
  self:setVisible(false)
 
  self:addEventListener(Event.TOUCHES_BEGIN, self.onTouchesBegin, self)
  self:addEventListener(Event.TOUCHES_MOVE, self.onTouchesMove, self)
  self:addEventListener(Event.TOUCHES_END, self.onTouchesEnd, self)
end
 
--
function VirtualRelativeJoystick:onTouchesCancel(e)
  self:onTouchesEnd(e)
end
 
--
function VirtualRelativeJoystick:onTouchesBegin(e)
  local tx, ty = e.touch.x, e.touch.y
  local mx, my = application:getContentWidth() * 0.5, application:getContentHeight() * 0.5
 
  if self.left then
    if tx > mx or ty < my then return end
  else
    if tx < mx or ty < my then return end
  end
 
  self.controlTouchId = e.touch.id
  self:setPosition(tx, ty)
  self:setVisible(true)
  self.enabled = true -- enable control
 
  if self.onPressed then
    self.onPressed()
  end -- run code
 
  e:stopPropagation()
end
 
--
function VirtualRelativeJoystick:onTouchesMove(e)
  local cos, sin, sqrt, atan2 = math.cos, math.sin, math.sqrt, math.atan2
  if not self.enabled then return end
  if e.touch.id == self.controlTouchId then
    local x, y = self:globalToLocal(e.touch.x, e.touch.y)
    local radius = self.outerRadius
    local distance = sqrt(* x + y * y) >< radius -- limit distance to outer radius
    -- normalized strength for use with angle
    local strength = (distance >< radius) / radius
    local angle = ^>atan2(y, x) + 90
 
    local ra = ^< self.angle
    y = -distance * cos(ra)
    x = distance * sin(ra)
    self.innerNubbin:setPosition(x, y)
 
    self.xpos, self.ypos = x / radius, -/ radius
 
    if self.onPressed then
      self.onDragged(angle, distance, strength) -- run code
    end
 
        self.angle, self.distance, self.strength = angle, distance, strength
 
    e:stopPropagation()
  end
end
 
--
function VirtualRelativeJoystick:onTouchesEnd(e)
  if not self.enabled then return end
  if e.touch.id == self.controlTouchId then
    self.innerNubbin:setPosition(0, 0)
    self.xpos, self.ypos = 0, 0
    self:setVisible(false)
 
    self.enabled = false
    if self.onReleased then
      self.onReleased() -- run code
    end
 
    e:stopPropagation()
  end
  self.controlTouchId = nil
end
 
--
function VirtualRelativeJoystick:getNewCircle(r, color, fill)
  local p = Path2D.new()
  p:setSvgPath(("M %s 0 a %s %s 0 0 0 %s 0 a %s %s 0 0 0 %s 0 Z"):format(-r, r, r, 2 * r, r, r, -2 * r))
  p:setLineThickness(10) -- Outline width
  p:setFillColor(color, fill and .6 or .0) --Fill color
  p:setLineColor(color, .6) --Line color
  return p
end

Немає коментарів:

Дописати коментар