I made a velocity script, but it's not quite working. The (project with the) script here.
The problem is that I tried to make the player slide after moving, and it works. But then it randomly starts flying off in the other direction on it's own accord. It's actually kinda funny, but still.
Can some expert programmers fix it please? Thanks
Last edited by geohendan (2012-04-28 15:23:08)
Offline
Basically, you need to have a variable that keeps track of velocity and change the x/y values by it every cycle. You also need to keep taking 1 away from the velocity value (or adding one) so that the object slows down.
Offline
I'm with rookwood.
when gf clicked forever change x by (x_speed) change y by (y_speed) end
Last edited by parcheesidude (2012-04-28 18:12:13)
Offline
parcheesidude wrote:
I'm with rookwood.
Edit:when gf clicked forever change x by (x_speed) change y by (y_speed) set (x_speed) to (x_speed)*[0.9] set (y_speed) to (y_speed)*[0.9] endThis will cause the player to slow down by air resistance/friction (drag forces).
Offline
Also, you need to make it so if it is less than zero, make it equal zero. (or vice versa, depending on the direction)
Offline
As a general rule, Scratch programs work better with a few simple scripts than with a lot of complicated ones. Go through the scripts you have in your main sprite and get rid of the unnecessary ones, and try to consolidate all of them into one. An example velocity base is below.
I find it useful to name my variables in a particular way, but it doesn't really matter what you call them. One benefit of the system used below is that the variable palette, which is alphabetical, groups together similar variables (all the "Velocity.Something"s will be together). The names also tell me exactly what each variable represents.
One other thing: I've found that it's much more convenient to use variables for x position and y position, rather than simply telling a sprite to "set x to (something)". This really helps in games if you want to prevent shakiness (you won't see the sprite rising out of the ground). Anyway, hope this is of use.
Of course, please substitute whatever values you want for the constants representing jump height, speed, speed limits, gravity, etc.
when gf clicked set [Acceleration.X v] to [0.5] set [Acceleration.Gravity v] to [-0.5] set [Acceleration.Jump v] to [4] set [Acceleration.AirFriction v] to [0.95] set [Acceleration.GroundFriction v] to [0.5] set [Jump.PressedLastFrame? v] to [false] set [Velocity.X v] to [0] set [Velocity.Y v] to [0] set [Velocity.X.Max v] to [5] set [Velocity.Y.Max v] to [5] set [Position.X v] to [?] // Replace with starting positions. set [Position.Y v] to [?] forever change [Velocity.Y v] by (Acceleration.Gravity) if<touching [ground v]?> set [Velocity.Y v] to [0] set [Velocity.X v] to ((Velocity.X) * (Acceleration.GroundFriction)) else set [Velocity.X v] to ((Velocity.X) * (Acceleration.AirFriction)) end if <<key [right arrow v] pressed?> or <key [d v] pressed?>> change [Velocity.X v] by (Acceleration.X) end if <<key [left arrow v] pressed?> or <key [a v] pressed?>> change [Velocity.X v] by ((-1)*(Acceleration.X)) end if <<key [up arrow v] pressed?> or <key [w v] pressed?>> if <<(Jump.PressedLastFrame?) = [false]> and <touching [ground v]?>> set [Velocity.Y v] to (Acceleration.Jump) set [Jump.PressedLastFrame? v] to [true] // Prevents repeated jumps. end else set [Jump.PressedLastFrame? v] to [false] end if <([abs v] of (Velocity.X)) > (Velocity.X.Max)> set [Velocity.X v] to ((Velocity.X.Max) * (([abs v] of (Velocity.X)) / (Velocity.X))) end if <([abs v] of (Velocity.Y)) > (Velocity.Y.Max)> set [Velocity.Y v] to ((Velocity.Y.Max) * (([abs v] of (Velocity.Y)) / (Velocity.Y))) end change [Position.X v] by (Velocity.X) change [Position.Y v] by (Velocity.Y) go to x: (Position.X) y: (Position.Y) end
Last edited by amcerbu (2012-04-28 22:13:52)
Offline
amcerbu wrote:
As a general rule, Scratch programs work better with a few simple scripts than with a lot of complicated ones. Go through the scripts you have in your main sprite and get rid of the unnecessary ones, and try to consolidate all of them into one. An example velocity base is below.
I find it useful to name my variables in a particular way, but it doesn't really matter what you call them. One benefit of the system used below is that the variable palette, which is alphabetical, groups together similar variables (all the "Velocity.Something"s will be together). The names also tell me exactly what each variable represents.
One other thing: I've found that it's much more convenient to use variables for x position and y position, rather than simply telling a sprite to "set x to (something)". This really helps in games if you want to prevent shakiness (you won't see the sprite rising out of the ground). Anyway, hope this is of use.
Of course, please substitute whatever values you want for the constants representing jump height, speed, speed limits, gravity, etc.when gf clicked set [Acceleration.X v] to [0.5] set [Acceleration.Gravity v] to [-0.5] set [Acceleration.Jump v] to [4] set [Acceleration.AirFriction v] to [0.95] set [Acceleration.GroundFriction v] to [0.5] set [Jump.PressedLastFrame? v] to [false] set [Velocity.X v] to [0] set [Velocity.Y v] to [0] set [Velocity.X.Max v] to [5] set [Velocity.Y.Max v] to [5] set [Position.X v] to [?] // Replace with starting positions. set [Position.Y v] to [?] forever change [Velocity.Y v] by (Acceleration.Gravity) if<touching [ground v]?> set [Velocity.Y v] to [0] set [Velocity.X v] to ((Velocity.X) * (Acceleration.GroundFriction)) else set [Velocity.X v] to ((Velocity.X) * (Acceleration.AirFriction)) end if <<key [right arrow v] pressed?> or <key [d v] pressed?>> change [Velocity.X v] by (Acceleration.X) end if <<key [left arrow v] pressed?> or <key [a v] pressed?>> change [Velocity.X v] by ((-1)*(Acceleration.X)) end if <<key [up arrow v] pressed?> or <key [w v] pressed?>> if <<(Jump.PressedLastFrame?) = [false]> and <touching [ground v]?>> set [Velocity.Y v] to (Acceleration.Jump) set [Jump.PressedLastFrame? v] to [true] // Prevents repeated jumps. end else set [Jump.PressedLastFrame? v] to [false] end if <([abs v] of (Velocity.X)) > (Velocity.X.Max)> set [Velocity.X v] to ((Velocity.X.Max) * (([abs v] of (Velocity.X)) / (Velocity.X))) end if <([abs v] of (Velocity.Y)) > (Velocity.Y.Max)> set [Velocity.Y v] to ((Velocity.Y.Max) * (([abs v] of (Velocity.Y)) / (Velocity.Y))) end change [Position.X v] by (Velocity.X) change [Position.Y v] by (Velocity.Y) go to x: (Position.X) y: (Position.Y) end
I'm not going to attempt to understand that, but thanks, looks like you put a lot of work into that :P Can you just explain what it does?
bobbybee (and what a few other people are saying) wrote:
Also, you need to make it so if it is less than zero, make it equal zero. (or vice versa, depending on the direction)
That's what I'm doing. I have
repeat until < (velocity) = [0.0] > change [velocity v] by [-0.3]//< or 0.3 end
Last edited by geohendan (2012-04-29 10:10:28)
Offline
Just have a simple velocity script:
when gf clicked forever set [xvel v] to ((xvel) 8 [0.9]) set [yvel v] to ((yvel) 8 [0.8]) end when [right arrow v] key pressed change [xvel v] by [0.2] end when [left arrow v] key pressed change [xvel v] by [-0.2] endet cetera for the other movement keys
Offline
geohendan wrote:
I'm not going to attempt to understand that, but thanks, looks like you put a lot of work into that :P Can you just explain what it does?
It basically says:
initialize all the constants that control speed, max speed, etc.
forever
{
apply gravity to y velocity
if touching ground, stop moving down
if touching ground, apply friction on x velocity; if in air, apply different friction.
if right/d key pressed, accelerate to the right
if left/a key pressed, accelerate to the left
if up/w key pressed, jump (makes sure that you can't hold up/w and jump)
if absolute value of x velocity is greater than x velocity max, set x velocity to max
if absolute value of y velocity is greater than y velocity max, set y velocity to max
change Position.X variable by Velocity.X
change Position.Y variable by Velocity.Y
go to Position.X, Position.Y
}
This will be a pretty smooth movement script. It's not exactly "accurate" physics (it won't do walls) but the velocity should work nicely.
Last edited by amcerbu (2012-04-29 16:51:19)
Offline
This is basically a simplified version of amcerbu's (because he is too awesome for all of our brains )
when gf clicked forever if <key [right arrow v] pressed?> change [xvel v] by (1) end if <key [left arrow v] pressed?> change [xvel v] by (-1) end set [xvel v] to ((xvel) * (.87)) change x by (xvel) if <touching [level v]?> change y by (([abs v] of (xvel)) + (1)) if <touching [level v]?> change y by ((0) - (([abs v] of (xvel)) + (1))) change x by ((0)-(xvel)) set [xvel v] to ((xvel) / (2)) end end if <key [up arrow v] pressed?> change y by (-1) if <touching [level v]?> set [yvel v] to (10) end change y by (1) end if <(yvel) < [3]> change y by (-1) if <not<touching [level v]?>> change [yvel v] by (-1) end change y by (1) end set [yvel v] to ((yvel) * (0.9)) change y by (yvel) if <touching [level v]?> change y by ((0) - (yvel)) set [yvel v] to ((yvel) / (2.5)) end end
Last edited by chanmanpartyman (2012-04-29 17:11:28)
Offline
Actually, chanmanpartyman's script is probably better than mine (it makes the sprite rise out of the ground). The only thing I would suggest would be to add acceleration constants for gravity, right/left motion, etc. It makes editing and fine-tuning the code easier.
Offline
geohendan wrote:
amcerbu wrote:
As a general rule, Scratch programs work better with a few simple scripts than with a lot of complicated ones. Go through the scripts you have in your main sprite and get rid of the unnecessary ones, and try to consolidate all of them into one. An example velocity base is below.
I find it useful to name my variables in a particular way, but it doesn't really matter what you call them. One benefit of the system used below is that the variable palette, which is alphabetical, groups together similar variables (all the "Velocity.Something"s will be together). The names also tell me exactly what each variable represents.
One other thing: I've found that it's much more convenient to use variables for x position and y position, rather than simply telling a sprite to "set x to (something)". This really helps in games if you want to prevent shakiness (you won't see the sprite rising out of the ground). Anyway, hope this is of use.
Of course, please substitute whatever values you want for the constants representing jump height, speed, speed limits, gravity, etc.when gf clicked set [Acceleration.X v] to [0.5] set [Acceleration.Gravity v] to [-0.5] set [Acceleration.Jump v] to [4] set [Acceleration.AirFriction v] to [0.95] set [Acceleration.GroundFriction v] to [0.5] set [Jump.PressedLastFrame? v] to [false] set [Velocity.X v] to [0] set [Velocity.Y v] to [0] set [Velocity.X.Max v] to [5] set [Velocity.Y.Max v] to [5] set [Position.X v] to [?] // Replace with starting positions. set [Position.Y v] to [?] forever change [Velocity.Y v] by (Acceleration.Gravity) if<touching [ground v]?> set [Velocity.Y v] to [0] set [Velocity.X v] to ((Velocity.X) * (Acceleration.GroundFriction)) else set [Velocity.X v] to ((Velocity.X) * (Acceleration.AirFriction)) end if <<key [right arrow v] pressed?> or <key [d v] pressed?>> change [Velocity.X v] by (Acceleration.X) end if <<key [left arrow v] pressed?> or <key [a v] pressed?>> change [Velocity.X v] by ((-1)*(Acceleration.X)) end if <<key [up arrow v] pressed?> or <key [w v] pressed?>> if <<(Jump.PressedLastFrame?) = [false]> and <touching [ground v]?>> set [Velocity.Y v] to (Acceleration.Jump) set [Jump.PressedLastFrame? v] to [true] // Prevents repeated jumps. end else set [Jump.PressedLastFrame? v] to [false] end if <([abs v] of (Velocity.X)) > (Velocity.X.Max)> set [Velocity.X v] to ((Velocity.X.Max) * (([abs v] of (Velocity.X)) / (Velocity.X))) end if <([abs v] of (Velocity.Y)) > (Velocity.Y.Max)> set [Velocity.Y v] to ((Velocity.Y.Max) * (([abs v] of (Velocity.Y)) / (Velocity.Y))) end change [Position.X v] by (Velocity.X) change [Position.Y v] by (Velocity.Y) go to x: (Position.X) y: (Position.Y) endI'm not going to attempt to understand that, but thanks, looks like you put a lot of work into that :P Can you just explain what it does?
bobbybee (and what a few other people are saying) wrote:
Also, you need to make it so if it is less than zero, make it equal zero. (or vice versa, depending on the direction)
That's what I'm doing. I have
repeat until < (velocity) = [0.0] > change [velocity v] by [-0.3]//< or 0.3 end
You can't use "=". Let's say the velocity is 1.4. After changing by -0.3 four times, it will be 0.2. The next time it changes, it will be -0.1. It still hasn't hit zero (although it's reached it), causing it to keep going down. Now that it's a negative value, it goes left. That's your little bitty probblem.
Last edited by PullJosh (2012-04-29 18:32:06)
Offline
PullJosh wrote:
geohendan wrote:
That's what I'm doing. I have
repeat until < (velocity) = [0.0] > change [velocity v] by [-0.3]//< or 0.3 endYou can't use "=". Let's say the velocity is 1.4. After changing by -0.3 four times, it will be 0.2. The next time it changes, it will be -0.1. It still hasn't hit zero (although it's reached it), causing it to keep going down. Now that it's a negative value, it goes left. That's your little bitty probblem.
Well, it can't ever be 1.4. I'm having it change by 0.3 the more it moves, so it can't be 1.4, or 0.4, or etc.
amcerbu wrote:
geohendan wrote:
I'm not going to attempt to understand that, but thanks, looks like you put a lot of work into that :P Can you just explain what it does?
It basically says:
initialize all the constants that control speed, max speed, etc.
forever
{
apply gravity to y velocity
if touching ground, stop moving down
if touching ground, apply friction on x velocity; if in air, apply different friction.
if right/d key pressed, accelerate to the right
if left/a key pressed, accelerate to the left
if up/w key pressed, jump (makes sure that you can't hold up/w and jump)
if absolute value of x velocity is greater than x velocity max, set x velocity to max
if absolute value of y velocity is greater than y velocity max, set y velocity to max
change Position.X variable by Velocity.X
change Position.Y variable by Velocity.Y
go to Position.X, Position.Y
}
This will be a pretty smooth movement script. It's not exactly "accurate" physics (it won't do walls) but the velocity should work nicely.
I'm okay for Y velocity and so on, I just need to figure out how to slow the X velocity down after it's been gaining speed. Any advice for that? Thanks :)
Last edited by geohendan (2012-04-29 20:56:31)
Offline
@SD7- Theoretically, you could make another sprite with identical scripts (and variables), but replace the "if <right key pressed?>" with something like "if (AI_move_right) = true." And then somewhere else in the program you have a script that changes the value of AI_move_right (and other variables for left movement and jumping). I'm not exactly how you would best go about programming an enemy player, especially in a non-tile-based game. If all the platforms were on a grid, you could use the A* algorithm to find the shortest path between two points and adapt it for the enemy's constraints: gravity, jump height, etc.
Last edited by amcerbu (2012-05-10 18:05:13)
Offline