Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Why won't "newton" move???? [FIXED]

edited January 2015 in Bugs Posts: 63

"Newton" (in my practice project) is supposed to be a square object that jumps constantly, moves to the side when you tilt your screen, and glides when you touch the screen. I also set it so that if he goes too far in any direction, he will be stopped (in terms of where he is on the screen) and the background will move in the opposite direction in his exact speed. Think of the background scrolling in super mario bros, but he just WONT MOVE!!! I can not figure out why this block isn't jumping constantly, gliding when you touch the screen, and moving side to side when you tilt the screen. Please someone help me with this. Side note: I am fairly experienced with codea programming as of now, so I knew what I was doing when constructing this code.
Main class:

supportedOrientations(PORTRAIT_ANY)
function setup()
    parameter.watch("test")
    parameter.watch("touching")
    parameter.watch("newtonxspeed")
    parameter.watch("newtonyspeed.linearVelocity.y")
    parameter.watch("newton.linearVelocity.x")
    parameter.watch("newton.linearVelocity.y")
    parameter.watch("stuff1center.y")
    displayMode(OVERLAY)
    x=TitleScreen
    i=0
end

function draw()
    x:draw()
end

function touched(t)
    x:touched(t)
end

----TitleScreen class: (only press start game when in this class)

TitleScreen = class()
--doodle jump like game
--sir newton jumps up endlessly tall tree
--falling apples that kill you if you hit below them, but you can jump off of
--branches produce apples, cam be jumped off of

function TitleScreen:init()
    rectMode(CORNER)
    textMode(CENTER)
    st=false
    cr=false
    he=false
end

function TitleScreen:draw()
    fontSize(HEIGHT/51.2)
    local rectheight=HEIGHT/20.48
    local rectwidth=rectheight*4
    sprite("SpaceCute:Background",WIDTH/2,HEIGHT/2,WIDTH,HEIGHT)
    stroke(0, 231, 255, 255)
    strokeWidth(5)
    fill(8, 255, 0, 255)
    if st then
        fill(11, 0, 255, 255)
    end
    rect(WIDTH/2-100,HEIGHT/2+125,rectwidth,rectheight)

    fill(8, 255, 0, 255)
    if cr then
        fill(11, 0, 255, 255)
    end    
    rect(WIDTH/2-100,HEIGHT/2-25,rectwidth,rectheight)

    fill(8, 255, 0, 255)
    if he then
        fill(11, 0, 255, 255)
    end    
    rect(WIDTH/2-100,HEIGHT/2-175,rectwidth,rectheight)
    fill(255, 0, 22, 255)
    text("Start Game",WIDTH/2,HEIGHT/2+HEIGHT/6.8)
    text("Credits",WIDTH/2,HEIGHT/2)
    text("Help",WIDTH/2,HEIGHT/2-HEIGHT/6.8)
    textSize(150,30)
end

function TitleScreen:touched(touch)
    if touch.x >= WIDTH/2-100 and touch.x <= WIDTH/2+100 and
        touch.y >= HEIGHT/2+125 and touch.y <= HEIGHT/2+175 then
        if touch.state==BEGAN then
            st=true
        elseif touch.state==ENDED then
            x=Game()
        end
    end
    if touch.x >= WIDTH/2-100 and touch.x <= WIDTH/2+100 and 
        touch.y >= HEIGHT/2-25 and touch.y <= HEIGHT/2+25 then
        if touch.state==BEGAN then
            cr=true
        elseif touch.state==ENDED then
            x=Credits()
        end
    end
    if touch.x >= WIDTH/2-100 and touch.x <= WIDTH/2+100 and 
        touch.y >= HEIGHT/2-175 and touch.y <= HEIGHT/2-125 then
        if touch.state==BEGAN then
            he=true
        elseif touch.state==ENDED then
            x=Help()
        end
    end
    if touch.state==ENDED then
        st=false
        cr=false
        he=false
    end
end

----Game class:

Game=class()

function Game:init()
    rectMode(CENTER)
    spriteMode(CENTER)
    textMode(CENTER)
    newtonsize=HEIGHT/102.4
    newton=physics.body(POLYGON,vec2(-newtonsize,newtonsize),vec2(-newtonsize,-newtonsize),vec2(newtonsize,-newtonsize),vec2(newtonsize,newtonsize))
    newton.type=DYNAMIC
    newton.info="main"
    newton.x=WIDTH/2
    newton.y=newtonsize
    newton.gravityScale=1
    stuff1center=physics.body(CIRCLE,1)
    stuff1center.x=WIDTH/2
    stuff1center.y=1
    stuff1center.gravityScale=-1
    stuff1center.type=KINEMATIC
    stuff1={}
    stuff2={}
    stuff3={}
    newtonxspeed=0
    newtonyspeed=physics.body(CIRCLE,1)
    newtonyspeed.type=KINEMATIC
    newtonyspeed.gravityScale=1 
    minheight1=0
    minheight2=-stuff1center.x
