def draw(self, window, offset = sf.Vector2f()): """Draw the asteroid, with a provided offset.""" self.shape.position = self.loc + offset self.shape.rotation = self.rotation self.shape.scale = sf.Vector2f(float(self.drawSize) / float(self.size), float(self.drawSize) / float(self.size)) window.draw(self.shape)
def __init__(self): """Initialize the render window and start the game running""" # Constants FULLSCREEN = True self.FONT = sf.Font.load_from_file(RESOURCE_DIR + "raleway_thin.ttf") self.num_asteroids = 3 self.view_size = sf.Vector2f(720, 450) # Initialize the window if FULLSCREEN: self.window = sf.RenderWindow(sf.VideoMode(1440, 900), "Multitroids", sf.Style.FULLSCREEN, sf.ContextSettings(antialiasing = 32)) # self.image = sf.Image(1440, 900) else: self.window = sf.RenderWindow(sf.VideoMode(720, 450), "Multitroids", sf.Style.DEFAULT, sf.ContextSettings(antialiasing = 32)) # self.image = sf.Image(720, 450) self.window.framerate_limit = 60 self.window.view = sf.View.from_center_and_size(sf.Vector2f(), self.view_size) self.window.show_mouse_cursor = False self.full_restart() self.state = 'start'
def __init__(self, mgr = None, loc = None, size = 25, clear_zone = None, seed = 1, fragment = False): # Each asteroid keeps a personal random number generator, to make its # behavior deterministic. self.rand = random.Random() self.rand.seed(seed) # To make particles, we set fragment to true. self.fragment = fragment # Initialize the asteroid's location to somewhere within the window, # far from the ship's location. if mgr: if loc: self.loc = loc.copy() else: self.loc = sf.Vector2f(self.rand.randint(0, mgr.view_size.x), self.rand.randint(0, mgr.view_size.y)) self.size = size * 4 # Look for a starting spot far away from the clear zone (which # is where the ship starts). while clear_zone: if self.touches(clear_zone): self.loc = sf.Vector2f( self.rand.randint(0, mgr.view_size.x), self.rand.randint(0, mgr.view_size.y)) else: clear_zone = None self.momentum = sf.Vector2f(self.rand.randint(-10, 10) / 5., self.rand.randint(-10, 10) / 5.) else: self.loc = sf.Vector2f() self.momentum = sf.Vector2f() # State variables. self.alive = True self.size = size self.drawSize = size # Make an irregular shape for the asteroid self.shape = sf.Shape() numPoints = 20 for i in range(0, numPoints): angle = i/float(numPoints) * 2 * pi if self.rand.random() < 0.2: scale = 0 while scale < 0.5: scale = self.rand.random() else: scale = 1 self.shape.add_point(cos(angle) * self.size * scale, sin(angle) * self.size * scale, sf.Color.BLACK, sf.Color.WHITE) self.shape.outline_thickness = 1 self.shape.outline_enabled = True self.shape.fill_enabled = False self.rotation = self.rand.randint(0, 360) self.dRot = self.rand.randint(-10, 10) / 10.0
def draw_HUD(self): """Draw text in the upper left corner showing how many ships have been used.""" text = sf.Text("Ships: %d" % len(self.players), self.FONT, 30) text.style = sf.Text.BOLD text.scale = sf.Vector2f(0.5, 0.5) text.position = sf.Vector2f(15, 15) self.window.draw(text)
def draw_FPS(self): """Write the number of frames per second in the upper left corner.""" ft = self.window.frame_time if (ft > 0): text = sf.Text("FPS: %(fps)03d" % {'fps': 1 / ft}) else: text = sf.Text("FPS:inf") text.scale = sf.Vector2f(0.5, 0.5) text.position = sf.Vector2f(0, self.view_size.y - 20) self.window.draw(text)
def reset(self, keyboard, startLoc=sf.Vector2f(0, 0)): """Reset a ship to its original state, and re-attach it to a keyboard (either real or virtual)""" if keyboard: self.LEFT = keyboard[sf.Key.LEFT] self.RIGHT = keyboard[sf.Key.RIGHT] self.THRUST = keyboard[sf.Key.UP] self.BRAKE = keyboard[sf.Key.DOWN] self.SHOOT = keyboard[sf.Key.SPACE] self.loc = startLoc self.momentum = sf.Vector2f() self.angle = 180 self.shootHeld = False self.alive = True self.is_clone = True
def __init__(self, loc, angle, speed=10): self.loc = loc self.angle = angle self.momentum = sf.Vector2f(-sin(radians(self.angle)), cos(radians(self.angle))) * speed self.life = 20 self.alive = True
def draw(self, target, states): if self.collision_rect != None: rect = self.getGlobalBounds() self.collision_rect.setSize(sf.Vector2f(rect.width, rect.height)) self.collision_rect.setPosition(rect.left, rect.top) target.draw(self.collision_rect) states.transform *= self.getTransform() target.draw(self.sprite, states)
def __init__(self, engine, id, pos=sf.Vector2f(), angle=90): Entity.__init__(self, id, pos, angle) subclass = self.__class__ # provides access to subclass static variables if not isinstance(subclass.texture, sf.Texture): subclass.texture = loadTexture(subclass.texture_path, engine) self.sprite = sf.Sprite(subclass.texture) self.collision_table = CollisionTable( self.sprite.getTexture().copyToImage()) if SpriteBasedEntity.show_collision_boxes: self.collision_rect = sf.RectangleShape() self.collision_rect.setFillColor( SpriteBasedEntity.collision_boxes_color) else: # avoid unnecessary memory consumption self.collision_rect = None
def __init__(self, keyboard, startLoc=sf.Vector2f(0, 0)): # Initialize inputs. self.LEFT = keyboard[sf.Key.LEFT] self.RIGHT = keyboard[sf.Key.RIGHT] self.THRUST = keyboard[sf.Key.UP] self.BRAKE = keyboard[sf.Key.DOWN] self.SHOOT = keyboard[sf.Key.SPACE] # And initialize movement state. self.loc = startLoc self.momentum = sf.Vector2f() self.angle = 180 # Corners are used for drawing. self.corners = [ sf.Vector2f(-5, -5), sf.Vector2f(5, -5), sf.Vector2f(0, 10) ] # Plus various other state things self.shootHeld = False self.alive = True self.is_clone = False
def init(self): self.paused = False self.engine.getRenderWindow().setFramerateLimit(0) self.engine.getRenderWindow().setVerticalSyncEnabled(False) # particle emitter self.emitter = thor.UniversalEmitter.create() self.emitter.setEmissionRate(30) self.emitter.setLifetime(sf.seconds(5)) self.emitter.setPositionCallback(self.mousePosition) # particle system particle = loadTexture("data/particle.png", self.engine) self.particle_system = thor.ParticleSystem(thor.noDeletePtr(particle)) self.particle_system.addEmitter(self.emitter) # particle affectors gradient = thor.createGradient(sf.Color(0, 150, 0), [ 1, sf.Color(0, 150, 100), 1, sf.Color(0, 0, 150), ]) self.particle_system.addAffector(thor.ColorAffector.create(gradient)) self.particle_system.addAffector(thor.FadeInAffector.create(0.1)) self.particle_system.addAffector(thor.FadeOutAffector.create(0.1)) self.particle_system.addAffector(thor.TorqueAffector.create(500)) self.particle_system.addAffector( thor.ForceAffector.create(sf.Vector2f(0, 100))) # particle parameters self.velocity = thor.PolarVector2f(200, -90) # text from script.entities_tools import loadFont self.font = loadFont("data/Crimson-Roman.otf", self.engine) self.text = sf.Text( "Left click: Enable/disable glow effect\n" "Right click: Pause\n" "Mouse wheel: Change direction\n", self.font) self.text.setCharacterSize(14) self.text.setColor(sf.Color(255, 255, 255)) return True
def update(self, mgr=None): """Update the ship's status.""" # If we're dead, then keep moving in the same direction, but don't do # anything else. if not self.alive: self.loc += self.momentum self.boundLoc(mgr) return # Check to see if we've hit any asteroid, using a circular collision # detection radius for simplicity. for asteroid in mgr.asteroids: if not asteroid.fragment and asteroid.distance(self.loc) < 5: self.alive = False # Turn! if self.LEFT and not self.RIGHT: self.angle -= 5 elif self.RIGHT and not self.LEFT: self.angle += 5 # Accelerate and decellerate! if self.THRUST: direction = sf.Vector2f(-sin(radians(self.angle)), cos(radians(self.angle))) self.momentum += 0.1 * direction speed = pow(self.momentum.x, 2) + pow(self.momentum.y, 2) if speed > 5: self.momentum *= 5 / speed elif self.BRAKE: self.momentum *= 0.9 self.loc += self.momentum self.boundLoc(mgr) # Shoot! If the key is held down, shoot once per 10 updates. if self.SHOOT and self.shootHeld == 0: self.shootHeld = 10 return bullet.Bullet(self.loc.copy(), self.angle) elif self.shootHeld > 0: self.shootHeld -= 1
def __init__(self): super(Level1, self).__init__() layer = core.Layer() self.add_layer(layer) self.im0 = sf.Texture.load_from_file(b'princess.png') for y in range(0, 501, 100): for x in range(0, 701, 100): s0 = sf.Sprite(self.im0) s0.position = (x, y) layer.add_actor(core.Actor(s0)) sprite = sf.Sprite(self.im0) sprite.position = 400, 300 sprite.origin = self.im0.width//2, self.im0.height//2 actor = core.Actor(sprite) actor.add_action(Mover(sf.Vector2f(0, -200))) layer.add_actor(actor) camera = game.default_camera camera.add_action(actions.CameraFollow(actor, True)) layer.add_camera(camera)
def draw(self): """Draw the entire game window.""" self.window.clear() self.window.view = sf.View.from_center_and_size(self.view_size / 2., self.view_size) if self.DEBUG: self.draw_FPS() # Draw the start screen. if self.state == 'start': text = sf.Text("Multitroids", self.FONT, 200) text.scale = sf.Vector2f(0.5, 0.5) text.position = sf.Vector2f(self.view_size.x / 2.0 - text.rect.width / 2.0, self.view_size.y / 2.0 - text.rect.height - 30) self.window.draw(text) text = sf.Text("Arrow keys to fly\nSpacebar to shoot and restart"+ "\n\n Press spacebar to begin", self.FONT, 60) text.scale = sf.Vector2f(0.5, 0.5) text.position = sf.Vector2f(self.view_size.x / 2.0 - text.rect.width / 2.0, self.view_size.y / 2.0 + text.rect.height / 2.0 - 30) self.window.draw(text) text = sf.Text("www.mattkeeter.com", self.FONT, 50) text.scale = sf.Vector2f(0.5, 0.5) text.position = sf.Vector2f(15, self.view_size.y - text.rect.height * 1.5) self.window.draw(text) self.window.display() return # Draw the end screen. elif self.state == 'win': text = sf.Text("YOU WIN", self.FONT, 160) text.scale = sf.Vector2f(0.5, 0.5) text.position = sf.Vector2f(self.view_size.x / 2.0 - text.rect.width / 2.0, self.view_size.y / 2.0 - text.rect.height) self.window.draw(text) text = sf.Text("Ships: %d" % len(self.players), self.FONT, 60) text.scale = sf.Vector2f(0.5, 0.5) text.position = sf.Vector2f(self.view_size.x / 2.0 - text.rect.width / 2.0, self.view_size.y / 2.0 + text.rect.height / 2.0) self.window.draw(text) text = sf.Text("Press spacebar to restart", self.FONT, 40) text.scale = sf.Vector2f(0.5, 0.5) text.position = sf.Vector2f(self.view_size.x / 2.0 - text.rect.width / 2.0, self.view_size.y / 2.0 + text.rect.height * 2.5) self.window.draw(text) self.window.display() return # Draw the rest of the game. for player in self.players: player.draw(self.window) [bullet.draw(self.window) for bullet in self.bullets] # Draw each asteroid at 8 positions, so that they wrap around cleanly. for offset in [sf.Vector2f(0, 0), sf.Vector2f(self.view_size.x, 0), sf.Vector2f(-self.view_size.x, 0), sf.Vector2f(0, self.view_size.y), sf.Vector2f(0, -self.view_size.y)]: [asteroid.draw(self.window, offset) for asteroid in self.asteroids] self.draw_HUD() self.window.display()
def mousePosition(self): pos = sf.Mouse.getPosition(self.engine.getRenderWindow()) return sf.Vector2f(pos.x, pos.y)
def entitySize(entity): """Compute an entity's size, taking in account its scale""" bounds, scale = entity.getLocalBounds(), entity.getScale() return sf.Vector2f(bounds.width * scale.x, bounds.height * scale.y)