Beginner here, so forgive me if I'm missing something obvious. I'm currently working on a simple clone of Twin Bee to learn a little bit about design. I'm running into a blockade due to my lack of programming experience, so I'm hoping someone may have some answers from me.
I've got clouds that fall from the top of the screen. The function that sets all the variables for the cloud table looks like this:
function spawncloud() local c = { x = rnd(95)+16, y = -16, dy = rnd(.5)+.75, sp = 5, hb = {x1=0,y1=0,x2=13,y2=1} } -- bell properties - is it necessary for me to declare -- these properties within the spawncloud function -- because the bell position depends on the cloud position? local b = { x=c.x, y=c.y, boost=3, dy=0, sp=7, hb={x1=0,y1=0,x2=3,y2=3} } --add to cloud table add(clouds,c) --add to bell table add(bells, b) end |
The cloud spawn perfectly when I iterate through the cloud array in the _draw() function.
My next objective is spawning a bell when my bullet hit's one of these clouds. As you can see in the spawncloud() function above, I'm setting up a local table for the bells as well, because their x&y variables are dependent on those of the cloud. I would like to have an entirely separate spawnbell() function so I can call it when necessary, but I'm not quite sure how I would go about this because of the dependent x&y variables.
Additionally, my collision seems to be working about 75% of the time, so any help with making that more consistent would be greatly appreciated. I've borrowed the code from another project, so I'm not 100% clear on what it's doing. Here's what that code looks like:
--creating a box collider function abs_box(s) local box = {} box.x1 = s.hb.x1 + s.x box.y1 = s.hb.y1 + s.y box.x2 = s.hb.x2 + s.x box.y2 = s.hb.y2 + s.y return box end --collision function function coll(a,b) --create relative hitboxes local box_a = abs_box(a) local box_b = abs_box(b) if box_a.x1 > box_b.x2 or box_a.y1 > box_b.y2 or box_b.x1 > box_a.x2 or box_b.y1 > box_a.y2 then return false end return true end --check if our bullet is colliding --with our cloud function checkbulletcoll() for e in all(bullets) do for c in all(clouds) do if coll(e,c) then --delete bullet if collision del(bullets,e) end end end end |
Please let me know if there's additional code you'd like to see.
Thanks for the help!
I believe the bug is caused by the cloud and bullet moving past each other at the same time. If you checked for collision after the bullet moved AND after the cloud moved, then cases like that wouldn't happen. Hope I could help!
The reason collision isn't working sometimes is because the objects can move completely past each other on the same frame, so their collision boxes never intersect. You can fix that by stretching the collision boxes to account for their movement.
Something like this:
function abs_box(s) local box = {} box.x1 = s.hb.x1 + s.x box.y1 = s.hb.y1 + s.y box.x2 = s.hb.x2 + s.x box.y2 = s.hb.y2 + s.y if s.dy>0 then box.y1 -= s.dy elseif s.dy<0 then box.y2 -= s.dy end return box end |
For spawning the bell you already have the code there that you need, it just needs to be moved to a separate function that allows you to pass the cloud in as a parameter. You can then call that function when the cloud is destroyed.
function spawnbell(c) local b = { x=c.x, y=c.y, boost=3, dy=0, sp=7, hb={x1=0,y1=0,x2=3,y2=3} } --add to bell table add(bells, b) end |
@paranoidcactus Thanks so much for the help! Making steady progress. I've got bells that pop out of the clouds and can be collected by the player (starting to deviate from the original idea). My current objective is to make it so that when the player shoots a bullet at the bell, it resets the DY and applies and upward boost, allowing the player to bounce the bell in the air for as long as they can.
EDIT
I solved it by subtracting boost instead of adding. Oops!
function checkbulletbellcoll() for e in all (bullets) do for b in all (bells) do if coll(e,b) then b.dy=0 b.dy-=b.boost b.hitcount+=1 del(bullets, e) end end end end |
THE PROBLEM
Currently, I'm applying a boost to the bell when it first spawns, which is working fine. The code looks like this:
function applyboost() for b in all(bells) do if b.spawned==false then b.dy=0 b.dy-=b.boost b.dx+=b.offset b.spawned = true end end end |
This function is called when the bullet hits the cloud, like this:
function checkbulletcoll() for e in all(bullets) do for c in all(clouds) do if coll(e,c) then --delete bullet if collision del(bullets,e) spawnbell(c) applyboost() end end end end |
I'm trying to apply the same boost when the bullet hits the bell, but nothing is happening. My attempt looks like this:
function checkbulletbellcoll() for e in all (bullets) do for b in all (bells) do if coll(e,b) then b.dy+=b.boost b.hitcount+=1 del(bullets, e) end end end end |
This function is called in update.
Again, thanks so much for the help.
[Please log in to post a comment]