def kill(self): self.lives -= 1 self.ship.momentum = three.Vector3(0, 0, 0) self.ship.position = three.Vector3(0, 0, 0) self.ship.geo.setRotationFromEuler(three.Euler(0, 0, 0)) self.keyboard.clear('spin') self.keyboard.clear('thrust') self.keyboard.clear('fire') self.ship.visible = False self.audio.fail.play() can_reappear = now() + 3.0 def reappear(t): if now() < can_reappear: return True, "waiting" for a in self.asteroids: if a.bbox.contains(self.ship.position): return True, "can't spawn" return False, "OK" def clear_resetter(): self.ship.visible = True self.resetter = None reset = coroutine(reappear, clear_resetter) next(reset) return reset
def setup(self): self.ship = Ship(self.keyboard, self) self.graphics.add(self.ship) def rsign(): if random.random() < .5: return -1 return 1 for a in range(8): x = (random.random() - 0.5) * 2 y = random.random() - 0.5 z = 0 offset = three.Vector3(x, y, z) offset.normalize(); push = random.randint(20, 60) offset = offset.multiplyScalar(push) r = (random.random() + 1.0) * 2.5 asteroid = Asteroid(r, offset) mx = random.random() + random.random() + random.random(2) - 2.0 my = random.random() + random.random() + random.random(2) - 2.0 asteroid.momentum = three.Vector3(mx, my, 0) self.graphics.add(asteroid) self.asteroids.append(asteroid) for b in range(8): bullet = Bullet() self.graphics.add(bullet) self.bullets.append(bullet) self.helptext = self.help_display()
def __init__(self): self.vector = three.Vector3(0, 0, 0) self.geo = three.Mesh(three.BoxGeometry(.25, .25, .25), three.MeshBasicMaterial({'color': 0xffffff})) self.lifespan = 0 self.momentum = three.Vector3(0, 0, 0) self.reset()
def __init__(self, radius, pos): Unit.__init__(self) self.radius = radius self.geo = three.Mesh(three.SphereGeometry(self.radius), three.MeshNormalMaterial()) self.geo.position.set(pos.x, pos.y, pos.z) self.bbox = AABB(self.radius * 2, self.radius * 2, self.geo.position) self.momentum = three.Vector3(0, 0, 0)
def fire(self, pos, vector, momentum, t): for each_bullet in self.bullets: if each_bullet.geo.position.z >= 1000: each_bullet.geo.position.set(pos.x, pos.y, pos.z) each_bullet.vector = vector each_bullet.lifespan = 0 each_bullet.momentum = three.Vector3().copy(momentum).multiplyScalar(.66) return True return False
def update(self, t): if self.geo.position.z < 1000: self.lifespan += t if self.lifespan > self.EXPIRES: self.reset() return delta = three.Vector3().copy(self.vector) delta.multiplyScalar(self.BULLET_SPEED * t) delta.add(self.momentum) current_pos = self.geo.position.add(delta) self.geo.position.set(current_pos.x, current_pos.y, current_pos.z) wrap(self.geo)
def handle_input(self, t): if self.keyboard.get_axis('fire') >= 1: mo = three.Vector3().copy(self.ship.momentum).multiplyScalar(t) if self.fire(self.ship.position, self.ship.heading, mo): self.audio.fire() self.keyboard.clear('fire') spin = self.keyboard.get_axis('spin') self.ship.spin(spin * t) thrust = self.keyboard.get_axis('thrust') self.audio.thrust.volume = clamp(thrust * 5, 0, 1) self.ship.thrust(thrust * t)
def __init__(self, keyboard, game): Unit.__init__(self) self.keyboard = keyboard self.geo = three.Mesh(three.ConeBufferGeometry(1, 3, 8), three.MeshNormalMaterial()) exhaust = three.Mesh(three.ConeBufferGeometry(.5, 2, 8), three.MeshBasicMaterial({'color': 0xffff00})) self.geo.add(exhaust) exhaust.translateY(-2) exhaust.rotateZ(3.14159) self.exhaust = exhaust self.momentum = three.Vector3(0, 0, 0) self.keyboard = keyboard self.bbox = AABB(2, 3, self.geo.position) self.game = game
class Bullet: EXPIRES = 1 RESET_POS = three.Vector3(0, 0, 1000) BULLET_SPEED = 50 def __init__(self): self.vector = three.Vector3(0, 0, 0) self.geo = three.Mesh( three.BoxGeometry(.25, .25, .25), three.MeshBasicMaterial({'color': 0xffffff}) ) self.lifespan = 0 self.momentum = three.Vector3(0, 0, 0) self.reset() def update(self, t): if self.geo.position.z < 1000: self.lifespan += t if self.lifespan > self.EXPIRES: self.reset() return delta = three.Vector3().copy(self.vector) delta.multiplyScalar(self.BULLET_SPEED * t) delta.add(self.momentum) current_pos = self.geo.position.add(delta) self.geo.position.set(current_pos.x, current_pos.y, current_pos.z) wrap(self.geo) def reset(self): self.lifespan = 0 self.momentum = three.Vector3(0, 0, 0) self.geo.position.set(self.RESET_POS.x, self.RESET_POS.y, self.RESET_POS.z) def get_position(self): return self.geo.position position = property(get_position)
def tick(self): if len(self.asteroids) == 0 or self.lives < 1: document.getElementById("game_over").style.visibility = 'visible' document.getElementById('credits').style.visibility = 'visible' document.getElementById('game_canvas').style.cursor = 'auto' return requestAnimationFrame(self.tick) t = (now() - self.last_frame) self.fps_counter.update(t) self.keyboard.update(t) # controls if self.ship.visible: self.handle_input(t) # clean up bullets, check for collisions dead = [] for b in self.bullets: if b.position.z < 1000: for a in self.asteroids: if a.bbox.contains(b.position): d = a.geo.position.distanceTo(b.position) if d < a.radius: b.reset() dead.append(a) if self.ship.visible: for a in self.asteroids: if a.bbox.contains(self.ship.position): d = a.geo.position.distanceTo(self.ship.position) if d < (a.radius + 0.5): self.resetter = self.kill() print("!!", self.resetter) dead.append(a) else: self.resetter.advance(t) for d in dead: self.asteroids.remove(d) new_score = int(100 * d.radius) self.update_score(new_score) d.geo.visible = False if d.radius > 1.5: self.audio.explode() new_asteroids = random.randint(2, 5) for n in range(new_asteroids): new_a = Asteroid((d.radius + 1.0) / new_asteroids, d.position) mx = (random.random() - 0.5) * 6 my = (random.random() - 0.5) * 4 new_a.momentum = three.Vector3().copy(d.momentum) new_a.momentum.add(three.Vector3(mx, my, 0)) self.graphics.add(new_a) self.asteroids.append(new_a) for b in self.bullets: b.update(t) self.ship.update(t) wrap(self.ship.geo) for item in self.asteroids: item.update(t) wrap(item.geo) # advance coroutines if self.resetter is not None: self.resetter.advance(t) if self.helptext is not None: self.helptext.advance(t) self.graphics.render() self.last_frame = now()
def get_heading(self): # return the local Y axis, since Z is 'up' m = self.geo.matrixWorld.elements return three.Vector3(m[4], m[5], m[6])
def __init__(self): self.geo = None self.momentum = three.Vector3(0, 0, 0)
def update(self, t): if self.visible: current_pos = self.geo.position move = three.Vector3().copy(self.momentum).multiplyScalar(t) current_pos = current_pos.add(move) self.geo.position.set(current_pos.x, current_pos.y, current_pos.z)
def reset(self): self.lifespan = 0 self.momentum = three.Vector3(0, 0, 0) self.geo.position.set(self.RESET_POS.x, self.RESET_POS.y, self.RESET_POS.z)