Fruit Ninja Game

Gameplay in which a combo is made and the player cuts the bomb, ending the game

Gameplay in which the player fails at cutting three fruit

Introduction

This project is a replication of the Fruit Ninja game, developed by Halfbrick Studios. It is an exercise in C++ programming and serves as an introduction to game development.

Project Specifications

  1. The fruit should follow a parabolic trajectory as governed by the laws of physics (with gravity acting downwards).  

  2. Fruits will be randomly generated in waves when the game starts. The number of fruits and bombs in each wave will increase as the player’s score increases (the difficulty will increase). 

  3. When the mouse button is pressed down and the mouse position enters a fruit and exits it while the mouse button is pressed down, the fruit will change from a whole circle to two halves of a circle. 

  4. When the fruit is “sliced,” it will continue falling in the same trajectory it set out on, but the fruit will no longer be able to be “sliced” again. In other words, the player cannot interact with a sliced fruit.  

  5. Player has 3 lives. If a fruit is not sliced and reaches the bottom of the screen, then one life is lost. A red circle indicates a lost life, and a green circle indicates a life. One of the green circles should turn red when a non-sliced fruit reaches the bottom of the screen. 

  6. If 3 lives are lost because 3 non-sliced fruit reach the bottom of the screen (the circles indicating lives are all red), then the game ends, and the menu should appear. 

  7. If a player slices a bomb, then the game ends and the menu should appear. 

  8. If three or more fruits are sliced in a single swipe while holding down the mouse button, then combo points are added to their total score along with the points they regularly get for slicing the individual fruits separately. The words “COMBO” will also appear on the screen. 

  9. There will be a pause button in the bottom left corner that, when clicked on, will take the player to the menu where they are able to restart the game or resume their current game.

  10. The positions of the mouse cursor will be tracked by a series of small white circles when the mouse button is held down and as the player moves the cursor older circles will disappear and new ones will be constructed where the cursor moves. 


Implementation

A snippet of code for the game is shown below. The on_frame function is run at the start of each frame. Within on_frame, a series of update functions for the blade, bombs, and fruits are executed. Updates are also made for the game state, score, and time. The update function for the fruit is provided. To view the entire codebase, click on the button.

Model::on_frame(double dt)
{
    update_blade();
    if (!game_over) {
        if (abs(elapsed_time/5.0 - round(elapsed_time/5.0)) < 0.002) {
            swipe_combo = 0;
            generate_fruitsnbombs();
        }
        update_bomb(dt);
        add_combo_points();
        update_fruit(dt);
        pause_game();
        elapsed_time += dt;
        if (display_combo) {
            display_time += dt;
            if (display_time > 2.0) {
                display_combo = false;
            }
        }
    }
    else {
        display_combo = false;
        update_gamestate();
    }
}

Model::update_fruit(double dt)
{
    if (!mouse_pressed) {
        swipe_combo = 0;
    }
    for (Fruit& fruit : fruits) {
        if (fruit.is_active() && mouse_pressed) {
            if (!fruit.blade_entered && fruit.inside_fruit(mouse_position)) {
                fruit.blade_entered = true;
            } else if (fruit.blade_entered &&
                       !fruit.inside_fruit(mouse_position)) {
                fruit.make_inactive();
                increase_score(1);
                swipe_combo += 1;
            }
        }
        else {
            fruit.blade_entered = false;
        }
        if (!fruit.below_screen()) {
            fruit.advance_position(dt);
        }
        else {
            if (fruit.is_active()) {
                decrease_lives();
                if (game_over) {
                    break;
                }
            }
            fruit = fruits.back();
            fruits.pop_back();
        }
    }
}
Previous
Previous

Particle Tracking in an Accelerator’s Vacuum Chamber

Next
Next

Angry Birds Space: A Custom Physics Engine