Program help

This is a spinoff of West’s side scroller code. We need help with code for collision between the hero and the plate objects. Any help would be appreciated. This isn’t going on the App Store, just for personal use. We have split the code in two.

-- Use this function to perform your initial setup
function setup()
   displayMode(FULLSCREEN)
    --gameState is the current state of play
    -- 0 is the splash screen
    -- 1 is normal gameplay
    -- 2 is gameover
    gameState=0
    x=math.random(401,500)
    y=math.random(301,400)
    z=math.random(201,300)
    r=math.random(100,200)
end

        
-- This function gets called once every frame
function draw()
--One if statement checks what game state we are currently in and executes the relevant code
if gameState==0 then
    --Draw the splash screen
    background(0,0,0,255)
    font("AmericanTypewriter-Bold")
    fontSize(40)
    --Set up a title
    text("Toasty",WIDTH/2,HEIGHT/2+150)
    fontSize(25)
    --add your name
    text("by: Peter Valesares",WIDTH/2,HEIGHT/2+75)
    text("& Jack Dew",WIDTH/2,HEIGHT/2+50)
    text("Music by: John Hutton", WIDTH/2, HEIGHT/2)
    text("Art by: Katie Hood", WIDTH/2, HEIGHT/2-50)
    --Draw a start button
    fill(127, 220, 23, 255)
    ellipse(WIDTH/2,HEIGHT/2-200,100)
    stroke(220, 217, 172, 255)
    fill(223, 230, 222, 255)
    fontSize(50)
    text("Go",WIDTH/2,HEIGHT/2-200)
    --Calculate the distance of the edge away from the centre of the button
    dist=math.sqrt(((CurrentTouch.x-WIDTH/2)^2)+((CurrentTouch.y-(HEIGHT/2)+200))^2)
    --check to see if the user has touched the button
    if CurrentTouch.state==ENDED and dist<50 then
        --put into the play game state
        gameState=1
        --Initialise some variables
        xpos=0 --used for the movement of the background
        speed=5 --initial speed
        speedCounter=0 --a counter to increment the speed
        speedMax=200 --the value at which the speed will increment
        topSpeed=50 --the top speed
        upthrust=0 --the upward force applied to the hero character
        herovel=0 --the vertical velocity of the hero character
        herox=100 --the horizontal position of the hero
        heroy=HEIGHT/2  -- the vertical position of the hero
        --an array of height values for the ground
        --add more values into the array to create a longer level
        ground={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
        --an array of height values for the ceiling
        --make sure that the two arrays are the same length
          roof={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}   
        plate={0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
        plate2={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
        plate3={0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0}
        plate4={0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0}
        t=0.1 -- a time variable used to calculate the position and velocity between frames
        acc=0  --an acceleration variable calculated each frame
        grav=-7--a constant gravitational force
        score=0  --the current score
        restartwait=0 --a timer for restarting the game at the end
    end           

elseif gameState==1 then
    
--Stretch an sprite to fill the background
--As this is the furthest away thing draw first and everything else will be drawn on top
    sprite("SpaceCute:Background",WIDTH/2,HEIGHT/2,WIDTH,HEIGHT)
  

--the screen in landscape will allow 12 sprites with a width of 100 to be drawn
--try reducing the second number to 10 to see the effect (make sure you hold in landcsape)    
    for i = 1,12 do
--the value in the current position (i) of the ground array is the number of blocks high to 
--draw at the current position
        for h=1,ground[i] do
            --draw the sprite at the current x position i * width of one sprite with the xpos
            --offset which creates the movement
            --the y position is calculated as a multiplier of the the height
            sprite("Documents:Butter",xpos+100*i-100,-40+70*h,100,100)
                
        end       
        --repeat the process for the ceiling
        for h=1,roof[i] do
            sprite("Documents:Butter",xpos+100*i-100,HEIGHT+90-70*h,100,100)
        end        
end
for i = 1,20 do
    for h=1,plate[i] do
            --draw the sprite at the current x position i * width of one sprite with the xpos
            --offset which creates the movement
            --the y position is calculated as a multiplier of the the height
            sprite("Documents:Plate",xpos+100*i, x, 100,100)         
        end  
    for h=1,plate2[i] do
            --draw the sprite at the current x position i * width of one sprite with the xpos
            --offset which creates the movement
            --the y position is calculated as a multiplier of the the height
            sprite("Documents:Plate",xpos+100*i, y,100,100)         
    end
end

for i = 1,20 do
    for h=1,plate3[i] do
        sprite("Documents:Plate",xpos+100*i, z,100,100)
    end
    for h=1,plate4[i] do
        sprite("Documents:Plate",xpos+100*i, r,100,100) 
    end
end
        
--Display the hero sprite
    sprite("Documents:Fancy Toast",herox,heroy,110,160)
--[[
--Gravity based version, touch anywhere to provide upthrust to counter gravity
    if CurrentTouch.state == MOVING or CurrentTouch.state== BEGAN then    
        upthrust = upthrust + speed/5
        if upthrust>20 then
            upthrust=20
        end
    end
    if CurrentTouch.state==ENDED then
        upthrust=0
    end
    acc=upthrust + grav
--equation of motion to calculate the displacement in the y direction s=ut+0.5at*t
    heroy=heroy+herovel*t+0.5*acc*t*t
--equation of motion for the new velocity v=u+at
    herovel=herovel+acc*t
--]]

      if CurrentTouch.state==MOVING or CurrentTouch.state==BEGAN then    
                upthrust = upthrust + 13--cumulatively add some upward force - alter the 10 to get different levels of force
                --limit the force
                if upthrust>16 then
                    upthrust=16
                end
            end
            --decrease the upward force when the finger is removed, but not immediately
            if CurrentTouch.state==ENDED then
                upthrust=upthrust-2
                if upthrust<0 then
                    upthrust=0
                end
            accx=0
        end
        acc=upthrust+grav -- change the vertical displacemnt according to the amount of force
    --equation of motion to calculate the displacement in the y direction s=ut+0.5at*t
        heroy=heroy+herovel*t+0.5*acc*t*t
    --equation of motion for the new velocity v=u+at
        herovel=herovel+acc*t

    
    
--stop the sprite going off the top of the screen
--redundant here, but if you wanted to have a narrower field of play then this what you would use
--try replacing both HEIGHT with HEIGHT/1.5 to try it out
    if heroy>HEIGHT then
        heroy=HEIGHT
    end
    if heroy<0 then
        heroy=0
    end
--dealing with collisions
--normally we would have to check to see if the hero has hit anything on the screen
--however as we are restricting the movement to up and down only then we only 
--need to check the sprites in the same vertical location
    if heroy<(30*(ground[2]+1)) then
        gameState=2
    end
    if heroy>(HEIGHT+70-70*(roof[2]+1)) then
        gameState=2
    end 
    
    
      if plate2[i] == xpos and plate2[i] ==heroy then
    gamestate=2
    end
    
      if plate4[i] == xpos and plate1[i] ==heroy then
    gamestate=2
    end

Here is the rest.

--xpos is a variable used to control the position of the sprites on the screen
--the variable speed determines how much each sprite is moved each time the screen is redrawn
    xpos=xpos-speed
--score is based on distance travelled
    score = score + speed
    highscore = score
    
    fill(255, 255, 255, 255)
    text("Score: "..score,WIDTH/2,HEIGHT-30)
   -- text("highscore: "..highscore,WIDTH/2,HEIGHT-60)
--need to reset xpos at an appropriate point to get wraparound
    if xpos<-100 then
        xpos=0
--store the value of the current first element of the array   
--for example, for the array {a,b,c,d} store the first element a in the variable temp
        temp=ground[1]
        tempr=roof[1]
        plater=plate[1]
        plate2r=plate2[1]
        plate3r=plate3[1]
        plate4r=plate4[1]
--shift the ground array along by one, overwriting the first element by the second element,
--the second element by the third element, etc, etc
--Note the last element is not overwritten yet
-- {a,b,c,d} becomes {b,c,d,d}
        for c=1,#ground-1 do
            ground[c]=ground[c+1]
            roof[c]=roof[c+1]
            plate[c]=plate[c+1]
            plate2[c]=plate2[c+1]
            plate3[c]=plate3[c+1]
            plate4[c]=plate4[c+1]
        end
--Move the previously saved first element (saved in the temp variable)to the last position
--{b,c,d,d} becomes {b,c,d,a}
        ground[#ground]=temp
        roof[#roof]=tempr
        plate[#plate]=plater
        plate2[#plate2]=plate2r
        plate3[#plate3]=plate3r
        plate4[#plate4]=plate4r
    end
--get faster over time
    speedCounter = speedCounter + 1
    if speedCounter>speedMax then
        speed=speed+1
        speedCounter=0
--set an upper limit on the speed
        if speed>topSpeed then
            speed=topSpeed
        end
    end 
--game over state       
elseif gameState==2 then   
    background(96, 77, 77, 255)   
    text("Game over",WIDTH/2,HEIGHT/2)
    text("Score:  "..score,WIDTH/2,HEIGHT/2-50)
--add a delay to stop overspill from the gameplay restarting the game instantly
    if restartwait>100 then
          text("Tap screen to restart",WIDTH/2,HEIGHT/2-100)
    end    
    if CurrentTouch.state==BEGAN and restartwait>100 then
        gameState=0
    end
    restartwait = restartwait + 1
end    
        
end

@Jdew, please please please, put three ~ on the line before and after your code for correct formatting, also, try to indent your code

@stevon8ter +1

Example:

~~~
Paste code here
~~~

Sorry, first time posting

It’s okay. Welcome to the forums!

Thanks!

Welcome indeed, but try to fix your post, you can get help easyer when one can copy or look at the code in a correct way

@Jdew You can “edit” the above posts and add the 3 tildes to correct it. Do a “preview” before you post it to see what it will look like on the forum.

Thanks for the tips, it should look better now

@Jdew Just set up a loop comparing the x,y value of the hero to the x,y values of the plates. If the distance between them is less than a certain value, then consider that a collision occurred.

Well i didn’t take a good look at the code, but here’s something that should explain collisions a bit, note that I only explain collsions between rectangles

function collision(x1, y1, w1, h1, x2, y2, w2, h2)
    -- x = x pos (center of the object)
    -- y = y pos (center of the object)
    -- w = total width of the object (left edge to right edge)
    -- h = total height of the object (bottom to top)
    -- 1 = the character, the main rectangle
    -- 2 = another object

    if math.abs(x1 - x2) <= w1/2 + w2/2 then
        if math.abs(y1 - y2) <= h1/2 + h2/2 then
            return true
        end
        return false
    end
    return false
end

function setup()
    
    rectMode(CENTER)
    
    xh = WIDTH/2
    yh = HEIGHT/2
    wh = 50
    hh = 100
    
    xo = WIDTH/2
    yo = HEIGHT/2
    wo = 50
    ho = 50
    
    if collision(xh, yh, wh, hh, xo, yo, wo, ho) then
        print('collision')
    end
    
end

function draw()
    
    fill(255, 0, 0, 255)
    rect(xh, yh, wh, hh)
    
    fill(2, 255, 0, 255)
    rect(xo, yo, wo, ho)
    
end

tested and working, just change the possition and size of the objects with

xh = x pos 'hero'
yh = x pos 'hero'
wh = width ...
hh = height ...

xo = x pos 'object'
....
-- vec2 syntax: vec2(x, y)
-- i.e. vec2(10, 15) would return a 2D coordinate with an X of 10  and a Y of 15

function isCollided(aPos, bPos, aSize, bSize)
    -- aPos is a vec2, the first element's position
    -- bPos is a vec2, the second element's position
    -- aSize is a vec2, the first element's size
    -- bSize is a vec2, the second element's size
    
    return aPos:dist(bPos) <= ((aSize.x + bSize.x) / 2 + (aSize.y + bSize.y) / 2) / 2
    
    -- The aPos:dist(bPos) part calculates the distance between aPos and bPos
    -- The <= ((aSize.x + bSize.x)... part just averages the size of both of the points
end

Untested, hopefully works, better for circles.

@stevon8ter math.abs, not math.abd*

@SkyTheCoder yeah I noticed that when I tried to run it, fixed already :wink:

So, I’ve tried implementing these ideas. I’m still struggling to get the right values to plug into the collision function. Any ideas?