/* Copyright (c)1998 by Pros Chum e-mail: gt7158a@prism.gatech.edu This program demonstrates a psuedo physics model of a space racing game. It was originally intended to include a track on top of a space-field background where you could race simultaneously between other human and/or computer opponents via the network or on the same computer. The race was going to incorporate a panning viewport to show the section of the track that the player is on. The tracks could be made out of bezier curves or some similar method. If anyone would like to aid me in completing this project together then please don't hesitate to respond via the e-mail address above. I haven't been able to complete a good game yet, and would like to try to do it as a team. If anyone is interested in helping to code or draw then e-mail me. However if you do decide to use this code in some form or manner in your own projects, then please e-mail me something (e.g. A thank-you note, the game, comments, etc). I would like to hear if this has been helpful or confusing. */ #include #include #include #include #include #include #include typedef unsigned char UINT8; typedef struct { double x,y; } Vector2d; #define kPi 3.14159 #define D_WIDTH 640 #define D_HEIGHT 480 #define kSpeed 0.2 #define kSpeedForward 1.5 #define kSpeedBackward 1.2 #define kTurnVelocity 0.2 // Percentage of current direction // Later modify code to create less torque for higher speeds FILE * fdebug; float hi = 0; Vector2d CarLocal[] = { {-5,5}, {8,0}, {-5,-5} }; Vector2d CarWorld[3]; void SetMode( int Mode ) { union REGS r; r.x.ax = Mode; int86 ( 0x10, &r, &r ); } double inline Mag( double x, double y ) { return sqrt( x*x + y*y ); } void Input ( Vector2d * Dir, Vector2d * TurVec, int * done ) { Vector2d DirUnit; double DirMag = Mag( Dir->x, Dir->y ); DirUnit.x = Dir->x / DirMag; DirUnit.y = Dir->y / DirMag; TurVec->x = 0; TurVec->y = 0; if (kbhit()) { switch (getch()) { case 'q': case 27: *done = 1; break; case '5': // Forward Dir->x = Dir->x + DirUnit.x * kSpeed; Dir->y = Dir->y + DirUnit.y * kSpeed; break; case '2': // Backward Dir->x = Dir->x - DirUnit.x * kSpeedBackward; Dir->y = Dir->y - DirUnit.y * kSpeedBackward; break; case '1': // Left // Create perpendicular vector -90 degree rotation with respect to Direction vector TurVec->x = Dir->y; TurVec->y = -Dir->x; // Make turn velocity a portion of the strength of the current direction TurVec->x *= kTurnVelocity; TurVec->y *= kTurnVelocity; break; case '3': // Right // Create perpendicular vector +90 degree rotation with respect to Direction vector TurVec->x = -Dir->y; TurVec->y = Dir->x; // Make turn velocity a portion of the strength of the current direction TurVec->x *= kTurnVelocity; TurVec->y *= kTurnVelocity; break; default: break; } } } void Rotate( double angle, Vector2d * loc, Vector2d * world ) { double sinr = sin(angle); double cosr = cos(angle); world->x = loc->x * cosr - loc->y * sinr; world->y = loc->x * sinr + loc->y * cosr; } void DrawCar( Vector2d * Pos, Vector2d * Dir ) { xycoord car[3]; double theta; double mag = Mag( Dir->x, Dir->y ); theta = asin( Dir->y / mag ); if (Dir->x < 0) { theta = -theta - kPi; } for (int i = 0; i < 3; i++) { Rotate( theta, &CarLocal[i], &CarWorld[i] ); car[i].xcoord = (int)(CarWorld[i].x + Pos->x); car[i].ycoord = (int)(CarWorld[i].y + Pos->y); } _polygon( _GFILLINTERIOR, 3, (xycoord *)&car[0] ); } void main() { fdebug = fopen( "debug.txt", "w" ); // SetMode ( 0x13 ); _setvideomode( _VRES16COLOR ); Vector2d Pos, CurPos; Vector2d Dir, TurnVec; Pos.x = 5; Pos.y = D_HEIGHT / 2; Dir.x = 1; Dir.y = 0; TurnVec.x = 0; TurnVec.y = 0; int done = 0; while (!done) { float DirMag = Mag( Dir.x, Dir.y ); Dir.x += TurnVec.x; Dir.y += TurnVec.y; float TurnPlusDirMag = Mag( Dir.x, Dir.y ); Dir.x /= TurnPlusDirMag; Dir.y /= TurnPlusDirMag; // Make the new direction the same speed as before Dir.x *= DirMag; Dir.y *= DirMag; CurPos.x = Pos.x + Dir.x; CurPos.y = Pos.y + Dir.y; if (CurPos.x < 0) { CurPos.x = -CurPos.x; Dir.x = -Dir.x * kSpeed; // Decrease the speed when hitting a boundary } if (CurPos.x > D_WIDTH) { CurPos.x = D_WIDTH - (CurPos.x - D_WIDTH) + 1; Dir.x = -Dir.x * kSpeed; } if (CurPos.y < 0) { CurPos.y = -CurPos.y; Dir.y = -Dir.y * kSpeed; } if (CurPos.y > D_HEIGHT) { CurPos.y = D_HEIGHT - (CurPos.y - D_HEIGHT) + 1; Dir.y = -Dir.y * kSpeed; } // screen[ (int)CurPos.x + (int)CurPos.y * 320 ] = 2; // _setcolor(2); // _setpixel( (int)CurPos.x, (int)CurPos.y ); _setcolor(2); DrawCar( &CurPos, &Dir ); delay( 80 ); _setcolor(0); DrawCar( &CurPos, &Dir ); // screen[ (int)CurPos.x + (int)CurPos.y * 320 ] = 0; Input ( &Dir, &TurnVec, &done ); Pos.x = CurPos.x; Pos.y = CurPos.y; } // SetMode ( 0x03 ); _setvideomode( _DEFAULTMODE ); fclose( fdebug ); }