Esempio n. 1
0
    //////////////////////////////////////////////////////////////////////

    bool fast_forward(Level level)
    {
        Level l = Instantiate(level);

        l.reset_board();
        l.copy_blocks_from(level);

        int move = l.solution.Count - 1;

        while (move >= 0)
        {
            int2 v = l.solution[move] * -1;
            move -= 1;
            int distance;
            Level.move_result r = l.get_move_result(v, out distance);
            if (r == Level.move_result.hit_side)
            {
                return(false);
            }
            if (r == Level.move_result.hit_solution)
            {
                return(true);
            }
            l.update_block_positions(v * distance);
            l.update_hit_blocks(v);
        }
        return(l.is_solution_complete(int2.zero));
    }
Esempio n. 2
0
    //////////////////////////////////////////////////////////////////////

    void Update()
    {
        switch (current_level.current_mode)
        {
        // drag mouse to set size of grid
        case Game.Mode.set_grid_size:
            Vector2 grid_pos = intersect_front_face_f(16, 16, Input.mousePosition);
            float   w        = Mathf.Min(8, Mathf.Max(1.5f, Mathf.Abs(grid_pos.x - 8)));
            float   h        = Mathf.Min(8, Mathf.Max(1.5f, Mathf.Abs(grid_pos.y - 8)));
            destroy_grid();
            int bw = (int)Mathf.Round(w * 2);
            int bh = (int)Mathf.Round(h * 2);
            if (Input.GetMouseButtonDown(0))
            {
                current_level = ScriptableObject.CreateInstance <Level>();
                current_level.get_board_coordinate = editor_board_coordinate;
                current_level.create_block_object  = create_block_object;
                current_level.reset();
                reset_level(current_level);
                current_level.create_board(bw, bh);
                current_level.current_mode = Game.Mode.create_solution;
                Debug.Log($"Board is {bw}x{bh}");
            }
            create_grid(bw, bh, square_size, grid_color, grid_line_width);
            break;

        // click some squares to create the solution blocks
        case Game.Mode.create_solution:
            int2 cp = intersect_front_face(current_level.width, current_level.height, Input.mousePosition);
            if (current_level.out_of_bounds(cp))
            {
                cursor_quad.SetActive(false);
            }
            else
            {
                Color cursor_color = Color.magenta;
                cursor_quad.transform.position = board_coordinate_z(cp, cursor_depth);
                cursor_quad.SetActive(true);
                Block cb = current_level.block_at(cp);
                if (cb != null)
                {
                    cursor_color = Color.Lerp(cursor_color, Color.black, 0.5f);
                }
                if (Input.GetMouseButtonDown(0))
                {
                    cursor_color = Color.white;
                    // if cursor on top of a solution block, click removes it
                    if (cb != null)
                    {
                        cursor_color = Color.black;
                        solution_objects.Remove(cb.game_object);
                        Destroy(cb.game_object);
                        current_level.set_block_at(cp, null);
                        current_level.active_win_blocks.Remove(cb.position);
                    }
                    // otherwise click adds one (TODO (chs): check it's a valid place to put a block
                    else
                    {
                        Block b = new Block();
                        b.position    = cp;
                        b.game_object = create_block_object(solution_color);
                        b.game_object.transform.position = board_coordinate_z(cp, solution_depth);
                        current_level.set_block_at(cp, b);
                        solution_objects.Add(b.game_object);
                        current_level.active_win_blocks.Add(cp);
                    }
                }
                set_color(cursor_quad, cursor_color);

                // right click moves to next phase (setting moves)
                if (Input.GetMouseButtonDown(1))
                {
                    current_level.solution.Clear();
                    move_direction = int2.zero;
                    cursor_quad.SetActive(false);
                    foreach (GameObject b in solution_objects)
                    {
                        b.transform.position = new Vector3(b.transform.position.x, b.transform.position.y, solution_depth);
                    }
                    current_level.blocks.Clear();
                    for (int y = 0; y < current_level.height; ++y)
                    {
                        for (int x = 0; x < current_level.width; ++x)
                        {
                            Block blk = current_level.block_at(x, y);
                            if (blk != null)
                            {
                                current_level.active_win_blocks.Add(blk.position);
                                blk.game_object = create_block_object(stuck_color);
                                blk.game_object.transform.position = board_coordinate_z(blk.position, block_depth);
                                blk.stuck = true;
                                current_level.blocks.Add(blk);
                            }
                        }
                    }
                    current_level.current_mode = Game.Mode.edit_solution;
                }
            }
            break;

        // create the moves
        // TODO (chs): store solution direction thingy
        case Game.Mode.edit_solution:

            choose_unstuck_blocks();
            int2 start_movement = KeyboardInput.get_key_movement();      // check if it's valid to move in this direction

            if (!start_movement.Equals(int2.zero))
            {
                if (move_direction.Equals(int2.zero))
                {
                    Debug.Log("Movement!");
                    move_direction = start_movement;
                    current_level.solution.Add(move_direction);
                }
                if (move_direction.Equals(start_movement))
                {
                    current_level.move_all_stuck_blocks(start_movement);
                }
                if (!fast_forward(current_level))
                {
                    current_level.move_all_stuck_blocks(start_movement * -1);
                    current_level.solution.RemoveAt(current_level.solution.Count - 1);
                    move_direction = int2.zero;
                }
            }
            if (Input.GetKeyDown(KeyCode.P))
            {
                current_level.set_banner_text("Play!");

                // create loaded_level from current_level
                foreach (Block b in current_level.blocks)
                {
                    current_level.active_start_blocks.Add(create_block(b));
                }

                cursor_quad.SetActive(false);
                start_level(current_level);
                current_level.current_mode = Game.Mode.make_move;
            }
            break;

        case Game.Mode.prepare_to_play:
            current_level.current_mode = Game.Mode.make_move;
            break;

        case Game.Mode.prepare_to_show_solution:
            if (current_level.mode_time_elapsed > 0.5f)
            {
                current_level.current_mode = Game.Mode.show_solution;
            }
            break;

        case Game.Mode.show_solution:
            if (solution_turn_enumerator < 0)
            {
                current_level.current_mode = Game.Mode.prepare_to_play;
            }
            else if (current_level.mode_time_elapsed > 0.333f)
            {
                current_move_vector        = current_level.solution[solution_turn_enumerator] * -1;
                solution_turn_enumerator  -= 1;
                current_move_result        = current_level.get_move_result(current_move_vector, out move_distance);
                move_start_time            = Time.realtimeSinceStartup;
                move_end_time              = move_start_time + (move_distance * 0.04f);
                current_level.current_mode = Game.Mode.make_help_move;
            }
            break;

        case Game.Mode.make_help_move:
            do_game_move(Game.Mode.show_solution);
            break;

        case Game.Mode.maybe:
            do_game_move(Game.Mode.make_move);
            break;

        case Game.Mode.make_move:
            current_move_vector = KeyboardInput.get_key_movement();
            if (!current_move_vector.Equals(int2.zero))
            {
                current_move_result        = current_level.get_move_result(current_move_vector, out move_distance);
                move_start_time            = Time.realtimeSinceStartup;
                move_end_time              = move_start_time + (move_distance * 0.05f);
                current_level.current_mode = Game.Mode.maybe;
            }
            break;

        case Game.Mode.failed:
            Color f = solution_color;
            win_flash_timer = (win_flash_timer + 1) % 10;
            if (win_flash_timer > 3)
            {
                f = solution_flash_color;
            }
            foreach (GameObject o in solution_objects)
            {
                set_color(o, f);
            }
            break;

        case Game.Mode.winner:
            Color c = win_color;
            win_flash_timer = (win_flash_timer + 1) % 10;
            if (win_flash_timer > 3)
            {
                c = stuck_color;
            }
            foreach (Block b in current_level.blocks)
            {
                set_color(b.game_object, c);
            }
            break;
        }

        debug($"MODE: {current_level.current_mode}");

        // space to reset level
        if (Input.GetKeyDown(KeyCode.Space))
        {
            start_level(current_level);
            current_level.current_mode = Game.Mode.make_move;
        }

        // Escape to quit
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            Statics.Quit();
        }
        // cube animation
        cube_angle += cube_angle_velocity;
        main_cube.transform.rotation = Quaternion.Euler(cube_angle.x, cube_angle.y, cube_angle.z);
        cube_angle_velocity         *= 0.95f;
        cube_angle *= 0.65f;

        current_level.update_banner_pos();

        debug_end_scene();
    }
