Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from vpython import *
- from math import *
- #import random
- ''' variables '''
- charge = 0.5
- speedRatio = 9
- playerAngle = (pi/2, pi/2)
- aimAngle = (0, pi)
- followPlayerView = False
- aimHint = True
- time = 0; dt = 1/240 #240fps owo
- score = 0
- ''' vpython objects '''
- #description = canvas(width = 1000, weight = 800)
- planets = []; bullets = []; targets = []; message = []
- planets.append(sphere(pos = vector(0, 0, 0), texture = textures.earth))
- color.miku = vector(0, 0.784, 0.686)
- planets.append(sphere(pos = vector(5, 4, 3), color = color.miku))
- planets.append(sphere(pos = vector(5, -4, 2), color = color.miku))
- planets.append(sphere(pos = vector(-2, 5, -5), color = color.miku))
- planets.append(sphere(pos = vector(-5, -3, 3), color = color.miku))
- planets.append(sphere(pos = vector(-3, -2, -3), color = color.miku))
- targets.append(sphere(pos = vector(4, 4, 3), radius = 0.3, color = color.green))
- targets.append(sphere(pos = vector(5, -3, 2), radius = 0.3, color = color.green))
- targets.append(sphere(pos = vector(-1, 5, -5), radius = 0.3, color = color.green))
- targets.append(sphere(pos = vector(-5, -3+0.5**0.5, 3-0.5**0.5), radius = 0.3, color = color.green))
- targets.append(sphere(pos = vector(-3+0.5, -2+0.5*(3**0.5), -3), radius = 0.3, color = color.green))
- targets.append(sphere(pos = vector(6, -4, 2), radius = 0.3, color = color.green))
- player = cone(color = color.red, pos = vector(0, 1, 0), radius = 0.1, length = 0.5, axis = vector(0, 1, 0))
- aim = arrow(color = color.blue, pos = vector(0, 1.3, 0), axis = vector(0.3, 0, 0))
- predict = sphere(
- radius = 0.08,
- make_trail = True,
- color = vector(1, 1, 0),
- trail_type = 'points',
- interval = 20,
- retain = 100,
- opacity = 0,
- v = vector(0, 0, 0)
- )
- ''' functions '''
- def checkVisible(x):
- if not x.visible:
- #del(x)
- return False
- return True
- def zeroScene():
- scene.autoscale = False
- scene.center = vector(0, 0, 0)
- scene.forward = vector(0, 0, -1)
- scene.range = 10
- scene.width = 1000
- scene.weight = 800
- scene.up = vector(0, 1, 0)
- #scene.background = color.white
- def updatePos():
- global player, aim, aimAngle, playerAngle, charge
- player.pos = vector(
- cos(playerAngle[1])*sin(playerAngle[0]),
- sin(playerAngle[1]),
- cos(playerAngle[1])*cos(playerAngle[0])
- )
- tmp = vector(
- cos(aimAngle[1])*sin(aimAngle[0]),
- sin(aimAngle[1]),
- cos(aimAngle[1])*cos(aimAngle[0])
- )
- aim.axis = (0.32-charge*0.04)*vector(
- tmp.x*cos(playerAngle[0]) - tmp.z*sin(playerAngle[1])*sin(playerAngle[0]) - tmp.y*cos(playerAngle[1])*sin(playerAngle[0]),
- tmp.x*0 + tmp.z*cos(playerAngle[1]) - tmp.y*sin(playerAngle[1]),
- -tmp.x*sin(playerAngle[0]) - tmp.z*sin(playerAngle[1])*cos(playerAngle[0]) - tmp.y*cos(playerAngle[1])*cos(playerAngle[0])
- )
- player.axis = player.pos*0.5
- aim.pos = player.pos*1.3
- if followPlayerView:
- u = norm(vector(
- sin(playerAngle[1])*sin(playerAngle[0]),
- -cos(playerAngle[1]),
- sin(playerAngle[1])*cos(playerAngle[0])
- ))
- scene.center = u*3
- scene.forward = u-player.pos*0.5
- scene.range = 4
- scene.up = player.pos
- predict.pos = aim.pos
- predict.clear_trail()
- predict.v = norm(aim.axis)*charge*speedRatio
- if aimHint:
- fps = int(1/dt)
- for t in range(fps*2):
- for p in planets:
- d = p.pos-predict.pos
- if mag(d) >= 0.9:
- predict.v += speedRatio*10/mag2(d)*dt*norm(d) #GMm/d^2
- else:
- return
- predict.pos += predict.v*dt
- ''' keyboard control '''
- def keydownControl(evt):
- global charge, charging, scene, playerAngle, aimAngle, followPlayerView
- aimAction = {
- 'w':(0, 1), #箭頭向上
- 's':(0, -1), #向下
- 'a':(-1, 0), #向左
- 'd':(1, 0) #向右
- }
- playerAction = {
- 'o':(0, -1), #玩家向北
- 'l':(0, 1), #向南
- 'k':(1, 0), #向西
- ';':(-1, 0) #向東
- }
- s = evt.key
- if s == ' ': #charge
- if charge < 3:
- charge += 0.1
- updatePos()
- elif s == 'q': #zeroing angle of vision
- zeroScene()
- elif s == 'e':
- if followPlayerView:
- followPlayerView = False
- scene.userzoom = True
- scene.userspin = True
- zeroScene()
- scene.up = vector(0, 1, 0)
- else:
- followPlayerView = True
- scene.userzoom = False
- scene.userspin = False
- scene.up = player.pos
- updatePos()
- else:
- if s in aimAction: #change aiming angle
- dAlpha = aimAction[s][0]*pi/60; dBeta = aimAction[s][1]*pi/60
- tmp = (aimAngle[0] + dAlpha, aimAngle[1] + dBeta)
- if tmp[1] >= 7*pi/12 and tmp[1] <= 16*pi/12:
- aimAngle = tmp
- if s in playerAction: #change player angle
- dAlpha = playerAction[s][0]*pi/60; dBeta = playerAction[s][1]*pi/60
- playerAngle = (playerAngle[0] + dAlpha, playerAngle[1] + dBeta)
- updatePos()
- scene.bind('keydown', keydownControl)
- def keyupControl(evt):
- global aim, charge
- if evt.key == ' ' and charge > 0:
- bullets.append(sphere(
- radius = 0.1,
- pos = aim.pos,
- v = norm(aim.axis)*charge*speedRatio,
- color = vector(1, 0.68, 0.9),
- make_trail = True,
- trail_type = 'points',
- interval = 15,
- retain = 25,
- inGround = None
- ))
- aim.axis = norm(aim.axis)*0.3
- charge = 0.5
- updatePos()
- scene.bind('keyup', keyupControl)
- ''' main '''
- zeroScene()
- updatePos()
- while time<300:
- rate(1/dt)
- # gravity effect
- for b in bullets:
- if mag(b.v) <= 10**-3:
- b.visible = False
- if b.inGround == None:
- for p in planets:
- d = p.pos-b.pos
- if mag(d) >= 0.9:
- b.v += speedRatio*10/mag2(d)*dt*norm(d) #GMm/d^2
- else:
- b.inGround = p
- break
- b.pos += b.v*dt
- for t in targets:
- d = t.pos-b.pos
- if mag(d) < 0.4:
- score += 1
- message.append(text(
- text = str(score)+'HIT',
- align = 'center',
- pos = t.pos,
- height = 0.5,
- billboard = True,
- color = color.magenta,
- displayTime = 1
- ))
- b.clear_trail()
- b.visible = t.visible = False
- else:
- p = b.inGround
- d = p.pos-b.pos
- if mag(d) >= 0.8:
- b.v = norm(d)*0.01
- b.pos += b.v*dt
- else:
- b.clear_trail()
- b.visible = False
- for m in message:
- m.displayTime -= dt
- if m.displayTime <= 0:
- m.visible = False
- bullets = list(filter(checkVisible, bullets))
- targets = list(filter(checkVisible, targets))
- message = list(filter(checkVisible, message))
- time += dt
- if len(targets) == 0:
- break
- ''' game ends '''
- for b in bullets:
- b.clear_trail()
- b.visible = False
- for p in planets:
- p.visible = False
- for t in targets:
- t.visible = False
- for m in message:
- m.visible = False
- predict.clear_trail()
- player.visible = aim.visible = False
- followPlayerView = False
- scene.userzoom = True
- scene.userspin = True
- zeroScene()
- scene.unbind('keydown', keydownControl)
- scene.unbind('keyup', keyupControl)
- if len(targets) == 0:
- text(
- text = 'Game ends!\nYou beated all the targets!',
- align = 'center',
- pos = vector(0, 0, 0),
- color = color.red
- )
- else:
- text(
- text = 'Time\'s up!\nYour score is ' + str(score) + ' PTS',
- align = 'center',
- pos = vector(0, 0, 0),
- color = color.red,
- )
Advertisement
Add Comment
Please, Sign In to add comment