projectile woes

Ask and answer questions about making games and related topics. Unrelated topics go in that other forum.

Moderators: marionline, SDHawk

Post Reply
User avatar
TheMan
Red Slime
Posts: 31
Joined: Wed Jul 05, 2017 8:42 pm

projectile woes

Post by TheMan »

so I was trying to create a script to shoot projectiles in a straight line with the "move slice with wall checking" command. It's easy to shoot one projectile at a time like this, but I have run into trouble trying to shoot multiple projectiles at once, and correctly referring to each of them. currently I have this, with projectile layer and projectile being constants

Code: Select all

  if ((key is pressed (key:SPACE)) == TRUE) then, begin
    if ((hero direction (me) == LEFT) == TRUE) then, begin
      bullet := load walkabout sprite (55)
      set parent (bullet, lookupslice(sli:projectile layer))
      set slice lookup (bullet, lookupslice(sli:projectile))
      put slice (bullet, pix x, pix y)
      play sound (7,false,true)
      sl := first child (lookupslice(sli:projectile layer))
      while (sl) do ( 
        next := next sibling (sl) 
        if (move slice with wallchecking(bullet, -10, 0)) then (
          replace walkabout sprite (sl, 60)
          wait (1)
          replace walkabout sprite (sl, 61)
          wait (1)
          replace walkabout sprite (sl, 62)
          wait (1)
          free slice (sl) 
        end
        sl := next 
      )
    end
the projectiles move only for 1 tick and then stop in place. I feel this is an issue with the sl slice definition, since I'm not very experienced with looking up slices.
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

You're going to need either a while loop or a timer to keep updating and checking the projectiles each tick after they're fired. Unfortunately, doing that animation inside the loop/timer-triggered script is tricky.

But luckily, there's already some scripts on the wiki that do this. See the last two scripts at Fire projectile. Now these scripts are for moving a projectile in an arc, and don't check for walls, but they can be easily adapted to do what you want. Actually it looks like you maybe did already adapt these scripts. But here's my version:

Code: Select all

script, dirX, dir, dist, begin
    switch (dir) do (
        case (up, down) do (return (0))
        case (right) do (return (dist))
        case (left) do (return (-1 * dist))
    )
end

script, dirY, dir, dist, begin
    switch (dir) do (
        case (left, right) do (return (0))
        case (down) do (return (dist))
        case (up) do (return (-1 * dist))
    )
end

define constant(10, bullet speed)

# Create a new bullet slice
script, fire bullet, begin
    variable(bullet)
    bullet := load walkabout sprite(55)
    setparent(bullet, lookupslice(sli: projectile layer))
    put slice(bullet, heropixelx, heropixely)
    setslicelookup(bullet, sli:projectile)  # Set this so we can find it later

    variable(vx, vy)
    vx := dirX(herodirection, bullet speed)
    vy := dirY(herodirection, bullet speed)
    set slice extra(bullet, extra 0, vx)
    set slice extra(bullet, extra 1, vy)
end

script, move bullet, bullet, begin
    variable(vx, vy)
    vx := get slice extra(bullet, extra 0)
    vy := get slice extra(bullet, extra 1)

    if (move slice with wallchecking(bullet, vx, vy)) then (
        # Hit a wall
        setslicelookup(bullet, sli:splash)
        replace walkabout sprite (bullet, 60)
    )
end

plotscript, main loop, begin
    while (true) do (
        if (key is pressed(key:space)) then (fire bullet)

        # Loop through projectiles and process them
        variable(sl, next)
        sl := firstchild(lookupslice(sli: projectile layer))
        while (sl) do (
            next := nextsibling(sl)

            if (getslicelookup(sl) == sli:projectile) then (
                # Update position and check for walls
                move bullet(sl)
            ) elseif (getslicelookup(sl) == sli:splash) then (
                # Play a three-frame splash animation
                setspriteframe(sl, getspriteframe(sl) + 1)
                if (getspriteframe(sl) == 63) then (free slice(sl))
            )

            sl := next
        )

        wait
    )
end
Not tested.
Call 'main loop' from your newgame/loadgame script. And add 'splash' as another slice lookup codename.
Last edited by TMC on Sun Dec 09, 2018 5:21 am, edited 1 time in total.
Post Reply