Need help creating a specific function

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
BoonyBuny
Prole
Posts: 31
Joined: Mon Jun 13, 2022 1:24 am
Location: France
Contact:

Need help creating a specific function

Post by BoonyBuny »

Hello! I got my head scratching right now. I'm making another test-game to learn more about Löve2d and it's going really well, I just cannot put my finger on how to construct this function. Each enemy spawned will run it at 2 seconds interval, and they despawn after 7 seconds of lifespan.

I need this function to get them to point A to point B smoothly in a set duration, beeing 1 second for my game.

Here is a vector plane I made to make my function help request more clear:
vector plane describing Goto(x1,y1, x2,y2, delay) function with a vector
vector plane describing Goto(x1,y1, x2,y2, delay) function with a vector
function demo.png (2.12 MiB) Viewed 3083 times
This function also means it will take the same time to go from point A to B beeing 500 pixels apart as it takes to go from point A to B beeing 1200 pixels apart.

Hope it's not too confusing or unclear, I can try to make it more clear if you ask! this vector plane was my best way to describe the desired function.
A coding begginer that is migrating from 8 years of Scratch... yea yikes. :emo:
User avatar
keharriso
Citizen
Posts: 93
Joined: Fri Nov 16, 2012 9:34 pm

Re: Need help creating a specific function

Post by keharriso »

Maybe this can help you get started?

Code: Select all

local enemy = {
	origin = {x = 100, y = 100}, -- pixels
	destination = {x = 400, y = 200},
	duration = 1.0, -- seconds
	elapsed = 0.0
}

local function lerp(from, to, t)
	return {x = from.x + (to.x - from.x) * t,
	        y = from.y + (to.y - from.y) * t}
end

function love.update(dt)
	enemy.elapsed = enemy.elapsed + dt
	enemy.position = lerp(enemy.origin, enemy.destination, enemy.elapsed / enemy.duration)
end

function love.draw()
	if enemy.elapsed < enemy.duration then
		love.graphics.circle('fill', enemy.position.x, enemy.position.y, 10)
	end
end
LÖVE-Nuklear - a lightweight immediate mode GUI for LÖVE games
User avatar
BoonyBuny
Prole
Posts: 31
Joined: Mon Jun 13, 2022 1:24 am
Location: France
Contact:

Re: Need help creating a specific function

Post by BoonyBuny »

I'm sorry I have trouble understanding that, since all enemies in my game are from a table and for i,v in ipairs(Enemy) method, here's my current enemy ai code:

Code: Select all

EnemySprite = love.graphics.newImage("/sprites/enemy.png")
require 'damage_indicator'

function Enemy_AI_update(dt) --AI code
    for i,v in ipairs(Enemy) do
        v.lifespan = v.lifespan - dt
        
        if v.lifespan >= 0 then
            v.AItimer = v.AItimer + dt
            v.timer = v.timer + dt
                if v.timer >= BPS(v.ebps) then
                    EnemyBullet.shoot(v.x, v.y)
                    TEsound.play("/sounds/enemy_shoot.wav","static", nil, 0.25)
                    v.timer = 0
                end
                if v.AItimer >= 2 then
                    Goto(v.x, v.y, math.random(50,710), math.random(50, 390), 1)
                    v.AItimer = 0
                end
        else
            if v.x > 380 then
                v.x = v.x + 500 * dt
                if v.x >= 810 then table.remove(Enemy,i) missed = missed + 1 end
            else
                v.x = v.x - 500 * dt
                if v.x <= -50 then table.remove(Enemy,i) missed = missed + 1  end
            end
        end

        for a,b in ipairs(bullet) do --miracle solution found on http://www.osmstudios.com/tutorials/your-first-love2d-game-in-200-lines-part-3-of-3 ! detects collision between each enemies and player's bullets
            if CheckCollision(v.x, v.y, v.width, v.height, b.x, b.y, b.width, b.height) then
                v.health = v.health - 1
                table.remove(bullet, a)
                damageIndicator.spawn(v.x,v.y, 1)
                TEsound.play("/sounds/enemy_hit.wav", "static")

                    if  v.health == 0 then
                        table.remove(Enemy, i)
                        table.remove(bullet, a)
                        Eexplosion_spawn(v.x, v.y)
                        score = score + 1

                        if math.random(0,1) == 1 then
                            TEsound.play("/sounds/explosion.wav","static")
                        else
                            TEsound.play("/sounds/explosion2.wav","static")
                        end
                    end
            end
        end

    end
end

function Enemy_draw()
    for i,v in ipairs(Enemy) do
        love.graphics.draw(EnemySprite, v.x, v.y, nil, nil, nil,25,25)
    end
end

