コード:
#include "DxLib.h"
#define MARGIN 5
#define RACKET_X 96
#define RACKET_Y 96
#define RACKET_SIZE 96 / 2
#define BALL_SIZE 16
#define BALL_CENTER 16 / 2
#define DEF_SPEED 4
// ボール座標
int ball_x = 0;
int ball_y = 0;
// ラケット座標
int racket_x;
int racket_y;
// ボール色
int ball_color;
// ラケット色
int racket_color;
// ボールの移動量
int ball_dx = DEF_SPEED;
int ball_dy = DEF_SPEED;
// ラケット情報
int cnt = 0;
//ハンドル
int BALLHandle;
int RKTHandle;
// ラケット座標保存領域
int racket_oldx;
int racket_oldy;
// 速度フラグ
bool speed_flg = false;
// ラケット移動量
struct racket_move
{
int up;
int down;
int left;
int right;
}racket_t;
// 描画処理
void draw()
{
// ボール中心座標変換
ball_x = ball_x - BALL_CENTER;
ball_y = ball_y - BALL_CENTER;
// 枠描画
DrawBox( racket_x + MARGIN,
racket_y + MARGIN,
racket_x + RACKET_X - MARGIN,
racket_y,
GetColor(255,0,0), true );
DrawBox( racket_x + MARGIN,
racket_y + RACKET_Y - MARGIN,
racket_x + RACKET_X - MARGIN,
racket_y + RACKET_Y,
GetColor(255,255,0), true );
DrawBox( racket_x,
racket_y + MARGIN,
racket_x + MARGIN,
racket_y + RACKET_Y - MARGIN,
GetColor(0,255,0), true );
DrawBox( racket_x + RACKET_X - MARGIN,
racket_y + MARGIN,
racket_x + RACKET_X,
racket_y + RACKET_Y - MARGIN,
GetColor(0,0,255), true );
// ボール描画
DrawGraph( ball_x, ball_y, BALLHandle, true );
// ラケット描画
DrawGraph( racket_x, racket_y, RKTHandle, true );
}
// アタックレシーブ判定
int attack_recv_chk( int x, int y )
{
int i;
VECTOR lineA1[4], lineA2[4], lineB1,lineB2;
float length;
// 1フレーム間で移動したボールの線分を設定
lineB1 = VGet( ball_x - ball_dx, ball_y - ball_dy, 0.0f );
lineB2 = VGet( ball_x, ball_y, 0.0f );
// 線分の描画
DrawLine( lineB1.x, lineB1.y, lineB2.x, lineB2.y, GetColor( 255, 255, 255 ) );
// ラケット上面部分に線分を設定
lineA1[0] = VGet( x, y, 0.0f );
lineA2[0] = VGet( x + RACKET_X, y, 0.0f );
// 線分の描画
//DrawLine( lineA1[0].x, lineA1[0].y, lineA2[0].x, lineA2[0].y, GetColor( 255, 255, 255 ) );
// ラケット下面部分に線分を設定
lineA1[1] = VGet( x, y + RACKET_Y, 0.0f );
lineA2[1] = VGet( x + RACKET_X, y + RACKET_Y, 0.0f );
// 線分の描画
//DrawLine( lineA1[1].x, lineA1[1].y, lineA2[1].x, lineA2[1].y, GetColor( 255, 255, 255 ) );
// ラケット左面部分に線分を設定
lineA1[2] = VGet( x, y, 0.0f );
lineA2[2] = VGet( x, y + RACKET_Y, 0.0f );
// 線分の描画
//DrawLine( lineA1[2].x, lineA1[2].y, lineA2[2].x, lineA2[2].y, GetColor( 255, 255, 255 ) );
// ラケット右面部分に線分を設定
lineA1[3] = VGet( x + RACKET_X, y, 0.0f );
lineA2[3] = VGet( x + RACKET_X, y + RACKET_Y, 0.0f );
// 線分の描画
//DrawLine( lineA1[3].x, lineA1[3].y, lineA2[3].x, lineA2[3].y, GetColor( 255, 255, 255 ) );
// 4面分判定
for( i = 0; i < 4; i++ )
{
// 二線分の最近点どうしの距離を求める
length = Segment_Segment_MinLength( lineA1[i], lineA2[i], lineB1, lineB2 );
if( length < 1.0f )
{
// 当たった
switch(i)
{
case 0:
ball_dx = - racket_t.up;
ball_dy = - racket_t.up;
ball_x += ball_dx;
ball_y += ball_dy;
return 1;
case 1:
ball_dx = + racket_t.down;
ball_dy = + racket_t.down;
ball_x += ball_dx;
ball_y += ball_dy;
return 1;
case 2:
ball_dx = - racket_t.left;
ball_dy = - racket_t.left;
ball_x += ball_dx;
ball_y += ball_dy;
return 1;
case 3:
ball_dx = + racket_t.right;
ball_dy = + racket_t.right;
ball_x += ball_dx;
ball_y += ball_dy;
return 1;
default:
break;
}
}
}
// 当たってない
return 0;
}
// 当たり判定
int hit_chk(int x, int y)
{
int i;
VECTOR lineA1[4], lineA2[4], lineB1,lineB2;
float length;
// 1フレーム間で移動したボールの線分を設定
lineB1 = VGet( ball_x - ball_dx, ball_y - ball_dy, 0.0f );
lineB2 = VGet( ball_x, ball_y, 0.0f );
// 線分の描画
DrawLine( lineB1.x, lineB1.y, lineB2.x, lineB2.y, GetColor( 255, 255, 255 ) );
// ラケット上面部分に線分を設定
lineA1[0] = VGet( x, y, 0.0f );
lineA2[0] = VGet( x + RACKET_X, y, 0.0f );
// 線分の描画
DrawLine( lineA1[0].x, lineA1[0].y, lineA2[0].x, lineA2[0].y, GetColor( 255, 255, 255 ) );
// ラケット下面部分に線分を設定
lineA1[1] = VGet( x, y + RACKET_Y, 0.0f );
lineA2[1] = VGet( x + RACKET_X, y + RACKET_Y, 0.0f );
// 線分の描画
DrawLine( lineA1[1].x, lineA1[1].y, lineA2[1].x, lineA2[1].y, GetColor( 255, 255, 255 ) );
// ラケット左面部分に線分を設定
lineA1[2] = VGet( x, y, 0.0f );
lineA2[2] = VGet( x, y + RACKET_Y, 0.0f );
// 線分の描画
DrawLine( lineA1[2].x, lineA1[2].y, lineA2[2].x, lineA2[2].y, GetColor( 255, 255, 255 ) );
// ラケット右面部分に線分を設定
lineA1[3] = VGet( x + RACKET_X, y, 0.0f );
lineA2[3] = VGet( x + RACKET_X, y + RACKET_Y, 0.0f );
// 線分の描画
DrawLine( lineA1[3].x, lineA1[3].y, lineA2[3].x, lineA2[3].y, GetColor( 255, 255, 255 ) );
// 4面分判定
for( i = 0; i < 4; i++ )
{
// 二線分の最近点どうしの距離を求める
length = Segment_Segment_MinLength( lineA1[i], lineA2[i], lineB1, lineB2 );
if( length < 1.0f )
{
// 当たった
// 0と1なら上下面で2と3なら左右面判定
if( i < 2 )
{
// 上面下面ボール反射
ball_dy *= -1;
// ボール加速
ball_x += ball_dx;
ball_y += ball_dy;
return 1;
}else{
// 左面右面ボール反射
ball_dx *= -1;
// ボール加速
ball_x += ball_dx;
ball_y += ball_dy;
return 1;
}
}
}
// 当たってない
return 0;
}
// ラケットの動いた1フレーム内で判定
int guard_frame_chk()
{
int vector1, vector2;
int start_cnt1, end_cnt1;
int start_cnt2, end_cnt2;
int ret;
// 左右移動方向チェック
if( racket_oldx < racket_x )
{
// 右に移動した
vector1 = +1;
racket_t.right = racket_x - racket_oldx;
if( racket_t.right > 100 )
{
racket_t.right = 100;
}
}else{
// 左に移動した
vector1 = -1;
racket_t.left = racket_oldx - racket_x;
if( racket_t.left > 100 )
{
racket_t.left = 100;
}
}
// 上下移動方向チェック
if( racket_oldy < racket_y )
{
// 下に移動した
vector2 = +1;
racket_t.down = racket_y - racket_oldy;
if( racket_t.down > 100 )
{
racket_t.down = 100;
}
}else{
// 上に移動した
vector2 = -1;
racket_t.up = racket_oldy - racket_y;
if( racket_t.up > 100 )
{
racket_t.up = 100;
}
}
// 移動量設定
start_cnt1 = racket_oldx;
end_cnt1 = racket_x;
start_cnt2 = racket_oldy;
end_cnt2 = racket_y;
// 1フレーム前に戻して2線分交差判定
while( start_cnt2 != end_cnt2 )
{
while( start_cnt1 != end_cnt1 )
{
// アタックレシーブ判定
ret = attack_recv_chk( start_cnt1, start_cnt2 );
if( ret != 0 )
{
// 当たった
return 1;
}
start_cnt1 += vector1;
}
start_cnt2 += vector2;
}
// 当たってない
return 0;
}
// ラケット処理
void racket_move()
{
// ラケット座標取得
GetMousePoint( &racket_x, &racket_y );
// 当たり判定
if( hit_chk( racket_x, racket_y ) == 0)
{
// 当たってないので、すり抜けガード
if( guard_frame_chk() == 0 )
{
// めり込みガード
}
}
// ラケット座標保存
racket_oldx = racket_x;
racket_oldy = racket_y;
}
// ボール処理
void ball_move()
{
// ボール中心座標変換
ball_x = ball_x + BALL_CENTER;
ball_y = ball_y + BALL_CENTER;
if( ball_dx == 0 || ball_dy == 0 )
{
ball_dx = DEF_SPEED;
ball_dy = DEF_SPEED;
}
// ボール移動量加算
ball_x += ball_dx;
ball_y += ball_dy;
// 壁判定
// 上壁
if( ball_y < 0 )
{
ball_y = 0;
// 上壁反射
ball_dy *= -1;
// ボール加速
ball_x += ball_dx;
ball_y += ball_dy;
}
// 下壁
if( ball_y > 720 )
{
ball_y = 720;
// 下壁反射
ball_dy *= -1;
// ボール加速
ball_x += ball_dx;
ball_y += ball_dy;
}
// 左壁
if( ball_x < 0 )
{
ball_x = 0;
// 左壁反射
ball_dx *= -1;
// ボール加速
ball_x += ball_dx;
ball_y += ball_dy;
}
// 右壁
if( ball_x > 1280 )
{
ball_x = 1280;
// 右壁反射
ball_dx *= -1;
// ボール加速
ball_x += ball_dx;
ball_y += ball_dy;
}
}
// 初期化
void init()
{
BALLHandle = LoadGraph( "./data/ball.png" );
RKTHandle = LoadGraph( "./data/cursor02.png" );
// ラケット座標取得
GetMousePoint( &racket_x, &racket_y );
// ラケット座標保存
racket_oldx = racket_x;
racket_oldy = racket_y;
}
// メイン関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
// 画面モードを32ビットカラーにセット
SetGraphMode( 1280, 720, 32 );
// タイトルを Test に変更
SetMainWindowText( "Test" );
// ウインドウモード起動
ChangeWindowMode( true );
// 描画先画面を表にする
SetDrawScreen( DX_SCREEN_BACK );
// 非アクティブでも処理実行
SetAlwaysRunFlag( true );
// DXライブラリ初期化処理
if( DxLib_Init() == -1 )
{
// エラーが起きたら直ちに終了
return -1;
}
// マウスを非表示にする
//SetMouseDispFlag(false);
// 初期化
init();
// メッセージループ処理
while( ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0 )
{
// 画面を初期化
ClearDrawScreen();
// ボール処理
ball_move();
// ラケット処理
racket_move();
// 描画処理
draw();
// 裏画面表示
ScreenFlip();
}
// DXライブラリ使用の終了処理
DxLib_End();
// ソフトの終了
return 0;
}