如何根据玩家的方向偏移子弹对象

Posted

技术标签:

【中文标题】如何根据玩家的方向偏移子弹对象【英文标题】:How to offset bullet object, based on player's direction 【发布时间】:2021-09-12 18:08:07 【问题描述】:

我正在运行 lua 5.1 和 love2d 11.3.0

在我的演示中,我有一个自上而下的射击游戏。出于视觉目的,角色看起来是这样的......从上到下的角度可以看到,他正在伸出他的武器。

我的问题是我很难弄清楚无论他面向什么方向,或者他在屏幕上的哪个位置,如何让他的子弹从枪尖开始。 目前,子弹总是从这个身体的中心射出。我已经尝试调整下面的 bullet.xbullet.y 属性,但这是一个不尊重玩家方向的静态更改...


function spawnBullet()
    local bullet = 
    bullet.x = player.x
    bullet.y = player.y
    bullet.speed = 500
    bullet.direction = playerMouseAngle()
    table.insert(bullets, bullet)
end

完整的游戏逻辑:

-- 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

提前感谢任何提示

【问题讨论】:

你需要做数学来确定偏移量。如果枪完全指向北方,则所有偏移量都在 y 方向上,完全在 x 方向上。 我尊重这一点。我应该研究什么样的数学?触发?或者之前在love2d社区中已经做过的事情?我不可能是唯一遇到这种情况的人...... ***.com/a/13667853/7396148 【参考方案1】:

在他们旅行期间,您已经掌握了所需的数学知识...

-- 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

只需要稍微调整一下即可创建子弹

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)

猜测规模。您可能需要将/2 更改为其他名称,例如*0.75

【讨论】:

非常感谢您让我看到这个。对于 bullet.x 和 bullet.y 方程,我最终将 + 0.5 添加到 bullet.direction。效果很好!

以上是关于如何根据玩家的方向偏移子弹对象的主要内容,如果未能解决你的问题,请参考以下文章

Libgdx 子弹偏移原点

player的Rect与玩家/角色不对齐

草的交互的几种实现

Windows 逆向内存地址分析 ( 动态地址 | 静态地址 | 偏移量 )

使用四元数的Unity3D相对偏移对象旋转

如何在 python 和 django 中使用 Pytz 根据给定的 UTC 偏移量转换数据和时间?