void Clear_Random_Field() /* Clear a random field to RB_EMPTY. There's a great chance, that we get an empty field, so we retry 50 times */ { int i,x,y; for(i=0;i<50;i++) /* Retry 50 times */ { x=(rand()%(RB_X-2))+1; /* Random position on playing ground */ y=(rand()%(RB_Y-2))+1; if(RB_Array[x][y]!=RB_EMPTY) /* Clear the symbol, but only if the field isn't empty */ { RB_Array[x][y]=RB_EMPTY; Draw_Bitmap(RB_EMPTY,ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE); break; } } }
void Put_Random_Field(void) /* Put a random symbol in a random field */ { int i,k,x,y; do { x=(rand()%(RB_X-2))+1; /* Random position on playing ground */ y=(rand()%(RB_Y-2))+1; i=(rand()%136); /* Fill symbols with probability classes */ if((i>=0) && (i<17)) k=RB_VP; if((i>=17) && (i<35)) k=RB_MP; if((i>=35) && (i<60)) k=RB_GP; if((i>=60) && (i<105)) k=RB_BP; if((i>=105) && (i<115)) k=RB_LX; if((i>=115) && (i<125)) k=RB_RX; if((i>=125) && (i<136)) k=RB_HOLE; if(RB_Array[x][y]==RB_EMPTY) /* Add the symbol, but only if the field is empty */ { RB_Array[x][y]=k; Draw_Bitmap(k,ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE); break; } }while(1); /* Loop until one symbol added in a random field */ }
int Game_Main(void *parms) { // this is the workhorse of your game it will be called // continuously in real-time this is like main() in C // all the calls for you game go here! int index; // looping var int dx,dy; // general deltas used in collision detection static int player_moving = 0; // tracks player motion static PALETTEENTRY glow = {0,0,0,PC_NOCOLLAPSE}; // used to animation red border static int glow_count = 0, glow_dx = 5; // start the timing clock Start_Clock(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // lock the back buffer DDraw_Lock_Back_Surface(); // draw the background reactor image Draw_Bitmap(&reactor, back_buffer, back_lpitch, 0); // unlock the back buffer DDraw_Unlock_Back_Surface(); // read keyboard and other devices here DInput_Read_Keyboard(); // reset motion flag player_moving = 0; // test direction of motion, this is a good example of testing the keyboard // although the code could be optimized this is more educational if (keyboard_state[DIK_RIGHT] && keyboard_state[DIK_UP]) { // move skelaton skelaton.x+=2; skelaton.y-=2; dx=2; dy=-2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_NEAST) Set_Animation_BOB(&skelaton,SKELATON_NEAST); } // end if else if (keyboard_state[DIK_LEFT] && keyboard_state[DIK_UP]) { // move skelaton skelaton.x-=2; skelaton.y-=2; dx=-2; dy=-2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_NWEST) Set_Animation_BOB(&skelaton,SKELATON_NWEST); } // end if else if (keyboard_state[DIK_LEFT] && keyboard_state[DIK_DOWN]) { // move skelaton skelaton.x-=2; skelaton.y+=2; dx=-2; dy=2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_SWEST) Set_Animation_BOB(&skelaton,SKELATON_SWEST); } // end if else if (keyboard_state[DIK_RIGHT] && keyboard_state[DIK_DOWN]) { // move skelaton skelaton.x+=2; skelaton.y+=2; dx=2; dy=2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_SEAST) Set_Animation_BOB(&skelaton,SKELATON_SEAST); } // end if else if (keyboard_state[DIK_RIGHT]) { // move skelaton skelaton.x+=2; dx=2; dy=0; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_EAST) Set_Animation_BOB(&skelaton,SKELATON_EAST); } // end if else if (keyboard_state[DIK_LEFT]) { // move skelaton skelaton.x-=2; dx=-2; dy=0; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_WEST) Set_Animation_BOB(&skelaton,SKELATON_WEST); } // end if else if (keyboard_state[DIK_UP]) { // move skelaton skelaton.y-=2; dx=0; dy=-2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_NORTH) Set_Animation_BOB(&skelaton,SKELATON_NORTH); } // end if else if (keyboard_state[DIK_DOWN]) { // move skelaton skelaton.y+=2; dx=0; dy=+2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_SOUTH) Set_Animation_BOB(&skelaton,SKELATON_SOUTH); } // end if // only animate if player is moving if (player_moving) { // animate skelaton Animate_BOB(&skelaton); // see if skelaton hit a wall // lock surface, so we can scan it DDraw_Lock_Back_Surface(); // call the color scanner with WALL_ANIMATION_COLOR, the color of the glowing wall // try to center the scan in the center of the object to make it // more realistic if (Color_Scan(skelaton.x+16, skelaton.y+16, skelaton.x+skelaton.width-16, skelaton.y+skelaton.height-16, WALL_ANIMATION_COLOR, WALL_ANIMATION_COLOR, back_buffer,back_lpitch)) { // back the skelaton up along its last trajectory skelaton.x-=dx; skelaton.y-=dy; } // end if // done, so unlock DDraw_Unlock_Back_Surface(); // check if skelaton is off screen if (skelaton.x < 0 || skelaton.x > (screen_width - skelaton.width)) skelaton.x-=dx; if (skelaton.y < 0 || skelaton.y > (screen_height - skelaton.height)) skelaton.y-=dy; } // end if // draw the skelaton Draw_BOB(&skelaton, lpddsback); // animate color glow.peGreen+=glow_dx; // test boundary if (glow.peGreen == 0 || glow.peGreen == 255) glow_dx = -glow_dx; Set_Palette_Entry(WALL_ANIMATION_COLOR, &glow); // draw some text Draw_Text_GDI("I STILL HAVE A BONE TO PICK!",0,screen_height - 32,WALL_ANIMATION_COLOR,lpddsback); Draw_Text_GDI("USE ARROW KEYS TO MOVE, <ESC> TO EXIT.",0,0,RGB(32,32,32),lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30ish fps Wait_Clock(30); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } // end if // return success return(1); } // end Game_Main
void Draw_Thread(ULONG ulThreadArg) { if(!(habDT=WinInitialize(0UL))) /* Initialize client window */ GEN_ERR(habDT,hwndFrame,hwndClient); /* Create a message queue */ if(!(hmqDT=WinCreateMsgQueue(habDT,0UL))) GEN_ERR(habDT,hwndFrame,hwndClient); if(!(hpsDT=WinGetPS(hwndClient))) /* Get a presentation space for client area */ GEN_ERR(habDT,hwndFrame,hwndClient); /* Initialize message queue */ WinPostQueueMsg(hmqDT,DT_PAINT,0UL,0UL); while(qmsqDT.msg!=DT_EXIT) { if(WinPeekMsg(habDT, /* Get the message into message queue */ &qmsqDT, /* Message structure */ NULLHANDLE, /* Window filter (none) */ 0UL, /* First message ID */ 0UL, /* Last message ID */ PM_REMOVE)==FALSE) /* Options (remove message) */ qmsqDT.msg=DT_IDLE; /* If no message available, assume idle */ switch(qmsqDT.msg) { case DT_PAINT: /* Repaint client window */ { RECTL rclDT; int x,y; /* Repaint client window aread */ WinQueryWindowRect(hwndClient,&rclDT); WinFillRect(hpsDT,&rclDT,CLR_WHITE); for(x=1;x<RB_X;x++) /* Draw the entries on playing ground */ for(y=1;y<RB_Y;y++) if(RB_Array[x][y]!=RB_EMPTY) Draw_Bitmap(RB_Array[x][y],ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE); break; } case DT_LBUTTON: { int x,y; /* Left button was pressed, get the location, add \ to RB_Array, and draw \ bitmap, if field is emty */ x=(LONGFROMMP(qmsqDT.mp1)/RB_SIZE)+1; y=(LONGFROMMP(qmsqDT.mp2)/RB_SIZE)+1; if(RB_Array[x][y]==RB_EMPTY) { RB_Array[x][y]=RB_LX; Draw_Bitmap(RB_LX,ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE); } break; } case DT_RBUTTON: { int x,y; /* Right button was pressed, get the location, add / to RB_Array, and draw / bitmap, if field is emty */ x=(LONGFROMMP(qmsqDT.mp1)/RB_SIZE)+1; y=(LONGFROMMP(qmsqDT.mp2)/RB_SIZE)+1; if(RB_Array[x][y]==RB_EMPTY) { RB_Array[x][y]=RB_RX; Draw_Bitmap(RB_RX,ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE); } break; } case DT_IDLE: { if(runRB==TRUE) { ULONG x,y,Symbol; /* Under DOS we would query the time in milliseconds from the system timer, to adjust graphics. This is accurate, but in a multitasking in a multitasking system, we must assume being pre-empted. Therefore we can't have an exact time bases. Hope that the system timer counts more often than all 31 milliseconds in future releases/machines */ /* Draw bitmap */ switch(RB_Dir) /* Test that RollBall doesn't leave borders. A border reverses the direction and produces a beep */ { case UP: RB_PosY++; if((RB_PosY+RB_SIZE)>=((RB_Y-2)*RB_SIZE)) { RB_PosY=(RB_Y-3)*RB_SIZE; RB_Dir=DOWN; DosBeep(800,50); } break; case DOWN: RB_PosY--; if(RB_PosY<0) { RB_PosY=0; RB_Dir=UP; DosBeep(800,50); } break; case LEFT: RB_PosX--; if(RB_PosX<0) { RB_PosX=0; RB_Dir=RIGHT; DosBeep(800,50); } break; case RIGHT: RB_PosX++; if((RB_PosX+RB_SIZE)>=((RB_X-2)*RB_SIZE)) { RB_PosX=(RB_X-3)*RB_SIZE; RB_Dir=LEFT; DosBeep(800,50); } break; } /* Draw RollBall at new position */ Draw_Bitmap(RB_RB,ROP_SRCCOPY,RB_PosX,RB_PosY); /* Now, test if the middle of RollBall is over any symbol. If a symbol is found, add points, deflect or end game */ /* RB_Array is 1 based, because 0 indices are the playing ground borders */ x=((RB_PosX)/RB_SIZE)+1; y=((RB_PosY)/RB_SIZE)+1; /* A Symbol if RB_SIZE*RB_SIZE in size, that means RollBall is exactly over a symbol, if the lower left edges of both symbols match. Then, and only then, we count points, deflect or loose */ if((RB_PosX==(x-1)*RB_SIZE) && (RB_PosY==(y-1)*RB_SIZE)) Symbol=RB_Array[x][y]; else Symbol=RB_EMPTY; switch(Symbol) { case RB_LX: /* We got a \ deflector */ { switch(RB_Dir) /* \ deflects direction of RollBall */ { case RIGHT: RB_Dir=DOWN; break; case UP: RB_Dir=LEFT; break; case LEFT: RB_Dir=UP; break; case DOWN: RB_Dir=RIGHT; break; } /* Remove deflector */ RB_Array[x][y]=RB_EMPTY; break; } case RB_RX: /* We got a / deflector */ { switch(RB_Dir) /* / deflects direction of RollBall */ { case RIGHT: RB_Dir=UP; break; case UP: RB_Dir=RIGHT; break; case LEFT: RB_Dir=DOWN; break; case DOWN: RB_Dir=LEFT; break; } /* Remove deflector */ RB_Array[x][y]=RB_EMPTY; DosBeep(600,20); break; } case RB_BP: /* We got a point */ case RB_GP: case RB_MP: case RB_VP: { /* Add the points for each symbol */ RB_Point[0]+=RB_Point[Symbol]; /* Remove the point */ RB_Array[x][y]=RB_EMPTY; if (ulDelay) ulDelay--; DosBeep(700,20); break; } case RB_HOLE: /* We got a hole, sorry but RollBall will be killed. We disable RollBall from rolling, and send a ID_STOPTHREAD message to our window, which informs the user about the points with a message box */ { int freq; for(freq=5000;freq>100;freq-=100) DosBeep(freq,5); runRB=FALSE; /* Prevent RollBall from further rolling */ WinPostMsg(hwndClient,WM_COMMAND,(MPARAM)ID_STOPTHREAD,(MPARAM)0); break; } } /* Randomly add and remove symbols on playing ground */ if((rand()%500)<2) { Put_Random_Field(); Clear_Random_Field(); } } } } DosOpen("TIMER0$", &hfile, &ulAction, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, NULL); ulDelay2=ulDelay/2; DosDevIOCtl(hfile, HRT_IOCTL_CATEGORY, HRT_BLOCKUNTIL, &ulDelay2, ulSize2, &ulSize2, NULL, 0, NULL); DosClose(hfile); } WinReleasePS(hpsDT); /* Clean up */ WinDestroyMsgQueue(hmqDT); WinTerminate(habDT); DosExit(EXIT_THREAD,0UL); }
int Game_Main(void *parms, int num_parms) { // this is the workhorse of your game it will be called // continuously in real-time this is like main() in C // all the calls for you game go here! int index; // looping var // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || KEY_DOWN(VK_SPACE)) PostMessage(main_window_handle, WM_DESTROY,0,0); // start the timing clock Start_Clock(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // get the input from the mouse lpdimouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mouse_state); // move the mouse cursor mouse_x+=(mouse_state.lX); mouse_y+=(mouse_state.lY); // test bounds // first x boundaries if (mouse_x >= screen_width) mouse_x = screen_width-1; else if (mouse_x < 0) mouse_x = 0; // now the y boundaries if (mouse_y >= screen_height) mouse_y= screen_height-1; else if (mouse_y < 0) mouse_y = 0; // position the pointer bob to the mouse coords pointer.x = mouse_x - 16; pointer.y = mouse_y - 16; // test what the user is doing with the mouse if ((mouse_x > 3) && (mouse_x < 500-3) && (mouse_y > 3) && (mouse_y < SCREEN_HEIGHT-3)) { // mouse is within canvas region // if left button is down then draw if (mouse_state.rgbButtons[0]) { // test drawing mode if (buttons_state[BUTTON_PENCIL]) { // draw a pixel Draw_Pixel(mouse_x, mouse_y, mouse_color, canvas.buffer, canvas.width); Draw_Pixel(mouse_x+1, mouse_y, mouse_color, canvas.buffer, canvas.width); Draw_Pixel(mouse_x, mouse_y+1, mouse_color, canvas.buffer, canvas.width); Draw_Pixel(mouse_x+1, mouse_y+1, mouse_color, canvas.buffer, canvas.width); } else { // draw spray for (index=0; index<10; index++) { // get next particle int sx=mouse_x-8+rand()%16; int sy=mouse_y-8+rand()%16; // make sure particle is in bounds if (sx > 0 && sx < 500 && sy > 0 && sy < screen_height) Draw_Pixel(sx, sy, mouse_color, canvas.buffer, canvas.width); } // end for index } // end else } // end if left button else // right button is eraser if (mouse_state.rgbButtons[1]) { // test drawing mode if (buttons_state[BUTTON_PENCIL]) { // erase a pixel Draw_Pixel(mouse_x, mouse_y, 0, canvas.buffer, canvas.width); Draw_Pixel(mouse_x+1, mouse_y, 0, canvas.buffer, canvas.width); Draw_Pixel(mouse_x, mouse_y+1, 0, canvas.buffer, canvas.width); Draw_Pixel(mouse_x+1, mouse_y+1, 0, canvas.buffer, canvas.width); } // end if else { // erase spray for (index=0; index<20; index++) { // get next particle int sx=mouse_x-8+rand()%16; int sy=mouse_y-8+rand()%16; // make sure particle is in bounds if (sx > 0 && sx < 500 && sy > 0 && sy < screen_height) Draw_Pixel(sx, sy, 0, canvas.buffer, canvas.width); } // end for index } // end else } // end if left button } // end if else if ( (mouse_x > 500+16) && (mouse_x < 500+16+8*9) && (mouse_y > 8) && (mouse_y < 8+32*9)) { // within palette // test if button left button is down if (mouse_state.rgbButtons[0]) { // see what color cell user is pointing to int cell_x = (mouse_x - (500+16))/9; int cell_y = (mouse_y - (8))/9; // change color mouse_color = cell_x + cell_y*8; } // end if } // end if else if ((mouse_x > 500) && (mouse_x < (500+100)) && (mouse_y > 344) && (mouse_y < (383+34)) ) { // within button area // test for each button for (index=0; index<4; index++) { if ((mouse_x > buttons_x[index]) && (mouse_x < (buttons_x[index]+32)) && (mouse_y > buttons_y[index]) && (mouse_y < (buttons_y[index]+34)) ) break; } // end for // at this point we know where the user is, now determine what he // is doing with the buttons switch(index) { case BUTTON_SPRAY: { // if left button is down simply activate spray mode if (mouse_state.rgbButtons[0]) { // depress button buttons_state[index] = 1; // de-activate pencil mode buttons_state[BUTTON_PENCIL] = 0; } // end if else { // make sure button is up // buttons_state[index] = 0; } // end else } break; case BUTTON_PENCIL: { // if left button is down activate spray mode if (mouse_state.rgbButtons[0]) { // depress button buttons_state[index] = 1; // de-activate spray mode buttons_state[BUTTON_SPRAY] = 0; } // end if else { // make sure button is up // buttons_state[index] = 0; } // end else } break; case BUTTON_ERASE: { // test if left button is down, if so clear screen if (mouse_state.rgbButtons[0]) { // clear memory memset(canvas.buffer,0,canvas.width*canvas.height); // depress button buttons_state[index] = 1; } // end if else { // make sure button is up buttons_state[index] = 0; } // end else } break; case BUTTON_EXIT: { // test if left button down, if so bail if (mouse_state.rgbButtons[0]) PostMessage(main_window_handle, WM_DESTROY,0,0); } break; } // end switch } // end if else { // no mans land } // end else // lock back buffer DDraw_Lock_Back_Surface(); // draw the canvas Draw_Bitmap(&canvas, back_buffer, back_lpitch,0); // draw control panel Draw_Bitmap(&cpanel,back_buffer,back_lpitch,0); // unlock back buffer DDraw_Unlock_Back_Surface(); // draw the color palette for (int col=0; col < 256; col++) { Draw_Rectangle(500+16+(col%8)*9, 8+(col/8)*9, 500+16+(col%8)*9+8, 8+(col/8)*9+8, col,lpddsback); } // end for col // draw the current color selected Draw_Rectangle(533,306,533+34,306+34,mouse_color,lpddsback); // draw the buttons for (index=0; index<4; index++) { // set position of button bob buttons.x = buttons_x[index]; buttons.y = buttons_y[index]; // now select the on/off frame based on if the // button is off if (buttons_state[index]==0) buttons.curr_frame = index; else // button is on buttons.curr_frame = index+4; // draw the button Draw_BOB(&buttons, lpddsback); } // end for index static int green = 0; // display coords sprintf(buffer,"Pointer (%d,%d)",mouse_x,mouse_y); Draw_Text_GDI(buffer, 8,screen_height - 16,RGB(0,255,0),lpddsback); Draw_Text_GDI("T3D Paint Version 2.0 - Press <ESC> to Exit.",0,0,RGB(0,(green & 255),0),lpddsback); // a little animation ++green; // draw the cursor last Draw_BOB(&pointer,lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30 fps Wait_Clock(30); // return success return(1); } // end Game_Main
int Game_Main(void *parms) { // this is the workhorse of your game it will be called // continuously in real-time this is like main() in C // all the calls for you game go here! int index; // looping var static int curr_angle = 0; // current angle of elevation from horizon static float curr_vel = 10; // current velocity of projectile // start the timing clock Start_Clock(); // clear the drawing surface //DDraw_Fill_Surface(lpddsback, 0); // lock back buffer and copy background into it DDraw_Lock_Back_Surface(); // draw background Draw_Bitmap(&background_bmp, back_buffer, back_lpitch,0); // do the graphics Draw_Polygon2D(&cannon, back_buffer, back_lpitch); // unlock back surface DDraw_Unlock_Back_Surface(); // read keyboard DInput_Read_Keyboard(); // test for rotate if ((curr_angle < 90) && keyboard_state[DIK_UP]) // rotate left { Rotate_Polygon2D_Mat(&cannon, -5); curr_angle+=5; } // end if else if ((curr_angle > 0) &&keyboard_state[DIK_DOWN]) // rotate right { Rotate_Polygon2D_Mat(&cannon, 5); curr_angle-=5; } // end if // test for projectile velocity if (keyboard_state[DIK_RIGHT]) { if (curr_vel < 30) curr_vel+=0.1; } // end if else if (keyboard_state[DIK_LEFT]) { if (curr_vel > 0) curr_vel-=0.1; } // end if // test for wind force if (keyboard_state[DIK_W]) { if (wind_force < 2) wind_force+=0.01; } // end if else if (keyboard_state[DIK_E]) { if (wind_force > -2) wind_force-=0.01; } // end if // test for gravity force if (keyboard_state[DIK_G]) { if (gravity_force < 15) gravity_force+=0.1; } // end if else if (keyboard_state[DIK_B]) { if (gravity_force > -15) gravity_force-=0.1; } // end if // test for fire! if (keyboard_state[DIK_LCONTROL]) { Fire_Projectile(curr_angle, curr_vel); } // end fire // move all the projectiles Move_Projectiles(); // draw the projectiles Draw_Projectiles(); // draw the title Draw_Text_GDI("Trajectory DEMO, Press <ESC> to Exit.",10, 10,RGB(255,255,255), lpddsback); Draw_Text_GDI("<RIGHT>, <LEFT> to adjust velocity, <UP>, <DOWN> to adjust angle",10, 25, RGB(255,255,255), lpddsback); Draw_Text_GDI("<G>, <B> to adjust gravity, <W>, <E> to adjust wind, <CTRL> to fire.",10, 40, RGB(255,255,255), lpddsback); sprintf(buffer, "Ang=%d, Vel=%f", curr_angle, curr_vel); Draw_Text_GDI(buffer,10, 60, RGB(255,255,255), lpddsback); sprintf(buffer, "Wind force=%f, Gravity Force=%f", wind_force, gravity_force); Draw_Text_GDI(buffer,10, 75, RGB(255,255,255), lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30 fps = 1/30sec = 33 ms Wait_Clock(33); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); // stop all sounds DSound_Stop_All_Sounds(); // do a screen transition Screen_Transitions(SCREEN_DARKNESS,NULL,0); } // end if // return success return(1); } // end Game_Main
int Game_Main(void *parms) { // this is the workhorse of your game it will be called // continuously in real-time this is like main() in C // all the calls for you game go here! int index; // looping var int dx,dy; // general deltas used in collision detection // start the timing clock Start_Clock(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // get the joystick data DInput_Read_Joystick(); // lock the back buffer DDraw_Lock_Back_Surface(); // draw the background reactor image Draw_Bitmap(&playfield, back_buffer, back_lpitch, 0); // unlock the back buffer DDraw_Unlock_Back_Surface(); // is the player moving? blaster.x+=joy_state.lX; blaster.y+=joy_state.lY; // test bounds if (blaster.x > SCREEN_WIDTH-32) blaster.x = SCREEN_WIDTH-32; else if (blaster.x < 0) blaster.x = 0; if (blaster.y > SCREEN_HEIGHT-32) blaster.y = SCREEN_HEIGHT-32; else if (blaster.y < SCREEN_HEIGHT-128) blaster.y = SCREEN_HEIGHT-128; // is player firing? if (joy_state.rgbButtons[0]) Start_Missile(); // move and draw missle Move_Missile(); Draw_Missile(); // is it time to blink eyes if ((rand()%100)==50) Set_Animation_BOB(&blaster,0); // draw blaster Animate_BOB(&blaster); Draw_BOB(&blaster,lpddsback); // draw some text Draw_Text_GDI("Make My Centipede!",0,0,RGB(255,255,255),lpddsback); // display joystick and buttons 0-7 sprintf(buffer,"Joystick Stats: X-Axis=%d, Y-Axis=%d, buttons(%d,%d,%d,%d,%d,%d,%d,%d)", joy_state.lX,joy_state.lY, joy_state.rgbButtons[0], joy_state.rgbButtons[1], joy_state.rgbButtons[2], joy_state.rgbButtons[3], joy_state.rgbButtons[4], joy_state.rgbButtons[5], joy_state.rgbButtons[6], joy_state.rgbButtons[7]); Draw_Text_GDI(buffer,0,SCREEN_HEIGHT-20,RGB(255,255,50),lpddsback); // print out name of joystick sprintf(buffer, "Joystick Name & Vendor: %s",joyname); Draw_Text_GDI(buffer,0,SCREEN_HEIGHT-40,RGB(255,255,50),lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30 fps Wait_Clock(30); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } // end if // return success return(1); } // end Game_Main
int Game_Init(void *parms) { // this function is where you do all the initialization // for your game int index; // looping var // start up DirectDraw (replace the parms as you desire) DDraw_Init(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BPP, WINDOWED_APP); // initialize directinput DInput_Init(); // acquire the keyboard DInput_Init_Keyboard(); // initialize the joystick DInput_Init_Joystick(-24,24,-24,24); // initialize directsound and directmusic DSound_Init(); DMusic_Init(); // hide the mouse ShowCursor(FALSE); // seed random number generator srand(Start_Clock()); // load the background Load_Bitmap_File(&bitmap8bit, "MUSH.BMP"); // set the palette to background image palette Set_Palette(bitmap8bit.palette); // load in the four frames of the mushroom for (index=0; index<4; index++) { // create mushroom bitmaps Create_Bitmap(&mushrooms[index],0,0,32,32); Load_Image_Bitmap(&mushrooms[index],&bitmap8bit,index,0,BITMAP_EXTRACT_MODE_CELL); } // end for index // now create the bug blaster bob Create_BOB(&blaster,0,0,32,32,3, BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_ANIM | BOB_ATTR_ANIM_ONE_SHOT, DDSCAPS_SYSTEMMEMORY); // load in the four frames of the mushroom for (index=0; index<3; index++) Load_Frame_BOB(&blaster,&bitmap8bit,index,index,1,BITMAP_EXTRACT_MODE_CELL); // unload the bitmap file Unload_Bitmap_File(&bitmap8bit); // set the animation sequences for bug blaster Load_Animation_BOB(&blaster,0,5,blaster_anim); // set up stating state of bug blaster Set_Pos_BOB(&blaster,320, 400); Set_Anim_Speed_BOB(&blaster,3); // set clipping rectangle to screen extents so objects dont // mess up at edges RECT screen_rect = {0,0,screen_width,screen_height}; lpddclipper = DDraw_Attach_Clipper(lpddsback,1,&screen_rect); // create mushroom playfield bitmap Create_Bitmap(&playfield,0,0,SCREEN_WIDTH,SCREEN_HEIGHT); playfield.attr |= BITMAP_ATTR_LOADED; // fill in the background Load_Bitmap_File(&bitmap8bit, "GRASS.BMP"); // load the grass bitmap image Load_Image_Bitmap(&playfield,&bitmap8bit,0,0,BITMAP_EXTRACT_MODE_ABS); Unload_Bitmap_File(&bitmap8bit); // create the random mushroom patch for (index=0; index<50; index++) { // select a mushroom int mush = rand()%4; // set mushroom to random position mushrooms[mush].x = rand()%(SCREEN_WIDTH-32); mushrooms[mush].y = rand()%(SCREEN_HEIGHT-128); // now draw the mushroom into playfield Draw_Bitmap(&mushrooms[mush], playfield.buffer, playfield.width,1); } // end for // return success return(1); } // end Game_Init
int Game_Main(void *parms) { // this is the workhorse of your game it will be called // continuously in real-time this is like main() in C // all the calls for you game go here! int index; // looping var // start the timing clock Start_Clock(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // lock back buffer and copy background into it DDraw_Lock_Back_Surface(); // draw background Draw_Bitmap(&background_bmp, back_buffer, back_lpitch,0); // unlock back surface DDraw_Unlock_Back_Surface(); // read keyboard DInput_Read_Keyboard(); // check the player controls // is the player turning right or left? if (keyboard_state[DIK_RIGHT]) { // there are 16 possible positions for the ship to point in if (++ship.varsI[0] >= 16) ship.varsI[0] = 0; } // end if else if (keyboard_state[DIK_LEFT]) { // there are 16 possible positions for the ship to point in if (--ship.varsI[0] < 0) ship.varsI[0] = 15; } // end if // now test for forward thrust if (keyboard_state[DIK_UP]) { // thrust ship in current direction float rad_angle = (float)ship.varsI[0]*(float)3.14159/(float)8; float xv = cos(rad_angle); float yv = sin(rad_angle); ship.varsF[0]+=xv; ship.varsF[1]+=yv; // animate the ship ship.curr_frame = ship.varsI[0]+16*(rand()%2); } // end if else // show non thrust version ship.curr_frame = ship.varsI[0]; // move ship ship.varsF[2]+=ship.varsF[0]; ship.varsF[3]+=ship.varsF[1]; // always apply friction in direction opposite current trajectory float fx = -ship.varsF[0]; float fy = -ship.varsF[1]; float length_f = sqrt(fx*fx+fy*fy); // normally we would avoid square root at all costs! // compute the frictional resitance if (fabs(length_f) > 0.1) { fx = FRICTION_FACTOR*fx/length_f; fy = FRICTION_FACTOR*fy/length_f; } // end if else fx=fy=0; // now apply friction to forward velocity ship.varsF[0]+=fx; ship.varsF[1]+=fy; //////////////////////////////////////////////////////////////////// // gravity calculation section // step 1: compute vector from black hole to ship, note that the centers // of each object are used float grav_x = (black_hole.x + black_hole.width/2) - (ship.x + ship.width/2); float grav_y = (black_hole.y + black_hole.height/2) - (ship.y + ship.height/2); float radius_squared = grav_x*grav_x + grav_y*grav_y; // equal to radius squared float length_grav = sqrt(radius_squared); // step 2: normalize the length of the vector to 1.0 grav_x = grav_x/length_grav; grav_y = grav_y/length_grav; // step 3: compute the gravity force float grav_force = (VIRTUAL_GRAVITY_CONSTANT) * (SHIP_MASS * BLACK_HOLE_MASS) / radius_squared; // step 4: apply gforce in the direction of grav_x, grav_y with the magnitude of grav_force ship.varsF[0]+=grav_x*grav_force; ship.varsF[1]+=grav_y*grav_force; //////////////////////////////////////////////////////////////////// // test if ship is off screen if (ship.varsF[2] > SCREEN_WIDTH) ship.varsF[2] = -ship.width; else if (ship.varsF[2] < -ship.width) ship.varsF[2] = SCREEN_WIDTH; if (ship.varsF[3] > SCREEN_HEIGHT) ship.varsF[3] = -ship.height; else if (ship.varsF[3] < -ship.height) ship.varsF[3] = SCREEN_HEIGHT; // test if velocity is insane if ( (ship.varsF[0]*ship.varsF[0] + ship.varsF[1]*ship.varsF[1]) > MAX_VEL) { // scale velocity down ship.varsF[0]*=.95; ship.varsF[1]*=.95; } // end if // animate the black hole Animate_BOB(&black_hole); // draw the black hole Draw_BOB(&black_hole, lpddsback); // copy floating point position to bob x,y ship.x = ship.varsF[2]; ship.y = ship.varsF[3]; // draw the ship Draw_BOB(&ship,lpddsback); // draw the title Draw_Text_GDI("GRAVITY MASS DEMO - Use Arrows to Control Ship.",10, 10,RGB(0,255,255), lpddsback); sprintf(buffer,"Friction: X=%f, Y=%f",fx, fy); Draw_Text_GDI(buffer,10,420,RGB(0,255,0), lpddsback); sprintf(buffer,"Velocity: X=%f, Y=%f",ship.varsF[0], ship.varsF[1]); Draw_Text_GDI(buffer,10,440,RGB(0,255,0), lpddsback); sprintf(buffer,"Gravity: X=%f, Y=%f",ship.varsF[2], ship.varsF[3]); Draw_Text_GDI(buffer,10,460,RGB(0,255,0), lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30 fps = 1/30sec = 33 ms Wait_Clock(33); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); // stop all sounds DSound_Stop_All_Sounds(); // do a screen transition Screen_Transitions(SCREEN_DARKNESS,NULL,0); } // end if // return success return(1); } // end Game_Main