Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Sinking through Platform
Index -> Programming, Turing -> Turing Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
pttptppt




PostPosted: Sun Mar 12, 2017 3:37 pm   Post subject: Sinking through Platform

What is it you are trying to achieve?
I want to be able to jump from platform to platform.


What is the problem you are having?
I can jump onto a platform (more or less). And i can jump from the lower platform to the higher platform. BUTTT if i jump from a higher platform to the lower platform, the character sinks through the lower one.


Describe what you have tried to solve this problem

Turing:

if y > platformy - 2 and y < platformy + 10 and vely > 0 and x2 > platformx and x2 < platformx2 then
    vely := 0
    y := platformy
end if


I tried adding this but it didnt fix anything

Post any relevant code (You may choose to attach the file instead of posting the code if it is too long)
<Answer Here>

Turing:


%Screen:
const SCREENWIDTH := 640
const SCREENHEIGHT := 480
View.Set ("graphics:SCREENWIDTH;SCREENHEIGHT")


%Jumping:
var vely, vely2 : real := 0
const JUMP_SPEED := 30
const GRAVITY := 2
const GROUND_HEIGHT := 5
const LEDGEofPLATFORM := 5

%Positions:
var x, y, x2, y2 : int
x := 100
y := 5
x2 := 300
y2 := 5

%Movement Keys:
var chars : array char of boolean
const MOVEMENT := 5
const UPDATESPEED := 15

%Platform1:
var platformx, platformy, platformx2, platformy2 : int
platformx := 200
platformy := 100
platformx2 := 400
platformy2 := 100

%Platform2:
var platform2x, platform2y, platform2x2, platform2y2 : int
platform2x := 450
platform2y := 220
platform2x2 := 550
platform2y2 := 220


proc movement
    if chars ('a') and x >= 11 then
        x := x - MOVEMENT
    elsif chars ('d') and x <= maxx - 11 then
        x := x + MOVEMENT
    end if
end movement

proc movement2
    if chars (KEY_LEFT_ARROW) and x2 >= 11 then
        x2 := x2 - MOVEMENT
    elsif chars (KEY_RIGHT_ARROW) and x2 <= maxx - 11 then
        x2 := x2 + MOVEMENT
    end if
end movement2

proc borders
    if x >= maxx - 11 then
        platformx -= MOVEMENT
        platformx2 -= MOVEMENT
        platform2x -= MOVEMENT
        platform2x2 -= MOVEMENT
    elsif x <= maxx - SCREENWIDTH + 11 then
        platformx += MOVEMENT
        platformx2 += MOVEMENT
        platform2x += MOVEMENT
        platform2x2 += MOVEMENT
        %end if
    elsif x2 >= maxx - 11 then
        platformx -= MOVEMENT
        platformx2 -= MOVEMENT
        platform2x -= MOVEMENT
        platform2x2 -= MOVEMENT
    elsif x2 <= maxx - SCREENWIDTH + 11 then
        platformx += MOVEMENT
        platformx2 += MOVEMENT
        platform2x += MOVEMENT
        platform2x2 += MOVEMENT
    end if

end borders

proc onplatformcheck
    %Ground
    if chars ('w') and x >= platformx and x <= platformx2 and y > platformy - 2 and y < platformy + 6 then
        vely := JUMP_SPEED
        y := platformy + LEDGEofPLATFORM

    end if
    if chars (KEY_UP_ARROW) and x2 >= platformx and x2 <= platformx2 and y2 > platformy - 2 and y2 < platformy + 6 then
        vely2 := JUMP_SPEED
        y2 := platformy + LEDGEofPLATFORM

    end if
    %Platform1
    if x >= platformx and x <= platformx2 and y > platformy - 2 and y < platformy + 6 then
        if chars ('w') then
            vely := JUMP_SPEED
        else
            vely := 0
        end if
        y := platformy + LEDGEofPLATFORM
    end if
    if x2 >= platformx and x2 <= platformx2 and y2 > platformy - 2 and y2 < platformy + 6 then
        if chars (KEY_UP_ARROW) then
            vely2 := JUMP_SPEED
        else
            vely2 := 0
        end if
        y2 := platformy + LEDGEofPLATFORM
    end if
    %Platform2
    if x >= platform2x and x <= platform2x2 and y > platform2y - 2 and y < platform2y + 10 then
        if chars ('w') then
            vely := JUMP_SPEED
        else
            vely := 0
        end if
        y := platform2y + LEDGEofPLATFORM
    end if
    if x2 >= platform2x and x2 <= platform2x2 and y2 > platform2y - 2 and y2 < platform2y + 10 then
        if chars (KEY_UP_ARROW) then
            vely2 := JUMP_SPEED
        else
            vely2 := 0
        end if
        y2 := platform2y + LEDGEofPLATFORM
    end if
