#include #include #include // usleep struct Object { int x, y; // center int width, height; // full, not half double scale; int Left() const { return x - (width / 2.0) * scale; } int Right() const { return x + (width / 2.0) * scale; } int Top() const { return y - (height / 2.0) * scale; } int Bottom() const { return y + (height / 2.0) * scale; } }; bool InBounds(Object bounds, Object object); int main(int argc, char *argv[]) { WINDOW * mainwin; // Initialize ncurses if ( (mainwin = initscr()) == NULL ) { fprintf(stderr, "Error initialising ncurses.\n"); exit(EXIT_FAILURE); } Object screen; screen.x = 20; screen.width = 20; screen.y = 13; screen.height = 6; screen.scale = 1.0; const Object initial_screen = screen; Object object; object.x = 3; object.width = 5; object.y = 6; object.height = 4; object.scale = 1.0; const Object initial_object = object; double scale_multiplier = 0.2; while(true) { screen = initial_screen; object = initial_object; object.scale *= scale_multiplier; scale_multiplier *= 2; // NOTE: This causes it to pause on each resize when it is immediately covered. // To avoid this, move this initialization outside of the "while(true)" loop. bool covered_last_frame = false; const int num_rows = 14; for(auto r = 0; r < num_rows; ++r) { const int num_columns = 40; for(auto c = 0; c < num_columns; ++c) { // DRAW clear(); int left; left = screen.Left(); if(left < 0) left = 0; // NOTE: +1 to account for full width std::string scr(screen.Right() - left + 1, '+'); for(auto row = screen.Top(); row <= screen.Bottom(); ++row) mvaddstr(row, left, scr.c_str()); left = object.Left(); if(left < 0) left = 0; // NOTE: +1 to account for full width std::string obj(object.Right() - left + 1, '*'); for(auto row = object.Top(); row <= object.Bottom(); ++row) mvaddstr(row, left, obj.c_str()); bool covered = InBounds(screen, object); mvaddstr(1, 1, covered ? "Covered: YES" : "Covered: NO"); refresh(); // When there is a change in "covered" status, freeze to show it: if(covered != covered_last_frame) usleep(300000); // 3/10 sec else usleep(5000); // quick (adjust to your PC's performance) covered_last_frame = covered; ++object.x; } ++object.y; object.x -= num_columns; } } // destroy ncurses delwin(mainwin); endwin(); refresh(); return 0; } bool InBounds(Object bounds, Object object) { if(object.Right() < bounds.Left() || object.Left() > bounds.Right() || object.Bottom() < bounds.Top() || object.Top() > bounds.Bottom()) return false; return true; }