Hasch question, cheking to see if key pressed
Author |
Message |
lordroba
|
Posted: Fri Aug 12, 2005 9:26 am Post subject: Hasch question, cheking to see if key pressed |
|
|
I'm making a racing game and I want the car speed up while the UP key is being pressed(i know how to do this), and I want the speed to slowly go down while no key is pressed.
How do I check if no key is being pressed and put this into an 'IF' condition so that it lowers the value of the speed variable when this is true?
|
|
|
|
|
|
Sponsor Sponsor
|
|
|
MihaiG
|
Posted: Fri Aug 12, 2005 10:59 am Post subject: (No subject) |
|
|
heres a small example
code: |
if not hasch then
speed := speed - 1 %speed -= 1
end if
|
|
|
|
|
|
|
lordroba
|
Posted: Fri Aug 12, 2005 11:07 am Post subject: (No subject) |
|
|
thank you very much
|
|
|
|
|
|
Cervantes
|
Posted: Fri Aug 12, 2005 11:32 am Post subject: (No subject) |
|
|
Use Input.KeyDown, not hasch and getch. It will allow you to get multiple keystrokes at once.
You probably don't want to slow your car down when no key is pressed. Think about it: the user could press "h" and he would go at a constant speed and not use any fuel or anything. Instead, you want the car to slow down when the up arrow is not pressed.
code: |
if keys (KEY_UP_ARROW) then
car.speed += car.acceleration
else
car.speed *= car.deceleration
end if
|
car.deceleration should be slightly less than 1. 0.99 is a good value to test.
Of course, you could use some physics to determine accelerations with regard to mass, applied force, and frictional forces.
Turing: |
View.Set ("offscreenonly")
var car :
record
x, y : real
mass : real
internal_friction, net_force : real
current_vert_angle : real
speed, applied_engine_force : real
current_surface_material, tire_material : string
end record := init (100, 100, 800, 200, 0, 0, 0, 10000, "dry asphault", "rubber")
type Friction_Coefficient :
record
surface1, surface2 : string
value : real
end record
fcn friction_coeffecient_init (surface1, surface2 : string, value : real) : Friction_Coefficient
var temp_coeff : Friction_Coefficient
temp_coeff.surface1 := surface1
temp_coeff.surface2 := surface2
temp_coeff.value := value
result temp_coeff
end friction_coeffecient_init
var coefficients : array 1 .. 2 of Friction_Coefficient
coefficients (1) := friction_coeffecient_init ("rubber", "dry asphault", 0. 6)
coefficients (2) := friction_coeffecient_init ("rubber", "wet asphault", 1. 2)
fcn friction_force (surface1, surface2 : string, N : real) : real
for i : lower (coefficients ) .. upper (coefficients )
if Str.Lower (coefficients (i ).surface1 ) = Str.Lower (surface1 ) and
Str.Lower (coefficients (i ).surface2 ) = Str.Lower (surface2 ) then
%Force of friction = mew (coefficient of friction) * Normal force
result coefficients (i ).value * N
end if
end for
end friction_force
var keys : array char of boolean
loop
car.net_force := -car.internal_friction - friction_force (car.tire_material, car.current_surface_material, cosd (car.current_vert_angle ) * car.mass * 9. 8) %- car.speed
% the last bit, - car.speed is an approximation for wind resistance. I'm not sure how wind resistance works. Anyone know the formula?
Input.KeyDown (keys )
if keys (KEY_UP_ARROW) then
car.net_force + = car.applied_engine_force
end if
car.speed + = car.net_force / car.mass
car.speed := max (0, car.speed )
car.x + = car.speed
car.x mod= maxx
cls
Draw.FillOval (round (car.x ), round (car.y ), 10, 10, black)
locate (1, 1)
put car.speed
View.Update
delay (10)
end loop
|
I think this is all correct, except for the fact that the coefficient of friction changes depending upon your speed. This also does not take into account air resistance, which is greater than the friction between the tires and the road.
|
|
|
|
|
|
lordroba
|
Posted: Sat Aug 13, 2005 9:00 am Post subject: (No subject) |
|
|
Alright now i'm really pissed, I spent all day yesterday trying to figure this out but I'm having no success. As you can see in the attached program, the car moves fine, and it turns and everything, but I can't figure out how to make it keep going for a while when you let go of the acceleration(UP) button! It just stops right where you let go of the key.
can someone plz help me.
I not only want the car to move a fair bit and eventually stop after you let go of the gas, but I also want it so that the user still has ability to steer the car thru the corner when its moving.
Any help greatly appreciated!
Description: |
The code with graphics for the car, and the quickly made test track |
|
Download |
Filename: |
Driftgame.zip |
Filesize: |
8.41 KB |
Downloaded: |
116 Time(s) |
|
|
|
|
|
|
Cervantes
|
Posted: Sat Aug 13, 2005 12:11 pm Post subject: (No subject) |
|
|
There are two tutorials you should look at:
First, check out zylum's spaceship movement tutorial.
Second, check out Asian's rotation and movement tutorial. It explains how to store the rotated pictures in an array, so you don't have to Pic.Rotate each time through you're loop. That will speed your program up a lot.
The reason it stops immediately after letting go of the up arrow is because you've got this part inside your if keys (KEY_UP_ARROW) statement:
code: |
player.x += cosd (player.dir) * player.forward_speed
player.y += sind (player.dir) * player.forward_speed
|
You want that to happen all the time. He won't move if his speed is 0, remember.
Here's the modified code.
Turing: |
var winID := Window.Open ("graphics:1200;800,nobuttonbar,offscreenonly")
colourback (2)
var player :
record
x, y : real
angle : real
speed : real
rotation_speed : real
forward_accel : real
backward_accel : real
max_forward_speed : real
max_backward_speed : real
end record
player.x := 100
player.y := 100
player.angle := 90
player.speed := 0
player.rotation_speed := 5
player.forward_accel := 1
player.backward_accel := 0. 5
player.max_forward_speed := 10
player.max_backward_speed := - 5
var picCar := Pic.FileNew ("Trueno.bmp")
var picCarRotated := Pic.Rotate (picCar, round (player.angle ), Pic.Width (picCar ) div 2, Pic.Height (picCar ) div 2)
var picRoad := Pic.FileNew ("Road1.jpg")
procedure playerControls
var keys : array char of boolean
Input.KeyDown (keys )
if keys (KEY_RIGHT_ARROW) & player.speed ~ = 0 then
player.angle := (player.angle - player.rotation_speed ) mod 360
end if
if keys (KEY_LEFT_ARROW) & player.speed ~ = 0 then
player.angle := (player.angle + player.rotation_speed ) mod 360
end if
if not keys (KEY_UP_ARROW) & not keys (KEY_DOWN_ARROW) then
if player.speed <= 0. 5 & player.speed >= - 0. 5 then
player.speed := 0
end if
player.speed * = 0. 97
else
if keys (KEY_UP_ARROW) then
player.speed := min (player.max_forward_speed, player.speed + player.forward_accel )
end if
if keys (KEY_DOWN_ARROW) then
player.speed := max (player.max_backward_speed, player.speed - player.backward_accel )
end if
end if
end playerControls
procedure updatePlayer
playerControls
player.x + = cosd (player.angle ) * player.speed
player.y + = sind (player.angle ) * player.speed
picCarRotated := Pic.Rotate (picCar, round (player.angle ), Pic.Width (picCar ) div 2, Pic.Height (picCar ) div 2)
Pic.Draw (picCarRotated, 600, 400, picMerge)
Pic.Free (picCarRotated )
put player.x, " ", player.y, " ", player.speed
end updatePlayer
loop
cls
Pic.Draw (picRoad, - round (player.x ), - round (player.y ), picCopy)
updatePlayer
View.Update
end loop
Window.Close (winID )
|
I also rotated the picture by 90°, so you don't have to bother with the Pic.Rotate in the initialization stages.
|
|
|
|
|
|
[Gandalf]
|
Posted: Sat Aug 13, 2005 3:52 pm Post subject: (No subject) |
|
|
I was wondering how would you check if the user hit any key at all, not everything (including having no key pressed at all) except some certain keys. Can't think of anything right now ... Thanks.
|
|
|
|
|
|
Cervantes
|
Posted: Sat Aug 13, 2005 4:17 pm Post subject: (No subject) |
|
|
Could you restate that?
|
|
|
|
|
|
Sponsor Sponsor
|
|
|
[Gandalf]
|
Posted: Sat Aug 13, 2005 9:07 pm Post subject: (No subject) |
|
|
Yeah, I knew it was a bit unclear...
When you have an Input.Keydown statment, like if keys ('a') then ... and then you add an else, that else will include when no keys are pressed at all. I only want to do something when an actual key is pressed (when a key is pressed that is not 'b' for example).
Basically, I want to do an 'else' like statement but without a null key - I can't think of how to detect that. Probably a pretty simple solution, but I've been wondering for a while and decided to ask.
|
|
|
|
|
|
Cervantes
|
Posted: Sun Aug 14, 2005 7:11 am Post subject: (No subject) |
|
|
code: |
if hasch and not keys ('b') then
|
[Gandalf] wrote: When you have an Input.Keydown statment, like if keys ('a') then ... and then you add an else, that else will include when no keys are pressed at all.
The else would be entered only if 'a' is not pressed. Other conditions, such as if 'b' is pressed, are irrelevent.
|
|
|
|
|
|
[Gandalf]
|
Posted: Sun Aug 14, 2005 5:56 pm Post subject: (No subject) |
|
|
Ok, thanks. I wasn't thinking about hasch/getch, trying to avoid it. Is there a way of doing it without them? Still, it's a pretty good use of hasch (as opposed to using it as a replacement of Input.Keydown).
I know about the else statment, I was just trying to explain the problem that I can't detect if keys(nothingatall).
|
|
|
|
|
|
Cervantes
|
Posted: Sun Aug 14, 2005 7:04 pm Post subject: (No subject) |
|
|
I agree: I try to avoid using hasch & getch with Input.KeyDown, because of problems with one catching keystrokes that I want the other to catch.
Here's another way to do it. There's some need tricks in here, particularly the range of the for loop.
Turing: |
var keys : array char of boolean
fcn key_pressed_other_than (key : char, keyboard : array char of boolean) : boolean
if keyboard (key ) then
result false
end if
for i : char
if keyboard (i ) then
result true
end if
end for
result false
end key_pressed_other_than
loop
Input.KeyDown (keys )
locate (1, 1)
if key_pressed_other_than ('b', keys ) then
put "A key has been pressed other than 'b'"
else
put "'b' has been pressed, or no key has been pressed"
end if
exit when keys (KEY_ESC)
end loop
|
|
|
|
|
|
|
[Gandalf]
|
Posted: Sun Aug 14, 2005 11:18 pm Post subject: (No subject) |
|
|
Nice. I'll try it out later on, thanks again .
Interesting way of doing it, I was wondering about different for loops, now I have something to think about.
|
|
|
|
|
|
|
|