Sinking through Platform
Author |
Message |
pttptppt
|
Posted: 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
|
|
|
Insectoid
|
Posted: 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
|
Posted: 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
|
Posted: 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
|
Posted: 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
|
Posted: Fri Mar 17, 2017 11:14 am Post subject: RE:Sinking through Platform |
|
|
IM STILL WAITING FOR HELP... |
|
|
|
|
|
Insectoid
|
Posted: 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
|
Posted: 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. |
|
|
|
|
|
Sponsor Sponsor
|
|
|
TokenHerbz
|
Posted: 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
|
Posted: 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
|
Posted: 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
|
Posted: 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... |
|
|
|
|
|
|
|