I'm running lua 5.1 and love2d 11.3.0
In my demo, I have a top down shooter game. For visual purposes the character looks like so...As you can see from this top down perspective, he is holding his weapon out.
My issue is that I am having a hard time figuring out how to have his bullets start from the tip of his gun no matter what direction he is facing, or where on the screen he is positioned. Currently, the bullets always shoot from the center of this body. I have tried adjusting the bullet.x and bullet.y properties below, but that is a static change that doesn't respect the players direction...
function spawnBullet()
local bullet = {}
bullet.x = player.x
bullet.y = player.y
bullet.speed = 500
bullet.direction = playerMouseAngle()
table.insert(bullets, bullet)
end
The full game logic :
-- top down shooter game demo 2021
function love.load()
-- create table to collect sprite assets
sprites = {}
sprites.bg = love.graphics.newImage('graphics/bg_grass.jpg')
sprites.hero = love.graphics.newImage('graphics/hero.png')
-- create table for our player hero
player = {}
player.x = love.graphics.getWidth() / 2
player.y = love.graphics.getHeight() / 2
player.speed = 360
player.injured = false
player.injuredSpeed = 270
-- create table for player bullets
bullets = {}
-- game state, timer and score globals
gameState = 1
maxTime = 2
timer = maxTime
score = 0
end
function love.update(dt)
if gameState == 2 then
-- player speed will be adjusted below
local moveSpeed = player.speed
-- adjust player speed if player was injured
if player.injured then moveSpeed = player.injuredSpeed end
-- player moves right
if love.keyboard.isDown("d") and player.x < love.graphics.getWidth() -
50 then player.x = player.x + moveSpeed * dt end
-- player moves left
if love.keyboard.isDown("a") and player.x > 50 then
player.x = player.x - moveSpeed * dt
end
-- player moves up
if love.keyboard.isDown("w") and player.y > 50 then
player.y = player.y - moveSpeed * dt
end
-- player moves down
if love.keyboard.isDown("s") and player.y < love.graphics.getHeight() -
50 then player.y = player.y + moveSpeed * dt end
end
-- make bullets move in desired direction
for i, b in ipairs(bullets) do
b.x = b.x + (math.cos(b.direction) * b.speed * dt)
b.y = b.y + (math.sin(b.direction) * b.speed * dt)
end
-- remove the bullets from the game once they go off-screen
for i = #bullets, 1, -1 do
local b = bullets[i]
if b.x < 0 or b.y < 0 or b.x > love.graphics.getWidth() or b.y >
love.graphics.getHeight() then table.remove(bullets, i) end
end
-- manage game state and timer
if gameState == 2 then
timer = timer - dt
if timer <= 0 then
maxTime = 0.95 * maxTime
timer = maxTime
end
end
end
function love.draw()
-- setup background
love.graphics.push()
love.graphics.scale(0.20, 0.20)
love.graphics.draw(sprites.bg, 0, 0)
love.graphics.pop()
-- click to begin
if gameState == 1 then
love.graphics.printf('Click anywhere to begin!', 0, 50, love.graphics.getWidth(), "center")
end
-- display score
love.graphics.printf('Score: ' .. score, 0, love.graphics.getHeight() - 100, love.graphics.getWidth(), "center")
-- adjust player color if player gets injured
if player.injured then love.graphics.setColor(1, 0, 0) end
-- draw player
love.graphics.draw(sprites.hero, player.x, player.y, playerMouseAngle(),
nil, nil, sprites.hero:getWidth() / 2,
sprites.hero:getHeight() / 2)
-- display player bullets
for i, b in ipairs(bullets) do
love.graphics.circle("fill", b.x, b.y, 10, 100)
end
end
-- enable player direction based on mouse movement
function playerMouseAngle()
return
math.atan2(player.y - love.mouse.getY(), player.x - love.mouse.getX()) +
math.pi
end
-- define bullet properties
function spawnBullet()
local bullet = {}
bullet.x = player.x
bullet.y = player.y
bullet.speed = 500
bullet.direction = playerMouseAngle()
table.insert(bullets, bullet)
end
-- game state determins shooting player bullets...
function love.mousepressed(x, y, button)
if button == 1 and gameState == 2 then
spawnBullet()
-- ..or starting the game
elseif button == 1 and gameState == 1 then
gameState = 2
maxTime = 2
timer = maxTime
score = 0
end
end
Thanks in advance for any tips
You already have the required math in there during their travel...
-- make bullets move in desired direction
for i, b in ipairs(bullets) do
b.x = b.x + (math.cos(b.direction) * b.speed * dt)
b.y = b.y + (math.sin(b.direction) * b.speed * dt)
end
Just need to tweak it a bit for bullet creation
local bullet = {}
bullet.speed = 500
bullet.direction = playerMouseAngle()
bullet.x = player.x +(math.cos(bullet.direction + 0.5) * (sprites.hero:getWidth() / 2))
bullet.y = player.y +(math.sin(bullet.direction + 0.5) * (sprites.hero:getWidth() / 2))
table.insert(bullets, bullet)
Guessing on the scale. You might have to change the /2
to something else, like *0.75
.