#include #include #include #include"hensu.h" #include"idou.h" #include"yudou.h" #include"mahiray.h" #include"koki.h" LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); ATOM InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE,int); char szClassName[]="stg27"; //ここに至るまでが長かった・・・ HINSTANCE hInst; int WINAPI WinMain(HINSTANCE hCurInst,HINSTANCE hPrevInst, LPSTR lpsCmdLine,int nCmdShow) { MSG msg; BOOL bRet; hInst=hCurInst; if(!InitApp(hCurInst)) return FALSE; if(!InitInstance(hCurInst,nCmdShow)) return FALSE; while((bRet=GetMessage(&msg,NULL,0,0))!=0){ if(bRet==-1){ MessageBox(NULL,"GetMessageエラー","Error",MB_OK); break; }else{ TranslateMessage(&msg); DispatchMessage(&msg); } } return (int)msg.wParam; } ATOM InitApp(HINSTANCE hInst) { WNDCLASSEX wc; wc.cbSize=sizeof(WNDCLASSEX); wc.style=CS_HREDRAW|CS_VREDRAW; wc.lpfnWndProc=WndProc; wc.cbClsExtra=0; wc.cbWndExtra=0; wc.hInstance=hInst; wc.hIcon=(HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE|LR_SHARED); wc.hCursor=(HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE|LR_SHARED); wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName=NULL; wc.lpszClassName=(LPCTSTR)szClassName; wc.hIconSm=(HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE|LR_SHARED); return (RegisterClassEx(&wc)); } BOOL InitInstance(HINSTANCE hInst,int nCmdShow) { HWND hWnd; hWnd=CreateWindow(szClassName, "BIG BOSS", WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, //ウィンドウサイズ変更&最大化禁止 CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInst, NULL); if(!hWnd) return FALSE; ShowWindow(hWnd,nCmdShow); UpdateWindow(hWnd); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) { HDC hdc; static HDC hdc_mem,hdc_ura; PAINTSTRUCT ps; HBITMAP hBmp; HPEN hPen,hOldPen; HBRUSH hBrush,hOldBrush; static RECT rc; //文字描画領域 char text[512],winer[16]; int i,j,k,l,x,y; static double w,h,r; //両機間の幅、高さ、距離 double yp; static BOOL yudou_hassha[yudou_max],shusoku,hissatsu,mahi,mahiray,bigray,kokiray,title=TRUE,tuning,play,end; static int timer_timer,mahi_t,dead_t,battle_t,battle_tc; //各種タイマー static int houkou,houkou_mahi,houkou_ken,kougeki,shusoku_x,x_win,bmp_n,point[4]; static int ptama_t,max_ptama_t,shufuku_t,max_shufuku_t,max_lpp,max_point=10; //チューニング項目 const int max_lpb=1500; //ボス機最高ライフポイント static double lp_player,lp_boss=max_lpb; const int r_player=25; //プレイヤー機 縦*横=50*50 static double x_player=-100,y_player=700; static int rx_boss=50,ry_boss=50; //ボス機 縦*横=100*200 static int rx2_boss=rx_boss,ry2_boss=ry_boss; //ボス機(収束用) static double x_boss=900,y_boss=-100; const int ptama_max=32,ptama_r=5; //プレイヤー機通常弾 static int ptama_x[ptama_max],ptama_y[ptama_max],ptama_vx[ptama_max],ptama_vy[ptama_max],ptama_n; const int btama_max=16,btama_r=5; //ボス機通常弾 static double btama_x[btama_max],btama_y[btama_max],btama_vx[btama_max],btama_vy[btama_max]; static int btama_n,btama_i; const int btama2_max=64,btama2_r=5; //ボス機全方位弾 static double btama2_x[btama2_max],btama2_y[btama2_max],btama2_vx[btama2_max],btama2_vy[btama2_max]; static int btama2_n; const int yudou_r=5; //ボス機誘導弾 static double yudou_x[yudou_max],yudou_y[yudou_max]; static int yudou_vy[yudou_max],yudou_n,yudou_i; const int ken_len=150; //ビームソード static int ken_kakudo=-60; static double ken_x,ken_y; static int bigray_x,bigray_t; //極太レーザー static int mahiray_x[mahiray_max][mahiray_max2],mahiray_y[mahiray_max][mahiray_max2],mahiray_n,mahiray_xb,mahiray_yb; //麻痺レーザー const int koki_max=6,koki_l=30,koki_s=10; //子機 static int koki_n,w_koki[koki_max],h_koki[koki_max],r_koki[koki_max],koki_state[koki_max],koki_t[koki_max],koki_i[koki_max],bx_kx[koki_max],by_ky[koki_max]; static int koki_l2[koki_max],koki_s2[koki_max]; //子機(収束用) static int kokiray_x[koki_max],kokiray_y[koki_max]; //子機レーザー static POINT koki[koki_max][5],koki2[koki_max][5]; switch(msg){ case WM_CREATE: rc.left=100; rc.top=100; rc.right=700; rc.bottom=500; GetClientRect(hWnd,&window); srand((unsigned)time(NULL)); hdc=GetDC(hWnd); hBmp=LoadBitmap(hInst,"BlueSky1"); hdc_mem=CreateCompatibleDC(hdc); SelectObject(hdc_mem,hBmp); DeleteObject(hBmp); hBmp=CreateCompatibleBitmap(hdc,800,600); hdc_ura=CreateCompatibleDC(hdc); SelectObject(hdc_ura,hBmp); DeleteObject(hBmp); ReleaseDC(hWnd,hdc); for(i=0;i2400-window.right) //背景繋ぎ目処理 BitBlt(hdc_ura,2400-x_win,0,window.right,window.bottom,hdc_mem,0,0,SRCCOPY); RoundRect(hdc_ura,x_boss,y_boss-ry_boss,x_boss+4*rx_boss,y_boss+ry_boss,20,20); //ボス機 RoundRect(hdc_ura,x_boss,y_boss-ry2_boss,x_boss+4*rx2_boss,y_boss+ry2_boss,20,20); //ボス機(収束用) hPen=CreatePen(PS_SOLID,1,RGB(255,0,0)); hOldPen=(HPEN)SelectObject(hdc_ura,hPen); MoveToEx(hdc_ura,x_player,y_player,NULL); //レーザーソード LineTo(hdc_ura,x_player+ken_x,y_player-ken_y); SelectObject(hdc_ura,hOldPen); DeleteObject(hPen); Ellipse(hdc_ura,x_player-r_player,y_player-r_player,x_player+r_player,y_player+r_player); //プレイヤー機 hPen=CreatePen(PS_SOLID,1,RGB(255,0,0)); hOldPen=(HPEN)SelectObject(hdc_ura,hPen); for(i=0;i0){ wsprintf(text,"Battle_Time = %03d.%03d s",battle_tc/1000,battle_tc%1000); //戦闘終了時間 TextOut(hdc_ura,325,250,text,(int)strlen(text)); } BitBlt(hdc,0,0,window.right,window.bottom,hdc_ura,0,0,SRCCOPY); //ウィンドウへコピー //以下はパソコンの処理限界により敢えてちらつかせる hBrush=(HBRUSH)GetStockObject(BLACK_BRUSH); hOldBrush=(HBRUSH)SelectObject(hdc,hBrush); RoundRect(hdc,x_boss+bigray_x,y_boss-ry_boss/2,x_boss,y_boss+ry_boss/2,20,20); //極太レーザー SelectObject(hdc,hOldBrush); DeleteObject(hBrush); hPen=CreatePen(PS_SOLID,1,RGB(255,255,0)); hOldPen=(HPEN)SelectObject(hdc,hPen); for(j=0;j0){ //ボスが右を向いている if(ptama_x[i]>x_boss && ptama_x[i]y_boss-ry_boss && ptama_y[i]x_boss+4*rx_boss && ptama_x[i]y_boss-ry_boss && ptama_y[i]=-45) //レーザーソード当たり判定 for(i=ken_len;i>r_player;i--){ //プレイヤー機内部はレーザーソードが発生していないとする j=i*cos(ken_kakudo*3.14/180)*houkou_ken; //実は先端にしか判定点がないので仮想的に長さを変えて・・ k=i*sin(ken_kakudo*3.14/180); if(rx_boss>0){ //ボスが右を向いている if(x_player+j>x_boss && x_player+jy_boss-ry_boss && y_player-kx_boss+4*rx_boss && x_player+jy_boss-ry_boss && y_player-k=-45){ //レーザーソード移動 45〜-45度まで描く ken_x=ken_len*cos(ken_kakudo*3.14/180)*houkou_ken; ken_y=ken_len*sin(ken_kakudo*3.14/180); ken_kakudo-=15; }else ken_x=ken_y=0; //移動量0のLineToは結局描画されないのと同じ for(i=0;ix_player-r_player && btama_x[i]y_player-r_player && btama_y[i]x_player-r_player && btama2_x[i]y_player-r_player && btama2_y[i]x_player-r_player && yudou_x[i]y_player-r_player && yudou_y[i]0) mahi_t--; //麻痺時間カウントダウン else mahi=FALSE; //麻痺状態解除 if(mahiray==TRUE){ //麻痺レーザー当たり判定 実は曲がり角にしか判定点がない for(j=0;jx_player-r_player && mahiray_x[j][i]y_player-r_player && mahiray_y[j][i]0){ //右方向に照射している for(i=x_boss+bigray_x;i>x_boss;i-=10) //判定点は1個/10pixel if(i>x_player-r_player && iy_player-r_player && jx_player-r_player && iy_player-r_player && j0;j--){ k=j*(koki[i][0].x-koki[i][1].x)/2; //実はこのレーザーは満遍なく判定点がある訳じゃない l=j*(koki[i][0].y-koki[i][1].y)/2; //直線上で1個/15pixel if(koki[i][4].x+k>x_player-r_player && koki[i][4].x+ky_player-r_player && koki[i][4].y+l=0){ //子機収束(500msかかる) *koki2[i]=draw_koki(w_koki[i],h_koki[i],r_koki[i],koki_l2[i],koki_s2[i],koki2[i]); koki_l2[i]-=3; koki_s2[i]--; }else{ //照準 kokiray_x[i]=100*(koki[i][0].x-koki[i][1].x); //各機正面に kokiray_y[i]=100*(koki[i][0].y-koki[i][1].y); koki_l2[i]=koki_l; //収束状態を元に戻す koki_s2[i]=koki_s; koki_state[i]++; } break; case 4: if(++koki_t[i]%20==0){ //1000ms照射 kokiray_x[i]=0; kokiray_y[i]=0; if(koki_t[i]<=40) //1回目、2回目の照射だったのならもう一度移動からやり直し koki_state[i]=2; else{ //ボス機に帰還する為の距離を取得(帰還完了までボス機の座標は再取得しない→誤差が出る) koki_t[i]=0; bx_kx[i]=x_boss+2*rx_boss-koki[i][4].x; by_ky[i]=y_boss-koki[i][4].y; koki_state[i]++; } } break; case 5: if(koki_i[i]++<5){ for(j=0;j<5;j++){ koki2[i][j].x=koki[i][j].x+=bx_kx[i]/5; //5回に分けて移動 koki2[i][j].y=koki[i][j].y+=by_ky[i]/5; } }else{ for(j=0;j<5;j++){ //帰還完了 全座標ボス機の座標に再修正(見えなくなる) koki2[i][j].x=koki[i][j].x=x_boss; koki2[i][j].y=koki[i][j].y=y_boss; } koki_i[i]=0; koki_state[i]++; } break; case 6: if(i==koki_max-1){ //全機帰還したら for(j=0;j0 && lp_player){ //何の攻撃状態でもなく両機共に生きている if(kokiray==TRUE) //子機レーザー状態の場合は必ず通常弾状態へ移行 特殊条件 kougeki=rand()%5+1; //連携攻撃! else if(y_boss>y_player-100 && y_bossy_player) yudou_vy[yudou_n]=-200; //上に撃つ プレイヤー機が上 else yudou_vy[yudou_n]=-400; //上に撃つ プレイヤー機が下 yudou_hassha[yudou_n]=TRUE; //発射状態へ移行 yudou_n=(yudou_n+1)%yudou_max; } yudou_i++; //連続発射回数をカウント }else{ yudou_i=0; kougeki=0; } break; case 6: //麻痺レーザー case 7: //麻痺レーザー case 8: //全方位弾 case 9: //極太レーザー case 10: //子機レーザー shusoku=hissatsu=TRUE; //収束状態、必殺技状態へ移行 break; default: kougeki=0; //0、その他の値が出た場合は何もしない } } rx2_boss=rx_boss=50*houkou; //ボス機の半径(?)を取得 方向によって右か左か if(shusoku==TRUE){ //ボス機収束 if(ry2_boss>0){ rx2_boss=rx_boss+(--shusoku_x)*houkou; ry2_boss--; }else{ //ry2_boss==0 既に0で描画している 収束完了→発射処理へ移行 shusoku_x=0; rx2_boss=rx_boss; //収束した半径(?)を元に戻しておく ry2_boss=ry_boss; shusoku=FALSE; //収束状態解除 switch(kougeki){ //選択された攻撃方法により分岐 case 6: case 7: //麻痺レーザー mahiray_xb=x_boss; //この時のボス機の座標を取得 ここを起点(実際には描画されないが)として mahiray_yb=y_boss; houkou_mahi=houkou; //方向取得 麻痺レーザーは同じ方向へ伸びてゆく(麻痺レーザーが描画されるのは一度移動してから) mahiray=TRUE; //麻痺レーザー状態へ移行 break; case 8: //全方位弾 発射処理 for(i=0;i<36;i++){ //1発/10度 btama2_x[btama2_n]=x_boss; btama2_y[btama2_n]=y_boss; btama2_vx[btama2_n]=12.5*cos(10*i*3.14/180); //速さは通常弾の1/2 btama2_vy[btama2_n]=12.5*sin(10*i*3.14/180); btama2_n=(btama2_n+1)%btama2_max; } hissatsu=FALSE; //必殺技状態解除 break; case 9: //極太レーザー bigray=TRUE; //極太レーザー状態へ移行 break; case 10: //子機レーザー kokiray=TRUE; //子機レーザー状態へ移行 break; } kougeki=0; //攻撃方法をリセット } } if(ptama_t>0) //プレイヤー機通常弾発射時間間隔制御 ptama_t--; if(shufuku_t>0) //自己修復時間間隔制御 shufuku_t--; if(mahi==FALSE && lp_player>0 && lp_boss>0){ //麻痺していない 両機共に生きている if(GetKeyState('S')<0){ //自己修復 Sキーを押している if(shufuku_t==0 && lp_player0){ if(lp_player<=0 && kougeki==0 && hissatsu==FALSE) //プレイヤー機死亡 ボス機は何の攻撃状態でもない yp=300; //y座標だけ真ん中に移動したと誤認させる else yp=y_player; //通常時 y_boss+=idou_boss_y(x_player,yp,x_boss,y_boss); //x_bossを使うのでy座標から移動 x_boss+=idou_boss_x(x_player,x_boss); }else y_boss++; //轟沈! if(lp_player>0){ x_player+=idou_player_x(x_player,x_boss,mahi); y_player+=idou_player_y(y_player,y_boss,mahi); }else y_player++; //撃沈! w=x_player-x_boss; //両機共に移動後の幅、高さ、距離を取得 h=y_player-y_boss; r=sqrt(w*w+h*h); if(lp_boss>0){ if(w>0) houkou=-1; //プレイヤー機が右 ボス機が左 else houkou=1; //プレイヤー機が左 ボス機が右 初期状態 } if(lp_player<=0 || lp_boss<=0){ //変数の値が元に戻る為には時間が必要なのですぐには終了しない if(lp_player<0) lp_player=0; //両方0未満になる可能性もある if(lp_boss<0) lp_boss=0; if(dead_t>=300){ //どちらかが死んでから15秒経った play=FALSE; //プレイ終了 end=TRUE; //終了画面へ移行 KillTimer(hWnd,1); //タイマーストップ dead_t=0; }else if(dead_t++>=150){ battle_tc+=rand()%1000+5000; //演出効果(スロット) if(battle_tc>battle_t) battle_tc=battle_t; } }else //両機共に生きている battle_t+=timer_ms; //戦闘時間を加算 x_win=(x_win+1)%2400; //背景画像をスクロール timer_timer=(timer_timer+1)%10; //WM_TIMERのタイマー 500msカウンター InvalidateRect(hWnd,NULL,FALSE); } break; case WM_KEYUP: if(GetKeyState('S')>=0 && GetKeyState(VK_SPACE)>=0 && mahi==FALSE && lp_player>0 && lp_boss>0){ switch(wp){ //自己修復中じゃない 通常弾を撃ちながらは攻撃できない case 'F': ken_kakudo=45; //レーザーソード houkou_ken=houkou; break; } //InvalidateRect(hWnd,NULL,FALSE); 連打するとかなり重たくなるので止めた } break; case WM_LBUTTONDOWN: x=LOWORD(lp); y=HIWORD(lp); if(title==TRUE){ if(x>525 && x<600 && y>375 && y<420){ //次へ title=FALSE; tuning=TRUE; } }else if(tuning==TRUE){ if(x>395 && x<470 && y>375 && y<420){ //戻る tuning=FALSE; title=TRUE; }else if(x>525 && x<600 && y>375 && y<420){ //開始 if(point[0]+point[1]+point[2]+point[3]<=max_point){ //最大ポイント以下 lp_player=max_lpp=100+(point[0]-2)*25; //最大ライフポイント max_speed=10000+(point[1]-2)*1000; //最大移動速度 max_shufuku_t=7+(point[2]-2)*(-1); //ライフポイントが回復する時間間隔 max_ptama_t=5+(point[3]-2)*(-1); //通常弾を発射できる時間間隔 tuning=FALSE; play=TRUE; SetTimer(hWnd,1,timer_ms,NULL); }else{ //最大ポイントオーバー MessageBeep(MB_ICONEXCLAMATION); FlashWindow(hWnd,TRUE); } }else{ for(j=0;j<4;j++) //縦の項目 for(i=0;i<5;i++) //横の項目 if(x>286+30*i && x<286+30*i+20 && y>189+36*j && y<189+36*j+20) point[j]=i; //設定取得 } }else if(end==TRUE){ if((x>190 && x<340 && y>375 && y<420) || (x>395 && x<470 && y>375 && y<420)){ //再戦(easy) or 再戦 DeleteDC(hdc_mem); DeleteDC(hdc_ura); hdc=GetDC(hWnd); bmp_n=(bmp_n+1)%3; //背景画像変更 switch(bmp_n){ case 0: hBmp=LoadBitmap(hInst,"BlueSky1"); case 1: hBmp=LoadBitmap(hInst,"BlueSky2"); case 2: hBmp=LoadBitmap(hInst,"BlueSky3"); } hdc_mem=CreateCompatibleDC(hdc); SelectObject(hdc_mem,hBmp); DeleteObject(hBmp); hBmp=CreateCompatibleBitmap(hdc,800,600); hdc_ura=CreateCompatibleDC(hdc); SelectObject(hdc_ura,hBmp); DeleteObject(hBmp); ReleaseDC(hWnd,hdc); x_player=-100; //時間で元に戻らない変数(の中で元に戻さないとまずい変数) y_player=700; x_boss=900; y_boss=-100; lp_boss=max_lpb; end=FALSE; title=TRUE; battle_t=0; battle_tc=0; if(x>190 && x<340 && y>375 && y<420) //再戦(easy) max_point=16; else //x>395 && x<470 && y>375 && y<420 再戦 max_point=10; } else if(x>525 && x<600 && y>375 && y<420) //終了 SendMessage(hWnd,WM_CLOSE,0,0); } InvalidateRect(hWnd,NULL,FALSE); break; case WM_CLOSE: DeleteDC(hdc_mem); DeleteDC(hdc_ura); DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd,msg,wp,lp)); } return 0; }