122 lines
2.7 KiB
C++
122 lines
2.7 KiB
C++
#include <string>
|
|
#include <curses.h>
|
|
#include <unistd.h> // 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;
|
|
}
|