Esempio n. 3
0
    // Update is called once per frame
    void Update()
    {
        current_level.update_banner_pos();

        switch (current_level.current_mode)
        {
        case Mode.make_move:
            flash_solution();
            current_move_vector = KeyboardInput.get_key_movement();
            if (!current_move_vector.Equals(int2.zero))
            {
                current_move_result = current_level.get_move_result(current_move_vector, out move_distance);
                Debug.Log($"MOVE: {current_move_result}");
                move_start_time            = Time.realtimeSinceStartup;
                move_end_time              = move_start_time + (move_distance * 0.025f);
                current_level.current_mode = Mode.maybe;
            }
            break;

        case Mode.prepare_to_play:
            current_level.current_mode = Mode.make_move;
            break;

        case Mode.maybe:
            flash_solution();
            do_game_move(Mode.make_move, Mode.winner);
            break;

        case Mode.failed:
        {
            float t = Mathf.Sin(current_level.mode_timer) * 0.35f + 0.5f;
            foreach (GameObject o in boundary_objects)
            {
                Main.set_color(o, Color.red);        // new Color(t, t, t, t));
            }
            if (current_level.mode_time_elapsed > 1)
            {
                SceneManager.LoadScene("GameScene", LoadSceneMode.Single);
            }
        }
        break;

        case Mode.solution_ended:
            animate_win(0);
            break;

        case Mode.winner:
            animate_win(1);
            break;

        case Mode.prepare_to_show_solution:
            if (current_level.mode_time_elapsed > 1)
            {
                current_level.current_mode = Mode.show_solution;
            }
            break;

        case Mode.show_solution:
            if (current_level.mode_time_elapsed > 0.333f)
            {
                current_move_vector        = current_level.solution[solution_turn_enumerator] * -1;
                solution_turn_enumerator  -= 1;
                current_move_result        = current_level.get_move_result(current_move_vector, out move_distance);
                move_start_time            = Time.realtimeSinceStartup;
                move_end_time              = move_start_time + (move_distance * 0.04f);
                current_level.current_mode = Mode.make_help_move;
            }
            break;

        case Mode.make_help_move:
            do_game_move(Mode.show_solution, Mode.solution_ended);
            break;
        }
        // space to reset level
        if (Input.GetKeyDown(KeyCode.Space))
        {
            restart();
        }

        if (Input.GetKeyDown(KeyCode.Escape))
        {
            quit();
        }

        // cube animation
        cube_angle += cube_angle_velocity;
        main_cube.transform.rotation = Quaternion.Euler(cube_angle.x, cube_angle.y, cube_angle.z);
        cube_angle_velocity         *= 0.95f;
        cube_angle *= 0.65f;
    }