end onplatformcheck

proc jump
    if chars ('w') and y = GROUND_HEIGHT then
        vely := JUMP_SPEED
    end if
    if chars ('w') and y = platformy2 and x > platformx and x < platformx2 then
        vely := JUMP_SPEED
    end if
    if chars ('w') and y = platform2y2 and x > platform2x and x < platform2x2 then
        vely := JUMP_SPEED
    end if


    if chars (KEY_UP_ARROW) and y2 = GROUND_HEIGHT then
        vely2 := JUMP_SPEED
    end if
    if chars (KEY_UP_ARROW) and y2 = platformy2 and x2 > platformx and x2 < platformx2 then
        vely2 := JUMP_SPEED
    end if
    if chars (KEY_UP_ARROW) and y2 = platform2y2 and x2 > platform2x and x2 < platform2x2 then
        vely2 := JUMP_SPEED
    end if

    vely -= GRAVITY
    vely2 -= GRAVITY
    y += round (vely)
    y2 += round (vely2)

    if y < GROUND_HEIGHT then
        y := GROUND_HEIGHT
        vely := 0
    end if
    if y2 < GROUND_HEIGHT then
        y2 := GROUND_HEIGHT
        vely2 := 0
    end if
   
    % if y > platformy - 2 and y < platformy + 10 and vely > 0 and x2 > platformx and x2 < platformx2 then
    %     vely := 0
    % y := platformy
    %
    % end if
end jump


loop
    View.Set ("offscreenonly")
    Input.KeyDown (chars)
    movement
    movement2

    onplatformcheck
    jump

    borders
    Draw.FillOval (x, y, 5, 5, black)
    Draw.FillOval (x2, y2, 5, 5, red)


    Draw.Box (platformx, platformy - 3, platformx2, platformy2 - 3, black)
    Draw.Box (platform2x, platform2y - 3, platform2x2, platform2y2 - 3, black)

    View.Update
    delay (UPDATESPEED)
    Draw.Cls

end loop




Please specify what version of Turing you are using
Latest
Sponsor
Sponsor
Sponsor
sponsor
Insectoid




PostPosted: Sun Mar 12, 2017 9:06 pm   Post subject: RE:Sinking through Platform

Your code is getting pretty long-winded and nonsensical and therefore difficult to read. Don't worry, it's not your fault. I suspect the bug is due to a typo somewhere. Re-organising your code has a tendency to fix that sort of bug without ever discovering what it was.

The problem right now is you have two functions that do essentially the same thing- jump and onplatformcheck. Both of those functions seem to handle jumping in different ways. We're really having a problem with landing, not jumping. I would suspect the code for landing on a platform is inside onPlatformCheck, but that doesn't do that! onPlatformCheck actually executes jumps! Why? It's called onPlatformCheck- all it should do is check if you're on a platform or not. In fact, that would be a very useful function to have!

I suggest you re-name your functions so you can tell what they do just by reading the name, or re-writing your functions so they do what the name says they do. Either way, your code is impossible to read as is.


Right, on to the good stuff. I see you have two characters and two platforms. That means you're doing everything FOUR TIMES! You've got code for player 1 colliding with platform 1, player 1 with platform 2, player 2 with platform 1, and player 2 with platform two. That's four copies of nearly identical code! This causes all kinds of typo-related bugs and headaches. If you have ten copies of the same code, and one has an error, good luck finding that error. Fortunately, there is a fix!

