class GameObject: def __init__(self, game, x, y, image): self.game = game self.x = x self.y = y self.sprite = Sprite(image, x=x, y=y, batch=self.game.batch, group=G_MAIN_0) def draw(self): self.sprite.draw() def early_update(self, dt): pass def update(self, dt): pass def late_update(self, dt): self.sprite.position = self.x, self.y def destroy(self): self.sprite.batch = None
class TemporaryEntity(Entity): defaults = { 'width': 48, 'height': 48, } attributes = { 'image_file': 'app/assets/corpse.png', 'chunk': None, 'timer': 60 } def init(self, **kwargs): self.image = load_image(self.image_file) self.sprite = Sprite(self.image, self.x, self.y, batch=self.batch, group=self.group) self.chunk.objects.append(self) clock.schedule_once(self.delete, self.timer) def delete(self, dt): if self in self.chunk.objects: self.chunk.objects.remove(self) self.sprite.delete() def update(self): pass def draw(self): self.sprite.draw()
class GameObject: def __init__(self, posx, posy, image, batch=None): self.in_opacity = False self.x_target = posx self.batch = batch self.begin = 255 self.opacity_target = 255 self.set_ok = False self.waiting = False if isinstance(image, str): self.sprite = Sprite(pyglet.image.load(f"res/{image}"), batch=self.batch) else: self.sprite = image self.sprite.x = posx self.sprite.y = posy self.opacity = self.sprite.opacity def draw(self): self.sprite.draw() def replace_bg(self, image): self.sprite = Sprite(pyglet.image.load(f"res/bg/{image}"), batch=self.batch) def update(self, dt): if not self.sprite.x == self.x_target: if ceil(self.sprite.x) < self.x_target: self.sprite.x += 150 * dt if ceil(self.sprite.x) == self.x_target or floor( self.sprite.x) == self.x_target: self.sprite.x = self.x_target self.set_ok = True if floor(self.sprite.x) > self.x_target: self.sprite.x -= 150 * dt if not self.sprite.opacity == self.opacity_target: if ceil(self.sprite.opacity) < self.opacity_target: self.sprite.opacity += 150 * dt if ceil(self.sprite.opacity) == self.opacity_target or floor( self.sprite.opacity) == self.opacity_target: self.sprite.opacity = self.opacity_target self.set_ok = True if floor(self.sprite.opacity) > self.opacity_target: self.sprite.opacity -= 150 * dt def set_opacity(self, opacity=255): self.sprite.opacity = opacity self.opacity_target = opacity def animate_opacity(self, opacity=255): self.begin = self.sprite.opacity self.opacity_target = opacity self.set_ok = False def animate_x(self, x): self.begin = self.sprite.x self.x_target = x self.set_ok = False
def _draw_overlay(self): pattern = SolidColorImagePattern((0, 0, 0, 200)) overlay_image = pattern.create_image(1000, 1000) overlay_image.anchor_x = overlay_image.width / 2 overlay_image.anchor_y = overlay_image.height / 2 overlay = Sprite(overlay_image, self.camera.x, self.camera.y) overlay.draw()
class PreviewWindow(BasePreview): colors = ((0, 0, 255), (255, 0, 0), (0, 255, 0), (0, 0, 255)) rotations = [0, 90, 180, 270] def __init__(self, runner): super().__init__(runner, width=512, height=512) tile = image('tile.png') tile.anchor_x = 32 tile.anchor_y = 32 self.sprite = Sprite(img=tile, x=0, y=0) def draw_tiles(self, pos, bits): if bits == 0: return x, y = pos[-2:] self.sprite.x = x * 64 + 32 self.sprite.y = self.height - y * 64 - 32 tiles = self.runner.model.get_allowed_tiles(bits) self.sprite.opacity = 255 / len(tiles) for tile in tiles: for direction, adj in enumerate(tile.adj): if adj < 1 or self.rotations[direction] == None: continue self.sprite.color = self.colors[adj] self.sprite.rotation = self.rotations[direction] self.sprite.draw() if self.debug: Label(str(bits), x=self.sprite.x, y=self.sprite.y).draw()
class Button(Rectangle): def __init__(self, x, y, width, height, image=None, caption=None, batch=None, group=None): super(Button, self).__init__(x, y, width, height) self.batch = batch self.group = group self.sprite = None self.label = None if image: self.sprite = Sprite(image.get_region(0, 0, self.width, self.height), batch=self.batch, group=self.group) if caption: self.label = Label(caption, font_name='Arial', font_size=12, anchor_x='center', anchor_y='center', color=(255, 255, 255, 255), batch=self.batch, group=self.group) self.set_position(x, y) def set_position(self, x, y): super(Button, self).set_position(x, y) if self.sprite: self.sprite.x, self.sprite.y = x, y if self.label: self.label.x, self.label.y = self.get_center() def draw(self): if self.sprite: self.sprite.draw() if self.label: self.label.draw()
class SpritePreviewWindow(BasePreview): def __init__(self, runner, tile_size): width = runner.model.world_shape[0] * tile_size height = runner.model.world_shape[1] * tile_size super().__init__(runner, width=width, height=height) self.sprite = Sprite(img=runner.model.tiles[0].image) self.tile_size = tile_size def draw_tiles(self, pos, bits): if bits == 0: return x, y = pos[-2:] self.sprite.x = x * self.tile_size + self.tile_size / 2 self.sprite.y = self.height - y * self.tile_size - self.tile_size / 2 tiles = self.runner.model.get_allowed_tiles(bits) self.sprite.opacity = 255 / len(tiles) for tile in tiles: tile.image.anchor_x = self.tile_size / 2 tile.image.anchor_y = self.tile_size / 2 self.sprite.image = tile.image self.sprite.rotation = tile.rotation * 90 self.sprite.draw() if self.debug: Label(str(bits), x=self.sprite.x, y=self.sprite.y).draw()
class Image(Widget): def __init__(self, x, y, image): self._size = win_width, win_height = get_size() self.sprite = Sprite(image, x, y) super().__init__(x, y, image.width, image.height) def draw(self): self.sprite.draw()
def _draw_action_menu(self): pattern = SolidColorImagePattern((0, 0, 150, 200)) overlay_image = pattern.create_image(1000, 200) overlay_image.anchor_x = overlay_image.width / 2 overlay_image.anchor_y = overlay_image.height + 100 overlay = Sprite(overlay_image, self.camera.x, self.camera.y) overlay.draw() self._generate_text()
class Game(Window): def __init__(self): """This is run when the game is created""" super(Game, self).__init__() # Create the sprites self.arch = Sprite(images['arch'], x=50, y=50) self.bullet = Sprite(images['bullet'], x=-50, y=-50) # A handler that watches the keyboard state self.keyboard = key.KeyStateHandler() self.set_handlers(self.keyboard) # Call update() 60 times a second clock.schedule_interval(self.update, 1/60.0) # Display the current FPS on screen self.fps_display = clock.ClockDisplay() def on_draw(self): """Clear the window, draw the sprites and display framerate""" self.clear() self.arch.draw() self.bullet.draw() self.fps_display.draw() def on_mouse_press(self, x, y, button, modifiers): """This is run when a mouse button is pressed""" if button == mouse.LEFT: print "The left mouse button was pressed." elif button == mouse.RIGHT: print "The right mouse button was pressed." def update(self, dt): """This is called on every update It uses the keyboard input to move the player at around 200 pixels per second""" if self.keyboard[key.RIGHT]: self.arch.x += dt * 200 if self.keyboard[key.LEFT]: self.arch.x -= dt * 200 if self.keyboard[key.UP]: self.arch.y += dt * 200 if self.keyboard[key.DOWN]: self.arch.y -= dt * 200 # Fire if spce bar pressed if self.keyboard[key.SPACE]: self.fire() def fire(self): print "Fire!"
def draw(self): Sprite.draw(self) self.life.draw() self.experience.draw() self.stat_boosted.draw() if (self.is_attacking): self.attack_sprite.update_self(player_x=self.x, player_y=self.y, direction=self.facing) self.attack_sprite.draw()
class HotBar(GUI): def __init__(self): width, height = get_size() GUI.__init__(self, width, height) self._index = 0 self._item = list() self._items = list() self._hotbar = Sprite( resource_pack.get_resource('textures/gui/widgets').get_region( 0, 234, 182, 22), x=(width - 364) / 2, y=2) self._select = Sprite( resource_pack.get_resource('textures/gui/widgets').get_region( 0, 210, 24, 24), x=(width - 364) / 2 + 40 * self._index - 2, y=0) self._hotbar.scale = 2 self._select.scale = 2 def draw(self): self._hotbar.draw() self._select.draw() for item in self._item: if item: item.draw() def set_all(self, items): width = get_size()[0] self._items = items self._item = list() for item in range(len(self._items)): if item <= 9: if self._items[item]: self._item.append( Sprite(get_block_icon(blocks[self._items[item]], 128), x=(width - 364) / 2 + 40 * item + 2, y=4)) self._item[item].scale = 40 / self._item[item].image.width else: self._item.append(None) else: return def set_index(self, index): width = get_size()[0] self._index = index self._select.position = ((width - 364) / 2 + 40 * self._index - 2, 0) def resize(self, width, height): self._hotbar.position = (width - 364) / 2, 2 self._select.position = (width - 364) / 2 + 40 * self._index - 2, 0 for i in range(len(self._item)): if self._item[i]: self._item[i].position = (width - 364) / 2 + 40 * i + 2, 4
class MusicPanel(Component): def __init__(self, uid: str, x: int, y: int, width: int, height: int, texture: AbstractImage, song_name: str = "", song_artist: str = ""): self.button_logger = logging.getLogger(__name__) Component.__init__(self, uid, x, y, width, height) self._song_data = {"song_name": song_name, "song_artist": song_artist} self._panel_texture = texture self._label_x = self._x + 85 self._name_label_y = self._y + 60 self._artist_label_y = self._y + 35 self.song_name_label = None self.song_artist_label = None self.music_panel_sprite = None self.load_labels() self.load_sprite() self.button_logger.debug("Music Panel Component initiated") def load_labels(self): self.song_name_label = Label(self._song_data["song_name"], font_size=20, font_name="Hydrophilia Iced", x=self._label_x, y=self._name_label_y, anchor_x="left", anchor_y="center") self.song_artist_label = Label(self._song_data["song_artist"], font_size=16, font_name="Hydrophilia Iced", x=self._label_x, y=self._artist_label_y, anchor_x="left", anchor_y="center") def load_sprite(self): self.music_panel_sprite = Sprite(self._panel_texture, self._x, self._y) def draw(self): self.music_panel_sprite.draw() self.song_name_label.draw() self.song_artist_label.draw()
def draw(self): if self.xpos > window.width / 2: self.x = window.width / 2 else: self.x = self.xpos if self.ypos > window.height / 2: self.y = window.height / 2 else: self.y = self.ypos Sprite.draw(self) self.goo_batch.draw()
class XPBar(GUI): def __init__(self): width, height = get_size() GUI.__init__(self, width, height) self._xpbar = Sprite(image.load(join(path['texture.gui'], 'icons.png')).get_region(0, 187, 182, 5), x=(width - 364) / 2, y=48) self._xpbar.scale_x = 2 self._xpbar.scale_y = 1.5 def draw(self): self._xpbar.draw() def resize(self, width, height): self._xpbar.position = (width - 364) / 2, 48
class XPBar(GUI): def __init__(self): width, height = get_size() GUI.__init__(self, width, height) self._xp_bar = Sprite(image.load( join(path['texture.ui'], 'xpbar_empty.png')), x=(width - 450) / 2, y=61) self._xp_bar.scale_y = 2 self._xp_bar.scale_x = 450 / 182 def draw(self): self._xp_bar.draw() def resize(self, width, height): self._xp_bar.position = (width - 450) / 2, 61
class StockLabelElement(pyglet.text.document.InlineElement): """Ammunition image representing first character of a StockLabel. Center of ammunition image will be vertically alligned with center of the StockLabel's text that follows it. """ def __init__(self, image: pyglet.image.Texture, separation=2): """ ++image++ Image representing ammunition type. ++separation++ distance between edge of image and subsequent text, in pixels. """ image = copy(image) image.anchor_x = 0 image.anchor_y = 0 self.image = image self.height = image.height super().__init__(ascent=0, descent=0, advance=image.width + separation) def place(self, layout, x: int, y: int): """Position ammunition image. +layout+ StockLabel object to which this StockLabelElement was inserted. Layout should have anchor_y set to 'bottom' and 'content_valign' set to 'center'. +x+ Left edge of box reserved for in-line element and in which ammunition image is to be positioned. +y+ Baseline level, on which layout text sits. """ # Defines y at level so center of in-line image alligns vertically # with center of subsequent text, for which requires: # layout.anchor_y is'bottom' and layout_content_valign is 'center' y = layout.y + (layout.content_height // 2) - (self.image.anchor_y + (self.height // 2)) self._sprite = Sprite(self.image, x, y, batch=layout.batch, group=layout.top_group) self._sprite.draw() def remove(self, layout): """Remove image from in-line element.""" self._sprite.delete()
class XPBar(GUI): def __init__(self): width, height = get_size() GUI.__init__(self, width, height) self._xpbar = Sprite( resource_pack.get_resource('textures/gui/icons').get_region( 0, 187, 182, 5), x=(width - 364) / 2, y=48) self._xpbar.scale_x = 2 self._xpbar.scale_y = 1.5 def draw(self): self._xpbar.draw() def resize(self, width, height): self._xpbar.position = (width - 364) / 2, 48
class Experience(): experience_bar = image.load('images/ExperienceBar.png') experience_bar.anchor_x = experience_bar.width // 2 experience_bar.anchor_y = experience_bar.height // 2 experience_green = image.load('images/Experience.png') experience_green.anchor_x = experience_green.width // 2 experience_green.anchor_y = experience_green.height // 2 def __init__(self, game_scale, backX, backY): self.startX = backX self.startY = backY self.bar = Sprite(img=Experience.experience_bar, x=backX + (930 * game_scale), y=backY + (940 * game_scale)) self.bar.scale = game_scale self.exp = Sprite(img=Experience.experience_green, x=backX + (930 * game_scale), y=backY + (940 * game_scale)) self.game_scale = game_scale self.exp.scale = 0 self.total_exp = 0 def draw(self): self.exp.draw() self.bar.draw() def add_exp(self, amount) -> int: self.total_exp = self.total_exp + amount amount_ups = 0 while (self.total_exp >= 100): self.total_exp = self.total_exp - 100 amount_ups = amount_ups + 1 self.exp.scale = (self.total_exp / 100) * self.game_scale return amount_ups def scale_experience(self, game_scale, x_offset): self.startX = x_offset self.bar.x = (self.bar.x * game_scale) + x_offset self.bar.y = (self.bar.y * game_scale) self.bar.scale = game_scale self.exp.x = (self.exp.x * game_scale) + x_offset self.exp.y = (self.exp.y * game_scale) self.game_scale = game_scale self.exp.scale = self.exp.scale * game_scale
class Pawn(object): def __init__(self, image): self._sprite = Sprite(image) self.position = None @property def opacity(self): return self._sprite.opacity @opacity.setter def opacity(self, value): self._sprite.opacity = value def render(self): self._sprite.draw() def set_position(self, position, offset): self.position = position self._sprite.x = position.x * STREET_GRID_SIZE + offset.x self._sprite.y = position.y * STREET_GRID_SIZE + offset.y
def draw_snake(self): if self.__alive: for block in self.__body: block_pic = Sprite(self.body_sprite, x=block[0] * BLOCK_SIZE[0], y=block[1] * BLOCK_SIZE[1]) block_pic.update(scale_x=SCALE_X, scale_y=SCALE_Y) block_pic.draw() if self.__direction == Side.west: head_sprite = self.head_sprites.w elif self.__direction == Side.north: head_sprite = self.head_sprites.n elif self.__direction == Side.south: head_sprite = self.head_sprites.s else: head_sprite = self.head_sprites.e head_pic = Sprite(head_sprite, x=self.__head[0] * BLOCK_SIZE[0], y=self.__head[1] * BLOCK_SIZE[1]) head_pic.update(scale_x=SCALE_X, scale_y=SCALE_Y) head_pic.draw()
class MainMenuFrame(frames.basicFrame): def __init__(self): frames.basicFrame.__init__(self) self.background = Sprite(assets.mainMenuBackground,0,0) self.background.scale = float(setting.SCREEN_HEIGHT) / self.background.height self.playButton = Sprite(assets.mainMenuPlay,0,0) self.optionsButton = Sprite(assets.mainMenuOptions,0,0) self.playButton.scale = self.optionsButton.scale = self.background.scale self.optionsButton.tx = self.optionsButton.x = self.playButton.x = self.playButton.tx = 1385 * self.playButton.scale self.playButton.ty = 520 * self.playButton.scale self.playButton.y = self.playButton.ty + 2000 self.optionsButton.ty = 300 * self.optionsButton.scale self.optionsButton.y = self.optionsButton.y + 1000 def update(self): self.playButton.x += (self.playButton.tx - self.playButton.x)/10 if (abs(self.playButton.x - eventManager.mouse.position.x)<self.playButton.width/2): self.playButton.y += (self.playButton.ty + (self.playButton.ty - eventManager.mouse.position.y)**3/80000.0 - self.playButton.y)/10 self.optionsButton.y += (self.optionsButton.ty + (self.optionsButton.ty - eventManager.mouse.position.y)**3/80000.0 - self.optionsButton.y)/10 else: self.playButton.y += (self.playButton.ty - self.playButton.y)/10 self.optionsButton.y += (self.optionsButton.ty - self.optionsButton.y)/10 self.optionsButton.x += (self.optionsButton.tx - self.optionsButton.x)/10 #check if play button pressed for event in eventManager.lastEvents: if (event.type == "mousedown" and event.value == 0): if (eventManager.mouse.position.withinRect(self.playButton,self.playButton.width,self.playButton.height)): frameController.add("game",GameFrame(GameData())) frameController.rem("main") self.finished = 1 def draw(self): self.background.draw() self.playButton.draw() self.optionsButton.draw()
class Goal(object): def __init__(self, pos): self._sprite = Sprite(FLOORTARGET_IMAGE) self._pos = pos self._sprite.opacity = FLOORTARGET_OPACITY @property def pos(self): return self._pos @pos.setter def pos(self, value): self._pos = value offset = Vector(self._sprite.width / 2, self._sprite.height / 2) pos = value * STREET_GRID_SIZE - offset self._sprite.set_position(pos.x, pos.y) def render(self): self._sprite.draw() def on_goal(self, position): distance = position - self._pos return distance.length2 < FLOORTARGET_RANGE ** 2
def draw(self): Sprite.draw(self)
class Window(pyglet.window.Window): def __init__(self, *args, **kwargs): super(Window, self).__init__(*args, **kwargs) self.score = 0 self.difficulty = self.score + 50 self.lives = 3 self.time = 0.5 self.ships = pyglet.graphics.Batch() self.rocks = pyglet.graphics.Batch() self.missiles = pyglet.graphics.Batch() self.started = False self.rock_trigger = 0 # Images self.background = pyglet.image.load('static/images/nebula_blue.s2014.png') self.rock_img = pyglet.image.load('static/images/asteroid_blue.png') utils.center_image_anchor(self.rock_img) ship_sequence = pyglet.image.load('static/images/double_ship.png') self.ship_imgs = pyglet.image.ImageGrid(ship_sequence, 1, 2) utils.center_image_grid_anchors(self.ship_imgs) self.splash_img = pyglet.image.load('static/images/splash.png') # Sounds self.thruster_snd = pyglet.media.load('static/sounds/rocket.ogg', streaming=False) self.explosion_snd = pyglet.media.load('static/sounds/explosion.ogg', streaming=False) self.background_music = pyglet.media.load('static/sounds/space1.mp3', streaming=False) self.background_music.play() # Sprite Groups self.rock_group = set() self.missile_group = set() # Spites self.ship = PlayerSprite(self.ship_imgs, self.thruster_snd, 400, 250, 0, 0, 270, 35, self.ships, self.missiles) self.splash = Sprite(self.splash_img, 200, 125) # Screen Text self.text_lives = pyglet.text.Label('Lives=' + str(self.lives), font_name='Times New Roman', font_size=36, x=10, y=10) self.text_score = pyglet.text.Label('Score=' + str(self.score), font_name='Times New Roman', font_size=36, x=10, y=60) # Keymaps self.key_downs = {key.UP:self.accel, key.LEFT:self.left, key.RIGHT:self.right, key.SPACE:self.fire, key.ESCAPE:pyglet.app.exit} self.key_ups = {key.UP:self.decel, key.LEFT:self.right, key.RIGHT:self.left} pyglet.clock.schedule_interval(self.update, 1/60.0) # update at 60Hz def game_reset(self): self.started = False self.rock_group = set() self.ship = PlayerSprite(self.ship_imgs, self.thruster_snd, 400, 250, 0, 0, 270, 35, self.ships, self.missiles) self.lives = 3 self.score = 0 # intro screen # self.splash.draw() def display_score(self): self.text_lives = pyglet.text.Label('Lives=' + str(self.lives), font_name='Times New Roman', font_size=36, x=10, y=10) self.text_score = pyglet.text.Label('Score=' + str(self.score), font_name='Times New Roman', font_size=36, x=10, y=60) def start_game(self): #Function to start game on initial mouse click self.splash.delete() self.started = True def accel(self): self.ship.thrusters = True def decel(self): self.ship.thrusters = False def left(self): self.ship.angle_vel -= 5 def right(self): self.ship.angle_vel += 5 def fire(self): self.ship.shoot(self.missile_group) def on_mouse_press(self, x, y, button, modifiers): self.start_game() def on_key_press(self, symbol, modifiers): for key in self.key_downs: if key == symbol: self.key_downs[symbol]() def on_key_release(self, symbol, modifiers): for key in self.key_ups: if key == symbol: self.key_ups[symbol]() def put_rock(self): rock_position = utils.random_position(WIDTH, HEIGHT) rock = MovingSprite (self.rock_img, rock_position[0], rock_position[1], sound=self.explosion_snd, diff=self.difficulty, radius=40, batch=self.rocks) self.rock_group.add(rock) def trigger_put_rock(self): self.rock_trigger += 1 if self.rock_trigger > 60 and len(self.rock_group) < 10: self.put_rock() self.rock_trigger = 0 # TODO Implement Sheilds def on_draw(self): self.clear() self.background.blit(0, 0) self.ships.draw() self.rocks.draw() self.missiles.draw() self.text_lives.draw() self.text_score.draw() if not self.started: self.splash = Sprite(self.splash_img, 200, 125) self.splash.draw() def update(self, dt): if self.started: self.trigger_put_rock() for rock in self.rock_group: rock.update(WIDTH, HEIGHT) self.ship.update(WIDTH, HEIGHT) local_missiles = set(self.missile_group) for missile in local_missiles: if not missile.update(WIDTH, HEIGHT): self.missile_group.remove(missile) missile.delete() if group_collide(self.rock_group, self.ship): self.lives -= 1 self.explosion_snd.play() if group_group_collide(self.missile_group, self.rock_group): self.score += 10 self.difficulty += self.score + 50 self.explosion_snd.play() self.display_score() if self.lives < 0: self.game_reset()
class Character(object): def __init__(self, x, y, facing=Direction.NORTH): self.sprite = Sprite(self.Sprite.faces[facing], x, y) self.facing = facing self.movement_queue = [] self.movement_ticks = 0 self.current_health = self.health def draw(self): self.sprite.draw() def delete(self): self.sprite.delete() @property def x(self): return self.sprite.x @x.setter def x(self, nx): self.sprite.x = nx @property def y(self): return self.sprite.y @y.setter def y(self, ny): self.sprite.y = ny @property def color(self): return self.sprite.color @color.setter def color(self, ncolor): self.sprite.color = ncolor def look(self, direction): self.facing = direction self.sprite.image = self.Sprite.faces[direction] def move_to(self, x, y, duration=1): self.movement_queue.append((x, y, duration)) def update(self, dt): if self.movement_queue: if self.movement_ticks == 0: self.last_stop = self.x, self.y ex, ey, time = self.movement_queue[0] sx, sy = self.last_stop if ex < sx and ey < sy: self.look(Direction.WEST) elif ex < sx: self.look(Direction.NORTH) elif ey < sy: self.look(Direction.SOUTH) else: self.look(Direction.EAST) self.movement_ticks += dt ex, ey, time = self.movement_queue[0] sx, sy = self.last_stop self.x += (ex - sx) * (dt / time) self.y += (ey - sy) * (dt / time) if self.movement_ticks >= time: self.x, self.y = int(ex), int(ey) del self.movement_queue[0] self.movement_ticks = 0 else: self.look(self.facing) class Sprite(namedtuple("CharacterSprite", "x y facing moving_to internal_clock")): # # @property # def image(self): # return self.faces[self.facing] # # def update(self, dt): # return self.__class__(self.x, self.y, self.facing, self.moving_to, self.internal_clock + dt) # # def move(self, new_x, new_y): pass
class GameWindow(pyglet.window.Window): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.set_location(400, 100) self.frame_rate = 1/60.0 area_image = preload_image('area.png') self.area_spr = Sprite(area_image, x=190, y=190) player_image = preload_image('tanks.png') self.player = PlayerObject(200, 200, Sprite(player_image), 0.1) self.enemy_image = preload_image('enemy.png') self.enemy_list = [] self.enemy_list.append(PlayerObject(320, 320, Sprite(self.enemy_image), 0.1)) self.bullet_image = preload_image('bullet.png') self.bullet_list = [] brick_image = preload_image('brick.png') brick_spr = pyglet.sprite.Sprite(brick_image) self.brick_list = [] for i in range(0, 13): for j in range(0, 13): if mapConfiguration[i][j] == 1: posx = 200 + j*40 posy = 680 - i*40 self.brick_list.append(BrickObject(posx, posy, Sprite(brick_image), scale=0.2)) self.brick_destroyed_label = Label('Brick destroyed', x=1000, y=850) self.brick_destroyed_label.italic = True self.brick_destroyed_label.bold = True self.brick_destroyed_number_label = Label('0', x=1000, y=750) self.brick_destroyed_number_label.italic = True self.brick_destroyed_number_label.bold = True self.brick_destroyed_number = 0 self.enemy_destroyed_label = Label('Enemy destroyed', x = 1000, y=650) self.enemy_destroyed_label.italic = True self.enemy_destroyed_label.bold = True self.enemy_destroyed_number_label = Label('0', x=1000, y=550) self.enemy_destroyed_number_label.italic = True self.enemy_destroyed_number_label.bold = True self.enemy_destroyed_number = 0 def player_move_to(self, posx, posy): for brick in self.brick_list: if posx == brick.posx_center and posy == brick.posy_center: return False for enemy in self.enemy_list: if posx == enemy.posx_center and posy == enemy.posy_center: return False return True def player_move(self, symbol): if symbol == key.LEFT and self.player.sprite.x > 200 + 40 \ and self.player_move_to(self.player.posx_center-40.0, self.player.posy_center): self.player.sprite.x -= 40 self.player.posx_center -= 40 if symbol == key.RIGHT and self.player.sprite.x < 720 - 40 \ and self.player_move_to(self.player.posx_center+40.0, self.player.posy_center): self.player.sprite.x += 40 self.player.posx_center += 40 if symbol == key.UP and self.player.sprite.y < 720 - 40 \ and self.player_move_to(self.player.posx_center, self.player.posy_center+40.0): self.player.sprite.y += 40 self.player.posy_center += 40 if symbol == key.DOWN and self.player.sprite.y > 200 + 40 \ and self.player_move_to(self.player.posx_center, self.player.posy_center-40.0): self.player.sprite.y -= 40 self.player.posy_center -= 40 self.player.posx = self.player.sprite.x self.player.posy = self.player.sprite.y def on_key_press(self, symbol, midifiers): if symbol == key.SPACE: if self.player.up_rotation: self.bullet_list.append(BulletObject(self.player.posx, self.player.posy, Sprite(self.bullet_image), scale=0.1, rotation='up')) elif self.player.right_rotation: self.bullet_list.append(BulletObject(self.player.posx, self.player.posy, Sprite(self.bullet_image), scale=0.1, rotation='right')) elif self.player.left_rotation: self.bullet_list.append(BulletObject(self.player.posx, self.player.posy, Sprite(self.bullet_image), scale=0.1, rotation='left')) elif self.player.down_rotation: self.bullet_list.append(BulletObject(self.player.posx, self.player.posy, Sprite(self.bullet_image), scale=0.1, rotation='down')) if not self.player.rotation(symbol): self.player_move(symbol) def on_draw(self): self.clear() self.area_spr.draw() self.player.draw() for enemy in self.enemy_list: enemy.draw() for bullet in self.bullet_list: bullet.draw() for brick in self.brick_list: brick.draw() self.brick_destroyed_label.draw() self.brick_destroyed_number_label.draw() self.enemy_destroyed_label.draw() self.enemy_destroyed_number_label.draw() def update_player(self, dt): self.player.update() def update_player_bullet(self, dt): for bullet in self.bullet_list: bullet.update(dt) bullet.move(dt) for brick in self.brick_list: if bullet.check_collision(brick): self.bullet_list.remove(bullet) self.brick_list.remove(brick) self.brick_destroyed_number += 1 self.brick_destroyed_number_label.text = str(self.brick_destroyed_number) for enemy in self.enemy_list: if bullet.check_collision(enemy): self.enemy_list.remove(enemy) self.bullet_list.remove(bullet) self.enemy_destroyed_number += 1 self.enemy_destroyed_number_label.text = str(self.enemy_destroyed_number) def update(self, dt): self.update_player_bullet(dt) pass
class GameWindow(pyglet.window.Window): def __init__(self, *args, **kwargs): # Refers to pyglet.window.Window super().__init__(*args, **kwargs) # set the window's location at a certain point, x-pos, y-pos self.set_location(400, 100) # set the window's frame-rate, this is 60.0 fps self.frame_rate = 1 / 60.0 # Screen or Window is self. self.fps_display = FPSDisplay(self) # Make fps display bigger. self.fps_display.label.font_size = 25 # Preload the background self.car_background = Sprite(preload_image('CarGameBackground.jpg')) # Preload the car car = preload_image('carFIXED.png') # Center the car's rotation at its center. center_image(car) # Transfer car to a sprite sprite_car = pyglet.sprite.Sprite(car) self.rotation = 0 self.car_acceleration = 0 self.car_max_acceleration = 300 self.car_max_velocity = 300 # Initial sprite position, rotation, image self.car = GameObject(135, 425, self.rotation, sprite_car) self.car_vector_position = Vector2(self.car.position_x, self.car.position_y) self.car_vector_velocity = Vector2(0, 0) # Two New Objects that are Circles. self.circle = CircleLines(200, 690, 288) self.circle2 = CircleLines2(200, 581, 227) # Death Counter self.death_counter = 0 # Keys self.right = False self.left = False self.forward = False self.back = False # KEY PRESS def on_key_press(self, symbol, modifiers): if symbol == key.RIGHT: self.right = True if symbol == key.LEFT: self.left = True if symbol == key.UP: self.forward = True if symbol == key.DOWN: self.back = True # Exit Window/Application if symbol == key.ESCAPE: pyglet.app.exit() # KEY RELEASE def on_key_release(self, symbol, modifiers): if symbol == key.RIGHT: self.right = False if symbol == key.LEFT: self.left = False if symbol == key.UP: self.forward = False if symbol == key.DOWN: self.back = False # Draw on Window def on_draw(self): death_label = pyglet.text.Label(str(int(self.death_counter)), font_name='Times New Roman', font_size=36, x=1500, y=800, anchor_x='center', anchor_y='center') # Check Collisions and position self.check_position() # Step 0: Clear the area. self.clear() # Step 1: Draw the background before the car. self.car_background.draw() # Step 2: Draw the Sprite. from GameObject, there's a method called draw. self.car.draw() # Outer self.circle.draw() # Inner self.circle2.draw() # Step 3: Draw on display FPS self.fps_display.draw() # Step 4: Draw the death counter death_label.draw() def update_car(self, dt): self.check_collision() self.car.update() self.car_acceleration = 50 if self.forward: self.check_velocity() self.check_acceleration() self.change_velocity(self.car_acceleration, dt) self.change_position(dt) if not self.forward: self.check_velocity() self.check_acceleration() self.change_velocity_negative(self.car_acceleration, dt) self.change_position(dt) if self.left: self.car.rotation -= 2 if self.right: self.car.rotation += 2 if self.back: self.brake_car(self.car_acceleration, dt) self.check_rotation() def brake_car(self, acceleration, dt): self.car_vector_velocity -= (acceleration * dt * 5, 0) def check_acceleration(self): if self.car_acceleration >= self.car_max_acceleration: self.car_acceleration = self.car_max_acceleration if self.car_acceleration <= 0: self.car_acceleration = 0 def change_position(self, dt): # Figure out what is going on with the math here. self.car_vector_position += self.car_vector_velocity.rotate( -self.car.rotation) * dt self.car.position_x, self.car.position_y = self.car_vector_position def check_collision(self): # Pythagorean Theorem def get_distance(x1, y1, x2, y2): xDistance = x2 - x1 yDistance = y2 - y1 return math.floor( math.sqrt(math.pow(xDistance, 2) + math.pow(yDistance, 2))) # Reset Position and Velocity # Enumerates through two lists at the same time, and compares the positions through each sharing index. def reset_position_velocity(circleX, circleY): for i, number_x in enumerate(circleX): number_y = circleY[i] distance_from_wall = get_distance(self.car.position_x, self.car.position_y, number_x, number_y) # Check this number to see how well it works with AI if distance_from_wall < 7.0: self.car_vector_position = [135, 450] self.car_vector_velocity = [0, 0] self.death_counter += 1 reset_position_velocity(self.circle.vertices_x, self.circle.vertices_y) reset_position_velocity(self.circle2.vertices_x, self.circle2.vertices_y) def check_position(self): if self.car.position_x < 0: self.car.position_x = 0 if self.car.position_x > 1600: self.car.position_x = 1600 if self.car.position_y > 900: self.car.position_y = 900 if self.car.position_y < 0: self.car.position_y = 0 def change_velocity(self, acceleration, dt): self.car_vector_velocity += (acceleration * dt, 0) def change_velocity_negative(self, acceleration, dt): if self.car_vector_velocity != [0, 0]: self.car_vector_velocity -= (acceleration * dt, 0) def check_velocity(self): self.car_vector_velocity_x, self.car_vector_velocity_y = self.car_vector_velocity if self.car_vector_velocity_x < 0: self.car_vector_velocity_x = 0 if self.car_vector_velocity_y < 0: self.car_vector_velocity_y = 0 if self.car_vector_velocity_x > self.car_max_velocity: self.car_vector_velocity_x = self.car_max_velocity if self.car_vector_velocity_y > self.car_max_velocity: self.car_vector_velocity_y = self.car_max_velocity self.car_vector_velocity = Vector2(self.car_vector_velocity_x, self.car_vector_velocity_y) def check_rotation(self): # Reset rotation degrees so that it doesn't go to a billion. if self.car.rotation == 360 or self.car.rotation == -360: self.car.rotation = 0 def update(self, dt): # Update car in order of Delta Time self.update_car(dt)
class GameInterface(Interface): attack: AttackPattern = None aii: ArrayInterfaceImage = None background_sprite: Sprite = None batch: Batch = None border: Rectangle = None enemy: Enemy = None image = None facecam: Facecam = None face_cascade = None foreground_sprite: Sprite = None fps_display: FPSDisplay = None keys = key.KeyStateHandler() player: Player = None projectiles: List[Projectile] = [] powerup: Powerup = None scheduled_functions = tuple() def __init__(self): super().__init__() window = system.get_window() gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) base_path = os.path.join('images', 'space_background_pack', 'layers') self.background = load(os.path.join(base_path, 'parallax-space-background.png')) self.background_sprite = Sprite(self.background) big_planet = load(os.path.join(base_path, 'parallax-space-big-planet.png')) self.big_planet_sprite = Sprite(big_planet) far_planet = load(os.path.join(base_path, 'parallax-space-far-planets.png')) self.far_planet_sprite = Sprite(far_planet) ring_planet = load(os.path.join(base_path, 'parallax-space-ring-planet.png')) self.ring_planet_sprite = Sprite(ring_planet) self.ring_planet_sprite.x = 100 self.ring_planet_sprite.y = 100 stars = load(os.path.join(base_path, 'parallax-space-stars.png')) self.stars_sprite = Sprite(stars) self.scheduled_functions = ( (self.randomize_projectiles, 2), (self.check_direction, 1 / 120), (self.generate_powerup, 20) ) if config.get_config('control') == 1: self.face_cascade = cv.CascadeClassifier( 'venv/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml') self.facecam = Facecam(face_cascade=self.face_cascade).start() self.aii = ArrayInterfaceImage(self.facecam.read(), 'BGR') self.image = self.aii.texture @self.facecam.event('on_face_move') def follow_face(x, y, width, height): # Need to flip things first to work x = self.image.width - x y = self.image.height - y new_x = self.border.x + x - width // 2 new_y = self.border.y + y - height // 2 self.player.move(new_x, new_y) self.scheduled_functions = ( (self.randomize_projectiles, 2), (self.generate_powerup, 20), ) window.push_handlers(self.facecam) self.player = Player(src='images/ufo.png') self.border = Rectangle( width=(500 if not self.image else self.image.width) + 10, height=(500 if not self.image else self.image.height) + 10, color=(0, 0, 0, 127) ) self.player.scale = 1.2 self.batch = Batch() self.projectiles: List[Projectile] = [] window.push_handlers(self.keys) def pause_game(symbol, modifiers): if symbol == key.ESCAPE: self.enemy.running = not self.enemy.running self.enemy.attack_pattern.running = not self.enemy.attack_pattern.running self.player.running = not self.player.running window.on_key_press = pause_game for func, interval in self.scheduled_functions: clock.schedule_interval(func, interval) self.fps_display = FPSDisplay(window) self.generate_enemy(0) self.resize() def generate_enemy(self, dt): enemy_index = config.get_config('enemy') if enemy_index > len(enemies) - 1: return system.get_window().load_interface(WinInterface()) window = system.get_window() self.enemy = enemies[enemy_index](self.batch, speed=100) self.enemy.move(window.width * 0.8, window.height / 2) self.enemy.next_x, self.enemy.next_y = self.enemy.x, self.enemy.y def on_die(): config.set_config('enemy', config.get_config('enemy') + 1) clock.schedule_once(self.generate_enemy, 2) self.enemy.on_die = on_die def resize(self): window = system.get_window() scale = window.width / self.background.width self.background_sprite.scale = scale self.big_planet_sprite.scale = scale / 2 self.far_planet_sprite.scale = scale / 2 self.ring_planet_sprite.scale = scale / 2 self.stars_sprite.scale = scale self.big_planet_sprite.x = window.width / 2 self.big_planet_sprite.y = window.height / 2 self.far_planet_sprite.x = window.width - self.far_planet_sprite.width self.far_planet_sprite.y = window.height - self.far_planet_sprite.height if self.image: self.image.x = (window.width - self.image.width) / 2 self.image.y = (window.height - self.image.height) / 2 self.border.x = window.width / 2 * 0.3 self.border.y = (window.height - self.border.height) / 2 self.generate_powerup(0) self.player.move(x=window.width / 2 * 0.3, y=window.height / 2) def on_draw(self): self.animate_background() self.background_sprite.draw() self.big_planet_sprite.draw() self.far_planet_sprite.draw() self.ring_planet_sprite.draw() self.stars_sprite.draw() self.border.draw() if self.facecam: img = self.facecam.read() img = cv.flip(img, -1) self.image.blit(self.border.x, self.border.y, 0) self.aii.view_new_array(img) # self.fps_display.draw() self.player.draw() self.batch.draw() # self.attack.draw() if self.enemy: self.enemy.draw() if self.powerup: self.powerup.forward() self.powerup.draw() if self.player.check_for_collision(self.powerup): self.powerup.on_collide(self.player) self.powerup.delete() self.powerup = None def animate_background(self): big_planet_sprite_depth = 3 far_planet_sprite_depth = 10 ring_planet_sprite_depth = 5 stars_sprite_depth = 8 window = system.get_window() self.big_planet_sprite.x = self.big_planet_sprite.x - 1 * (1 / big_planet_sprite_depth) if self.big_planet_sprite.x + self.big_planet_sprite.width <= 0: self.big_planet_sprite.x = window.width self.far_planet_sprite.x = self.far_planet_sprite.x - 1 * (1 / far_planet_sprite_depth) if self.far_planet_sprite.x + self.far_planet_sprite.width <= 0: self.far_planet_sprite.x = window.width self.ring_planet_sprite.x = self.ring_planet_sprite.x - 1 * (1 / ring_planet_sprite_depth) if self.ring_planet_sprite.x + self.ring_planet_sprite.width <= 0: self.ring_planet_sprite.x = window.width self.stars_sprite.x = self.stars_sprite.x - 1 * (1 / stars_sprite_depth) if self.stars_sprite.x + self.stars_sprite.width <= 0: self.stars_sprite.x = window.width def generate_powerup(self, dt): window = system.get_window() # roll = random.randint(1, 10) roll = 1 if roll <= 3: # 30% chance of getting a powerup powerup = random.choice(powerups)(batch=self.batch) x = random.randint(int(self.border.x), int(self.border.x + self.border.width)) powerup.move(x=x, y=window.height) @powerup.movement def movement(): powerup.move(powerup.x, powerup.y - powerup.calculate_speed()) self.powerup = powerup def randomize_projectiles(self, dt): if self.enemy: self.enemy.attack_pattern.generate() def check_direction(self, dt): unit = 500 * dt if self.keys[key.DOWN]: if self.player.get_bot_bound() - unit >= self.border.y: self.player.move(self.player.x, self.player.y - unit) elif self.keys[key.UP]: if self.player.get_bot_bound() + self.player.height + unit <= self.border.y + self.border.height: self.player.move(self.player.x, self.player.y + unit) # self.player.y += unit if self.keys[key.LEFT]: if self.player.get_left_bound() - unit >= self.border.x: self.player.move(self.player.x - unit, self.player.y) elif self.keys[key.RIGHT]: if self.player.get_left_bound() + self.player.width + unit <= self.border.x + self.border.width: self.player.move(self.player.x + unit, self.player.y) # if self.keys[key.ESCAPE]: # fg_ratio = 0.4 # bg_ratio = 0.1 # self.foreground_sprite.x = (window.width * (1 + fg_ratio)) / 2 - self.player.x * fg_ratio # self.foreground_sprite.y = (window.height * (1 + fg_ratio)) / 2 - self.player.y * fg_ratio # self.background_sprite.x = (window.width * (1 + bg_ratio)) / 2 - self.player.x * bg_ratio # self.background_sprite.y = (window.height * (1 + bg_ratio)) / 2 - self.player.y * bg_ratio def clean(self): self.enemy.clean() if self.facecam: self.facecam.clean() print(f'Deleting {self}') super().clean()
def draw(self): self.rarity_img.draw() Sprite.draw(self) if (self.durability != self.durability_max): self.cracks.draw()
class HotBar(GUI): def __init__(self): width, height = get_size() GUI.__init__(self, width, height) self._element = [] self._items = [] self._item = [] self.start = Sprite(image.load( join(path['texture.ui'], 'hotbar_start.png')), x=(width - 450) / 2 - 2, y=0) self.start.scale = 2.5 self.end = Sprite(image.load(join(path['texture.ui'], 'hotbar_end.png')), x=(width - 450) / 2 + 450, y=0) self.end.scale = 2.5 for i in range(9): self._element.append( Sprite(image.load(join(path['texture.ui'], 'hotbar_%d.png' % i)), x=(width - 450) / 2 + 50 * i, y=0)) self._element[i].scale = 2.5 self.set_index(0) def draw(self): self.start.draw() self.end.draw() for i in range(len(self._element)): if i != self.index: self._element[i].draw() else: self._element[self.index].draw() for i in range(len(self._item)): self._item[i].draw() def set_all(self, items): width = get_size()[0] self._items = items for item in range(len(self._items)): if item <= len(self._element): self._item.append( Sprite(get_block_icon(blocks[self._items[item]], 64), x=(width - 450) / 2 + 50 * item + 1, y=3)) self._item[item].scale = 48 / self._item[item].image.width else: return def set_index(self, index): width = get_size()[0] for i in range(len(self._element)): self._element[i] = Sprite(image.load( join(path['texture.ui'], 'hotbar_%d.png' % i)), x=(width - 450) / 2 + 50 * i, y=0) self._element[i].scale = 2.5 if 0 <= index < len(self._element): self._element[index] = Sprite(image.load( join(path['texture.ui'], 'hotbar_highlight.png')), x=(width - 450) / 2 + 50 * index - 5, y=-3) self._element[index].scale = 2.5 self.index = index def resize(self, width, height): self.start.position = (width - 450) / 2 - 2, 0 self.end.position = (width - 450) / 2 + 450, 0 for i in range(len(self._element)): if i != self.index: self._element[i].position = (width - 450) / 2 + 50 * i, 0 else: self._element[i].position = (width - 450) / 2 + 50 * i - 5, -3 for i in range(len(self._item)): self._item[i].position = (width - 450) / 2 + 50 * i + 1, 3
class Editor(object): def __init__(self, game, world): self.game = game self.window = game.window self.world = world self.squid = world.squid self.slots = self.squid.slots self.background = Sprite(loader.image('data/sprites/editor-bg.png')) #self.squid.attachments[0].selected = True self.editor = None self.scroll_state = 0 self.bubble = None self.hud = EditorHud(self.squid, max_money=world.money) def update(self, dt): if self.editor: if self.editor.component not in self.slots.components: self.editor = None def draw(self): self.background.draw() if self.editor: self.squid.draw_selected(editor=self.editor) else: self.squid.draw() self.hud.draw() if self.bubble: self.bubble.draw() def get_handlers(self): return { 'on_draw': self.draw, 'on_mouse_press': self.on_mouse_press, 'on_mouse_scroll': self.on_mouse_scroll, 'on_mouse_release': self.on_mouse_release, 'on_mouse_drag': self.on_mouse_drag, 'on_mouse_motion': self.on_mouse_motion } def set_editor(self, editor): if self.editor: self.window.pop_handlers() self.editor = editor if editor: self.window.push_handlers(**editor.get_handlers()) def clear_editor(self): if self.editor: self.window.pop_handlers() self.editor = None def start(self): self.squid.reset(position=(255, 145)) self.hud = EditorHud(self.squid, max_money=self.world.money) def stop(self): self.clear_editor() def on_mouse_press(self, x, y, button, modifiers): if x > SCREEN_SIZE[0] - self.hud.tile_size.x - 10: self.clear_editor() self.scroll_state = 1 self.scroll_start = v(x, y) else: self.scroll_state = 0 if not self.editor: self.find_editor(x, y) if self.editor: return self.editor.on_mouse_press(x, y, button, modifiers) return EVENT_HANDLED def on_mouse_motion(self, x, y, dx, dy): mpos = v(x, y) for b in self.buttons(): if b.tooltip and mpos in b.rect: self.bubble = SpeechBubble((90, 223), text=b.tooltip, width=300) break else: self.bubble = None def on_mouse_scroll(self, x, y, scroll_x, scroll_y): if x > SCREEN_SIZE[0] - self.hud.tile_size.x - 10: self.hud.scroll_rows(scroll_y) return EVENT_HANDLED def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): if not self.scroll_state: return if self.scroll_state == 2: self.hud.scroll_by(-dy) return EVENT_HANDLED p = v(x, y) - self.scroll_start if p.length2 > 64: self.scroll_state = 2 self.hud.scroll_by(-p.y) return EVENT_HANDLED def on_mouse_release(self, x, y, button, modifiers): if self.scroll_state == 2: self.scroll_state = 0 return EVENT_HANDLED mpos = v(x, y) if not self.editor: for b in self.buttons(): if mpos in b.rect: b.callback() return else: self.find_editor(x, y) def buttons(self): from .editor_hud import Button return list(self.hud.buttons()) + [ Button(self.hud.startbutton.rect, self.game.start_game, 'You are ready to fly already?') ] def find_editor(self, x, y): mpos = v(x, y) closest_dist = 1000 closest = None for a in self.slots.components: r = min(a.radius(), 70) dist = (a.position - mpos).length if dist < r and dist < closest_dist: closest = a closest_dist = dist if closest: self.set_editor(closest.editor()) else: self.clear_editor()
def draw(sprite: Sprite): sprite.draw()
class GarbageCan: def __init__(self): self.image_opened = image.load(data_file('garbagecan-open.png')) self.image_closed = image.load(data_file('garbagecan-closed.png')) self.image_lid = image.load(data_file('garbagecan-lid.png')) self.image_opened.anchor_x = self.image_opened.width/2 self.image_opened.anchor_y = self.image_opened.height/2 self.image_closed.anchor_x = self.image_opened.width/2 self.image_closed.anchor_y = self.image_opened.height/2 self.candidateLeaves = {} self.opened = True self.lid_active = False self.can_active = False self.fallen = False self.can_highlighted = False self.lid_highlighted = True self.can_rect = Rect(0, 0, self.image_closed) self.can_rect.center = (80, 90) self.can_sprite = Sprite(self.image_opened) self.can_sprite.set_position(self.can_rect.x, self.can_rect.y) self.lid_rect = Rect(20, 40, self.image_lid) window.game_window.push_handlers(self.on_mouse_release) window.game_window.push_handlers(self.on_mouse_press) window.game_window.push_handlers(self.on_mouse_drag) window.game_window.push_handlers(self.on_mouse_motion) events.AddListener(self) def update(self, timechange): pass def draw(self): if not self.can_active: if self.can_highlighted: self.can_sprite.color = (255, 20, 25) else: self.can_sprite.color = (255, 255, 255) else: self.can_sprite.color = (255, 255, 255) self.can_sprite.draw() glColor4f(1, 1, 1, 1) if not self.lid_active: if self.lid_highlighted: glColor4f(1, 0.1, 0.1, 1) else: glColor4f(1, 1, 1, 1) if self.opened: self.image_lid.blit(*self.lid_rect.bottomleft) glColor4f(1, 1, 1, 1) def on_mouse_press(self, x, y, button, modifiers): if self.opened and self.lid_rect.collide_point(x, y): self.set_lid_active() elif self.collides(x, y): self.fallen = False self.set_can_active() self.can_sprite.rotation = 0 if self.opened: self.can_sprite.image = self.image_opened else: self.can_sprite.image = self.image_closed def set_can_active(self): window.game_window.set_mouse_visible(False) self.can_active = True events.Fire('CanTaken') def set_lid_active(self): window.game_window.set_mouse_visible(False) self.lid_active = True events.Fire('LidTaken') def collides(self, x,y): cs = self.can_sprite return (x > cs.x - cs.image.width/2 and x < cs.x + cs.image.width/2 and y > cs.y - cs.image.height/2 and y < cs.y + cs.image.height/2 ) def on_mouse_release(self, x, y, button, modifiers): window.game_window.set_mouse_visible(True) #print "x=%d y=%d" % (x, y) if self.lid_active: if self.collides(x, y): self.can_sprite.image = self.image_closed self.opened = False events.Fire('LidClosed') else: self.lid_rect.x = x self.lid_rect.y = y events.Fire('LidDropped') self.lid_active = False elif self.can_active: self.can_sprite.rotation = 0 #self.can_sprite.set_position(x,y) self.can_active = False events.Fire('CanDropped') def on_mouse_motion(self, x, y, dx, dy): if self.collides(x, y): self.can_highlighted = True else: self.can_highlighted = False if self.lid_rect.collide_point(x, y): self.lid_highlighted = True else: self.lid_highlighted = False def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): if self.can_active: self.can_sprite.x = x self.can_sprite.y = y #self.can_rect.centerx = x #self.can_rect.centery = y #self.can_sprite.set_position(self.can_rect.x, self.can_rect.y) dist = math.sqrt(abs(dx*dx + dy*dy)) self.can_sprite.rotation = dx / 10.0 * 45 if dist > 10: self.fallen = True self.can_active = False if dx > 0: self.can_sprite.rotation = 90 else: self.can_sprite.rotation = -90 events.Fire('CanTipped') if not self.opened: self.opened = True self.can_sprite.image = self.image_opened self.lid_rect.bottomleft = self.can_rect.bottomleft self.lid_rect.x += dx * 5 self.lid_rect.y += dy * 5 for leaf in self.candidateLeaves: if self.collides(leaf.x, leaf.y): leaf.die() elif self.lid_active: self.lid_rect.center = (x, y) def On_LeafSweptOff(self, leaf): self.candidateLeaves[leaf] = 1 def On_LeafDeath(self, leaf): if leaf in self.candidateLeaves: del self.candidateLeaves[leaf]
class SceneMainMenu(Scene): def __init__(self, window): super().__init__(window) self.batch = Batch() self.menu = 0 self.main_index = 0 self.practice_index = 0 self.config_index = 0 self.t = 0 self.background = Sprite(IMAGES['ui']['mainmenu_bg'], -15, -15) self.background.opacity = 100 self.background2 = Sprite(IMAGES['ui']['mainmenu_bg2'], 0, 0, blend_src=774) self.left_sprite = Sprite(IMAGES['ui']['mainmenu_left'], 0, 0, batch=self.batch) self.left_sprite.opacity = 50 # Main menu options: options_text = ['Start game', 'Practice', 'High scores', 'Config', 'Exit'] self.main_options_shadow = [Label(text=options_text[i], font_name=MENU_FONT, color=(100, 100, 100, 100), font_size=22, x=199, y=401 - 32*i, batch=self.batch) for i in range(len(options_text))] self.main_options = [Label(text=options_text[i], font_name=MENU_FONT, font_size=22, x=200, y=400 - 32*i, batch=self.batch) for i in range(len(options_text))] # Practice options: options_text = ['Level 1', 'Level 2', 'Level 3', 'Level 4', 'Level 5'] self.practice_options_shadow = [Label(text=options_text[i], font_name=MENU_FONT, color=(100, 100, 100, 0), font_size=22, x=499, y=401 - 32*i, batch=self.batch) for i in range(len(options_text))] self.practice_options = [Label(text=options_text[i], font_name=MENU_FONT, font_size=22, x=500, y=400 - 32*i, color=(255,255,255,0), batch=self.batch) for i in range(len(options_text))] # Config options: options_text = ['SFX volume', 'BGM volume', 'Controls'] self.config_options_shadow = [Label(text=options_text[i], font_name=MENU_FONT, color=(100, 100, 100, 0), font_size=22, x=499, y=401 - 32*i, batch=self.batch) for i in range(len(options_text))] self.config_options = [Label(text=options_text[i], font_name=MENU_FONT, font_size=22, x=500, y=400 - 32*i, color=(255,255,255,0), batch=self.batch) for i in range(len(options_text))] def draw(self): self.background.draw() self.background2.draw() self.batch.draw() def update(self, dt): super().update(dt) self.t += 1 # Animate background: self.background.x = -15 + 11*sin(0.021*self.t) self.background.y = -15 + 10*sin(0.024*self.t) self.background2.opacity = 70 + 60*sin(0.01*self.t) # Manage input: if self.menu is 0: # Main menu if KEYS['up'] in self.keys and self.keys[KEYS['up']] is KEY_PRESSED and self.main_index > 0: self.main_index -= 1 elif KEYS['down'] in self.keys and self.keys[KEYS['down']] is KEY_PRESSED and self.main_index < 4: self.main_index += 1 elif KEYS['shoot'] in self.keys and self.keys[KEYS['shoot']] is KEY_PRESSED: if self.main_index is 0: # Start self.window.change_scene(SceneGame) if self.main_index is 1: # Practice self.menu = 2 if self.main_index is 2: # Scores pass if self.main_index is 3: # Config self.menu = 4 if self.main_index is 4: # Exit app.exit() if self.menu is 2: # Practice menu if KEYS['up'] in self.keys and self.keys[KEYS['up']] is KEY_PRESSED and self.practice_index > 0: self.practice_index -= 1 elif KEYS['down'] in self.keys and self.keys[KEYS['down']] is KEY_PRESSED and self.practice_index < 4: self.practice_index += 1 elif KEYS['bomb'] in self.keys and self.keys[KEYS['bomb']] is KEY_PRESSED: self.menu = 0 self.practice_index = 0 if self.menu is 4: # Config menu if KEYS['up'] in self.keys and self.keys[KEYS['up']] is KEY_PRESSED and self.config_index > 0: self.config_index -= 1 elif KEYS['down'] in self.keys and self.keys[KEYS['down']] is KEY_PRESSED and self.config_index < 2: self.config_index += 1 elif KEYS['bomb'] in self.keys and self.keys[KEYS['bomb']] is KEY_PRESSED: self.menu = 0 self.config_index = 0 # Animate labels: for i in range(len(self.main_options)): l = self.main_options[i] s = self.main_options_shadow[i] if self.menu is 0 and l.color[3] < 255: l.color = (l.color[0], l.color[1], l.color[2], l.color[3] + 5) if self.menu is 0 and s.color[3] < 100: s.color = (s.color[0], s.color[1], s.color[2], s.color[3] + 5) if self.menu is not 0 and l.color[3] > 110: l.color = (l.color[0], l.color[1], l.color[2], l.color[3] - 5) if self.menu is not 0 and s.color[3] > 40: s.color = (s.color[0], s.color[1], s.color[2], s.color[3] - 5) if l.x < 210 and self.main_index == i: l.x += 1 elif l.x > 200 and self.main_index != i: l.x -= 1 if s.x > 189 and self.main_index == i: s.x -= 1 elif s.x < 199 and self.main_index != i: s.x += 1 for i in range(len(self.practice_options)): l = self.practice_options[i] s = self.practice_options_shadow[i] if self.menu is 2 and l.color[3] < 255: l.color = (l.color[0], l.color[1], l.color[2], l.color[3] + 5) if self.menu is 2 and s.color[3] < 100: s.color = (s.color[0], s.color[1], s.color[2], s.color[3] + 5) if self.menu is not 2 and l.color[3] > 0: l.color = (l.color[0], l.color[1], l.color[2], l.color[3] - 5) if self.menu is not 2 and s.color[3] > 0: s.color = (s.color[0], s.color[1], s.color[2], s.color[3] - 5) if l.x < 510 and self.practice_index == i: l.x += 1 elif l.x > 500 and self.practice_index != i: l.x -= 1 if s.x > 489 and self.practice_index == i: s.x -= 1 elif s.x < 499 and self.practice_index != i: s.x += 1 for i in range(len(self.config_options)): l = self.config_options[i] s = self.config_options_shadow[i] if self.menu is 4 and l.color[3] < 255: l.color = (l.color[0], l.color[1], l.color[2], l.color[3] + 5) if self.menu is 4 and s.color[3] < 100: s.color = (s.color[0], s.color[1], s.color[2], s.color[3] + 5) if self.menu is not 4 and l.color[3] > 0: l.color = (l.color[0], l.color[1], l.color[2], l.color[3] - 5) if self.menu is not 4 and s.color[3] > 0: s.color = (s.color[0], s.color[1], s.color[2], s.color[3] - 5) if l.x < 510 and self.config_index == i: l.x += 1 elif l.x > 500 and self.config_index != i: l.x -= 1 if s.x > 489 and self.config_index == i: s.x -= 1 elif s.x < 499 and self.config_index != i: s.x += 1
class Button(Widget): def __init__(self, x, y, width, height, text): self._size = win_width, win_height = get_size() super().__init__(x, win_height - y, width, height) self._width = width self._depressed_img = image.load( join(path['texture.ui'], 'widgets.png')).get_region(0, 170, 200, 20) self._pressed_img = image.load(join(path['texture.ui'], 'widgets.png')).get_region( 0, 150, 200, 20) self._unable_img = image.load(join(path['texture.ui'], 'widgets.png')).get_region( 0, 190, 200, 20) self._sprite = Sprite(self._depressed_img, x, win_height - y) self._text = text self._label = ColorLabel(self._text, color='white', align='center', anchor_x='center', anchor_y='center', x=x + width / 2, y=win_height - y + height / 2 - 2, font_name='minecraftia') self._pressed = False self._enable = True def draw(self): self._sprite.scale_x = self._width / 200 self._sprite.scale_y = self._height / 20 self._sprite.draw() self._label.draw() def enable(self, status): self._enable = bool(status) if self._enable: self._label.color = 'white' else: self._label.color = 'gray' def text(self, text): self._text = text self._label.text = self._text def on_mouse_press(self, x, y, buttons, modifiers): if self.check_hit(x, y) and self._enable: self._sprite.image = self._pressed_img self._pressed = True self.dispatch_event('on_press') def on_mouse_release(self, x, y, buttons, modifiers): if self._pressed: self._sprite.image = self._depressed_img self._pressed = False self.dispatch_event('on_release') def on_mouse_motion(self, x, y, dx, dy): if not self._pressed: if self.check_hit(x, y) and self._enable: self._sprite.image = self._pressed_img self._label.color = 'yellow' else: self._sprite.image = self._depressed_img if self._enable else self._unable_img self._label.color = 'white' if self._enable else 'gray' def on_resize(self, width, height): self._x *= width / self._size[0] self._y = (height / self._size[1]) * self._y self._size = width, height self._sprite.position = self._x, self._y self._label.x = self._x + self._width / 2 self._label.y = self._y + self._height / 2
class Player: def __init__(self, x, y, game, weapon): self.pos = Vector(x, y) self.vel = Vector(0, 0) self.rot = 0 self.game = game self.weapons = [None, Weapon("pistol")] self.grenades = [ Grenade(self.game, "grenade"), Grenade(self.game, "grenade"), Grenade(self.game, "grenade"), Grenade(self.game, "grenade"), Grenade(self.game, "grenade") ] self.grenade_num = 0 self.last_shot = 0 self.hit_box = PLAYER_HIT_BOX.copy() self.hit_box.x = x self.hit_box.y = y self.o = Vector(self.pos.x, self.pos.y) self.health = PLAYER_HEALTH self.num = 1 self.sprite = Sprite(game.player_images[self.weapons[self.num].name]) self.width = self.sprite.width self.height = self.sprite.height self.sprite.image.anchor_x = self.sprite.image.width / 2 - WEAPONS[ self.weapons[self.num].name]['img_offset'].x self.sprite.image.anchor_y = self.sprite.image.height / 2 - WEAPONS[ self.weapons[self.num].name]['img_offset'].y self.knock_back = Vector(0, 0) def see_player(self, player): corner2 = Vector(self.hit_box.x + self.hit_box.width / 2, self.hit_box.y + self.hit_box.height / 2) return self.see_point(player, corner2) def see_point(self, player, point_1): o_point_1 = player.hit_box.copy() o_point_2 = Vector(player.hit_box.x, player.hit_box.y + player.hit_box.height) o_point_3 = Vector(player.hit_box.x + player.hit_box.width, player.hit_box.y + player.hit_box.height) o_point_4 = Vector(player.hit_box.x + player.hit_box.width, player.hit_box.y) glBegin(GL_LINES) glVertex2i(int(point_1.x), int(point_1.y)) glVertex2i(int(o_point_1.x), int(o_point_1.y)) glEnd() glBegin(GL_LINES) glVertex2i(int(point_1.x), int(point_1.y)) glVertex2i(int(o_point_2.x), int(o_point_2.y)) glEnd() glBegin(GL_LINES) glVertex2i(int(point_1.x), int(point_1.y)) glVertex2i(int(o_point_3.x), int(o_point_3.y)) glEnd() glBegin(GL_LINES) glVertex2i(int(point_1.x), int(point_1.y)) glVertex2i(int(o_point_4.x), int(o_point_4.y)) glEnd() if self.line_collide(self.game, point_1, o_point_1) and self.line_collide(self.game, point_1, o_point_2) and self.line_collide(self.game, point_1, o_point_3) \ and self.line_collide(self.game, point_1, o_point_4): return False return True def line_collide(self, game, pos, o): for wall in game.walls: topleft = [wall.pos.x, wall.pos.y + wall.height] topright = [wall.pos.x + wall.width, wall.pos.y + wall.height] bottomleft = [wall.pos.x, wall.pos.y] bottomright = [wall.pos.x + wall.width, wall.pos.y] left = lineLine(pos.x, pos.y, o.x, o.y, topleft[0], topleft[1], topleft[0], bottomleft[1]) right = lineLine(pos.x, pos.y, o.x, o.y, topright[0], topright[1], topright[0], bottomright[1]) top = lineLine(pos.x, pos.y, o.x, o.y, topleft[0], topleft[1], topright[0], topright[1]) bottom = lineLine(pos.x, pos.y, o.x, o.y, bottomleft[0], bottomleft[1], bottomright[0], bottomright[1]) if left or right or top or bottom: return True return False def switch(self): self.num += 1 if len(self.weapons) - 1 < self.num: self.num = 0 if self.weapons[self.num] is None: self.switch() def get_rotation(self, point1, point2): return math.degrees( math.atan2(point1.x - point2.x, point1.y - point2.y)) def throw(self, dt): if len(self.grenades) > 0: self.grenades[self.grenade_num].throw( Vector(self.pos.x, self.pos.y), GRENADE_STARTING_VEL + self.vel * Vector(dt, dt), self.rot) self.grenades.remove(self.grenades[self.grenade_num]) self.grenade_num = 0 def shoot(self): if self.last_shot <= 0 < self.health: rot = self.get_rotation(self.o, self.game.mouse.get_map_pos()) + 90 if abs(self.rot) - abs(rot) > 10 or abs(rot) - abs(self.rot) > 10: rot = self.rot if self.weapons[self.num].ammo_in_mag > 0 and ( not self.weapons[self.num].fired or self.weapons[self.num].type == "auto"): self.knock_back = WEAPONS[self.weapons[ self.num].name]["knock_back"].rotate(self.rot) self.weapons[self.num].shoot(self.o, self.pos, rot, self.game) self.last_shot = WEAPONS[self.weapons[self.num].name]["rate"] def rotate_to_mouse(self): ''' v = self.pos - self.game.mouse.get_map_pos() s = self.game.mouse.get_map_pos() pos = pg.Vector2(self.pos.x, self.pos.y) pos2 = pg.Vector2(s.x, s.y) v2 = pos - pos2 print("v: ", v) print("v2: ", v2) # print(v.angle_to(Vector(-1, 0))) # print(v2.angle_to(pg.Vector2(-1, 0))) # print(self.rot) print(v.magnitude()) print(v2.magnitude()) ''' self.rot = self.get_rotation(self.pos, self.game.mouse.get_map_pos()) + 90 def collide_with_walls(self, dir): if self.health > 0: if dir == "x": for wall in self.game.walls: if (self.hit_box.x + self.hit_box.width > wall.pos.x and self.hit_box.y + self.hit_box.height > wall.pos.y ) and (self.hit_box.x < wall.pos.x + wall.width and self.hit_box.y < wall.pos.y + wall.height): if wall.center.x > self.hit_box.get_center().x: self.hit_box.x = wall.pos.x - self.hit_box.width elif wall.center.x < self.hit_box.get_center().x: self.hit_box.x = wall.pos.x + wall.width self.vel.x = 0 for mob in self.game.mobs: if (self.hit_box.x + self.hit_box.width > mob.hit_box.x and self.hit_box.y + self.hit_box.height > mob.hit_box.y) and ( self.hit_box.x < mob.hit_box.x + mob.hit_box.width and self.hit_box.y < mob.hit_box.y + mob.hit_box.height): if mob.hit_box.get_center( ).x > self.hit_box.get_center().x: self.hit_box.x = mob.hit_box.x - self.hit_box.width elif mob.hit_box.get_center( ).x < self.hit_box.get_center().x: self.hit_box.x = mob.hit_box.x + mob.hit_box.width self.vel.x = 0 elif dir == "y": for wall in self.game.walls: if (self.hit_box.x + self.hit_box.width > wall.pos.x and self.hit_box.y + self.hit_box.height > wall.pos.y ) and (self.hit_box.x < wall.pos.x + wall.width and self.hit_box.y < wall.pos.y + wall.height): if wall.center.y > self.hit_box.get_center().y: self.hit_box.y = wall.pos.y - self.hit_box.height elif wall.center.y < self.hit_box.get_center().y: self.hit_box.y = wall.pos.y + wall.height self.vel.y = 0 for mob in self.game.mobs: if (self.hit_box.x + self.hit_box.width > mob.hit_box.x and self.hit_box.y + self.hit_box.height > mob.hit_box.y) and ( self.hit_box.x < mob.hit_box.x + mob.hit_box.width and self.hit_box.y < mob.hit_box.y + mob.hit_box.height): if mob.hit_box.get_center( ).y > self.hit_box.get_center().y: self.hit_box.y = mob.hit_box.y - self.hit_box.height elif mob.hit_box.get_center( ).y < self.hit_box.get_center().y: self.hit_box.y = mob.hit_box.y + mob.hit_box.height self.vel.y = 0 def update(self, dt, server=False): self.sprite = Sprite( self.game.player_images[self.weapons[self.num].name]) self.width = self.sprite.width self.height = self.sprite.height self.sprite.image.anchor_x = self.sprite.image.width / 2 - WEAPONS[ self.weapons[self.num].name]['img_offset'].x self.sprite.image.anchor_y = self.sprite.image.height / 2 - WEAPONS[ self.weapons[self.num].name]['img_offset'].y self.vel.x -= self.knock_back.x self.vel.y += self.knock_back.y # check hit box collisions self.hit_box.x += self.vel.x * dt if not server: self.collide_with_walls("x") self.hit_box.y += self.vel.y * dt if not server: self.collide_with_walls("y") self.knock_back.multiply(0) self.pos.x = self.hit_box.x + self.hit_box.width / 2 self.pos.y = self.hit_box.y + self.hit_box.height / 2 o = WEAPONS[self.weapons[self.num].name]['offset'].copy().rotate( -self.rot) self.o = Vector(self.pos.x, self.pos.y) self.o.x += o.x self.o.y += o.y if self.last_shot > 0: self.last_shot -= dt if not self.game.buy_menu: self.rotate_to_mouse() self.sprite.update(rotation=self.rot) self.sprite.x = self.hit_box.get_center().x self.sprite.y = self.hit_box.get_center().y self.weapons[self.num].update(dt) def draw_hit_box(self): glBegin(GL_LINES) glVertex2i(int(self.hit_box.x), int(self.hit_box.y)) glVertex2i(int(self.hit_box.x), int(self.hit_box.y + self.hit_box.height)) glVertex2i(int(self.hit_box.x), int(self.hit_box.y + self.hit_box.height)) glVertex2i(int(self.hit_box.x + self.hit_box.width), int(self.hit_box.y + self.hit_box.height)) glVertex2i(int(self.hit_box.x + self.hit_box.width), int(self.hit_box.y + self.hit_box.height)) glVertex2i(int(self.hit_box.x + self.hit_box.width), int(self.hit_box.y)) glVertex2i(int(self.hit_box.x + self.hit_box.width), int(self.hit_box.y)) glVertex2i(int(self.hit_box.x), int(self.hit_box.y)) glEnd() def draw(self): s = self.game.mouse.get_map_pos() pyglet.gl.glBegin(pyglet.gl.GL_LINES) pyglet.gl.glVertex2i(int(self.pos.x), int(self.pos.y)) pyglet.gl.glVertex2i(int(s.x), int(s.y)) pyglet.gl.glEnd() pyglet.gl.glBegin(pyglet.gl.GL_LINES) pyglet.gl.glVertex2i(int(self.o.x), int(self.o.y)) pyglet.gl.glVertex2i(int(s.x), int(s.y)) pyglet.gl.glEnd() self.draw_hit_box() self.sprite.draw()
def draw(self): Sprite.draw(self) if (not self.item is None): self.item.draw()
class MapMaker: def __init__(self, frame: Frame, grid: Grid, renderbox: RenderBox, mouse: Mouse, game_obj_handler: GameObjectHandler, platform_list: List[Platform] = None, block_queue: Platform = None): self.frame = frame self.grid = grid self.renderbox = renderbox self.mouse = mouse self.game_obj_handler = game_obj_handler self.platform_list = platform_list if platform_list is not None else [] for platform in self.platform_list: self.game_obj_handler.append(platform) self.block_queue = block_queue if block_queue is not None else \ Platform(frame=self.frame, grid=self.grid, renderbox=self.renderbox, batch=Batch(), name=f'Platform{len(self.platform_list)}') self.game_obj_handler.append(self.block_queue) # Block Preview Related self.block_selector_handler = BlockSelectorHandler( [BlockSelector(TileImages), BlockSelector(ItemImages)]) self.block_preview_rect_color = (100, 255, 20) self.block_preview_rect_opacity = 50 self.block_preview_sprite_opacity = 130 self.block_preview_rect = cast(Rectangle, None) self.block_preview_sprite = cast(Sprite, None) def add_block_to_queue(self, x: int, y: int, res_img: ResourceImage): self.block_queue.add_block(x=x, y=y, res_img=res_img) self.game_obj_handler.append(self.block_queue.blocks[-1], to_renderbox=False) def add_block_to_queue_from_space(self, grid_space_x: int, grid_space_y: int, res_img: ResourceImage): x, y = self.grid.grid_space_to_world_coord(space_x=grid_space_x, space_y=grid_space_y) self.add_block_to_queue(x=x, y=y, res_img=res_img) def add_block_to_queue_from_mouse(self): self.add_block_to_queue_from_space( grid_space_x=self.mouse.grid_space_x, grid_space_y=self.mouse.grid_space_y, res_img=self.block_selector_handler.res_img) def remove_queue_block(self, name: str): self.game_obj_handler.remove(name) self.block_queue.remove_block(name=name) def remove_queue_block_from_space(self, grid_space_x: int, grid_space_y: int): names = self.grid.grid_spaces_to_names([(grid_space_x, grid_space_y)]) for name in names: self.remove_queue_block(name=name) def remove_queue_block_from_mouse(self): self.remove_queue_block_from_space( grid_space_x=self.mouse.grid_space_x, grid_space_y=self.mouse.grid_space_y) def push_queue(self): self.platform_list.append(self.block_queue.copy()) self.block_queue = Platform(frame=self.frame, grid=self.grid, renderbox=self.renderbox, batch=Batch(), name=f'Platform{len(self.platform_list)}') self.game_obj_handler.append(self.block_queue) def update_block_preview(self): if self.mouse.grid_space_x is not None and self.mouse.grid_space_y is not None: rect_x = self.grid.tile_width * self.mouse.grid_space_x + self.grid.grid_origin_x - self.frame.x rect_y = self.grid.tile_height * self.mouse.grid_space_y + self.grid.grid_origin_y - self.frame.y if self.block_preview_sprite is None: self.block_preview_rect = Rectangle( x=rect_x, y=rect_y, width=self.grid.tile_width, height=self.grid.tile_height, color=self.block_preview_rect_color, transparency=self.block_preview_rect_opacity) self.block_preview_sprite = Sprite( img=self.block_selector_handler.res_img.img, x=rect_x, y=rect_y) self.block_preview_sprite.opacity = self.block_preview_sprite_opacity else: self.block_preview_rect.move_to(x=rect_x, y=rect_y) self.block_preview_sprite.position = (rect_x, rect_y) def reset_block_preview(self): self.block_preview_rect = None self.block_preview_sprite = None def toggle_block_preview_selector(self): self.block_selector_handler.toggle_selector() self.reset_block_preview() self.update_block_preview() def toggle_block_preview_img(self): self.block_selector_handler.current_selector.toggle_img() self.reset_block_preview() self.update_block_preview() def draw_block_preview(self): if self.block_preview_sprite is not None: self.block_preview_rect.draw() self.block_preview_sprite.draw()
class MobileEntity(Entity): defaults = { 'collidable': True, 'mobile': True, 'width': 50, 'height': 50, 'stat_modifiers': { 'str': 0, 'dex': 0, 'wis': 0, 'int': 0, 'con': 0, 'lck': 0 } } attributes = { 'dead': False, 'image_file': 'app/assets/zombie.png', 'moving_to': None, 'chunk': None, 'sprinting': False, 'in_combat': False, #'in_combat_with': [], 'attack_cooldown': 0, 'projectile_cooldown': 0, 'damage_text_color': (255, 255, 255, 255), 'chunk_container': 'npcs' } overwrite = {} def __init__(self, **kwargs): self.pre_init(**kwargs) super(MobileEntity, self).__init__(**kwargs) def init(self, **kwargs): self.in_combat_with = [] self.image = load_image(self.image_file) self.sprite = Sprite(self.image, self.x, self.y) self.hp_image = load_image('app/assets/healthbar.png') self.hp_sprite = Sprite(self.hp_image, self.x + 1, self.y + self.height + 5) self.set_sprite_render(self.group) self.stats = Stats(modifiers=self.stat_modifiers) entity_container = getattr(self.chunk, self.chunk_container) if self.chunk and self not in entity_container: entity_container.append(self) self.post_init(**kwargs) def pre_init(self, **kwargs): self.attributes = {**self.attributes, **self.overwrite} def post_init(self, **kwargs): pass def set_sprite_render(self, group): self.sprite.batch = self.chunk.draw_batch self.sprite.group = group self.hp_sprite.batch = self.chunk.draw_batch self.hp_sprite.group = group @property def speed(self): walk_speed = self.stats.dex // 3 if self.sprinting: return walk_speed * config.sprint_modifier return walk_speed def check_state(self): if self.dead: self.on_death() elif self.in_combat: if not self.in_combat_with: self.in_combat = False else: self.do_combat() else: self.do_idle() def on_death(self): print(f'{self.name} died!') if self.in_combat: for entity in self.in_combat_with: if self in entity.in_combat_with: entity.in_combat_with.remove(self) self.remove_from_chunk() self.sprite.delete() self.hp_sprite.delete() self.after_death() def remove_from_chunk(self): if self.chunk: container = getattr(self.chunk, self.chunk_container) if self in container: container.remove(self) def after_death(self): pass def do_combat(self): pass def do_idle(self): pass def check_bounds(self): if (self.x + self.width) > config.window_width: self.out_of_bounds('e') elif self.x < 0: self.out_of_bounds('w') elif (self.y + self.height) > config.window_height: self.out_of_bounds('n') elif self.y < 0: self.out_of_bounds('s') def out_of_bounds(self, direction): pass def on_collision(self, obj): x_intersect = calc_1D_intersect(*self.x_1D, *obj.x_1D) y_intersect = calc_1D_intersect(*self.y_1D, *obj.y_1D) if x_intersect < y_intersect: if self.x < obj.x: self.x = obj.x - self.width else: self.x = obj.x + obj.width else: if self.y < obj.y: self.y = obj.y - self.height else: self.y = obj.y + obj.height self.after_collision(obj) def after_collision(self, obj): pass def attack(self): if not self.attack_cooldown: atk_range = 75 for entity in self.chunk.attackable_objects: if entity is not self: if distance(*self.coord, *entity.coord) < atk_range: self.in_combat = True if entity not in self.in_combat_with: self.in_combat_with.append(entity) self.do_damage(entity, d6(num=self.stats.str // 2)) self.attack_cooldown = 50 def do_damage(self, target, dmg): target.take_damage(self, dmg) def take_damage(self, source, dmg): dmg_text = Label(f'{dmg}', x=randint((self.x - 5) // 1, (self.x + self.width + 5) // 1), y=self.y + self.height + 15, font_name='courier new', color=self.damage_text_color, bold=True, batch=self.chunk.draw_batch, group=self.chunk.foreground) clock.schedule_once(lambda df: dmg_text.delete(), 0.5) if (source is not None) and (source is not self): self.in_combat = True if source not in self.in_combat_with: self.in_combat_with.append(source) self.stats.hp -= dmg if self.stats.hp < 1: self.dead = True print( f'{self.name} ({self.stats.hp}/{self.stats.base_hp}) took {dmg} damage from {source.name}!' ) def fire_proj(self): velocity = 10 p_x = self.cursor_coord.x - self.center.x p_y = self.cursor_coord.y - self.center.y d = distance(self.center.x, self.center.y, self.cursor_coord.x, self.cursor_coord.y) r = velocity / d r_p = 30 / d if not self.projectile_cooldown: proj = Projectile(owner=self, chunk=self.chunk, x=self.center.x + p_x * r_p, y=self.center.y + p_y * r_p, damage=d20(num=self.stats.int // 3), velocity_x=p_x * r, velocity_y=p_y * r, batch=self.chunk.draw_batch, group=self.chunk.foreground) self.chunk.objects.append(proj) self.projectile_cooldown = 10 def update_cooldowns(self): if self.attack_cooldown > 0: self.attack_cooldown -= 1 if self.projectile_cooldown > 0: self.projectile_cooldown -= 1 def move(self): if self.moving_to: dist_from_target = np.sqrt((self.x - self.moving_to.x)**2 + (self.y - self.moving_to.y)**2) if dist_from_target <= self.speed: self.x = self.moving_to.x self.y = self.moving_to.y else: dist_ratio = self.speed / dist_from_target self.x = (1.0 - dist_ratio) * self.x + dist_ratio * self.moving_to.x self.y = (1.0 - dist_ratio) * self.y + dist_ratio * self.moving_to.y def update_sprites(self): self.sprite.update(x=self.x, y=self.y) self.hp_sprite.update(x=self.x + 1, y=self.y + self.height + 5, scale_x=self.stats.hp / self.stats.base_hp) def update(self): self.check_state() if not self.dead: self.update_cooldowns() self.move() self.check_bounds() self.update_sprites() else: self.after_death() def draw(self): self.sprite.draw()