/* * 壁打ちテニス Ver.0(未完成版) * by yanagawa@kushiro-ct.ac.jp * * Done:(できたこと) * ラケットをキーボードで操作できる. * ボールが動き,壁で跳ね返る. * * To-Do:(やるべきこと) * ラケットでボールを打ち返す. * ラケットの移動範囲を制限. * 得点・ゲームオーバー処理を追加. * タイトル画面を追加. * ... */ #include #include #include #include //#include /* 移動物体の構造体 */ typedef struct { double px, py; // Position(位置) double vx, vy; // Velocity(速度) double sx, sy; // Size(サイズ) } Mobj; // Mobile Object(移動物体) /* 移動物体の初期化 */ void InitMobj(Mobj *obj, double px, double py, double vx, double vy, double sx, double sy) { obj->px = px; obj->py = py; obj->vx = vx; obj->vy = vy; obj->sx = sx; obj->sy = sy; } /* ラケットの表示 */ void DrawRacket(Mobj *r) { int i; attrset(COLOR_PAIR(1)); move((int)(r->py), (int)((r->px)-(r->sx))); for (i = -(int)(r->sx); i <= (int)(r->sx); i++) { addch('#'); } } /* ボールの表示 */ void DrawBall(Mobj *b) { attrset(COLOR_PAIR(2)); mvaddch((int)(b->py), (int)(b->px), '#'); } /* ラケットの移動 */ void MoveRacket(Mobj *r) { int w, h; getmaxyx(stdscr, h, w); // 移動 r->px += r->vx; r->py += r->vy; // 画面から はみ出さないようにする *** 未完成 *** // r->px, r->py を調べ,画面外に出ていたら,画面内に収まるようにする } /* ボールの移動 */ void MoveBall(Mobj *b) { int w, h; getmaxyx(stdscr, h, w); // 壁に衝突したら跳ね返る.fabs(x) は絶対値 |x| if ((b->px) < (b->sx)) b->vx = +fabs(b->vx); if (((double)(w-1) - b->px) < (b->sx)) b->vx = -fabs(b->vx); if ((b->py) < (b->sy)) b->vy = +fabs(b->vy); if (((double)(h-1) - b->py) < (b->sy)) b->vy = -fabs(b->vy); // 移動 b->px += b->vx; b->py += b->vy; } /* ラケットとボールの衝突の判定 *** 未完成 *** * 戻り値: 衝突したとき 1 * してないとき 0 */ int ChkHit(Mobj *r, Mobj *b) { return (0); } /* ラケットによるボールの方向転換 */ void Shoot(Mobj *r, Mobj *b) { if ((b->py) > (r->py)) { b->vy = +fabs(b->vy); } else { b->vy = -fabs(b->vy); } beep(); } /* ラケット等の操作 */ int Control(Mobj *r) { int key; key = getch(); r->vx = r->vy = 0.0; switch (key) { case KEY_UP : r->vy = -1.0; break; case KEY_DOWN : r->vy = 1.0; break; case KEY_LEFT : r->vx = -1.0; break; case KEY_RIGHT : r->vx = 1.0; break; case 'q': case 'Q': case '\e': return ('q'); break; default: break; } return (key); } /* ゲームの本体 */ void Game() { Mobj r; // ラケット Mobj b; // ボール int w, h; // 初期設定 getmaxyx(stdscr, h, w); InitMobj(&r, (double)w/2.0, (double)(h-4), 0.0, 0.0, 4.0, 0.5); InitMobj(&b, (double)w/2.0, (double)h/2.0, 0.5, 0.5, 0.5, 0.5); timeout(0); while (1) { // キャラクタの表示 erase(); DrawRacket(&r); DrawBall(&b); move(0, 0); // カーソルを隅へ移動(curs_set() が無効でも,画面の乱れを最小化) refresh(); // キー入力/キャラクタの移動 if (Control(&r) == 'q') break; MoveRacket(&r); MoveBall(&b); // キャラクタ間の相互作用(衝突判定と打ち返し) if (ChkHit(&r, &b) != 0) Shoot(&r, &b); // 動作速度調整 usleep(20000); // 20,000μ秒=20 m秒=0.02秒 停止 } } int main() { /* curses の設定 */ initscr(); curs_set(0); // カーソルを表示しない noecho(); // 入力されたキーを表示しない cbreak(); // 入力バッファを使わない(Enter 不要の入力) keypad(stdscr, TRUE); // カーソルキーを使用可能にする /* カラーの設定 */ start_color(); init_pair(1, COLOR_CYAN, COLOR_CYAN); // 水色の■ init_pair(2, COLOR_YELLOW, COLOR_YELLOW); // 黄色の■ init_pair(10, COLOR_WHITE, COLOR_BLACK); // 白字/黒地 bkgd(COLOR_PAIR(10)); /* ゲーム本体 */ Game(); /* 終了 */ endwin(); return (0); }