I see you already know about procedures. Have you learned about procedure arguments yet? Well, you're going to now.

A procedure with an argument looks like this:
code:


proc printInt (a : int) % a is the argument
    print a %prints a
end printInt

printInt (5) %output is 5
printInt (11) %output is 11


As you can see, printInt has an argument a, which is an int. When you call printInt, you can pass is any int, and it will work its magic on that int. Can you see how this might be useful to you?

Your collision is pretty crazy because you've got to compare two patforms to two characters. Which arguments, however, you can write a single function that compares *any* platform to any character. It will look like this:

code:

proc checkCollision (platform coords, character coords)
%Collision detection goes here. DO NOT use platformx1, platformx2, etc. Use the argument variables
end checkCollision


checkCollision (player1, platform1) %will check for a collision against player 1 and platform 1


Now we have just one function that does it all! Plug in whatever platform and player you want, and it will tell you if they've collided or not. It will only be three or four lines long, super easy to read, and super easy to confirm that it works. It also makes it far, far easier to add more players and platforms- you don't have to write any extra code! Define some coordinates and the checkCollision function will just work.

Now we have eliminated a ton of typo-prone code. Has it resolved our bug? Maybe, maybe not. We'll probably introduce some new bugs too, but that's all part of learning.
pttptppt




PostPosted: Mon Mar 13, 2017 7:45 am   Post subject: Re: Sinking through Platform

Okay, I have no idea if Im doing this right. I tried what you did (only for 1 platform just for testing and 1 player) and now it works even less. Like the player can only jump from the platform if "w" key is being held. This time I included only the necessary code (minus the variables which are in my first post)

Note: the character being tested is blue and the platform being tested is the lower one

Turing:

% proc onplatformcheck
%     %Ground
%     if chars ('w') and y > GROUND_HEIGHT - 2 and y < GROUND_HEIGHT + 6 then
%         vely := JUMP_SPEED
%        % y := platformy + LEDGEofPLATFORM
%
%     end if
%     if chars (KEY_UP_ARROW) and y > GROUND_HEIGHT - 2 and y < GROUND_HEIGHT + 6 then
%         vely2 := JUMP_SPEED
%         y2 := platformy + LEDGEofPLATFORM
%
%     end if
%     %Platform1
%     if x >= platformx and x <= platformx2 and y > platformy - 2 and y < platformy + 6 then
%         if chars ('w') then
%             vely := JUMP_SPEED
%         else
%             vely := 0
%         end if
%         y := platformy + LEDGEofPLATFORM
%     end if
%     if x2 >= platformx and x2 <= platformx2 and y2 > platformy - 2 and y2 < platformy + 6 then
%         if chars (KEY_UP_ARROW) then
%             vely2 := JUMP_SPEED
%         else
%             vely2 := 0
%         end if
%         y2 := platformy + LEDGEofPLATFORM
%     end if
%     %Platform2
%     if x >= platform2x and x <= platform2x2 and y > platform2y - 2 and y < platform2y + 10 then
%         if chars ('w') then
%             vely := JUMP_SPEED
%         else
%             vely := 0
%         end if
%         y := platform2y + LEDGEofPLATFORM
%     end if
%     if x2 >= platform2x and x2 <= platform2x2 and y2 > platform2y - 2 and y2 < platform2y + 10 then
%         if chars (KEY_UP_ARROW) then
%             vely2 := JUMP_SPEED
%         else
%             vely2 := 0
%         end if
%         y2 := platform2y + LEDGEofPLATFORM
%     end if
% end onplatformcheck




var onplatform : array 1 .. 2 of boolean := init (false, false) % 2 because 2 platforms


proc checkCollision (platformnumber, pcx, pcx2, pcy, cx, cy : int)
if cx >= pcx and cx <= pcx2 and cy > pcy - 2 and cy < pcy + 6 then
onplatform (platformnumber) := true
end if
end checkCollision