floor=physics.body(EDGE,vec2(-WIDTH,-1),vec2(WIDTH*2,-1))
    floor.type=STATIC
    --make sure newtonyspeed is given a gravity scale and it is what newton.linearVelocity.y AND stuff1center.linearVelocity.y follow, those two variables will no longer need a gravity scale after that.
    test=false
    touching=false
end

function Game:draw()
    sprite("Cargo Bot:Game Area",stuff1center.x,stuff1center.y+HEIGHT/2,WIDTH*3,HEIGHT)
    fill(255, 19, 0, 255)
    rect(newton.x,newton.y,newtonsize*2,newtonsize*2)
    --remember: have everything in the main perspective backgrounds coordinates be relative to stuff1center
    minheight1=stuff1center.x+minheight2
    --if newton goes below minheight1, the game will end. the minheight2 will become -stuff1center every time newton hits a platform so that minheight1 will be brought up to that point.
    newtonxspeed=Gravity.x*100
    --If newton goes to the right
    if stuff1center.x<=-WIDTH and newtonxspeed>0 then
        stuff1center.x=-WIDTH
        stuff1center.linearVelocity=0
        if newton.x>=WIDTH-WIDTH/51.2 and newtonxspeed>0 then
            newton.linearVelocity.x=0
            newton.x=WIDTH-WIDTH/51.2
        end
    elseif stuff1center.x>=WIDTH*2 and newtonxspeed<0 then
    stuff1center=WIDTH*2
    stuff1center.linearVelocity.x=0
        if newton.x<=0+WIDTH/51.2 and newtonxspeed<0 then
        newton.linearVelocity.x=0
        newton.x=0+WIDTH-WIDTH/51.2
        end
    else
    if newton.x>=WIDTH/2+WIDTH/5.12 and stuff1center.x>=-WIDTH+WIDTH/5.12 and newtonxspeed>0 then
          stuff1center.x=stuffcenter.x-newtonxspeed
          newton.linearVelocity.x=0
    elseif newton.x<=WIDTH/2-WIDTH/5.12 and stuff1center.x<=WIDTH*2-WIDTH*5.12 and newtonxspeed<0 then
        stuff1center.x=stuffcenter.x+newtonxspeed
    else
        if newton.x>=-WIDTH and newton.x<=WIDTH*2 then
              newton.linearVelocity.x=newtonxspeed
        test=true
        else test=false
        end
        stuff1center.x=0
    end
    end
        --Complete: have newton be stopped byright wall wall once center gets past a certain point.
    if newton.y>=HEIGHT/5.12 and newtonyspeed.linearVelocity.y>0 then
        newton.linearVelocity.y=0
        stuff1center.linearVelocity.y=-newtonyspeed.linearVelocity.y
        elseif newton.y<=0 and newtonyspeed.linearVelocity.y<0 then
        newton.linearVelocity.y=0
        stuff1center.linearVelcotiy.y=newtonyspeed.linearVelocity.y
        else newton.linearVelocity.y=newtonyspeed.linearVelocity.y
        stuff1center.linearVelocity.y=0
    end
end

function Game:touched(touch)
    if touch.state==BEGAN then
        touching=true
        if newtonyspeed.linearVelocity.y~=0 then
        newtonyspeed.linearVelocity.y=-10
    end
    else touching=false
    end
end

function collide(c)
    if c.state==BEGAN then
        if c.bodyA.info==main then
            newtonyspeed.linearVelocity.y=20
        elseif c.bodyB.info==main then
            newtonyspeed.linearVelocity.y=20
        end
    end
end

