//=========================================================================== // Kitten, Yarn & Baby // Inspired by an MIT Media Lab installation at SIGGRAPH //=========================================================================== #include #pragma hdrstop #include // Type this in for math functions #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { DoubleBuffered = true; } //--------------------------------------------------------------------------- //=========================================================================== // VARIABLES //=========================================================================== bool stop = true; double ballCenterX; double ballCenterY; double ballRight; double ballBottom; int ballDownX, ballDownY; bool ballDown = false; double kittenCenterX ; double kittenCenterY; double kittenRight; double kittenBottom; int kittenDownX, kittenDownY; bool kittenDown = false; int worldTime = 0; //double force, mass, acceleration; double distanceX, distanceY; double deltaX, deltaY; bool xIsNegative, yIsNegative; bool attract = true; //=========================================================================== // FUNCTIONS //=========================================================================== void reset (void) { worldTime = 0; Form1->EditTime->Text = worldTime; } void step (void) { worldTime++; Form1->EditTime->Text = worldTime; // if kitten is out of bounds, then attract if ( Form1->ImageKitten->Top <= 0 || Form1->ImageKitten->Left <= 0 || kittenBottom >= Form1->Height - 37 || kittenRight >= Form1->Width - 13) { Form1->RadioGroupField->ItemIndex = 0; } // get kitten coordinates kittenCenterX = Form1->ImageKitten->Left + (Form1->ImageKitten->Width / 2); kittenCenterY = Form1->ImageKitten->Top + (Form1->ImageKitten->Height / 2); kittenRight = Form1->ImageKitten->Left + Form1->ImageKitten->Width; kittenBottom = Form1->ImageKitten->Top + Form1->ImageKitten->Height; // get ball coordinates ballCenterX = Form1->ImageBall->Left + (Form1->ImageBall->Width / 2); ballCenterY = Form1->ImageBall->Top + (Form1->ImageBall->Height / 2); ballRight = Form1->ImageBall->Left + Form1->ImageBall->Width; ballBottom = Form1->ImageBall->Top + Form1->ImageBall->Height; // move kitten left or right distanceX = Form1->ImageBall->Left - kittenCenterX; if (distanceX < 0) { xIsNegative = true; } else xIsNegative = false; distanceX = abs(distanceX); deltaX = sqrt(distanceX) * .7; if (xIsNegative) deltaX = 0 - deltaX; if (Form1->RadioGroupField->ItemIndex == 0) { // Attract Form1->ImageKitten->Left = Form1->ImageKitten->Left + deltaX; } else { // Repulse Form1->ImageKitten->Left = Form1->ImageKitten->Left - deltaX; } // move kitten up or down distanceY = ballCenterY - kittenBottom; if (distanceY < 0) { yIsNegative = true; } else yIsNegative = false; distanceY = abs(distanceY); deltaY = sqrt(distanceY) * .7; if (yIsNegative) deltaY = 0 - deltaY; if (Form1->RadioGroupField->ItemIndex == 0) { // Attract Form1->ImageKitten->Top = Form1->ImageKitten->Top + deltaY; } else { // Repulse Form1->ImageKitten->Top = Form1->ImageKitten->Top - deltaY; } } void go (void) { Form1->TimerWorld->Enabled = true; step(); } //=========================================================================== // EVENT HANDLERS //=========================================================================== //----------------------------------------------------------- Ball Mouse Move void __fastcall TForm1::ImageBallMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { if (ballDown) { ImageBall->Left = ImageBall->Left + X - ballDownX; ImageBall->Top = ImageBall->Top + Y - ballDownY; } } //----------------------------------------------------------- Ball Mouse Down void __fastcall TForm1::ImageBallMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { ballDown = true; ballDownX = X; ballDownY = Y; } //------------------------------------------------------------- Ball Mouse Up void __fastcall TForm1::ImageBallMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { ballDown = false; } //--------------------------------------------------------- Kitten Mouse Move void __fastcall TForm1::ImageKittenMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { if (kittenDown) { ImageKitten->Left = ImageKitten->Left + X - kittenDownX; ImageKitten->Top = ImageKitten->Top + Y - kittenDownY; } } //--------------------------------------------------------- Kitten Mouse Down void __fastcall TForm1::ImageKittenMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { kittenDown = true; kittenDownX = X; kittenDownY = Y; } //----------------------------------------------------------- Kitten Mosue Up void __fastcall TForm1::ImageKittenMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { kittenDown = false; kittenCenterX = Form1->ImageKitten->Left + (Form1->ImageKitten->Width / 2); kittenCenterY = Form1->ImageKitten->Top + (Form1->ImageKitten->Height / 2); kittenRight = Form1->ImageKitten->Left + Form1->ImageKitten->Width; kittenBottom = Form1->ImageKitten->Top + Form1->ImageKitten->Height; } //----------------------------------------------------------------- Go Button void __fastcall TForm1::ButtonGoClick(TObject *Sender) { Form1->TimerWorld->Enabled = true; go(); } //--------------------------------------------------------------- Stop Button void __fastcall TForm1::ButtonStopClick(TObject *Sender) { TimerWorld->Enabled = false; } //-------------------------------------------------------------- Reset Button void __fastcall TForm1::ButtonResetClick(TObject *Sender) { reset(); } //--------------------------------------------------------------- World Timer void __fastcall TForm1::TimerWorldTimer(TObject *Sender) { step(); } //------------------------------------------------------- Attract/Repel Timer void __fastcall TForm1::TimerAttractRepelTimer(TObject *Sender) { if (Form1->RadioGroupField->ItemIndex == 0) { Form1->RadioGroupField->ItemIndex = 1; } else { Form1->RadioGroupField->ItemIndex = 0; } } //----------------------------------------------------------------------- End