I was making a small game for me to play when I’m bored and I came across an issue.
What I want to do is shoot bullets by clicking on the screen and it also happens that way.
But if I click quickly then the first bullet disappears and a new bullet is formed. I need to know how can I make the first bullet go on even after making a second one. I tried to see the inbuilt physics example, test 1, where he creates multiple polygons but I couldn’t understand it.
Here is my code.
function setup()
bullet = physics.body(CIRCLE,10)
end
function draw()
background(0, 0, 0, 255)
pushStyle()
fill(255, 255, 255, 255)
ellipse(bullet.x,bullet.y,10)
popStyle()
end
function createBullet()
bullet.x = x
bullet.y = y
bullet.linearVelocity = vec2(1000,0)
bullet.restitution = 0
bullet.type = DYNAMIC
end
function touched(touch)
x = touch.x
y = touch.y
if touch.state == BEGAN then
createBullet()
end
end
You need to add your bullets to a table, so in set up you add
bullets={}
Then in createBullet you add at the end
table.insert(bullets,bullet)
Then in draw, you loop through your bullets
for i,b in bullets do
ellipse(b.x,b.y,10)
--insert code here to adjust position of bullet for next time
--then check if bullet is off screen
if b.x<1 or b.x>WIDTH or b.y<1 or b.y>HEIGHT or [anything else you want to test] then
b=nil --remove bullet from table
end
end
Thanks for the quick reply!
But I’m getting an error stating “attempt to call table value” in function setup.
Can you explain what you mean by inserting code to adjust position of next bullet
I’m new to coding, I’m interested in it too, but a few things are just going a bouncer
This is untested, but I think it’s what Ignatz meant.
I suspect the error you got was due to a missing pairs.
function setup()
bullets = {}
end
function draw()
background(0, 0, 0, 255)
pushStyle()
fill(255, 255, 255, 255)
local dels = {}
for k,v in ipairs(bullets) do
ellipse(v.x,v.y,10)
if v.x<1 or v.x>WIDTH or v.y<1 or v.y>HEIGHT then
table.insert(dels,k,1)
end
end
for _,v in ipairs(dels) do
table.remove(bullets,v)
end
popStyle()
end
function createBullet(x,y)
local bullet = physics.body(CIRCLE,10)
bullet.x = x
bullet.y = y
bullet.linearVelocity = vec2(1000,0)
bullet.restitution = 0
bullet.type = DYNAMIC
table.insert(bullets,bullet)
end
function touched(touch)
if touch.state == BEGAN then
createBullet(touch.x,touch.y)
end
end
I hadn’t noticed you were using physics objects. Try this code. Note I’ve moved the definition of bullet into createBullet, and made it local, so a new bullet is created each time. If you create your bullet in setup, then even if you add it to a table, you are adding the same old bullet.
I might write a post about this because it is interesting.
function setup()
physics.gravity(0,0) -- turn gravity off
bullets={}
end
function draw()
background(0, 0, 0, 255)
pushStyle()
fill(255, 255, 255, 255)
for i,b in pairs(bullets) do
ellipse(b.x,b.y,10)
--then check if bullet is off screen
if b.x<1 or b.x>WIDTH or b.y<1 or b.y>HEIGHT then
b=nil --remove bullet from table
end
end
popStyle()
end
function createBullet()
--create bullet in here
local bullet = physics.body(CIRCLE,10)
bullet.x = x
bullet.y = y
bullet.linearVelocity = vec2(100,0)
bullet.restitution = 0
bullet.type = DYNAMIC
table.insert(bullets,bullet)
end
function touched(touch)
x = touch.x
y = touch.y
if touch.state == BEGAN then
createBullet()
end
end
I am into a new issue now what I did is that I added some ballons which rise from the bottom and we have to shoot those ballons using the bullets.
I can make the ballons but I can’t make them disappear properly I am using table.remove and collide(contact) as all of them are physics objects but I can’t figure out how to give each ballon a unique name I tried out the following code but most of the times I hit one ballon and some other ballon pops and though the ballon disappears the physics object stays there and I also want the bullets to burst along with the ballon
I used sound so that I can come to know when there’s contact
Here’s the code
function setup()
physics.gravity(0,0)
bullets={}
ball = {}
for i = 1,5 do
ball[i] = Ballons()
ball[i].info = "ball[i]"
end
end
function draw()
background(255, 255, 255, 255)
pushStyle()
fill(0, 0, 0, 255) -- drawing the bullets
for i,b in pairs(bullets) do
ellipse(b.x,b.y,10)
if b.x<1 or b.x>WIDTH or b.y<1 or b.y>HEIGHT then
b=nil
end
end
popStyle()
for i = 1,#ball do -- drawing the ballons
pushStyle()
fill(ball[i].ballon.colr)
ellipse(ball[i].ballon.x, ball[i].ballon.y, ball[i].radius*2)
popStyle()
end
end
function createBullet()
local bullet = physics.body(CIRCLE,5)
bullet.x = x
bullet.y = y
bullet.linearVelocity = vec2(1000,0)
bullet.restitution = 0
bullet.type = DYNAMIC
bullet.info = "bullet"
table.insert(bullets,bullet)
end
function touched(touch)
x = touch.x
y = touch.y
if touch.state == BEGAN then
createBullet()
end
end
function collide(contact)
if contact.bodyA.info == "ball[i]" or contact.bodyB.info == "ball[i]" and
contact.bodyA.info == "bullet" or contact.bodyB.info == "bullet" then
if contact.state == BEGAN then
sound(DATA, "ZgNAfj01Pzc2Qz1AnatePohA3T0LSTE+YgB/fz54NlVoQ0A6")
table.remove(ball,i,ball[i])
table.remove(bullets,bullet)
end
end
end
Ballons = class()
function Ballons:init(x,y,r,c,lv)
self.radius = r or math.random(25,50)
self.ballon = physics.body(CIRCLE,self.radius)
self.ballon.x = x or math.random(WIDTH/2,WIDTH)
self.ballon.y = y or math.random(-HEIGHT/2,-self.radius)
self.ballon.linearVelocity = lv or vec2(0,math.random(100,150))
self.ballon.colr = c or color(math.random(255),math.random(255),math.random(255),math.random(100,150))
end
You can edit your posts so there’s no need to double post the code. I added the tildes to the first post and deleted (removed from view, nothing gets truly deleted) the second. Hope that’s okay.
when you are deleting objects in tables, it’s probably best to use the for…pairs approach when looping, because the usual for i=1,… loop may not work properly once there are gaps in the table
you need to destroy the physics objects with the destroy function before setting them to nil, otherwise they will live on
however…
destroying physics objects in the collide function seems to cause Codea to crash, so I’ve simply stored the details and done the deletion in draw
function setup()
physics.gravity(0,0)
bullets={}
ball = {}
for i = 1,5 do
ball[i] = Ballons()
end
end
function draw()
background(255, 255, 255, 255)
if collision~=nil then ------------------- see note 3. above
ball[collision[1]].ballon:destroy() --- see note 2 above
table.remove(ball,collision[1])
bullets[collision[2]]:destroy()
table.remove(bullets,collision[2])
collision=nil
end
pushStyle()
fill(0, 0, 0, 255) -- drawing the bullets
for i,b in pairs(bullets) do
ellipse(b.x,b.y,10)
if b.x<1 or b.x>WIDTH or b.y<1 or b.y>HEIGHT then
b=nil
end
end
popStyle()
for i,b in pairs(ball) do -- drawing the ballons
pushStyle()
fill(b.colr)
ellipse(b.ballon.x, b.ballon.y, b.radius*2)
popStyle()
end
end
function createBullet()
local bullet = physics.body(CIRCLE,5)
bullet.x = x
bullet.y = y
bullet.linearVelocity = vec2(1000,0)
bullet.restitution = 0
bullet.type = DYNAMIC
bullet.info = "bullet"
table.insert(bullets,bullet)
end
function touched(touch)
x = touch.x
y = touch.y
if touch.state == BEGAN then
createBullet()
end
end
function collide(contact)
if contact.bodyA.info~=nil and contact.bodyB.info~=nil then
for i,b in pairs(ball) do
if b.ballon==contact.bodyA or b.ballon==contact.bodyB then
for j,bb in pairs(bullets) do
if bb==contact.bodyA or bb==contact.bodyB then
sound(DATA, "ZgNAXS4wQEBAQEBA/9iePiN3mD64nKs+cgBAf0BAQEBAb0BA ")
collision={i,j} -- see note 3 above
end
end
end
end
end
end
Ballons = class()
function Ballons:init(x,y,r,c,lv)
self.radius = r or math.random(25,50)
self.ballon = physics.body(CIRCLE,self.radius)
self.ballon.x = x or math.random(WIDTH/2,WIDTH)
self.ballon.y = y or math.random(-HEIGHT/2,-self.radius)
self.ballon.linearVelocity = lv or vec2(0,math.random(100,150))
self.ballon.info="ball"
self.colr = c or color(math.random(255),math.random(255),math.random(255),math.random(100,150))
end
.@Ignatz, @Saurabh There is still one more thing you need to do, that’s to destroy the physics.bodies that were removed from the table. If you shoot at a ballon and remove it, even though you don’t see it anymore, the bullets still bounce off it and the program crashes after awhile.
Thanks for the post Ignatz.
But the code you have shared in the post is not working properly, the code over here is working perfectly fine I can’t find out what you have missed out. I think you should paste the code from here to your post.
And by the way I’m a guy and 16
. @Ignatz Another way you could destroy the objects is to set up a variable like self.ballon.destroy and bullet.destroy. Set them to false when each object is created, then set them to true when they need to be destroyed. In the draw function, if they need to be destroyed, destroy them and remove them from the table, else draw them.
@dave1707 absolutely. I took the suggestion of a table (or “stack”) of objects to be destroyed from one of the help pages, but your way looks good, too.
How can we keep track of the number of bullets that don’t hit the ballon and go beyond the WIDTH of the screen if I make a function to increase count by one then if its called the number keeps on increasing (60 per second)
I tried it using this class
Point = class()
function Point:init(score)
self.score = score or 0
end
function Point:ScoreIncrease()
for i,b in pairs(bullets) do
if b.x<1 or b.x>WIDTH or b.y<1 or b.y>HEIGHT then
self.score = self.score + 1
end
end
end
The inbuilt codes like invader were too complicated for me to understand.
And I had parameter.watch in setup to check value
Try this, see the line marked ADD THIS. This should only increase when a bullet goes off the edge.
function draw()
....other code
pushStyle()
fill(0, 0, 0, 255) -- drawing the bullets
for i,b in pairs(bullets) do
ellipse(b.x,b.y,10)
if b.x<1 or b.x>WIDTH or b.y<1 or b.y>HEIGHT then
b=nil
score=score+1. -- ADD THIS
end
end
popStyle()
.....other code....
end