Comments

  • IgnatzIgnatz Mod
    Posts: 5,396

    I tidied up the formatting, which was messy in places, making it hard to follow. I made it all one block of code to make it easier for people to copy in one go.

  • Oh and I apologize for the games background mistake, it was a quick replacement for some custom design that is not in codeas selection. It was fixed, but for those of you who already copied/pasted this code I suggest that you replace the tabs background sprite with the one in the new one, for the sake of testing the background translation

  • edited January 2015 Posts: 63

    I can't even be sure if the scrolling system works (although it should), because of course I haven't been able to get the character to move in the first place.

  • IgnatzIgnatz Mod
    Posts: 5,396

    Perhaps you can help by telling us what testing you've already done, ie what you know works properly.

  • edited January 2015 Posts: 63

    Alright. So for the scrolling up and down (for when newton jumps) I have a 1 pixel kinematic physics body named newtonyspeed that jumps when told, unlike newton, this physics body has a gravityScale, so it will fall back down, and newtons linear velocity is then equal to newtonyspeed.linearVelocity.y.

    But then if newton goes high up above a certain point, he stops, and it is the background that instead follows newtonyspeed.linearVelocity.y*-1 (so that it seems like he is moving and the screen is following his movement), until its linear velocity is less than or equal to zero, ie he's reached his apex, and he falls back down, and once he reaches that apex, newton once again follows newtonyspeeds vertical linear velocity, and the background stops moving.

    As for if he goes too far down, the opposite happens Newtonyspeed exists for that purpose, or so that's how it is supposed to work. There is a edge body at y=-1 that keeps newton and the other kinematic bodies from falling, and when newton collides with that edge, he's supposed to be given a vertical linear velocity of 10, meaning he should bounce up whenever he hits the floor.

    For some reason however, newtonyspeed cannot be given this linearVelocity, when I see it tracked on the display it's always 0, even though there is literally NO CONDITION that gives newtonyspeed a linear velocity of 0, except for its gravityScale, which even when removed does not change a single thing.

    Something similar applies to his x movement. There is a variable like newtonyspeed for horizontal scrolling, it's called newtonxspeed, only unlike this one, it is just a numerical variable, and not a physics body, because it needs to gravityScale.

    Newtonxspeed=Gravity.x100, and newton.linearVelocity.x equals newtonxspeed unless he goes a certain distance to the left or right, in which case newton becomes frozen on the screen and the background to the left goes left or right according to newtonxspeed, of course idk if any of this actually will happen because newton.linearVelocity.x is always 0, even though newtonxspeed does follow Gravity.x100 and inside of the condition where newton.linearVelocity.x=newtonxspeed there is the variable named test that is switched to true when that condition is chosen, else it is false.

    When the game is played, test sets to true, meaning that newton.linearVelocity.x=newtonxspeed, meaning that he should be able to move when I tilt the screen.

    The only possible explanation for what is happening here is that all of the physics bodies (including the dynamic ones) for some reason cannot be forced. If you maybe can get newton moving I can actually see if the scrolling systactually works, but as of now that isn't the problem.

    Sorry for any typos or repitition in this comment as it is a very long explanation.

  • Ever since I posted that last code all i did was change up the code so that literally everything is proportional to the devices HEIGHT. Idk if you might want that instead, incase you use an iPad Air.

  • Here it is just incase:

    --Main class:
    
    supportedOrientations(PORTRAIT_ANY)
    function setup()
    parameter.watch("test")
    parameter.watch("touching")
    parameter.watch("newtonxspeed")
    parameter.watch("newtonyspeed.linearVelocity.y")
    parameter.watch("newton.linearVelocity.x")
    parameter.watch("newton.linearVelocity.y")
    parameter.watch("stuff1center.y")
    parameter.integer("WIDTH",0,1536,768)
    parameter.integer("HEIGHT",0,2048,1024)
    displayMode(OVERLAY)
    x=TitleScreen
    end
        function draw()
        x:draw()
    end
    function touched(t)
        x:touched(t)
    end
    
    --TitleScreen class: (only press start game when in this class)
    
    TitleScreen = class()
    --doodle jump like game
    --sir newton jumps up endlessly tall tree
    --falling apples that kill you if you hit below them, but you can jump off of
    --branches produce apples, cam be jumped off of
    function TitleScreen:init()
        rectMode(CORNER)
        textMode(CENTER)
        st=false
        cr=false
        he=false
    end
    function TitleScreen:draw()
        background(0, 72, 255, 255)
        fontSize(HEIGHT/51.2)
        local rectheight=HEIGHT/20.48
        local rectwidth=rectheight*4
        sprite("SpaceCute:Background",WIDTH/2,HEIGHT/2,WIDTH,HEIGHT)
        stroke(0, 231, 255, 255)
        strokeWidth(HEIGHT/204.8)
        fill(8, 255, 0, 255)
        if st then
            fill(11, 0, 255, 255)
        end
        rect(WIDTH/2-HEIGHT/10.24,HEIGHT/2+HEIGHT/8.192,rectwidth,rectheight)
    
        fill(8, 255, 0, 255)
        if cr then
            fill(11, 0, 255, 255)
        end    
        rect(WIDTH/2-HEIGHT/10.24,HEIGHT/2-HEIGHT/40.96,rectwidth,rectheight)
    
        fill(8, 255, 0, 255)
        if he then
            fill(11, 0, 255, 255)
        end    
        rect(WIDTH/2-HEIGHT/10.24,HEIGHT/2-HEIGHT/5.85142857143,rectwidth,rectheight)
        fill(255, 0, 22, 255)
        text("Start Game",WIDTH/2,HEIGHT/2+HEIGHT/6.8)
        text("Credits",WIDTH/2,HEIGHT/2)
        text("Help",WIDTH/2,HEIGHT/2-HEIGHT/6.8)
        textSize(150,30)
    end
    
    function TitleScreen:touched(touch)
        if touch.x >= WIDTH/2-HEIGHT/10.24 and touch.x <= WIDTH/2+HEIGHT/10.24 and
            touch.y >= HEIGHT/2+HEIGHT/8.192 and touch.y <= HEIGHT/2+HEIGHT/5.85142857143 then
            if touch.state==BEGAN then
                st=true
            elseif touch.state==ENDED then
                x=Game()
            end
        end
        if touch.x >= WIDTH/2-HEIGHT/10.24 and touch.x <= WIDTH/2+HEIGHT/10.24 and 
            touch.y >= HEIGHT/2-HEIGHT/40.96 and touch.y <= HEIGHT/2+HEIGHT/40.96 then
            if touch.state==BEGAN then
                cr=true
            elseif touch.state==ENDED then
                x=Credits()
            end
        end
        if touch.x >= WIDTH/2-HEIGHT/10.24 and touch.x <= WIDTH/2+HEIGHT/10.24 and 
            touch.y >= HEIGHT/2-HEIGHT/5.85142857143 and touch.y <= HEIGHT/2-HEIGHT/8.192 then
            if touch.state==BEGAN then
                he=true
            elseif touch.state==ENDED then
                x=Help()
            end
        end
        if touch.state==ENDED then
            st=false
            cr=false
            he=false
        end
    end
    
    --Game class:
    
    Game=class()
    
    function Game:init()
        rectMode(CENTER)
        spriteMode(CENTER)
        textMode(CENTER)
        newtonsize=HEIGHT/56.2
        newton=physics.body(POLYGON,vec2(-newtonsize,newtonsize),vec2(-newtonsize,-newtonsize),vec2(newtonsize,-newtonsize),vec2(newtonsize,newtonsize))
        newton.type=DYNAMIC
        newton.info="main"
        newton.x=WIDTH/2
        newton.y=newtonsize
        newton.gravityScale=1
        stuff1center=physics.body(CIRCLE,1)
        stuff1center.x=WIDTH/2
        stuff1center.y=1
        stuff1center.gravityScale=-1
        stuff1center.type=KINEMATIC
        stuff1={}
        stuff2={}
        stuff3={}
        newtonxspeed=0
        newtonyspeed=physics.body(CIRCLE,1)
        newtonyspeed.type=KINEMATIC
        newtonyspeed.gravityScale=1 
        minheight1=0
        minheight2=-stuff1center.x
    floor=physics.body(EDGE,vec2(-HEIGHT,-1),vec2(HEIGHT*2,-1))
        floor.type=STATIC
        --make sure newtonyspeed is given a gravity scale and it is what newton.linearVelocity.y AND stuff1center.linearVelocity.y follow, those two variables will no longer need a gravity scale after that.
        test=false
        touching=false
    end
    
    function Game:draw()
        background(0, 72, 255, 255)
        sprite("Cargo Bot:Game Area",stuff1center.x+WIDTH/2,stuff1center.y+HEIGHT/2,HEIGHT*2,HEIGHT)
        fill(255, 19, 0, 255)
        rect(newton.x,newton.y,newtonsize*2,newtonsize*2)
        --remember: have everything in the main perspective backgrounds coordinates be relative to stuff1center
        minheight1=stuff1center.x+minheight2
        --if newton goes below minheight1, the game will end. the minheight2 will become -stuff1center every time newton hits a platform so that minheight1 will be brought up to that point.
        newtonxspeed=Gravity.x*100
        --If newton goes to the right
        if stuff1center.x<=-HEIGHT and newtonxspeed>0 then
            stuff1center.x=-HEIGHT
            stuff1center.linearVelocity=0
            if newton.x>=WIDTH-HEIGHT/51.2 and newtonxspeed>0 then
                newton.linearVelocity.x=0
                newton.x=WIDTH-HEIGHT/51.2
            end
        elseif stuff1center.x>=HEIGHT*2 and newtonxspeed<0 then
        stuff1center=HEIGHT*2
        stuff1center.linearVelocity.x=0
            if newton.x<=0+HEIGHT/51.2 and newtonxspeed<0 then
            newton.linearVelocity.x=0
            newton.x=0+WIDTH-HEIGHT/51.2
            end
        else
        if newton.x>=WIDTH/2+HEIGHT/5.12 and stuff1center.x>=-HEIGHT+HEIGHT/5.12 and newtonxspeed>0 then
              stuff1center.x=stuffcenter.x-newtonxspeed
              newton.linearVelocity.x=0
        elseif newton.x<=WIDTH/2-HEIGHT/5.12 and stuff1center.x<=HEIGHT*2-HEIGHT*5.12 and newtonxspeed<0 then
            stuff1center.x=stuffcenter.x+newtonxspeed
        else
            if newton.x>=-HEIGHT and newton.x<=HEIGHT*2 then
                  newton.linearVelocity.x=newtonxspeed
            test=true
            else test=false
            end
            stuff1center.x=0
        end
        end
            --Complete: have newton be stopped byright wall wall once center gets past a certain point.
        if newton.y>=HEIGHT/5.12 and newtonyspeed.linearVelocity.y>0 then
            newton.linearVelocity.y=0
            stuff1center.linearVelocity.y=-newtonyspeed.linearVelocity.y
            elseif newton.y<=0 and newtonyspeed.linearVelocity.y<0 then
            newton.linearVelocity.y=0
            stuff1center.linearVelcotiy.y=newtonyspeed.linearVelocity.y
            else newton.linearVelocity.y=newtonyspeed.linearVelocity.y
            stuff1center.linearVelocity.y=0
        end
    end
    
    function Game:touched(touch)
        if touch.state==BEGAN then
            touching=true
            if newtonyspeed.linearVelocity.y~=0 then
            newtonyspeed.linearVelocity.y=-10
        end
        else touching=false
        end
    end
    
    function collide(c)
        if c.state==BEGAN then
            if c.bodyA.info==main then
                newtonyspeed.linearVelocity.y=20
            elseif c.bodyB.info==main then
                newtonyspeed.linearVelocity.y=20
            end
        end
    end
    
  • IgnatzIgnatz Mod
    Posts: 5,396

    You have quite a complex set of behaviours, and if (as it seems) you programmed the whole thing without testing any of it as you added it, I think that was a mistake, because now it is really hard to debug. (Programming books like "Clear Code" stress the importance of adding and then testing very small sections of code, piece by piece, so you never have to look very far to find errors).

    But given all this code, how to find the error(s)?

    I'd still do what Clear Code suggests, which is to start small, and add small pieces, checking them as I go. Only in this case, you do it by uncommenting code.

    First you strip the code down to the basics, by commenting out code as much as possible, to the minimum that you are sure works.

    Then you can begin uncommenting the code just a little part at a time, eg one of the physics bodies or player behaviours, and test if it works. This takes a while, but it always works, and it is more likely to find less obvious errors.

    You can, instead, continue running it and using print statements or watch variables to try to figure out the problem(s), but this can take a long time and be very difficult if there are multiple errors.

  • edited January 2015 Posts: 2,049

    @Paintcannon, I think your problem is that you can't set a body's linearVelocity x and y separately, you have to set the linearVelocity to a new vec2() value.

    So, body.linearVelocity.x = -10 is a no, but body.linearVelocity = vec2(-10, body.linearVelocity.y) achieves the correct result.

    Also, you claim to be experienced in Codea, and yet your code is very messy and hard to read, and your title screen for example could be achieved much cleaner with tables. I'm not trying to be mean, just suggesting you try to clean up your code a bit :)

    Running your code with proper velocity settings, I don't think it does what you wanted, but he does move side to side when you tilt.

  • To clarify I said I was FAIRLY experienced, meaning I understand the syntax enough to where it doesn't look entirely alien to me. The initial code was also formed on two separate text editors with different indentation sizes, which is too much of a hassle to fix.

  • Thank you, though, for the suggestion, all I had to do was make velocity presets for every condition and he was able to move around freely. With some minor tweaking, the scrolling system now works perfectly too.

Sign In or Register to comment.