proc jump
    if chars ('w') and y = GROUND_HEIGHT then
        vely := JUMP_SPEED
    end if
    if chars ('w') and onplatform (1) = true then
        vely := JUMP_SPEED
    end if
    if chars ('w') and y = platform2y2 and x > platform2x and x < platform2x2 then
        vely := JUMP_SPEED
    end if


    if chars (KEY_UP_ARROW) and y2 = GROUND_HEIGHT then
        vely2 := JUMP_SPEED
    end if
    if chars (KEY_UP_ARROW) and y2 = platformy2 and x2 > platformx and x2 < platformx2 then
        vely2 := JUMP_SPEED
    end if
    if chars (KEY_UP_ARROW) and y2 = platform2y2 and x2 > platform2x and x2 < platform2x2 then
        vely2 := JUMP_SPEED
    end if

    vely -= GRAVITY
    vely2 -= GRAVITY
    y += round (vely)
    y2 += round (vely2)

    if y < GROUND_HEIGHT then
        y := GROUND_HEIGHT
        vely := 0
    end if
    if y2 < GROUND_HEIGHT then
        y2 := GROUND_HEIGHT
        vely2 := 0
    end if

    % if y > platformy - 2 and y < platformy + 10 and vely > 0 and x2 > platformx and x2 < platformx2 then
    %     vely := 0
    % y := platformy
    %
    % end if
end jump




loop
    View.Set ("offscreenonly")
    Input.KeyDown (chars)
    movement
    movement2

    %onplatformcheck
   
   
    checkCollision (1, platformx, platformx2, platformy, x, y)

put onplatform (1)
%delay (1000)
   
   
   
   
   
   
    jump

    shooting

    borders
    Draw.FillOval (x, y, 5, 5, black)
    Draw.FillOval (x2, y2, 5, 5, red)


    Draw.Box (platformx, platformy - 3, platformx2, platformy2 - 3, black)
    Draw.Box (platform2x, platform2y - 3, platform2x2, platform2y2 - 3, black)

    View.Update
    delay (UPDATESPEED)
    Draw.Cls
   
    if bulletexplode = true then
    size += 5
    Draw.Oval (bulletx, bullety, size, size, black)
    if size = 38 then
    bulletexplode := false
    size := 8
    end if
    end if

   
    onplatform (1) := false
end loop

Insectoid




PostPosted: Mon Mar 13, 2017 12:37 pm   Post subject: RE:Sinking through Platform

It's gotta get worse before it gets better, right? We're making progress though!

I notice you still have movement1 and movement2 procedures. Can you re-write it into one procedure that's called with movement (1) and movement (2) instead? Again, that's probably not related to your bug, but learning this will help prevent bugs in future projects.

Your jump procedure is still pretty long. I think we can break it up into some smaller procedures to make it easier to read (and therefore easier to debug).

Let's look at this bit:
code:
if y < GROUND_HEIGHT then
        y := GROUND_HEIGHT
        vely := 0
    end if
    if y2 < GROUND_HEIGHT then
        y2 := GROUND_HEIGHT
        vely2 := 0
    end if


This bit of code moves the player up if it falls below ground, right? It's pretty simple code and it does one simple job, so it makes sense to give it its own procedure:
code:
proc resetIfBelowGround
    if y < GROUND_HEIGHT then
        y := GROUND_HEIGHT
        vely := 0
    end if
    if y2 < GROUND_HEIGHT then
        y2 := GROUND_HEIGHT
        vely2 := 0
    end if
end resetIfBelowGround


Oh, but I did just teach you about arguments, so we might as well use them:
code:
proc resetIfBelowGround (y : int, velocity : int)
if y < GROUND_HEIGHT then
    y := GROUND_HEIGHT
    velocity := 0
end if
end resetIfBelowGround


There, now it's a very short procedure. It's easy to read and easy to debug. We've significantly cleaned up the jump procedure and reduced the overall amount of code. I call that a win/win/win!

We also have this bit of code:
code:
if chars ('w') and y = GROUND_HEIGHT then
        vely := JUMP_SPEED
    end if
    if chars ('w') and onplatform (1) = true then
        vely := JUMP_SPEED
    end if
    if chars ('w') and y = platform2y2 and x > platform2x and x < platform2x2 then
        vely := JUMP_SPEED
    end if


