I am getting this error:
error: [string “–tween.lua…”]:472 :attempt to perform arithmetic on local ‘d’ (a nil value)
I didn’t use d as a variable in my code. Can someone explain what this means?
I am getting this error:
error: [string “–tween.lua…”]:472 :attempt to perform arithmetic on local ‘d’ (a nil value)
I didn’t use d as a variable in my code. Can someone explain what this means?
And here is my code:
function setup()
supportedOrientations(CurrentOrientation)
boy = vec2(300,70)
eb = vec2(0,70) --enemy bug
lcx1 = 150 -- Large Crate 1 x
lcy1 = 170 -- Large Crate 1 y
lcx2 = 370 -- Large Crate 2 x
lcy2 = 370 -- Large Crate 2 y
dx2 = 5 -- Mine Spiked deltax
msx = 400 -- Mine Spiked x
msy = 530 -- Mine Spiked y
parameter.watch("delta_x")
end
function draw()
background()
sprite("SpaceCute:Background",374,374)
sprite("Cargo Bot:Title Large Crate 1",lcx1,lcy1)
sprite("Cargo Bot:Title Large Crate 2",lcx2,lcy2)
sprite("Planet Cute:Enemy Bug",eb.x,eb.y)
sprite("Tyrian Remastered:Mine Spiked Huge",msx,msy)
sprite("Platformer Art:Cloud 3",600,600)
sprite("Planet Cute:Character Cat Girl",600,650)
sprite("Planet Cute:Character Boy",boy.x,boy.y)
msx = msx + dx2
if msx >= WIDTH - 50 then dx2 = -dx2 end
if msx <= 50 then dx2 = -dx2 end
if math.abs(eb.x-boy.x)<=65 and math.abs(eb.y-boy.y)<=10 then
tween.stopAll()
else tween(4.0, eb, {WIDTH-50,70},tween.easing.linear,tween.loop.forever) end
if eb.x-65<=boy.x and boy.x<=eb.x+65 and eb.y-10<=boy.y and boy.y<=eb.y+10 then
background()
font("Futura-Medium")
fontSize(40)
textWrapWidth(150)
text("GAME OVER", 350,450)
w,h = textSize("RESTART")
fill(120,0,40)
strokeWidth(2)
rectMode(CENTER)
rect(350,250,w+15,h-50)
fontSize(30)
fill(255)
text("RESTART",350,250)
end
stroke(37, 202, 38, 255)
strokeWidth(10)
line(0,10,WIDTH,10)
end
function touched(touch)
delta_x = touch.deltaX
if delta_x < 0 then boy.x = boy.x - 10 end
if delta_x > 0 then boy.x = boy.x + 10 end
if touch.deltaY > 6 and boy.y == 70 and math.abs(eb.x-boy.x)>65 then
sound(SOUND_JUMP, 32003)
t1 = tween(0.35, boy, {y=300}, tween.easing.expoOut)
t2 = tween(0.35, boy, {y=70}, tween.easing.expoInOut)
tween.sequence(t1,t2)
end
if eb.x-65<=boy.x and boy.x<=eb.x+65 and eb.y-10<=boy.y and boy.y<=eb.y+10 then
if touch.x<=450 and touch.x>=250 and touch.y<=300 and touch.y>200 then
tween.resetAll() else tween.stopAll() end
end
end
It means that you’ve passed something to a tween function that it didn’t expect. d
is just the internal name for whatever it was. Look carefully through your code to see if you either pass a nil or forget to pass something to a tween function.
Thanks but I have ran over the code many times, still I can’t see the mistake.
Assuming the tween library is the same as one I found on the web, then d internally will be duration. I also played with your game and it’s a bit intermittent to get it to crash… Addint loads of print statements it seems to die in the draw loop…
I think you might be hitting a bug in tween, rather than something you’ve written.
One thing I noticed is that you’re constantly calling tween routines in draw. You should create a tween once, let it do it’s thing, and when it’s done call it again. If you need to stop a tween that’s running, call tween.stop . It looks like you need to review what you’re trying to do with the Tweens.
The error you’re getting is probably because of tween calls on Tweens that aren’t running anymore.
.@inancyuce Here is a simple example of what I was trying to explain above about creating a tween, letting it do it’s thing, and creating it again if needed.
EDIT: changed tween.easing.linear to tween.easing.cubicOut and cubicIn.
supportedOrientations(LANDSCAPE_ANY)
displayMode(FULLSCREEN)
function setup()
val=2
done=true
cb={x=60,y=50}
end
function setupTween()
t1=tween(.5,cb,{y=600},tween.easing.cubicOut)
t2=tween(.5,cb,{y=100},tween.easing.cubicIn,tweenDone)
tween.sequence(t1,t2)
end
function draw()
background(40, 40, 50)
fill(255)
if done then
text("Tap screen to jump",WIDTH/2,700)
end
if cb.x<50 or cb.x>WIDTH-50 then -- keep sprite on the screen
val=- val
end
cb.x=cb.x+val -- move sprite
sprite("Planet Cute:Character Boy",cb.x,cb.y) -- draw sprite
end
function tweenDone()
done=true -- tween is done, allow next tween
end
function touched(t)
if t.state==BEGAN and done then -- if tween is done, allow another
done=false
setupTween() -- start the next tween
end
end
Thank you guys. I reviewed my code as you told and I discovered that when I erase the tween.loop part I didn’t get the same error so space monkey is probably right about the bug. There’s something wrong with tween.loop. Anyway, I changed my code as the following and achieved what I was trying for.
Next thing I need to do is make the crates solid. It would be nice if you gave me a hint about how to do it in an easy way. I guess I will need to implement physics bodies into my code, right?
function setup()
supportedOrientations(CurrentOrientation)
sm = vec2(50,530) -- spiked mine
dx = 5 -- delta x of spiked mine
boy = vec2(300,70) -- boy
lcx1 = 150 -- Large Crate 1 x
lcy1 = 170 -- Large Crate 1 y
lcx2 = 370 -- Large Crate 2 x
lcy2 = 370 -- Large Crate 2 y
ebx = 0 -- enemy bug x
eby = 70 -- enemy bug y
delta_x = 0
delta_y = 0
end
function draw()
background()
sprite("SpaceCute:Background",374,374)
sprite("Cargo Bot:Title Large Crate 1",lcx1,lcy1)
sprite("Cargo Bot:Title Large Crate 2",lcx2,lcy2)
sprite("Planet Cute:Enemy Bug",ebx,eby)
sprite("Tyrian Remastered:Mine Spiked Huge",sm.x,sm.y)
sprite("Platformer Art:Cloud 3",600,600)
sprite("Planet Cute:Character Cat Girl",600,650)
sprite("Planet Cute:Character Boy",boy.x,boy.y)
stroke(37, 202, 38, 255)
strokeWidth(10)
line(0,10,WIDTH,10)
sm.x = sm.x + dx
if sm.x >= WIDTH - 50 then dx = -dx end
if sm.x <= 50 then dx = -dx end
if math.abs(ebx-boy.x)<=65 and math.abs(eby-boy.y)<=10 then
background()
font("Futura-Medium")
fontSize(40)
textWrapWidth(150)
text("GAME OVER", 350,450)
w,h = textSize("RESTART")
fill(120,0,40)
strokeWidth(2)
rectMode(CENTER)
rect(350,250,w+15,h-50)
fontSize(30)
fill(255)
text("RESTART",350,250)
else ebx = ebx + 4
if ebx >= WIDTH - 50 then ebx = 0 end
end
end
function touched(touch)
delta_x = touch.deltaX
delta_y = touch.deltaY
if delta_x < 0 then boy.x = boy.x - 10 end
if delta_x > 0 then boy.x = boy.x + 10 end
if touch.deltaY > 6 and boy.y == 70 and math.abs(ebx-boy.x)>65 then
sound(SOUND_JUMP, 32003)
t1 = tween(0.35, boy, {y=300}, tween.easing.expoOut)
t2 = tween(0.35, boy, {y=70}, tween.easing.expoInOut)
tween.sequence(t1,t2)
end
if math.abs(ebx-boy.x)<=65 and math.abs(eby-boy.y)<=10 then
ebx = ebx
boy.x = ebx
boy.y = eby
if touch.x<=450 and touch.x>=250 and touch.y<=300 and touch.y>200 then
ebx = 0 boy.x = 300
end
end
end
You could write some collision detection and make your character stand on the box if the jump collides on its way down. Then have the collision detection set the players y to the top of the box.
Thanks for the hint. I tried this but it didn’t work although it didn’t give an error.
function collide(contact)
lc1edge = physics.body(EDGE, vec2(97,170), vec2(203,170))
boyedge = physics.body(DYNAMIC, vec2(boy.x-50,boy.y-85), vec2(boy.x+50,boy.y-85))
if lc1edge:testOverlap(boyedge) then boy.y = 170 end
end
Any more suggestions?
Instead of trying to do collisions, just keep track of the top edge of the crates. When the characters x,y position is in the correct area, then set the characters position.
@dave1707 yeah thats what I was trying to say When i said collision I was not referring to physics bodies. wrtie your own function to check if the bottom of your character sprite is on the top of the crate and set coords accordingly
I am going to use an if statement as the following but in which function will I put it? And how will I assure that this is true only when the boy is falling down?
function()
if boy.x <= 200 and boy.x >= 100 and boy.y == 220
then boy.y = 220 end
end
Place it in the draw function, or create a function and put the call in draw. Add a function to compare the current boy.y with the previous boy.y values. If the current boy.y is less that the previous boy.y, the boy is falling. You also have a lot of changes to make to your code. The tween y value is always 300 and 70. If the boy jumps from a crate, those values need to be adjusted for the crate height. Also, you’re constantly creating Tweens in you touch function. You need to create a tween once, let it finish or stop it, before creating the tween again. See the example code I showed you above on how to create a tween, let it run, and create it again.
Ok, I will do that. finally can you show me an example of how to create an arbitrary function for an arbitrary purpose? Is my syntax correct above?
Here’s some examples
-- add this line to setup
prevY=0
-- add this if statement at the end of the draw function
if falling() then -- boy is falling
if boy.x>lcx1-50 and boy.x<lcx1+50 and boy.y<lcy1+120 then
tween.stopAll() -- stop the tween
boy.y=lcy1+100 -- set boy y value
prevY=0 -- zero prevY
end
end
end -- last end of draw
-- add this function anywhere
function falling() -- check if boy is falling
if boy.y<prevY then
prevY=boy.y
return true
else
prevY=boy.y
return false
end
end
I have modified my code according to your instructions Dave, I am grateful for all your help but the crate is still not solid. Where am I doing wrong?
supportedOrientations(LANDSCAPE_ANY)
function setup()
sm = vec2(50,530) -- spiked mine
dx = 5 -- delta x of spiked mine
boy = vec2(300,70) -- boy
lc1 = vec2(150,170) -- Large Crate 1
lc2 = vec2(370,370) -- Large Crate 2
ebx = 0 -- enemy bug x
eby = 70 -- enemy bug y
delta_x = 0 -- variable to be used for moving right or left
delta_y = 0 -- variable to be used for jumping
prevY = 0 -- used in falling function
done = true -- used in tweenDone function
end
function tweenDone()
done = true
end
function setupTween()
t1 = tween(0.35, boy, {y = boy.y + 230}, tween.easing.cubicOut)
t2 = tween(0.35, boy, {y = boy.y}, tween.easing.cubicIn, tweenDone)
tween.sequence(t1,t2)
end
function falling() -- check if boy is falling
if boy.y < prevY then
prevY = boy.y
return true
else prevY = boy.y
return false
end
end
function draw()
background()
sprite("SpaceCute:Background",374,374)
sprite("Cargo Bot:Title Large Crate 1",lc1.x,lc1.y)
sprite("Cargo Bot:Title Large Crate 2",lc2.x,lc2.y)
sprite("Planet Cute:Enemy Bug",ebx,eby)
sprite("Tyrian Remastered:Mine Spiked Huge",sm.x,sm.y)
sprite("Platformer Art:Cloud 3",600,600)
sprite("Planet Cute:Character Cat Girl",600,650)
sprite("Planet Cute:Character Boy",boy.x,boy.y)
stroke(37, 202, 38, 255)
strokeWidth(10)
line(0,10,WIDTH,10) -- ground line
sm.x = sm.x + dx -- spiked mine is constantly moving right and left
if sm.x >= WIDTH - 50 or sm.x <= 50 then dx = -dx end
if math.abs(ebx-boy.x)<=65 and math.abs(eby-boy.y)<=10 then -- the condition when boy is eaten by enemy bug
background()
font("Futura-Medium")
fontSize(40)
textWrapWidth(150)
text("GAME OVER", 350,450)
w,h = textSize("RESTART")
fill(120,0,40)
strokeWidth(2)
rectMode(CENTER)
rect(350,250,w+15,h-50)
fontSize(30)
fill(255)
text("RESTART",350,250)
ebx = ebx
boy.x = ebx
boy.y = eby
else ebx = ebx + 4 -- enemy bug is constantly moving from point x=0 to right
if ebx >= WIDTH - 50 then ebx = 0 end
end
if falling() then -- trying to land the boy on the surface of large crate 1 while falling on it.(not working)
if boy.x >= lc1.x-53 and boy.x <= lc1.x+53 and boy.y == lc1.y+120 then
tween.stopAll()
boy.y = lc1.y + 120
prevY = 0
end
end
end
function touched(touch)
delta_x = touch.deltaX
delta_y = touch.deltaY
if delta_x < 0 then boy.x = boy.x - 10 end -- for moving left on left drag of touch
if delta_x > 0 then boy.x = boy.x + 10 end -- for moving right on right drag of touch
if touch.deltaY > 6 and math.abs(ebx-boy.x)>65 and done then -- for jump with up drag of touch
sound(SOUND_JUMP, 32003)
done = false
setupTween() -- calling the next tween(jump) after previous one is done
end
if math.abs(ebx-boy.x)<=65 and math.abs(eby-boy.y)<=10 then -- when game over screen comes
if touch.x<=450 and touch.x>=250 and touch.y<=300 and touch.y>200 then -- for touching restart button
ebx = 0 boy.x = 300 sound(SOUND_PICKUP, 607)
end
end
end
Change the if falling() statement to what’s below. You had >=, <=, and == . It was very unlikely that you would hit the == condition. I originally had it as >, <, and < in the above post. This will land the boy on the crate, but there is still a lot more that has to be done because the boy doesn’t do anything but move side to side after that. I’ll post more code later to help you out, but you can try making changes if you want.
if falling() then
if boy.x > lc1.x-53 and boy.x < lc1.x+53 and boy.y < lc1.y+120 then
tween.stopAll()
boy.y = lc1.y + 100
prevY = 0
end
end
Look over this code to see what I did. You’ll still have to fix some things for what you want. I added code for when the boy collides with the mine and when the boy reaches the girl. You’ll have to create functions for what you want to do with those conditions.
supportedOrientations(LANDSCAPE_ANY)
function setup()
tx1=300
tx2=70
sm = vec2(50,530) -- spiked mine
dx = 5 -- delta x of spiked mine
boy = vec2(300,70) -- boy
lc1 = vec2(150,170) -- Large Crate 1
lc2 = vec2(370,370) -- Large Crate 2
ebx = 0 -- enemy bug x
eby = 70 -- enemy bug y
delta_x = 0 -- variable to be used for moving right or left
delta_y = 0 -- variable to be used for jumping
prevY = 0 -- used in falling function
done = true -- used in tweenDone function
done3=true
end
function tweenDone()
done = true
end
function tween3Done()
done3=true
end
function setupTween()
t1 = tween(0.35, boy, {y = tx1}, tween.easing.cubicOut)
t2 = tween(0.35, boy, {y = tx2}, tween.easing.cubicIn, tweenDone)
tween.sequence(t1,t2)
end
function setupTween3()
if done3 then
done3=false
t3 = tween(0.35, boy, {y = 70}, tween.easing.cubicIn, tween3Done)
end
end
function falling() -- check if boy is falling
if boy.y < prevY then
prevY = boy.y
return true
else prevY = boy.y
return false
end
end
function draw()
background()
sprite("SpaceCute:Background",374,374)
sprite("Cargo Bot:Title Large Crate 1",lc1.x,lc1.y)
sprite("Cargo Bot:Title Large Crate 2",lc2.x,lc2.y)
sprite("Planet Cute:Enemy Bug",ebx,eby)
sprite("Tyrian Remastered:Mine Spiked Huge",sm.x,sm.y)
sprite("Platformer Art:Cloud 3",600,600)
sprite("Planet Cute:Character Cat Girl",600,650)
sprite("Planet Cute:Character Boy",boy.x,boy.y)
stroke(37, 202, 38, 255)
strokeWidth(10)
line(0,10,WIDTH,10) -- ground line
sm.x = sm.x + dx -- spiked mine is constantly moving right and left
if sm.x >= WIDTH - 50 or sm.x <= 50 then
dx = -dx
end
-- check if boy and spiked mine collide
if math.abs(boy.x-sm.x)<50 and math.abs(boy.y-sm.y)<50 then
print("mine collision") -- call your function for the collision
end
if math.abs(ebx-boy.x)<=65 and math.abs(eby-boy.y)<=10 then
-- the condition when boy is eaten by enemy bug
background()
font("Futura-Medium")
fontSize(40)
textWrapWidth(150)
text("GAME OVER", 350,450)
w,h = textSize("RESTART")
fill(120,0,40)
strokeWidth(2)
rectMode(CENTER)
rect(350,250,w+15,h-50)
fontSize(30)
fill(255)
text("RESTART",350,250)
else
ebx = ebx + 4 -- enemy bug is constantly moving from point x=0 to right
if ebx >= WIDTH - 50 then
ebx = 0
end
end
if falling() or done then
if boy.x > lc1.x-53 and boy.x < lc1.x+53 and boy.y > lc1.y+100 and boy.y < lc1.y+120 then
if not done then
tween.stopAll()
end
done=true
boy.y = lc1.y + 105
tx1=500
tx2=70
elseif boy.x > lc2.x-53 and boy.x < lc2.x+53 and boy.y>lc2.y+100 and boy.y < lc2.y+120 then
if not done then
tween.stopAll()
end
done=true
boy.y = lc2.y + 105
tx1=800
tx2=70
elseif boy.x > 530 and boy.x < 680 and boy.y>620 and boy.y < 650 then
if not done then
tween.stopAll()
print("girl reached") -- add your function here
end
done=true
boy.y = 625
tx1=625
tx2=70
else
tx1=300
tx2=70
if boy.y>70 and done then
setupTween3()
end
end
end
end
function touched(touch)
delta_x = touch.deltaX
delta_y = touch.deltaY
if delta_x < 0 then
boy.x = boy.x - 10
end -- for moving left on left drag of touch
if delta_x > 0 then
boy.x = boy.x + 10
end -- for moving right on right drag of touch
if touch.deltaY > 6 and math.abs(ebx-boy.x)>65 and done then
-- for jump with up drag of touch
sound(SOUND_JUMP, 32003)
setupTween() -- calling the next tween(jump) after previous one is done
done=false
end
if math.abs(ebx-boy.x)<=65 and math.abs(eby-boy.y)<=10 then
-- when game over screen comes
if touch.x<=450 and touch.x>=250 and touch.y<=300 and touch.y>200 then
-- for touching restart button
setup()
sound(SOUND_PICKUP, 607)
end
end
end
Thanks Dave. I will study these for a while to understand what’s happening why. I didn’t understand why the if statement doesn’t work with == .