Пример #1
0
bool update_game()
{
    int in = get_input(get_map_window());
    if(in == INPUT_ACTION && get_last_action() == ACTION_QUIT)
        return false;
    else if(in == INPUT_ACTION && (get_last_action() == ACTION_SCROLL_UP || get_last_action() == ACTION_SCROLL_DOWN)) {
        log_scroll(get_last_action() == ACTION_SCROLL_UP);
        draw_log();
    } else if(!dead) {
        update_player();
        if(get_current_floor() != current_level) {
            set_current_map(world[get_current_floor()], current_level < get_current_floor(), current_level > get_current_floor());
            current_level = get_current_floor();
        }
        update_map(1, world[current_level]);
        if(is_dead()) {
            add_message(COLOR_HP_CRIT, "Oh dear, you've died!");
            add_message(COLOR_DEFAULT, "Press q to return to the main menu");
            dead = true;
        }
        if(game_won())
            dead = true;
        draw_log();
    }
    return true;
}
	void elevator_system_drawer::draw_all_queues(Wt::WPainter& painter, Wt::WRectF const& rc)
	{
		auto const num_floors = get_num_floors();
		auto const floor_height = get_floor_height(SizeFormat::Pixels);
		auto const q_height = get_queue_height(SizeFormat::Pixels);

		for(elevator_system::floor_t floor = 0; floor < num_floors; ++floor)
		{
			auto rc_floor = floor_rect(floor, rc);

			for(size_t dir = 0; dir < 2; ++dir)
			{
				if(
					m_stage == AnimationStage::GettingOn &&
					floor == get_current_floor() &&
					dir == m_sys.m_state.direction
					)
				{
					continue;
				}

				auto length = get_queue_length(floor, (Direction)dir);
				if(length > 0)
				{
					auto rc_q_corridor = queue_corridor_rect((Direction)dir, rc_floor);
					auto rc_q = queue_rect(
						length,
						QueueSide::Right,
						rc_q_corridor
						);
					draw_queue(length, painter, rc_q);
				}
			}
		}
	}
	void elevator_system_drawer::draw_getting_on(Wt::WPainter& painter, Wt::WRectF const& rc)
	{
		auto const floor = get_current_floor();
		Direction const dir = m_sys.m_state.direction;
		auto count = m_sys.m_transitions.num_got_on;

		auto rc_floor = floor_rect(floor, rc);
		auto rc_q_corridor = queue_corridor_rect(dir, rc_floor);
		auto rc_q = queue_rect(
			count,
			QueueSide::Right,
			rc_q_corridor
			);

		auto walked = WalkingSpeed * m_stage_step * m_pix_multiplier;
		rc_q = Wt::WRectF(
			rc_q.left() + walked,
			rc_q.top(),
			rc_q.width(),
			rc_q.height()
			);

		painter.save();
		Wt::WPainterPath clip_path;
		clip_path.addRect(
			rc_q_corridor.left(),
			rc_q_corridor.top(),
			rc_q_corridor.width() + get_door_gap_width(SizeFormat::Pixels),
			rc_q_corridor.height()
			);
		painter.setClipping(true);
		painter.setClipPath(clip_path);

		draw_queue(count, painter, rc_q);

		painter.restore();
	}
	void elevator_system_drawer::draw_elevator(Wt::WPainter& painter, Wt::WRectF const& rc)
	{
		const auto floor_height = get_floor_height(SizeFormat::Pixels);
		const auto elevator_height = get_elevator_height(SizeFormat::Pixels);

		painter.save();

		Wt::WRectF rc_elevator(
			rc.left(),
			rc.bottom() - get_current_floor() * floor_height - elevator_height,
			rc.width(),
			elevator_height
			);

		if(m_stage == AnimationStage::Moving)
		{
			auto travelled = m_stage_step * ElevatorSpeed * m_pix_multiplier;
			travelled = std::min(travelled, floor_height);
			auto sign = m_sys.m_state.direction == Direction::Up ? 1.0 : -1.0;
			rc_elevator = Wt::WRectF(
				rc_elevator.left(),
				rc_elevator.top() - sign * travelled,
				rc_elevator.width(),
				rc_elevator.height()
				);
		}

		double exit_door_openness = 0.0;
		switch(m_stage)
		{
			case AnimationStage::ExitDoorsOpening:
			exit_door_openness = m_stage_step * DoorSpeed * m_pix_multiplier / elevator_height;
			exit_door_openness = std::min(exit_door_openness, 1.0);
			break;
			case AnimationStage::ExitDoorsClosing:
			exit_door_openness = 1.0 - m_stage_step * DoorSpeed * m_pix_multiplier / elevator_height;
			exit_door_openness = std::max(exit_door_openness, 0.0);
			break;
			case AnimationStage::GettingOff:
			exit_door_openness = 1.0;
			break;
		}

		double entry_door_openness = 0.0;
		switch(m_stage)
		{
			case AnimationStage::EntryDoorsOpening:
			entry_door_openness = m_stage_step * DoorSpeed * m_pix_multiplier / elevator_height;
			entry_door_openness = std::min(entry_door_openness, 1.0);
			break;
			case AnimationStage::EntryDoorsClosing:
			entry_door_openness = 1.0 - m_stage_step * DoorSpeed * m_pix_multiplier / elevator_height;
			entry_door_openness = std::max(entry_door_openness, 0.0);
			break;
			case AnimationStage::GettingOn:
			entry_door_openness = 1.0;
			break;
		}

		painter.drawLine(rc_elevator.topLeft(), rc_elevator.topRight());
		painter.drawLine(rc_elevator.bottomLeft(), rc_elevator.bottomRight());

		painter.drawLine(
			rc_elevator.left(),
			rc_elevator.top(),
			rc_elevator.left(),
			rc_elevator.top() + (1.0 - entry_door_openness) * elevator_height
			);
		painter.drawLine(
			rc_elevator.right(),
			rc_elevator.top(),
			rc_elevator.right(),
			rc_elevator.top() + (1.0 - exit_door_openness) * elevator_height
			);

		if(m_sys.is_moving(m_sys.m_state.direction))
		{
			painter.save();
			painter.translate(rc_elevator.left(), rc_elevator.top());
			if(m_sys.m_state.direction == elevator_system::Direction::Down)
			{
				painter.translate(0.0, rc_elevator.height() * 0.5);
				painter.scale(1.0, -1.0);
			}
			painter.scale(rc_elevator.width(), rc_elevator.height());
			std::array< Wt::WPointF, 3 > points{ {
					{ 0.5, 0.1 },
					{ 0.2, 0.4 },
					{ 0.8, 0.4 },
					} };
			painter.setPen(Wt::WPen(Wt::green));
			painter.setBrush(Wt::WBrush(Wt::green));
			painter.drawPolygon(&points[0], 3);
			painter.restore();
		}

		Wt::WFont font = painter.font();
		//font.setFamily(Wt::WFont::Default);
		font.setSize(20);
		painter.setFont(font);
		painter.drawText(
			Wt::WRectF(rc_elevator.left(), rc_elevator.center().y(), rc_elevator.width(), rc_elevator.height() * 0.5),
			Wt::AlignCenter | Wt::AlignMiddle,
			std::to_string(get_current_occupancy())
			);

		painter.restore();
	}