This code does a bunch of stuff. It checks for input, checks if you can jump, and then performs the actual jump. Why don't we split that up into some smaller, clearer functions? You already have a one called movement that handles input, so don't we merge that so there's one function doing all the input, and call the jump function from there?

code:
proc movement (player : int)
%put code for left and right here
    if keys ('w') and canJump (player) then
        jump (player)
    end if
end movement


I didn't fill out the left/right stuff, I'll leave that to you. Notice I've called a canJump function. Giant if statements are a great source of bugs, so we're going to stick the gross collision detection part into its own function- canJump:

code:
function canJump (player : int) : int %we'll make this return 1 if you can jump, and 0 if you can't.
    if (y = GROUND_HEIGHT or onplatform (1) or onplatform (2) then
        result 1
    else
        result 0
end if


Basically, any time you have a giant procedure or function, or a giant loop, or a giant if statement, or any giant chunk of code that's hard to read, that's bad news. Break up your code into small functions and procedures that do one very simple task very well, and glue them together to make up your bigger functions. You should rarely have functions longer than ten lines of code. Similarly, if you find yourself writing nearly-identical code, you can usually write it as a function or procedure that takes arguments instead.

I realize I haven't even tried to fix your bug yet. I'm not going to either. The problem is your style of writing code is extremely prone to producing bugs that are very difficult to find and debug. Once you clean up your code, the source of the bug will become obvious. If you're falling through a platform, then your bug can only be one of three things: The code to check for a collision doesn't run, the code to check for a collision is incorrect, or the code that responds to a collision is incorrect. If each of those is in its own function, you know the error is in one of those functions. If the code is spread all over like yours is, you won't even know where to start looking.
pttptppt




PostPosted: Mon Mar 13, 2017 3:12 pm   Post subject: Re: Sinking through Platform

You are right, my code is messy and its confusing me. So i comment ranged unnecessary things like shooting and stuff and focusing on the jumping. And your changes to my code are helpful, but im sorry im having a hard time following. Im fairly used to using processes and arguments from past assignments at school but for some reason i read your message but i dont understand. It also doesn't help that english is my first language.

Anyway, i tried doing what you said but i already have some problems with your codes. For instance, the "proc jump" that you gave returns the error "operands of boolean operators must be boolean" for the line that says if chars ('w')...

can you help show me what to do with your snippets of code? i know the community doesnt like helping TOO much but i feel like i can understand better if i see what the code does as opposed to reading what it does (my learning style)
pttptppt




PostPosted: Fri Mar 17, 2017 11:14 am   Post subject: RE:Sinking through Platform

IM STILL WAITING FOR HELP...
Insectoid




PostPosted: Sat Mar 18, 2017 8:31 am   Post subject: RE:Sinking through Platform

I do have other things going on in my life. I'm not on here 24/7.
pttptppt




PostPosted: Sun Mar 19, 2017 5:17 pm   Post subject: Re: RE:Sinking through Platform

Insectoid @ Sat Mar 18, 2017 8:31 am wrote:
I do have other things going on in my life. I'm not on here 24/7.

Okay well when u can... you seem to be the only person active here and i would like help.
TokenHerbz




PostPosted: Tue Mar 21, 2017 2:55 am   Post subject: RE:Sinking through Platform

if you can PM me your code i'll take a look at it..

without reading the comments here though it's probably an issue with your velocity check (from what i read on the first post)
pttptppt




PostPosted: Fri Apr 07, 2017 6:56 pm   Post subject: RE:Sinking through Platform

hi its been a few weeks and i never got a pm reply or any solution
TokenHerbz




PostPosted: Fri Apr 07, 2017 11:26 pm   Post subject: RE:Sinking through Platform

i asked you to PM me, not vise versa.

" you can PM me your code i'll take a look at it.. "
pttptppt




PostPosted: Mon Apr 10, 2017 3:15 pm   Post subject: RE:Sinking through Platform

Hi that's what i meant. i sent you a PM and never got a reply. I just checked and it shows as sent from my end...
Display posts from previous:   
   Index -> Programming, Turing -> Turing Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 12 Posts ]
Jump to:   


Style:  
Search: