Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
How to implement bullet raycast in 2D? — Gideros Forum

How to implement bullet raycast in 2D?

Hello guys!

Just a noob question here.

So here's the setup.
I want to implement a bullet hit using raycast function.

For example I have a resolution of 480x980.

Let's say my hero is at (240, 900) and the enemy is at (400, 200)

I want to hit the enemy instantly using bullet from my players coordinate. I want to use raycast if possible.

Please help me for the logic, and event listeners .

Thank you ☺️☺️

Comments

  • MoKaLuxMoKaLux Member
    edited June 2021
    are you using box2d (liquidfun)?
    if so have you checked this wiki page? https://wiki.gideros.rocks/index.php/B2.World:rayCast

    I used it once but I think that was with reactphysics3d plugin. That should work the same for 2d.
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • @MoKaLux
    I have read math.raycast api but I don't know how to implement. I don't want to use box2d if possible because it is a very tiny game. 😅

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    Accepted Answer
    oh I see :) a new addition to gideros. I haven't used it yet. Do you have a sample code to share so we can try to implement it?
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • MoKaLuxMoKaLux Member
    edited June 2021
    Let's try to understand the wiki :)
    local player = Pixel.new(0x0000ff, 1, 32, 64)
    player:setPosition(64, 64*2)
    stage:addChild(player)
     
    local nme = Pixel.new(0xff0000, 1, 32, 72)
    nme:setPosition(64*8, 64*2.1)
    stage:addChild(nme)
     
    --(table) = math.raycast(origin,direction,shape)
    local origin = {
    	x = player:getX(), -- player position x
    	y = player:getY(), -- player position y
    }
    local direction = {
    	x = 1000,
    	y = 0,
    }
    local myshape = { -- I chose the circle shape for the nme
    	x = nme:getX(), -- the shape should be at the nme position x
    	y = nme:getY(), -- the shape should be at the nme position y
    	radius = 32/2, -- radius should be the radius of the nme
    }
     
    -- let's raycast
    local myraycast = {}
    myraycast = math.raycast(origin.x, origin.y, 0, direction.x, direction.y, 0, myshape)
    print(#myraycast)
    for k, v in ipairs(myraycast) do
    	print(k, v.point.x, v.point.y)
    	print(k, v.distance)
    	print(k, v.normal.x, v.normal.y)
    	print(k, v.reflect.x, v.reflect.y)
    end
    I think this should be a good starting point? Hope this helps. If you change the player or the nme position you should have different results.
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • MoKaLuxMoKaLux Member
    edited June 2021 Accepted Answer
    this code is shorter but I don't know how to calculate the direction!
    local player = Pixel.new(0x0000ff, 1, 32, 64)
    player:setPosition(240, 400)
    stage:addChild(player)
     
    local nme = Pixel.new(0xff0000, 1, 32, 72)
    nme:setPosition(400, 390)
    stage:addChild(nme)
     
    --(table) = math.raycast(origin,direction,shape)
    local direction = {
    	x = 1000,
    	y = 35,
    }
    local myshape = { -- I chose the circle shape for the nme
    	x = nme:getX(), -- the shape should be at the nme position x
    	y = nme:getY(), -- the shape should be at the nme position y
    	radius = 32/2, -- radius should be the radius of the nme
    }
     
    -- let's raycast
    local myraycast = {}
    myraycast = math.raycast(player:getX(), player:getY(), 0, direction.x, direction.y, 0, myshape)
     
    print(#myraycast)
    for k, v in ipairs(myraycast) do
    	print(k, v.point.x, v.point.y)
    	print(k, v.distance)
    	print(k, v.normal.x, v.normal.y)
    	print(k, v.reflect.x, v.reflect.y)
    end
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    I have an example project somewhere, let me dig in my tests folder, and I’ll post it here
  • hgy29hgy29 Maintainer
    Accepted Answer
    Here it is.
    In the example, four things happen:
    - the nearest shape to the mouse is returned.
    - The shape is colored in green or yellow depending on wether the mouse is inside or outside.
    - The nearest point on that shape (from the mouse) is computed (in purple)
    - A ray cast from the center of the scene and in the direction of the mouse is performed. The resulting collision (if any) is shown with a blue dot.
    local p=Particles.new()
    local sc=Sprite.new()
    stage:addChild(sc)
    stage:addChild(p)
    local pts={}
    for i=1,30 do 
    	local sz=5+math.random()*20
    	if math.random()>0.5 then
    		pts[#pts+1]={x=math.random()*320,y=math.random()*480,size=sz*2, radius=sz, color=0xFF0000, id=#pts+1} 
    	else
    		pts[#pts+1]={x=math.random()*320,y=math.random()*480,size=0.1,id=#pts+1, color=0xFF9000} 
    		local an=math.random()*7
    		local dx,dy=math.cos(an),math.sin(an)
    		pts[#pts].x2=pts[#pts].x+sz*dx
    		pts[#pts].y2=pts[#pts].y+sz*dy
    		pts[#pts].x=pts[#pts].x-sz*dx
    		pts[#pts].y=pts[#pts].y-sz*dy
    		local px=Pixel.new(0xFF8000,1,sz*2,3)
    		px:setAnchorPoint(0,0.5)
    		px:setPosition(pts[#pts].x,pts[#pts].y)
    		px:setRotation(^>an)
    		sc:addChild(px)
    	end
    end
    p:addParticles(pts)
     
    local pp=p:addParticles{{x=0,y=0,size=5,color=0x0000FF}}[1]
    local pe=p:addParticles{{x=0,y=0,size=5,color=0xFF00FF}}[1]
     
    local psel
    stage:addEventListener(Event.MOUSE_HOVER,function (e)
    	local mouse={x=e.x,y=e.y}
    	local nrs,nd=math.nearest(mouse,pts)
    	if psel then p:setParticleColor(psel,0xFF0000,1) end
    	psel=nrs.id
    	local inside=math.inside(mouse,nrs)
    	if inside>0 then
    		p:setParticleColor(psel,0x00FF00,1)
    	else
    		p:setParticleColor(psel,0xFFFF00,1)
    	end
    	local e=math.edge(mouse,nrs)
    	p:setParticlePosition(pe,e.x,e.y) 
     
    	local c=math.raycast({x=160,y=240},math.normalize({x=mouse.x-160,y=mouse.y-240}),pts)
    	if c[1] then 
    		p:setParticlePosition(pp,c[1].point.x,c[1].point.y) 
    		p:setParticleColor(pp,0x0000FF,1)
    	else
    		p:setParticleColor(pp,0x0000FF,0)
    	end
    end)
    +1 -1 (+2 / -0 )Share on Facebook
  • Thank you so much guys 😊 . This helps me a lot.

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • @MoKaLux I think math.normalize function may help 😊

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • antixantix Member
    If you are using cbump, then you can do a segment check (line).
Sign In or Register to comment.