function CheckCollision(x1,y1,w1,h1,x2,y2,w2,h2) --miracle solution.................. had to add 25 offset for the enemy(half of the enemy's size) for some hecking reason or the hitbox was offset to the right smh
    return  x1-25 < x2+w2 and
            x2 < x1-25+w1 and
            y1 < y2+h2 and
            y2 < y1+h1
end

function GoTo(x1,y1, x2,y2, delay) --x1,y1 enemy current position ;;; x2,y2 destination point ;;; delay is the time it takes to go from point 1 to point 2
    --missing function
end
Last edited by BoonyBuny on Fri Jun 17, 2022 11:15 pm, edited 1 time in total.
A coding begginer that is migrating from 8 years of Scratch... yea yikes. :emo:
Xugro
Party member
Posts: 110
Joined: Wed Sep 29, 2010 8:14 pm

Re: Need help creating a specific function

Post by Xugro »

The x and y position are independent and therefore can be calculated independently. I just calculated the formula for x, but for y it is the same:
lerp.jpg
lerp.jpg (105.42 KiB) Viewed 3054 times
The first part is a sketch of the function. Before the delay and after the delay + the duration the enemies do not move. In between I used an linear interpolation.

The function you want is written in the second part. If you do not want any ifs, then you can use the min- and max-functions to clamp the position between x¹ and x².

In the third part I calculated the linear part of the function.

Edit: To slow! :D
A few things that spring to mind seeing your code:
  • You only need a simple lerp (look at keharrisos post). And not my more complicated version.
  • Do not delete entries in a table you are currently iterating over! This will mess up the iteration counter and strange things will happen.
  • Enemy_AI_update(dt) will run multiple times a second. Every time you choose a new target for your enemy to go to. This will end up in your enemies all "shivering", but not moving somewhere else. You need to choose a target position for each enemy once and then update its position a fraction of the distance between its starting position and target position (1 second / dt). After an enemy reached its target position you could choose a new one.
User avatar
BoonyBuny
Prole
Posts: 31
Joined: Mon Jun 13, 2022 1:24 am
Location: France
Contact:

Re: Need help creating a specific function

Post by BoonyBuny »

Holy, I'm so sorry but my 11th grade school dropped self just cannot understand this at all, im sorry for making you waste your time on writing all of this
A coding begginer that is migrating from 8 years of Scratch... yea yikes. :emo:
User avatar
BoonyBuny
Prole
Posts: 31
Joined: Mon Jun 13, 2022 1:24 am
Location: France
Contact:

Re: Need help creating a specific function

Post by BoonyBuny »

https://scratch.mit.edu/projects/226938852/ Is the thing im basing my project on, it's a project I made 4 years ago, and my function will just allow them to "glide"/lerp to a set point, like I did on scratch at the time, since scratch has its own "Glide to x() y() in () seconds"

scratch really messed me up
A coding begginer that is migrating from 8 years of Scratch... yea yikes. :emo:
User avatar
keharriso
Citizen
Posts: 93
Joined: Fri Nov 16, 2012 9:34 pm

Re: Need help creating a specific function

Post by keharriso »

What you want is a function that acts across frames to move your enemy to the desired location over a period of time. Unfortunately, this is not possible. No matter what you do, you need to have *something* in love.update that moves the enemy frame by frame. You can take my code as an example and add the requisite fields to your enemy objects:
  • origin
  • destination
  • duration
  • elapsed
Then for each enemy, use some kind of interpolation (a simple example is in my code) to calculate the enemy's position at the current frame. There is nothing I do with my single enemy that you cannot do with your list of enemies. You just handle one enemy at a time.
LÖVE-Nuklear - a lightweight immediate mode GUI for LÖVE games
User avatar
BoonyBuny
Prole
Posts: 31
Joined: Mon Jun 13, 2022 1:24 am
Location: France
Contact:

Re: Need help creating a specific function

Post by BoonyBuny »

Thank you for your help, I will try to """""convert"""""" it for my code ! I understand how it works mostly, i'll give updates when things starts to look better than a blue screen :D
A coding begginer that is migrating from 8 years of Scratch... yea yikes. :emo:
User avatar
keharriso
Citizen
Posts: 93
Joined: Fri Nov 16, 2012 9:34 pm

Re: Need help creating a specific function

Post by keharriso »

BoonyBuny wrote: Sat Jun 18, 2022 12:08 am Thank you for your help, I will try to """""convert"""""" it for my code ! I understand how it works mostly, i'll give updates when things starts to look better than a blue screen :D
No problem! And please do post updates, I love to see what other people are working on. :nyu:
Last edited by keharriso on Sat Jun 18, 2022 5:59 pm, edited 1 time in total.
LÖVE-Nuklear - a lightweight immediate mode GUI for LÖVE games
User avatar
BoonyBuny
Prole
Posts: 31
Joined: Mon Jun 13, 2022 1:24 am
Location: France
Contact:

Re: Need help creating a specific function

Post by BoonyBuny »

I almost got it, i just need some polishing and fix some minors not-BSOD worthy bugs ! when i'm done i'll post a webm video of my project and the result
A coding begginer that is migrating from 8 years of Scratch... yea yikes. :emo:
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 85 guests