Skip to content

Instantly share code, notes, and snippets.

@horstjens
Created April 7, 2023 08:35
Show Gist options
  • Save horstjens/2a33b0c0c617dc6db585e97c7fc0a022 to your computer and use it in GitHub Desktop.
Save horstjens/2a33b0c0c617dc6db585e97c7fc0a022 to your computer and use it in GitHub Desktop.
cannon vpython
import vpython as vp
xarrow = vp.arrow(pos=vp.vector(0,0,0), axis=vp.vector(1,0,0), color=vp.vector(1,0,0))
yarrow = vp.arrow(pos=vp.vector(0,0,0), axis=vp.vector(0,1,0), color=vp.vector(0,1,0))
zarrow = vp.arrow(pos=vp.vector(0,0,0), axis=vp.vector(0,0,1), color=vp.vector(0,0,1))
barrel1 = vp.cylinder(pos=vp.vector(-1,1,0), radius=0.25, axis=vp.vector(3,0,0), color=vp.vector(0.6,0.6,0.6))
bar1 = vp.cylinder(pos=vp.vector(0,1,0), radius=0.01, axis=vp.vector(0,0,0.5), color=vp.color.red)
bar2 = vp.cylinder(pos=vp.vector(0,1,0), radius=0.01, axis=vp.vector(0,0,-0.5), color=vp.color.red)
left_wheel = vp.cylinder(pos=vp.vector(0,0.5,0.3), axis=vp.vector(0,0,0.2), radius=0.5)
right_wheel = vp.cylinder(pos=vp.vector(0,0.5,-0.3), axis=vp.vector(0,0,-0.2), radius=0.5)
barrel = vp.compound([barrel1, bar1, bar2], origin=vp.vector(0,1,0))
wheels = vp.compound([left_wheel, right_wheel], origin=vp.vector(0,1,0))
zrotspeed = vp.radians(20)
yrotspeed = vp.radians(15)
dt = 1/30
gravity= vp.vector(0,-9.81,0)
size = 20
ground = vp.box(pos = vp.vector(size/2,-0.05,0), size=vp.vector(size,0.1,size), color=vp.vector(0.5, 0.1, 0.1))
class Game:
balls = []
class Cannonball(vp.sphere):
def __init__(self, **kwargs):
#super().__init__(**kwargs)
# # except 2 vectors: self.startspeed and self.startpos
super().__init__(pos = barrel.pos, radius=0.15, color=vp.color.yellow, **kwargs)
self.startpos = vp.vector(barrel.pos.x, barrel.pos.y, barrel.pos.z)
self.startspeed = vp.vector(barrel.axis.x, barrel.axis.y, barrel.axis.z) * 10
self.flying = True
self.t = 0
self.max_time = 10
Game.balls.append(self)
#print(self)
def update(self, dt):
#return
if self.flying:
self.pos.x = self.startpos.x + self.startspeed.x * self.t
self.pos.z = self.startpos.z + self.startspeed.z * self.t
self.pos.y = self.startpos.y + self.startspeed.y * self.t + 0.5 * gravity.y * self.t * self.t
self.t += dt
#print(self.t, self.pos)
if self.pos.y <= 0:
self.flying = False
if self.t > self.max_time:
self.visible = False
t = 0 # time
last_shot = 0
reload_time = 0.5
while True:
vp.rate(30) # fps?
t += dt # time increase
keys = vp.keysdown() # get list of pressed_keys
dy, dz = 0, 0
if "d" in keys:
dy += -1
if "a" in keys:
dy += 1
if "w" in keys:
dz += 1
if "s" in keys:
dz += -1
# roll around y axis
if dy != 0:
barrel.rotate(angle=yrotspeed * dy * dt, axis=vp.vector(0,1,0))
wheels.rotate(angle=yrotspeed * dy * dt, axis=vp.vector(0,1,0))
# roll around z axis
if dz != 0:
barrel.rotate(angle=zrotspeed * dz * dt, axis=vp.cross(barrel.axis, barrel.up))
# fire
if " " in keys:
if t > last_shot + reload_time:
Cannonball()
last_shot = t
for ball in Game.balls:
ball.update(dt)
# delete reference to invisible cannonballs
Game.balls = [ball for ball in Game.balls if ball.t < ball.max_time]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment