I'm trying to time how long a key is held down using vPython

1k views Asked by At

I'm writing a program for my physics final. Throughout the semester we have used vPython to model situations and get exact answers, etc. Our final project is to create a game using vPython that includes some type of physics.

I chose to remake Bowman except with tanks. So you have a tank on the right hand of the screen and left hand of the screen with a wall in the middle. The object is to aim your cannon and shoot the right velocity to hit your opponent's tank. I have the a good chunk of the program complete however I am stuck on a few different things.

First, how can I time a keystroke? I have it so I shoot from the each cannon however I want to be able to hold down a key and dependent on how long it's held down for the faster the initial velocity will be.

Second, where would I incorporate gravity into the program? I have a general idea of how to but I just don't know which function to put it into.

Lastly, I have a wall height being generated randomly each time the program is run. However sometimes the wall is so small you can't see it. Is there a way I can set a range of values for this?

Here is my code:

from visual import*
from random import*

scene.autoscale=False
scene.width = 1500
scene.height = 800
scene.title='Tanks'


def moveaup(gun):
    theta=arctan(gun.axis.y/gun.axis.x)
    dtheta=.1

    if (theta<pi/2):
        theta=theta+dtheta
        if not (theta>pi/2):
            gun.axis=(cos(theta),sin(theta),0)
    else:
        gun.axis=vector(0,1,0)

def moveadown(gun):
    theta=arctan(gun.axis.y/gun.axis.x)
    dtheta=.1

    if (theta>0):
        theta=theta-dtheta
        gun.axis=(cos(theta),sin(theta),0)

def movebup(gun):
    theta=arctan(gun.axis.y/gun.axis.x)+pi
    dtheta=.1

    if (theta>pi/2):
        theta=theta-dtheta
        if not (theta<pi/2):
            gun.axis=(cos(theta),sin(theta),0)
    else:
        gun.axis=vector(0,1,0)

def movebdown(gun):
    theta=arctan(gun.axis.y/gun.axis.x)+pi
    dtheta=.1

    if (theta<pi):
        theta=theta+dtheta
        gun.axis=(cos(theta),sin(theta),0)


def shoota(gun):
    vel = vector(1,1,0)
    bullet = sphere(pos=(gun.pos.x+gun.axis.x,gun.pos.y+gun.axis.y,0),radius=(.0785),color=color.yellow)
    bullet.v = vector(0,0,0)
    bullet.v = bullet.v+vel
    bulletlist.append(bullet)


def shootb(gun):
    vel = vector(-1,1,0)
    bullet = sphere(pos=(gun.pos.x+gun.axis.x,gun.pos.y+gun.axis.y,0),radius=(.0785),color=color.green)
    bullet.v = vector(0,0,0)
    bullet.v = bullet.v+vel
    bulletlist.append(bullet)

def bulletlistupdate(bulletlist):
    dt=.01
    for a in bulletlist:
        a.pos=a.pos+a.v*dt


def checks(agun,bgun):
    if scene.kb.keys:
        key=scene.kb.getkey()
        if key=='a':
            moveaup(agun)
        if key=='s':
            moveadown(agun)
        if key=='l':
            movebup(bgun)
        if key=='k':
            movebdown(bgun)
        if key=='d':
            shoota(agun)
        if key=='j':
            shootb(bgun)


#enviroment
ground = box(pos=(0,-8,0),size=(50,5,0),color=color.red)
wall = box(pos=(0,-8,0),size=(.25,20*random(),0),color=color.red)

#playerA
abody = box(pos=(-11,-5.25,0),size=(.5,.5,0),color=color.blue)
agun = cylinder(pos=(-11,-5.1,0),axis=(.8,.8,0),radius=(.08),color=color.blue)

#playerB
bbody= box(pos=(11,-5.25,0),size=(.5,.5,0),color=color.yellow)
bgun = cylinder(pos=(11,-5.1,0),axis=(-.8,.8,0),radius=(.08),color=color.yellow)

bulletlist = []

while True:
    rate(1000)
    checks(agun,bgun)
    bulletlistupdate(bulletlist)

Any and all help is welcome!

Thanks much!

2

There are 2 answers

3
cstack On

You can time things in python using the time module

import time

start = time.time()
finish = time.time()
print start # 1386269106.18
print finish # 1386269111.11
print (finish - start) # 4.9276599884

So when the player first starts pressing the button, save the time. Then save the time again when the player stops pressing the button. The difference between these two times is the number of seconds the player held the button.

[Edit] If all you can do is check if the key is pressed down, you can get the time inside the main loop and calculate dt (the amount of time that has passed):

t = time.time()
while True:
    new_t = time.time()
    dt = new_t - t
    t = new_t

    rate(1000)
    checks(agun,bgun, dt)
    bulletlistupdate(bulletlist)

Then pass dt to checks, and if the key is pressed down, you know the key has been held down for another dt seconds, and you can add it to your running total of time that it has been held down.

3
Bmart15 On

For the random you would need to enter a command similar to this:

    random.randrange(5,31) #this would give you a random range between the numbers 4-30

I don't want to do your homework for you as I don't think you are asking for that. I hope this helps you.

I'm sorry this should be the correct code for you:

    random.randint(7,40)  # this would get you a random integer of 7-40

I apologize for the misinformation.