Rotating a weapon around the player.

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Itswolfcity811
Prole
Posts: 7
Joined: Tue Jun 27, 2023 12:38 am

Rotating a weapon around the player.

Post by Itswolfcity811 »

I'm trying to add a weapon to my game and I'm trying to get it to rotate around the player according to the mouse. I have tried the distance formula and that kinda got it working but not really.
Can someone tell me how to do this?

Code: Select all

local love = _G.love

function Weapon(Weapons, _Id, Player, _Distance)
    Distance = _Distance + Player.Radius

    return {
        Id = _Id or 1,
        Distance = Distance,
        Player = Player,
        x = Player.x,
        y = Player.y,

        Draw = function (self)
            if (self.Id == self.Player.WeaponId) then
                local MouseX, MouseY = functions.Mouse.Position()

                local NewX = ((self.Player.x + self.Distance) + MouseX) / 2
                local NewY = ((self.Player.y + self.Distance) + MouseY) / 2

                if (functions.Math.Distance({self.Player.x, self.Player.y}, {NewX, NewY}) <= self.Player.Radius * 2) then
                    love.graphics.circle("fill", NewX, NewY, self.Player.Radius / 2)

                    self.x = NewX
                    self.y = NewY

                    return
                else
                    love.graphics.circle("fill", self.x, self.y, self.Player.Radius / 2)
                    
                    return
                end

                love.graphics.circle("line", self.Player.x, self.Player.y, self.Player.Radius * 2, 0)
            else
                return
            end
        end
    }
end

return Weapon
If you need it I can make a .love file.
Or if you need the main.lua file let me know.
User avatar
darkfrei
Party member
Posts: 1204
Joined: Sat Feb 08, 2020 11:09 pm

Re: Rotating a weapon around the player.

Post by darkfrei »

Itswolfcity811 wrote: Wed Jun 28, 2023 11:08 pm I'm trying to add a weapon to my game and I'm trying to get it to rotate around the player according to the mouse. I have tried the distance formula and that kinda got it working but not really.
Can someone tell me how to do this?

Code: Select all

local love = _G.love

function Weapon(Weapons, _Id, Player, _Distance)
    Distance = _Distance + Player.Radius

    return {
        Id = _Id or 1,
        Distance = Distance,
        Player = Player,
        x = Player.x,
        y = Player.y,

        Draw = function (self)
            if (self.Id == self.Player.WeaponId) then
                local MouseX, MouseY = functions.Mouse.Position()

                local NewX = ((self.Player.x + self.Distance) + MouseX) / 2
                local NewY = ((self.Player.y + self.Distance) + MouseY) / 2

                if (functions.Math.Distance({self.Player.x, self.Player.y}, {NewX, NewY}) <= self.Player.Radius * 2) then
                    love.graphics.circle("fill", NewX, NewY, self.Player.Radius / 2)

                    self.x = NewX
                    self.y = NewY

                    return
                else
                    love.graphics.circle("fill", self.x, self.y, self.Player.Radius / 2)
                    
                    return
                end

                love.graphics.circle("line", self.Player.x, self.Player.y, self.Player.Radius * 2, 0)
            else
                return
            end
        end
    }
end

return Weapon
If you need it I can make a .love file.
Or if you need the main.lua file let me know.
You are need to store just parent (player) dx, dt, maybe angle for not round weapons:

Code: Select all

local function drawWeapon (weapon)
  local x = weapon.parent.x + weapon.dx
  local y = weapon.parent.y + weapon.dy
  local radius= weapon.radius
  love.graphics.circle("fill", x, y, radius)
end
The all other update must be in update function.

Or mouse moved:

Code: Select all

function love.mousemoved (mx, my)
  local player = Player -- get local player from global Player 
  local px, py = player.x, player.y
  local angle = math.atan2 (my-py, mx-px)
  local weapon = player.weapon -- store weapon in player!
  weapon.dx = weapon.distance * math.cos (angle)
  weapon.dy = weapon.distance * math.sin (angle)
