def update(s, gs, dt): #print(s.vel) if s.thrusting: force = s.thrustForce * dt facing = vec.fromAngle(s.facing + 180) f = vec.mul(facing, force) s.applyForce(f) offset = vec.fromAngle(s.facing) offset = vec.mul(offset, s.radius) loc = vec.add(s.loc, offset) # v = vec.invert(s.vel) s.driveEmitter.emit(gs, dt, loc, s.facing, vel=s.vel) if not s.engineSoundPlayer.playing: s.engineSoundPlayer.seek(0.0) s.engineSoundPlayer.eos_action = s.engineSoundPlayer.EOS_LOOP s.engineSoundPlayer.play() else: s.engineSoundPlayer.eos_action = s.engineSoundPlayer.EOS_PAUSE # Turning should be either 0, -1 or +1 if s.turning != 0: force = s.turnForce * dt * s.turning s.applyRforce(force) Planet.update(s, gs, dt)
def startControl(s): if s.parent.__class__ != SteerablePlanet: return locvec = vec.fromAngle(s.loc) controlpointvec = vec.fromAngle(s.parent.controlPoint) diff = vec.angleBetween(locvec, controlpointvec) if abs(diff) < 10.0: #print("Took control") s.controlling = True s.loc = s.parent.controlPoint s.clearInput() else: pass
def spray(gs, particle, loc, vel, count): for i in range(count): velscale = random.gauss(vel, (vel / 3.0)) direction = random.random() * 360 velvec = vec.mul(vec.fromAngle(direction), velscale) p = particle(loc, velvec) gs.addParticle(p)
def doAttack(s, gs): s.controlled.on_key_release(gs, keys.LEFT) s.controlled.on_key_release(gs, keys.RIGHT) target = gs.player.loc distance = (s.controlled.loc - target) % 360 desiredDistance = 30 if distance < desiredDistance: # Move further away s.controlled.on_key_press(gs, keys.LEFT) s.controlled.attack(gs) s.controlled.on_key_press(gs, keys.RIGHT) elif distance > (360 - desiredDistance): # Move further away s.controlled.on_key_press(gs, keys.RIGHT) s.controlled.attack(gs) s.controlled.on_key_press(gs, keys.LEFT) elif distance < 180: # and distance > desiredDistance, implicitly # Move closer s.controlled.on_key_press(gs, keys.LEFT) s.controlled.attack(gs) elif distance > 180: # and distance < (360 - desiredDistance), implicitly # Move closer s.controlled.on_key_press(gs, keys.RIGHT) s.controlled.attack(gs) return runfrom = gs.player.loc rvloc = vec.fromAngle(runfrom - s.controlled.loc) reference = vec.fromAngle(0) distance = vec.angleBetween(reference, rvloc) print "Distance:", distance desiredDistance = 25 if distance > desiredDistance: s.controlled.on_key_press(gs, keys.LEFT) s.controlled.attack(gs) elif distance > 0: s.controlled.on_key_press(gs, keys.RIGHT) s.controlled.attack(gs) s.controlled.on_key_press(gs, keys.LEFT) elif distance < -desiredDistance: s.controlled.on_key_press(gs, keys.RIGHT) s.controlled.attack(gs) elif distance < 0: s.controlled.on_key_press(gs, keys.LEFT) s.controlled.attack(gs) s.controlled.on_key_press(gs, keys.RIGHT)
def canCapture(s, point, distance, targetPlanet): if s.isParent(targetPlanet): #print "Nope, is parent" return False if targetPlanet.parent != None: #print "Nope, has parent" return False if targetPlanet == s: #print "Nope, self" return False if s in targetPlanet.children: #print "Nope, is a child already" return False vecBetweenPlanets = vec.sub(targetPlanet.loc, s.loc) # Adjust distance to measure from surface to surface, not center # to center distance += s.radius + targetPlanet.radius if vec.magSquared(vecBetweenPlanets) > (distance * distance): #print "Nope, out of range" return False # Okay we are close enough to an eligible planet, are we facing it? angleBetweenPlanets = vec.toAngle(vecBetweenPlanets) # Urrrrrg I hate this, -180 to 180 and 0-360 behave differently and both are # awful in different situations so neither one is really correct. point = (point + 360) % 360 angleBetweenPlanets = (angleBetweenPlanets + 360) % 360 #print "Point and angle:", point, angleBetweenPlanets if abs(angleBetweenPlanets - point) < 10: #print "Yep!" return True #print "Nope, angle too great", angleBetweenPlanets, point, abs(angleBetweenPlanets - point) return False vecBetweenPlanets = vec.sub(targetPlanet.loc, s.loc) vecBPU = vec.unit(vecBetweenPlanets) vecToPlanetEdge = vec.mul(vec.perpendicular(vecBPU), targetPlanet.radius) #print("Vec between planets: {0}, vec to planet edge: {1}".format(vecBPU, vec.unit(vecToPlanetEdge))) angularSize = vec.angleBetween( vecBetweenPlanets, vec.add(vecBetweenPlanets, vecToPlanetEdge)) vecToPoint = vec.mul(vec.fromAngle(point), s.radius) angularDistance = vec.angleBetween(vecBetweenPlanets, vecToPoint) #print("Angular size: {0}, angular distance: {1}".format(angularSize, angularDistance)) if angularDistance > abs(angularSize): return False else: # Check distance between planets surfaces distance = distance + (s.radius + targetPlanet.radius) # Can't capture a planet if you're overlapping it # XXX: Doesn't seem to work, but... if distance < 0: return False return vec.within(s.loc, targetPlanet.loc, distance)
def emit(s, gs, dt, loc, facing, vel=vec.ZERO): s.timer += dt while s.timer > s.interval: s.timer -= s.interval for i in range(s.count): variance = + (s.angle * random.random()) - (s.angle / 2.0) angle = facing + variance v = vec.mul(vec.fromAngle(angle), s.speed) v = vec.add(vel, v) part = s.particleType(loc, v) gs.addParticle(part)
def draw(s, gs): rot = s.parent.facing + s.loc totalAngle = vec.fromAngle(rot) offsetVec = vec.mul(totalAngle, s.radius) location = vec.add(s.parent.loc, offsetVec) (scx, scy) = gs.screenCoords(location) #print "rot: %s, totalAngle: %s, offsetVec: %s, location: %s, sc: %s" % (rot, totalAngle, offsetVec, location, (scx, scy)) # Add a slight offset to center the image rather than drawing # it from the lower-left corner... # Also add oregano. s.sprite.rotation = s.loc + s.parent.facing #print s.sprite.rotation, s.loc, s.parent.facing s.sprite.position = (scx, scy) s.sprite.draw()
def draw(s, gs): swingSpeed = 190.0 # Degrees per second startingFacing = 90.0 if s.direction > 0: swing = startingFacing + -(s.lifetime * swingSpeed) else: swing = (s.lifetime * swingSpeed) - startingFacing rot = s.parent.facing + s.loc totalAngle = vec.fromAngle(rot) offset = vec.mul(totalAngle, s.radius) location = vec.add(s.parent.loc, offset) s.sprite.position = gs.screenCoords(location) #print location s.sprite.rotation = rot + swing s.sprite.draw()
def on_key_press(s, gs, key): if key == keys.SPACE: if not s.controlling: s.startControl() else: s.endControl() elif s.controlling: s.parent.on_key_press(gs, key) else: if key == keys.LEFT: s.facing = -1 s.moving = -1 elif key == keys.RIGHT: s.facing = 1 s.moving = 1 elif key == keys.X: # Try capture some nearby planet... #print("Trying capture...") for p in gs.planets: facingpoint = (s.parent.facing + s.loc) % 360 #print("Trying to capture {0} at facing {1}".format(p, facingpoint)) # XXX: Make it only capture the closest planet, dammit! # XXX: Ideally it will also go off the distance between the planet # surfaces, not the centers This needs to happen! if s.parent.canCapture(facingpoint, s.captureRange, p): print("Captured, facing {0}!".format(facingpoint)) s.parent.capture(p) sound = resource.getSound("capture") sound.play() break elif key == keys.Z: # Try uncapture # XXX: At the moment we can't uncapture from the child side... hmm. # XXX: At the moment also, if there are multiple planets # captured close to each other, it essentially releases # one at random rather than doing the one closest to # where you're standing. for p in s.parent.children: # This is a little f****d up but should work... facingpoint = (s.parent.facing + s.loc) % 360 facingvec = vec.fromAngle(facingpoint) offset = vec.sub(p.loc, s.parent.loc) diff = vec.angleBetween(facingvec, offset) if abs(diff) < 0.2: #print("Uncapturing") s.parent.uncapture(p) sound = resource.getSound("uncapture") sound.play() break elif key == keys.C: if s.attackCooldown < 0.0: s.attack(gs) s.attackCooldown = s.attackCooldownTotal s.attackSound.play() elif key == keys.UP: # Transport to captured planet. teleportAngle = 10.0 for p in s.parent.children: facingpoint = (s.parent.facing + s.loc) % 360 facingvec = vec.fromAngle(facingpoint) offset = vec.sub(p.loc, s.parent.loc) diff = vec.angleBetween(facingvec, offset) if abs(diff ) < teleportAngle and s.transportCooldown <= 0.0: s.sprayParticles(gs, particles.WarpSpark, 50, 30) facingdiff = s.parent.facing - p.facing s.loc += facingdiff + 180 s.setParent(p) s.transportCooldown = s.transportCooldownTotal s.sprayParticles(gs, particles.WarpSpark, 50, 30) s.teleportSound.play() return # Oooor, if this planet is captured, you can go back to the parent if s.parent.parent != None: p = s.parent.parent facingpoint = (s.parent.facing + s.loc) % 360 facingvec = vec.fromAngle(facingpoint) offset = vec.sub(p.loc, s.parent.loc) diff = vec.angleBetween(facingvec, offset) if abs(diff ) < teleportAngle and s.transportCooldown <= 0.0: s.sprayParticles(gs, particles.WarpSpark, 50, 30) facingdiff = s.parent.facing - p.facing s.loc += facingdiff + 180 s.setParent(p) s.transportCooldown = s.transportCooldownTotal s.sprayParticles(gs, particles.WarpSpark, 50, 30) s.teleportSound.play() return # If we've gotten this far, then you're not sitting on a connection, # So jump! if s.jumpCooldown < 0: s.jump() s.jumpSound.play()
def isTouching(s, other): lvec = vec.fromAngle(s.loc) olvec = vec.fromAngle(other.loc) return (abs(vec.angleBetween(lvec, olvec)) < (s.size + other.size)) \ and abs(s.radius - other.radius) < ((s.size + other.size) * 10)
def sprayParticles(s, gs, particle, speed, count): offset = vec.fromAngle(s.loc + s.parent.facing) offset = vec.mul(offset, s.radius) loc = vec.add(s.parent.loc, offset) particles.spray(gs, particle, loc, speed, count)