def __init__(self, width=853, height=480, show_fps=False): self.size = v(width, height) self.show_fps = show_fps self.next_group_num = 0 self.controls = { key.LEFT: Control.MoveLeft, key.RIGHT: Control.MoveRight, key.UP: Control.MoveUp, key.DOWN: Control.MoveDown, key.SPACE: Control.Attack, key._1: Control.Rotate1, key._2: Control.Rotate2, key._3: Control.Rotate3, key._4: Control.Rotate4, key._5: Control.Rotate5, key._6: Control.Rotate6, } self.control_state = [False] * (len(dir(Control)) - 2) self.scroll = v(0,0) self.filename = None self.enemy = None self.enemy_number = 1 self.level = 1 self.own_enemies = False self.camera = None self.message = None self.timers = []
def __init__(self, world, space, pos, color, capsules, radius, mass=2, fixed=False, orientation=v(1, 0, 0, 0)): "capsules is a list of (start, end) points" self.capsules = capsules self.body = ode.Body(world) self.body.setPosition(pos) self.body.setQuaternion(orientation) m = ode.Mass() # computing MOI assuming sphere with .5 m radius m.setSphere(mass/(4/3*math.pi*.5**3), .5) # setSphereTotal is broken self.body.setMass(m) self.geoms = [] self.geoms2 = [] for start, end in capsules: self.geoms.append(ode.GeomTransform(space)) x = ode.GeomCapsule(None, radius, (end-start).mag()) self.geoms2.append(x) self.geoms[-1].setGeom(x) self.geoms[-1].setBody(self.body) x.setPosition((start+end)/2 + v(random.gauss(0, .01), random.gauss(0, .01), random.gauss(0, .01))) a = (end - start).unit() b = v(0, 0, 1) x.setQuaternion(vector.axisangle_to_quat((a%b).unit(), -math.acos(a*b))) self.color = color self.radius = radius if fixed: self.joint = ode.FixedJoint(world) self.joint.attach(self.body, None) self.joint.setFixed()
def __init__(self, world, jointdef, body1, body2): self.jointdef = jointdef self.world = world self.joint = self.make_joint(jointdef) self.body1 = body1 self.body2 = body2 self.b1_anchor = v(*self.jointdef.localAnchor1) / body1.scale self.b2_anchor = v(*self.jointdef.localAnchor2) / body2.scale
def union(self, ano): l, t = self.tl al, at = ano.tl r, b = self.br ar, ab = ano.br return Rect(v(min(l, al), max(t, at)), v(max(r, ar), min(b, ab)))
def draw_level(self, pos): p = pos for i in range(self.part.level): self.star.blit(*p) p += v(self.star.width, 0) if self.part.can_upgrade(): p = pos + v(self.healthbar_empty.width - self.upgrade_button.width, 0) self.upgrade_button.blit(*p) self.upgrade_button_rect = Rect(p + v(0, self.upgrade_button.height), p + v(self.upgrade_button.width, 0))
def __init__(self, world, monster, camera): self.world = world self.monster = monster self.camera = camera self.icons = {} self.init_icons() self.scroll_y = 0 self.mousedown = False self.parthud = None self.mutagen_count = Digits(v(20, 410), anchor=Digits.ANCHOR_LEFT) self.cost_display = Digits(v(200, 410), anchor=Digits.ANCHOR_LEFT) self.cost_value = None
def get_bounds(self): ang = self.sprite.rotation * math.pi / 180 bounds = None basepos = v(*self.sprite.position) for s in self.get_shapes(): center = v(*s.center) center = center.rotated(ang) + basepos diag = v(-s.radius, s.radius) sbounds = Rect(center + diag, center - diag) if bounds is None: bounds = sbounds else: bounds = bounds.union(sbounds) return bounds
def __init__(self, world, pos=(0,0), radius=50, bearing=0, image_file=None, name=None, **kwargs): self.world = world self.pos = v(pos) self.old_pos = v(pos) self.radius = radius self.bearing = bearing self.old_bearing = bearing self.image_file = image_file self.image = squirtle.SVG(data.file_path(image_file), anchor_x='center', anchor_y='center') self.dead = False self.impulse = v((0,0)) self.name = name # do not use self.scale = 0.0 self.z = 0
def load(cls): PartHud.load() Digits.load() imgs = {} for icon in ICONS: img = pyglet.resource.image(icon.sprite) img.anchor_x = 90 - ICON_HALF img.anchor_y = ICON_HALF imgs[icon.name] = img cls.mutagen_label = pyglet.sprite.Sprite(pyglet.resource.image("ui/mutagen.png")) cls.cost_label = pyglet.sprite.Sprite(pyglet.resource.image("ui/cost.png")) cls.mutagen_label.position = v(20, 440) cls.cost_label.position = v(200, 443) cls.images = imgs
def tick(self): # objects by default continue to move in a straight line (see Newton) delta = self.pos - self.old_pos self.old_pos = self.pos dtheta = self.bearing - self.old_bearing self.old_bearing = self.bearing self.bearing += dtheta * ANGULAR_DRAG real_old_pos = self.old_pos # add drag forces to delta drag = delta * -delta.length * self.radius * self.world.drag delta += drag # add other accumulated forces to delta delta += self.impulse self.impulse = v((0,0)) if not self.collides: self.pos += delta else: steps = 1 + int(1.05 * delta.length / self.radius) sub_delta = delta / steps for ii in xrange(steps): self.pos += sub_delta original_pos = self.pos check_collisions = True tries = 0 while check_collisions: check_collisions = False tries += 1 if tries > 200: # this is a problem, so rather than take the game down, we do something which just # looks bad self.pos = original_pos return for wall in self.world.static.overlaps(self): cp = wall.closest_point(self.pos) approach = (self.pos - cp) if approach.length < self.radius - EPSILON: self.pos = cp + approach.normalised() * self.radius check_collisions = True # now, the actor is definitely in a safe place # work backwards to work out its eventual reflection and update old_pos to make it bounce displacement = self.pos - original_pos if displacement.length > 0: mirror_point = original_pos + displacement * 0.5 mirror_line = Line(displacement.normalised(), mirror_point * displacement.normalised()) self.old_pos = mirror_line.reflect(self.old_pos) sub_delta = mirror_line.parallel_through_origin.reflect(sub_delta) self.old_pos = self.pos + (self.old_pos - self.pos) * ELASTICITY
def __init__(self, world, space, pos, color, capsules, radius, mass=2, fixed=False, orientation=v(1, 0, 0, 0)): "capsules is a list of (start, end) points" self.capsules = capsules self.body = ode.Body(world) self.body.setPosition(pos) self.body.setQuaternion(orientation) m = ode.Mass() # computing MOI assuming sphere with .5 m radius m.setSphere(mass / (4 / 3 * math.pi * .5**3), .5) # setSphereTotal is broken self.body.setMass(m) self.geoms = [] self.geoms2 = [] for start, end in capsules: self.geoms.append(ode.GeomTransform(space)) x = ode.GeomCapsule(None, radius, (end - start).mag()) self.geoms2.append(x) self.geoms[-1].setGeom(x) self.geoms[-1].setBody(self.body) x.setPosition((start + end) / 2 + v(random.gauss( 0, .01), random.gauss(0, .01), random.gauss(0, .01))) a = (end - start).unit() b = v(0, 0, 1) x.setQuaternion( vector.axisangle_to_quat((a % b).unit(), -math.acos(a * b))) self.color = color self.radius = radius if fixed: self.joint = ode.FixedJoint(world) self.joint.attach(self.body, None) self.joint.setFixed()
def make_projectile(self, world, pos, bearing): p = Projectile(world, pos=pos, radius=self.projectile_radius, bearing=bearing, image_file=self.projectile_image) d = (random.random() - 0.5) * self.scatter p.apply_impulse(v((self.muzzle_velocity, d)).rotated(bearing)) p.force = self.projectile_force return p
def draw(self, camera): frac = min(1, float(self.part.health) / self.part.get_max_health()) pos = self.part.get_position() + v(0, self.part.get_base_shape().radius) pos = camera.world_to_screen(pos) pos = v(int(pos.x + 0.5), int(pos.y + 0.5)) gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) w = self.healthbar_empty.width h = self.healthbar_empty.height p = pos - v(w / 2, 0) self.healthbar_empty.blit(*p) fillw = frac * w fill = self.healthbar_full.get_region(0, 0, fillw, h) fill.blit(*p) if hasattr(self.part, "level"): self.draw_level(p + v(0, 20))
def load_resource(resource_file): with pyglet.resource.file('components/%s.json' % resource_file) as f: definition = json.loads(f.read()) # load the associated image img = pyglet.resource.image(definition['name']) # <mauve> [offset is] the amount you have to translate the image # <mauve> So -1 * the position of the centre in the image # also we have to flip the y axis because this is pyglet img.anchor_x = -definition['offset'][0] img.anchor_y = img.height + definition['offset'][1] definition['img'] = img offset = v(definition['offset']) circles = [Circle(v(0, 0), definition['radius'])] for p in definition.get('points', []): centre = v(p['offset']) + offset circles.append(Circle(v(centre.x, -centre.y), p['radius'])) definition['shapes'] = circles return definition
def flock(self, sense_radius=500, target_sep=100, effect=1): flock_vector = v((0,0)) for other in self.neighbours(sense_radius): if self.__class__ == other.__class__ and self.sees(other, sight_radius=sense_radius): relative_pos = other.pos - self.pos d = relative_pos.length if d: sgn = 1 if d > target_sep else -1 flock_vector += (relative_pos.normalised() * sgn) if flock_vector.length > 0: self.apply_impulse(flock_vector.normalised() * effect)
def draw(self): glBegin(GL_LINES) for x in xrange(-10, 10+1): for y in xrange(-10, 10+1): pos = v(x, y, 0) vel = self.func(pos) glColor3d(1, 0, 0) glVertex3f(*pos-vel/2) glColor3d(1, 1, 0) glVertex3f(*pos+vel/2) glEnd()
def flock(self, sense_radius=500, target_sep=100, effect=1): flock_vector = v((0, 0)) for other in self.neighbours(sense_radius): if self.__class__ == other.__class__ and self.sees( other, sight_radius=sense_radius): relative_pos = other.pos - self.pos d = relative_pos.length if d: sgn = 1 if d > target_sep else -1 flock_vector += (relative_pos.normalised() * sgn) if flock_vector.length > 0: self.apply_impulse(flock_vector.normalised() * effect)
def init(self, world, pos=v(0, -10, 2)): self.world = world self.pos = pos self.display_flags = pygame.DOUBLEBUF | pygame.OPENGL | pygame.RESIZABLE self.display = pygame.display.set_mode((640, 480), self.display_flags) self.clock = pygame.time.Clock() self.pitch = self.yaw = 0 self.grabbed = False self.fovy = 100
def init(self, world, pos=v(0, -10, 2)): self.world = world self.pos = pos self.display_flags = pygame.DOUBLEBUF|pygame.OPENGL|pygame.RESIZABLE self.display = pygame.display.set_mode((640, 480), self.display_flags) self.clock = pygame.time.Clock() self.pitch = self.yaw = 0 self.grabbed = False self.fovy = 100
def update_velocity(self): #doesn't actually speed things up #if (self.dest != self.last_dest): direction = (self.dest - self.pos) if direction.length2 > self.speed**2: #avoid scaled_to here - we can do better old_length = direction.length scale_factor = self.speed / old_length direction = v( (direction[0] * scale_factor, direction[1] * scale_factor)) self.vel = direction return self.vel
def start(self): Monster.load_all() self.window = pyglet.window.Window(width=self.size.x, height=self.size.y, caption=name) self.camera = Camera(v(self.size.x, self.size.y) * 0.5, self.size.x, self.size.y) Background.load() self.background = Background(self.window) self.world = World() self.monster = Monster.create_initial(self.world, v(400, 80)) self.monster.add_death_listener(self.show_game_over) self.world.add_monster(self.monster) self.auto_monster() if self.filename is not None: self.world.add_monster(Monster.enemy_from_json(self.world, self.filename)) self.show_message('fight', 2) else: self.set_timer(self.spawn_next_enemy, 1.5) self.show_message('get-ready') Shelf.load() self.hud = Shelf(self.world, self.monster, self.camera) self.fps_display = pyglet.clock.ClockDisplay() pyglet.clock.schedule_interval(self.update, 1/target_fps) self.window.set_handlers( on_draw=self.on_draw, on_key_press=self.on_key_press, on_key_release=self.on_key_release, on_mouse_press=self.hud.on_mouse_press, on_mouse_release=self.hud.on_mouse_release, on_mouse_motion=self.hud.on_mouse_motion, on_mouse_drag=self.hud.on_mouse_drag, on_mouse_scroll=self.hud.on_mouse_scroll, ) pyglet.app.run()
def update_velocity(self): direction = self.dest - self.pos if self.vel is None or self.vel.is_zero: if direction.length2 > self.speed**2: #avoid scaled_to here - we can do better old_length = direction.length scale_factor = self.speed / old_length direction = v( (direction[0] * scale_factor, direction[1] * scale_factor)) self.vel = direction else: tturn = self.vel.signed_angle_to(direction) if abs(tturn) <= self.turn_rate: if direction.length2 > self.speed**2: #avoid scaled_to here - we can do better old_length = direction.length scale_factor = self.speed / old_length direction = v((direction[0] * scale_factor, direction[1] * scale_factor)) self.vel = direction else: self.vel = self.vel.rotated(cmp(tturn, 0) * self.turn_rate) return self.vel
def kill(self): for p, j in self._joints: p.kill() if self._parent is not None: self._parent._joints = [(p, j) for p, j in self._parent._joints if p is not self] for p, radius in self.get_shapes(): for i in range(int(radius * radius / 100.0)): off = v(random.gauss(0, radius * 0.5), random.gauss(0, radius * 0.5)) self.world.spawn(Blood(self.get_position() + p + off, name='')) self.world.destroy(self) self.monster.remove_part(self) if self._parent is None: self.monster.kill()
def update(self, dt): if self.controller: self.controller.update(dt) if self.moving in [LEFT, RIGHT]: self.phase += self.moving * dt * 2 for p in self.parts: if not isinstance(p, Leg): continue ppos = p.get_position() step = math.sin(ppos.x / 50.0 + self.phase) f = step * 0.5 + 0.5 p.set_position(ppos + v(self.moving * 200 * f * dt, 10 * f * dt)) rot = p.body.get_rotation() p.body.set_rotation(rot + self.moving * step * dt) self.moving = 0
def on_mouse_press(self, x, y, button, modifiers): self.draggedicon = self.icon_for_point(x, y) if self.parthud: s = v(x, y) if self.parthud.upgrade_button_rect and self.parthud.upgrade_button_rect.contains(s): self.parthud.part.upgrade() else: wpos = self.camera.screen_to_world(s) for m in self.world.monsters: part = m.colliding_point(wpos) if part and part is self.parthud.part: break else: self.parthud = None self.mousedown = True
def on_mouse_motion(self, x, y, dx, dy): icon = self.icon_for_point(x, y) if icon: self.cost_value = self.icons[icon].cost else: self.cost_value = None if self.parthud: s = v(x, y) if self.parthud.upgrade_button_rect and self.parthud.upgrade_button_rect.contains(s): self.cost_value = self.parthud.part.upgrade_cost() if self.parthud.locked: return wpos = self.camera.screen_to_world(v(x, y)) for m in self.world.monsters: part = m.colliding_point(wpos) if part: break else: if self.parthud and not self.parthud.locked: self.parthud = None return if self.parthud is None or part is not self.parthud.part: self.parthud = PartHud(part)
def __init__(self, world, pos=(0, 0), radius=50, bearing=0, image_file=None, name=None, **kwargs): self.world = world self.pos = v(pos) self.old_pos = v(pos) self.radius = radius self.bearing = bearing self.old_bearing = bearing self.image_file = image_file self.image = squirtle.SVG(data.file_path(image_file), anchor_x='center', anchor_y='center') self.dead = False self.impulse = v((0, 0)) self.name = name # do not use self.scale = 0.0 self.z = 0
def on_mouse_release(self, x, y, button, modifiers): if self.draggedpart: wpos = self.camera.screen_to_world(v(x, y)) self.draggedpart.set_position(wpos) try: self.monster.attach_and_grow(self.draggedpart) except ValueError: pass else: self.monster.spend_mutagen(self.draggedpart.cost) elif self.parthud: self.parthud.locked = True self.draggedpart = None self.draggedicon = None self.mousedown = False
def draw(self): q = gluNewQuadric() glColor3f(*self.color) with GLMatrix: rotate_to_body(self.body) for start, end in self.capsules: with GLMatrix: glTranslate(*start) gluSphere(q, self.radius, 30, 15) with GLMatrix: glTranslate(*end) gluSphere(q, self.radius, 30, 15) with GLMatrix: glTranslate(*start) a = (end - start).unit() b = v(0, 0, 1) glRotate(-math.degrees(math.acos(a*b)), *(a%b).unit()) gluCylinder(q, self.radius, self.radius, (end - start).mag(), 10, 1)
def on_mouse_drag(self, x, y, dx, dy, button, modifiers): if x > (853 - ICON_HEIGHT - MARGIN) and not self.draggedpart: self.scroll_y += dy wpos = self.camera.screen_to_world(v(x, y)) if self.draggedicon and x < (853 - ICON_HEIGHT - MARGIN): self.draggedpart = self.create_virtual_part(self.draggedicon, wpos) self.draggedicon = None if self.draggedpart: self.draggedpart.set_position(wpos) attachment = self.monster.attachment_point(self.draggedpart) if attachment is not None: self.draggedpart.position_to_joint(attachment[1] - attachment[2]) self.draggedpart.set_position(attachment[1]) self.draggedpart.set_style(STYLE_VALID) else: self.draggedpart.set_style(STYLE_INVALID)
def draw(self): q = gluNewQuadric() glColor3f(*self.color) with GLMatrix: rotate_to_body(self.body) for start, end in self.capsules: with GLMatrix: glTranslate(*start) gluSphere(q, self.radius, 30, 15) with GLMatrix: glTranslate(*end) gluSphere(q, self.radius, 30, 15) with GLMatrix: glTranslate(*start) a = (end - start).unit() b = v(0, 0, 1) glRotate(-math.degrees(math.acos(a * b)), *(a % b).unit()) gluCylinder(q, self.radius, self.radius, (end - start).mag(), 10, 1)
def create_body(self, world): """Create the physics body for the part""" #print "Spawning", self.__class__.__name__, self.name + self.type self.body = world.create_body(self.get_shapes(), collision_class=self.name + self.type) self.body.set_position(v(*self.sprite.position))
def random_point_on_circle(centre, radius): from vector import Vector as v import random return centre + v((radius, 0)).rotated(random.random() * 360)
from vehicle import Vehicle from vector import Vector as v from world import World, Path from gui import GUI from PyQt5 import QtGui, QtCore, QtWidgets if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) dw = QtWidgets.QDesktopWidget() w = dw.width() * 0.9 h = dw.height() * 0.8 v0 = v(0, 0) vel = v(10, 10) v1 = v(20, 20) paths = [] vehicleCount = 8 path1 = Path([ v(100, 100), v(200, 100), v(300, 100), v(400, 100), v(500, 100), v(500, 200), v(500, 300), v(500, 400),
def map_centre(self): return v((self.w / 2, self.h / 2))
def int_point(pt): return v((pt.x // 1.0, pt.y // 1.0))
def bumble(self): self.apply_impulse(v((random.gauss(0, 1), random.gauss(0, 1))))
def initial_setup(self): self.game.add_plant_at(plant.Cherry, self.game.map_centre) self.game.add_plant_at(plant.Daisy, self.game.map_centre + v((200, 0))) self.game.add_plant_at(plant.Bluebell, self.game.map_centre - v((200, 0)))
def step(self): dt = self.clock.tick()/1000 for event in pygame.event.get(): if event.type == pygame.MOUSEMOTION: if self.grabbed: self.yaw += event.rel[0]/100 self.pitch += -event.rel[1]/100 # caps it to a quarter turn up or down self.pitch = min(max(self.pitch, -math.pi/2), math.pi/2) elif event.type == pygame.KEYDOWN: if event.key == pygame.K_TAB: self.grabbed = not self.grabbed pygame.event.set_grab(self.grabbed) pygame.mouse.set_visible(not self.grabbed) elif event.key == pygame.K_q: sys.exit() elif event.type == pygame.QUIT: sys.exit() elif event.type == pygame.VIDEORESIZE: self.display = pygame.display.set_mode(event.size, self.display_flags) glViewport(0, 0, self.display.get_width(), self.display.get_height()) rot_matrix = euler_matrix(self.yaw, self.pitch, 0) forward = rotate_vec(v(1,0,0), rot_matrix) left = rotate_vec(v(0,1,0), rot_matrix) local_up = rotate_vec(v(0,0,1), rot_matrix) keys = pygame.key.get_pressed() speed = 50 if keys[pygame.K_LSHIFT] else 5 speed *= (.1 if keys[pygame.K_LCTRL] else 1) if keys[pygame.K_w]: self.pos += forward*dt*speed if keys[pygame.K_s]: self.pos += -forward*dt*speed if keys[pygame.K_a]: self.pos += left*dt*speed if keys[pygame.K_d]: self.pos += -left*dt*speed if keys[pygame.K_SPACE]: self.pos += v(0, 0, 1)*dt*speed if keys[pygame.K_c]: self.pos += v(0, 0, -1)*dt*speed glMatrixMode(GL_PROJECTION) glLoadIdentity() perspective(self.fovy, self.display.get_width()/self.display.get_height(), 0.1) glMatrixMode(GL_MODELVIEW) glLoadIdentity() # rotates into the FLU coordinate system glMultMatrixf([ [ 0., 0.,-1., 0.], [-1., 0., 0., 0.], [ 0., 1., 0., 0.], [ 0., 0., 0., 1.] ]) # after that, +x is forward, +y is left, and +z is up glMultMatrixf(rot_matrix.T) glTranslate(*-self.pos) pos = self.pos self.world.draw() glDisable(GL_LIGHTING) glDisable(GL_DEPTH_TEST) with GLMatrix: glTranslate(*self.pos + forward + left - local_up) glBegin(GL_LINES) for i in xrange(3): glColor3f(*(j==i for j in xrange(3))) glVertex3f(0, 0, 0) glVertex3f(*(.1*(j==i) for j in xrange(3))) glEnd() glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) pygame.display.flip()
def __init__(self, world, pos): super(SmokePuff, self).__init__(world, pos=pos, radius=10, image_file="images/all/star.svgz") self.apply_impulse(v((random.gauss(0, 2), random.gauss(0, 2))))
def accelerate(self): self.apply_impulse(v((self.thrust, 0)).rotated(self.bearing))
def initial_setup(self): self.game.add_plant_at(plant.Rose, v((0.2 * self.game.w, 0.5 * self.game.h)), True) self.game.add_plant_at(plant.Apple, v((0.8 * self.game.w, 0.5 * self.game.h)), True) self.game.add_creature_at(creatures.Ladybird, v((0.3 * self.game.w, 0.5 * self.game.h))) self.game.add_creature_at(creatures.Dragonfly, v((0.7 * self.game.w, 0.5 * self.game.h)))
def tick(self): for c in self.colliders(): if c.mass > 0: rpn = (c.pos - self.pos).normalised() c.apply_impulse(rpn * self.mass) self.apply_impulse(-rpn * c.mass) self.bearing += self.rotation if self.thrust or self.lift: dir = v((self.thrust, self.lift)).rotated(self.bearing) self.apply_impulse(dir) if self.engine_fx_cooldown <= 0: self.world.new_active.add( effects.SmokePuff(self.world, self.pos)) self.engine_fx_cooldown = SMOKEPUFF_RATE else: self.engine_fx_cooldown -= 1 old_pos = v( self.pos ) #Need to store this, because we may mess with it to do bouncing, etc. super(Player, self).tick() def candidate_key(pt): v1 = self.pipe[-1] - pt v2 = self.pipe[-1] - old_pos return v1.angle_to(v2) #, v1.length def int_point(pt): return v((pt.x // 1.0, pt.y // 1.0)) hooked = False unhooked = [] swept_angle = 0 while True: candidates = [] for wall in self.world.static.in_tri(self.pipe[-1], old_pos, self.pos): pt = int_point(wall.start) # why does this work? if pt not in unhooked and pt.in_tri(self.pipe[-1], old_pos, self.pos): angle = candidate_key(pt) if angle > swept_angle: candidates.append((angle, pt)) if not hooked and len(self.pipe) > 1 and self.pipe[-1].in_tri( self.pipe[-2], old_pos, self.pos): unhook_angle = (self.pipe[-1] - old_pos).angle_to(self.pipe[-2] - self.pipe[-1]) else: unhook_angle = None if not candidates and unhook_angle is None: break if unhook_angle is not None and (not candidates or unhook_angle < min(candidates)): swept_angle = (self.pipe[-2] - old_pos).angle_to(self.pipe[-2] - self.pipe[-1]) self.pinned_length -= (self.pipe[-2] - self.pipe[-1]).length unhooked.append(self.pipe.pop()) else: angle, pivot = min(candidates) swept_angle = angle self.pipe.append(pivot) self.pinned_length += (self.pipe[-2] - self.pipe[-1]).length hooked = True pipe_vector = self.pos - self.pipe[-1] if pipe_vector.length > self.pipe_length - self.pinned_length: sf = (self.pipe_length - self.pinned_length) / pipe_vector.length self.pos = (1 - sf) * self.pipe[-1] + self.pos * sf self.pipe_used = min(pipe_vector.length + self.pinned_length, self.pipe_length) if self.firing and self.cooldown > SHOT_COOLDOWN: self.cooldown = 0 p = self.weapon.make_projectile(self.world, pos=self.pos, bearing=self.bearing + 90) p.apply_impulse(self.pos - self.old_pos) self.world.new_active.add(p) self.world.dispatch_event('on_shoot') self.cooldown += 1 if not self.firing: self.cooldown = SHOT_COOLDOWN self.oxygen.contained -= 1 for c in self.colliders(): if isinstance(c, swag.Swag): self.world.dispatch_event('on_get_swag', c) if c.goal: self.world.dispatch_event('on_finish_level') c.dead = True
def get_position(self): if self.body: return self.body.get_position() else: return v(*self.sprite.position)
from line import Line as l from plane import Plane as p from linsys import LinearSystem as linSys # Test for Lines def checkLine(line1, line2): if line1.is_equal(line2): print "They are equal" elif line1.is_parallel(line2): print "They are parallel" else: print line1.intersection(line2) a = l(v([4.046, 2.836]), 1.21) b = l(v([10.115, 7.09]), 3.025) checkLine(a, b) c = l(v([7.204, 3.182]), 8.68) d = l(v([8.172, 4.114]), 9.883) checkLine(c, d) e = l(v([1.182, 5.562]), 6.744) f = l(v([1.773, 8.343]), 9.525) checkLine(e, f) # Test for ps def checkp(p1, p2): if p1.is_equal(p2):
def step(self): dt = self.clock.tick() / 1000 for event in pygame.event.get(): if event.type == pygame.MOUSEMOTION: if self.grabbed: self.yaw += event.rel[0] / 100 self.pitch += -event.rel[1] / 100 # caps it to a quarter turn up or down self.pitch = min(max(self.pitch, -math.pi / 2), math.pi / 2) elif event.type == pygame.KEYDOWN: if event.key == pygame.K_TAB: self.grabbed = not self.grabbed pygame.event.set_grab(self.grabbed) pygame.mouse.set_visible(not self.grabbed) elif event.key == pygame.K_q: sys.exit() elif event.type == pygame.QUIT: sys.exit() elif event.type == pygame.VIDEORESIZE: self.display = pygame.display.set_mode(event.size, self.display_flags) glViewport(0, 0, self.display.get_width(), self.display.get_height()) rot_matrix = euler_matrix(self.yaw, self.pitch, 0) forward = rotate_vec(v(1, 0, 0), rot_matrix) left = rotate_vec(v(0, 1, 0), rot_matrix) local_up = rotate_vec(v(0, 0, 1), rot_matrix) keys = pygame.key.get_pressed() speed = 50 if keys[pygame.K_LSHIFT] else 5 speed *= (.1 if keys[pygame.K_LCTRL] else 1) if keys[pygame.K_w]: self.pos += forward * dt * speed if keys[pygame.K_s]: self.pos += -forward * dt * speed if keys[pygame.K_a]: self.pos += left * dt * speed if keys[pygame.K_d]: self.pos += -left * dt * speed if keys[pygame.K_SPACE]: self.pos += v(0, 0, 1) * dt * speed if keys[pygame.K_c]: self.pos += v(0, 0, -1) * dt * speed glMatrixMode(GL_PROJECTION) glLoadIdentity() perspective(self.fovy, self.display.get_width() / self.display.get_height(), 0.1) glMatrixMode(GL_MODELVIEW) glLoadIdentity() # rotates into the FLU coordinate system glMultMatrixf([[0., 0., -1., 0.], [-1., 0., 0., 0.], [0., 1., 0., 0.], [0., 0., 0., 1.]]) # after that, +x is forward, +y is left, and +z is up glMultMatrixf(rot_matrix.T) glTranslate(*-self.pos) pos = self.pos self.world.draw() glDisable(GL_LIGHTING) glDisable(GL_DEPTH_TEST) with GLMatrix: glTranslate(*self.pos + forward + left - local_up) glBegin(GL_LINES) for i in xrange(3): glColor3f(*(j == i for j in xrange(3))) glVertex3f(0, 0, 0) glVertex3f(*(.1 * (j == i) for j in xrange(3))) glEnd() glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) pygame.display.flip()
def somewhere(self): return v((distribute_outwards(random.random()) * self.w, distribute_outwards(random.random()) * self.h))
def accelerate(self): self.apply_impulse(v((self.thrust,0)).rotated(self.bearing))
def tick(self): # objects by default continue to move in a straight line (see Newton) delta = self.pos - self.old_pos self.old_pos = self.pos dtheta = self.bearing - self.old_bearing self.old_bearing = self.bearing self.bearing += dtheta * ANGULAR_DRAG real_old_pos = self.old_pos # add drag forces to delta drag = delta * -delta.length * self.radius * self.world.drag delta += drag # add other accumulated forces to delta delta += self.impulse self.impulse = v((0, 0)) if not self.collides: self.pos += delta else: steps = 1 + int(1.05 * delta.length / self.radius) sub_delta = delta / steps for ii in xrange(steps): self.pos += sub_delta original_pos = self.pos check_collisions = True tries = 0 while check_collisions: check_collisions = False tries += 1 if tries > 200: # this is a problem, so rather than take the game down, we do something which just # looks bad self.pos = original_pos return for wall in self.world.static.overlaps(self): cp = wall.closest_point(self.pos) approach = (self.pos - cp) if approach.length < self.radius - EPSILON: self.pos = cp + approach.normalised() * self.radius check_collisions = True # now, the actor is definitely in a safe place # work backwards to work out its eventual reflection and update old_pos to make it bounce displacement = self.pos - original_pos if displacement.length > 0: mirror_point = original_pos + displacement * 0.5 mirror_line = Line( displacement.normalised(), mirror_point * displacement.normalised()) self.old_pos = mirror_line.reflect(self.old_pos) sub_delta = mirror_line.parallel_through_origin.reflect( sub_delta) self.old_pos = self.pos + (self.old_pos - self.pos) * ELASTICITY
def good_creature_arrival_location(self): return v((self.game.w * (0.2 + 0.6*random.random()), -200))
def initial_setup(self): self.game.add_plant_at(plant.Orange, v((80, self.game.h/2)), True) self.game.add_plant_at(plant.Orange, v((self.game.w - 80, self.game.h/2)), True)
def inv_camera_transform(self, screen_loc): return (v(screen_loc) - (self.window.width * 0.5, self.window.height * 0.2)).rotated(self.camera_bearing) / (self.camera_scale * self.camera_zoom) + self.camera_pos
def on_mouse_release(self, x, y, buttons, mods): self.g.plants.add(Plant(v((x, y))))
def hit(self, victim): self.dead = True # check this next line - I think crazy stuff might happen if a projectile hits an enemy just # after it's bounced off a wall victim.apply_impulse(v((self.force, 0)).rotated(self.bearing)) victim.stun(STUN_FRAMES)
def initial_setup(self): self.game.add_plant_at(plant.Rose, self.game.map_centre + v((-150, 0)), True) self.game.add_plant_at(plant.Rose, self.game.map_centre + v((150, 0)), True) self.game.add_creature_at(creatures.Ladybird, self.game.map_centre)