@Override
  public void draw() {
    // world_darkness.fill(darkness_color);

    FlxG.batch.end();
    frame_buffer.begin();
    FlxG.batch.begin();
    frame_buffer_fill.draw();
    player.drawGlow();
    world.firefish_group.callAll("drawGlow");
    FlxG.batch.end();
    frame_buffer.end();
    FlxG.batch.begin();

    super.draw();
  }
  @Override
  public void update() {
    // CHEAT CODE LOL
    if (cheats) {
      if (FlxG.keys.justPressed("N")) {
        skip_ahead();
        super.update();
        return;
      }
    }

    if (player.won_game) {
      oxygen_timer_display.setAlpha(0);
      darkness.setAlpha(0);

      int speed = 400;
      FlxPoint target = new FlxPoint(world.octopus.x - 16, world.octopus.y + 4);

      if (player.x < target.x) {
        player.velocity.x += speed * FlxG.elapsed;
      } else if (player.x > target.x) {
        player.velocity.x -= speed * FlxG.elapsed;
      }

      if (player.y > target.y) {
        player.velocity.y -= speed * FlxG.elapsed;
      } else if (player.y < target.y) {
        player.velocity.y += speed * FlxG.elapsed;
      }

      if (Math.abs(player.y - target.y) < 16 && Math.abs(player.x - target.x) <= 16 && !won_done) {
        player.setFacing(FlxSprite.RIGHT);
        won_done = true;

        FlxG.fade(
            0xff000000,
            5,
            new IFlxCamera() {

              @Override
              public void callback() {
                FlxG.switchState(new EndGameState());
              }
            });
      }

      super.update();
      return;
    }

    if (player_dead) {
      player.active = false;

      player_death_timer -= FlxG.elapsed;

      if (player_death_timer <= 0.0) {
        player_dead = false;
        player.active = true;
      }

      super.update();
      return;
    }

    FlxG.collide(player, world.walls_map);
    FlxG.collide(world.firefish_group, world.walls_map, Firefish.callback);

    if (world.water_map.overlaps(player)) {
      player.in_water = true;
      player.glow.scale.x = player.glow.scale.y = 4;
    } else {
      player.in_water = false;
      player.glow.scale.x = player.glow.scale.y = 8;
    }

    if (world.safezone_map.overlaps(player) || world.water_map.overlaps(player)) {
      player.gravity_on = false;
    } else {
      player.gravity_on = true;
    }

    // Nudge the player up if they're in the safe zone.
    if (world.safezone_map.overlaps(player)) {
      player.push_up = true;
    } else {
      player.push_up = false;
    }

    // Check air bubble entrances
    for (String bubble_id : world.airbubble_entrances.keySet()) {
      FlxObject air_bubble_entrance = world.airbubble_entrances.get(bubble_id);
      if (air_bubble_entrance.overlaps(player)) {
        if (bubble_id != saved_restore_point) {
          saved_restore_point = bubble_id;
        }
      }
    }

    // Check story points
    for (String restore_point_id : world.airbubble_restore_points.keySet()) {
      RestorePoint restore_point = world.airbubble_restore_points.get(restore_point_id);

      if (player.overlaps(restore_point)) {
        if (world.stories.containsKey(restore_point_id)) {
          story_overlay.showText(world.stories.get(restore_point_id));
        }
      }
    }

    // Check oxygen level & update label
    if (player.in_water) {
      oxygen_timer_display.setText(Integer.toString((int) (Math.ceil(oxygen_timer))));
      oxygen_timer_display.setAlpha(1.0f - (oxygen_timer / 10.0f));

      darkness.setAlpha((float) Math.pow(1.0f - (oxygen_timer / 10.0f), 2));

      float max_overlay_alpha = 0.9f;

      if (darkness.getAlpha() > max_overlay_alpha) {
        darkness.setAlpha(max_overlay_alpha);
      }

      if (oxygen_timer_display.getAlpha() > max_overlay_alpha) {
        oxygen_timer_display.setAlpha(max_overlay_alpha);
      }

      oxygen_timer -= FlxG.elapsed;

      if (oxygen_timer < 0.0f) {
        oxygen_timer = 0.0f;
        kill_player();
      }
    } else {
      oxygen_timer = 10.0f;
      darkness.setAlpha(0);
      oxygen_timer_display.setAlpha(0);
    }

    // Start music
    if (!game_started && player.overlaps(world.darkness_init_area)) {
      game_started = true;

      FlxG.playMusic(GameMusic);
    }

    // World darkness init and kill titles (when the player dives into the pond);
    if (world_darkness.getAlpha() < 1
        && (world_darkness.getAlpha() > 0 || player.overlaps(world.darkness_init_area))) {
      world_darkness.visible = true;
      world_darkness.setAlpha(world_darkness.getAlpha() + FlxG.elapsed);
      title_text.setAlpha(title_text.getAlpha() - FlxG.elapsed);
    }

    // Endgame init
    if (player.overlaps(world.endgame_area)) {
      player.won_game = true;
    }

    super.update();
  }