end
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
Itswolfcity811
Prole
Posts: 7
Joined: Tue Jun 27, 2023 12:38 am

Re: Rotating a weapon around the player.

Post by Itswolfcity811 »

I asked ChatGPT 4 https://chat.openai.com/?model=text-dav ... render-sha and it gave me this:

Code: Select all

local love = _G.love

function Weapon(_Id, Player, _Distance, Size)
    local Distance = _Distance + Player.Radius

    return {
        Id = _Id or 1,
        Distance = Distance,
        Player = Player,
        Size = Size,

        Draw = function (self)
            if (self.Id == self.Player.WeaponId) then
                local MouseX, MouseY = love.mouse.getPosition()

                -- Calculate the angle between player and mouse cursor
                local angle = math.atan2(MouseY - self.Player.y, MouseX - self.Player.x)

                -- Calculate the new weapon position based on the angle and distance
                local NewX = self.Player.x + math.cos(angle) * self.Distance
                local NewY = self.Player.y + math.sin(angle) * self.Distance

                love.graphics.circle("fill", NewX, NewY, self.Size)
            end
        end
    }
end

return Weapon

And it works perfictly!
User avatar
Bobble68
Party member
Posts: 162
Joined: Wed Nov 30, 2022 9:16 pm
Contact:

Re: Rotating a weapon around the player.

Post by Bobble68 »

Itswolfcity811 wrote: Fri Jun 30, 2023 6:12 pm I asked ChatGPT 4 https://chat.openai.com/?model=text-dav ... render-sha and it gave me this:

Code: Select all

local love = _G.love

function Weapon(_Id, Player, _Distance, Size)
    local Distance = _Distance + Player.Radius

    return {
        Id = _Id or 1,
        Distance = Distance,
        Player = Player,
        Size = Size,

        Draw = function (self)
            if (self.Id == self.Player.WeaponId) then
                local MouseX, MouseY = love.mouse.getPosition()

                -- Calculate the angle between player and mouse cursor
                local angle = math.atan2(MouseY - self.Player.y, MouseX - self.Player.x)

                -- Calculate the new weapon position based on the angle and distance
                local NewX = self.Player.x + math.cos(angle) * self.Distance
                local NewY = self.Player.y + math.sin(angle) * self.Distance

                love.graphics.circle("fill", NewX, NewY, self.Size)
            end
        end
    }
end

return Weapon

And it works perfictly!
I know I'm a bit of a perfectionist, but it would probably be marginally faster to use vectors instead of trigonometry. Gimme a moment to create an example

Code: Select all

local love = _G.love

function Weapon(_Id, Player, _Distance, Size)
  local Distance = _Distance + Player.Radius

  return {
    Id = _Id or 1,
    Distance = Distance,
    Player = Player,
    Size = Size,

    Draw = function (self)
      if (self.Id == self.Player.WeaponId) then
        local MouseX, MouseY = love.mouse.getPosition()
        
        -- Get the vector of the mouse relative to the player - this is essentially just direction and distance expressed in a 2D form
        
        local VecX = MouseX - Player.x
        local VecY = MouseY - Player.y
        
        -- Convert the vector into a unit vector - this is a vector with the same direction, but the length is 1. We can find this by finding the length of the vector, and dividing it's x and y components by it
        
        local length = math.sqrt(VecX^2 + VecY^2)
        
        VecX = VecX/length
        VecY = VecY/length
        
        -- We finally multiply the unit vector by the distance we want it away from the player
        
        local NewX = VecX * self.Distance
        local NewY = VecY * self.Distance

        love.graphics.circle("fill", NewX, NewY, self.Size)
      end
    end
  }
end

return Weapon

I believe this should work - however, if I were you, I would store the direction vector somewhere, because then you can use it to simplify other bits of code! For example, you can use it to get the x and y velocity of a bullet fired from said weapon.
Dragon
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 7 guests