見出し画像

GameMaker「卓球」を作ってみた

これまで、ブロック崩しをベースにインベーダーやワニワニパニックなど、色々と作ってみたが、今度は、デジタルゲームの元祖と言っても良い「Pong(卓球)」を作ってみる。
参考にしたのは、以下のページ。Google自動翻訳でスタート。

Pong(卓球)

「ボール」と「バー」のスプライトとオブジェクトを用意する

絵素材を描く

スプライトとオブジェクトの作り方は、ブロック崩しの作り方と同じ。
spr_ballとspr_playerのスプライトを obj_ballとobj_playerのオブジェクトに登録して準備完了。

ルームの準備

ルームの背景

・640×360の16:9の横長のルームを作る
・BackGroundに背景を追加

ルームの準備

ルームにプレイヤーを配置

・プレイヤーのバーを配置

ボールとバーを配置

プレイヤーのバーを上下に動かす

プレイヤーの初期設定
・obj_playerのオブジェクトに「作成」イベントを追加
・ここでは、プレイヤーのバーの移動の速度とプレイヤーの色を白に設定。

プレイヤーの初期設置
current_spd = 0;       // ボールの現在の速度を定義
max_spd = 2.5;         // ボールの速度
image_blend = c_white; // プレイヤーのバーの色を白に設定

プレイヤーを上に動かす
・obj_playerのオブジェクトに「キーホールド・上」イベントを追加
・上の矢印が押された時、yが画面外でなければ、yをマイナスして上に移動

プレイヤーを上に動かす
current_spd = -max_spd;  // ボールの速度をマイナスに設定
y = y + current_spd;     // y方向に移動

// 画面外に出ないようにする
y = clamp(y + current_spd, sprite_height /2, room_height - sprite_height /2);

プレイヤーを下に動かす
・obj_playerのオブジェクトに「キーホールド・上」イベントを追加
・下の矢印が押された時、yが画面外でなければ、yをプラスして下に移動

プレイヤーをしたに動かす
current_spd = max_spd; // ボールの速度をプラスに設定
y = y + current_spd;  // y方向に移動

// 画面外に出ないようにする
y = clamp(y + current_spd, sprite_height /2, room_height - sprite_height /2);

ここで、F5で実行すると、1Pと2Pのプレイヤーが上下に動く。

プレイヤーの上下動

ボールの制御

ボールの初期設定
・obj_ballに「作成」イベントを作成
・ボールの状態を設定
・ボールの初期速度やバーや壁に当たった時の加速度などを設定
・ボールの初期の大きさを設定

ボールの初期設定
lostball = true;     // ボールの状態

speed = 0;           // 最初はボールが止まっている

spd = 4;             // ボールの初期速度
a_spd = 0.3;         // バーに当たった時の加速度
w_spd = 0.1;         // 壁に当たった時の速度

image_xscale = 0.5;  // x方向のボールの大きさ
image_yscale = 0.5;  // y方向のボールの大きさ

alarm[0] = 60;       // 60経過後、アラーム0へ移動

ボールがランダム方向に移動
・obj_ballに「アラーム0」イベントを追加
・ゲーム開始時とプレイヤーか敵がボールをロストした時に、ボールが中央に出現し、ランダムな方向に移動を開始する

ボールがランダム方向に移動
// ボールがランダム方向に移動

if (lostball == true)
{
	speed = spd;

	if (irandom(1)=0)	direction = random_range (75,-75); // 敵方向に移動
	else	direction = random_range (105,255); // プレイヤー方向に移動
}
lostball = false;

ボールの画面外チェック
・obj_ballに「その他>境界と交差」イベントを追加
・ボールが上下の壁に当たったら反射
・ボールが左右の画面外に出たら、画面中央にボールを配置

ボールの画面外チェック
// ボールが上下の壁に当たったら反射
if (bbox_bottom > room_height or 0 > bbox_top) // 縦方向の壁に当たったか?
{
	vspeed = -vspeed; // 縦方向の速度を反転
	speed += w_spd;   // 壁で加速
	y = clamp(y, sprite_yoffset, room_height-sprite_yoffset); // めり込み対策
}

// ボールが左右の画面外に出たら、画面中央にボールを配置
if (x < 0 or x > room_width)
{
	x = room_width / 2;
	y = room_height / 2;
	speed = 0;
	lostball = true;
	alarm[0] = 60;
}

ボールとプレイヤーの反射
・obj_ballに「コリジョン>オブジェクト>obj_player」イベントを追加
・プレイヤーのバーに当たった時の反射と加速を設定

ボールとプレイヤーの反射
direction = point_direction (other.x, other.y, x, y); // 反射方向の計算
speed += a_spd; // プレイヤーに当たった時の加速度

ここでF5で実行すると、1人で卓球が可能。
ここでは、1Pも2Pも両方一人で動かしている。
次は、敵の行動パターンを作る。

1人でプレイ

敵の行動パターン

敵の初期設定
・obj_enemyを作る。スプライトは一旦プレイヤーと同じものを使う。
・obj_enemyに「作成」イベントを追加
・速度や色を設定

敵の初期設定
current_spd = 0;
max_spd = 2.5;
image_blend = c_red;

敵の行動パターン
・obj_enemyに「ステップ」イベントを追加
・ボールが敵の陣地に居る場合は動かない
・ボールのy座標と自分のy座標を比較して、上下どちらかに移動する
・差を0にすると敏感に動き過ぎるので、y座標の差が20以内は止まる
・画面外に出ないように設定

敵の行動パターン
// 敵の陣地に居る場合は動かない
if (obj_ball.x < room_width / 2) current_spd = 0;

// ボールのy座標と自分のy座標が20より離れていれば移動する
else
{
	if (abs(obj_ball.y - y) > 20)
	{
		if (obj_ball.y < y) current_spd = -max_spd; // 上に移動
		else current_spd = max_spd;                 // 下に移動
	}
	else current_spd = 0;
}

y = y + current_spd;

// 画面外に出ないように設定
y = clamp(y + current_spd, sprite_height /2, room_height - sprite_height /2);

ボールと敵の反射
・obj_ballに「コリジョン>オブジェクト>obj_enemy」イベントを追加
・敵のバーに当たった時の反射と加速を設定

ボールとプレイヤーの反射
direction = point_direction (other.x, other.y, x, y); // 反射方向の計算
speed += a_spd; // 敵に当たった時の加速度

ここでF5で実行すると、敵と対戦できる。
敵は、初期設定のmax_spdを変えると強くなったり弱くなったりする。

敵とプレイ

得点とゲーム終了

ゲームの初期設定
・obj_controlを追加
・obj_controlに「作成」イベントを追加
・ゲームの初期設定を追加

ゲームの初期設定
draw_set_font(fnt_game); // フォントを指定 
gameset = false;         // ゲームが終了したかどうか
gscore = 5;              // 何点先取か?
randomise();             // 初期をランダムにする

初期スコア設定
・obj_controlに「その他>ルーム開始」イベントを追加
・globalとして敵味方の初期得点を追加

初期スコア
global.e_score = 0; // 敵の初期得点
global.p_score = 0; // プレイヤーの初期得点

ゲーム終了条件
・obj_controlに「ステップ」イベントを追加
・どちらかが既定の得点に達したか?
・enterで再試合

ゲーム終了
// どちらかが既定の得点に達したか?
if(global.e_score >= gscore or global.p_score >= gscore)
{
	gameset = true;
}
else gameset = false;

// 勝敗決定後、enterキーで再試合
if(gameset == true)
{
	if(keyboard_check_pressed(vk_enter))	
	{
		room_restart();
	}
}	

表示
・obj_controlに「描画」イベントを追加
・得点を表示
・決着がついた時に「Game Set」と表示

表示
draw_set_halign(fa_center); // 文字をセンター
draw_text(room_width /2 -50, 16, string(global.p_score)); // プレイヤーの得点
draw_text(room_width /2 +50, 16, string(global.e_score)); // 敵の得点

// クリア表示。enterを押したら再試合。
if(gameset == true)
{
	draw_text_transformed(room_width/2, room_height/2 - 60, "Game Set", 1.5, 1.5, 0);
	draw_text_transformed(room_width/2, room_height/2, "Press Enter", 0.75, 0.75, 0);
}

フォントの追加
・フォントを追加

フォントの追加
フォント設定

ここで実行すると得点が表示され、勝敗が決まるとGameSetが表示される。

得点とゲーム終了

次にやりたいこと

二番手の奥義「組み合わせの術」を用いて、「ブロック崩し」「卓球」を組み合わせて色々作ってみる。

テニス崩し

・上下左右に移動できるようにしてテニスを作る
・ブロックを入れて障害物テニスをしてみる

テニス崩し

怪獣タワーディフェンス

・傍若無人に街を壊しまくる怪獣
・ザコをボールのようにぶっ飛ばして怪獣の向きを変え敵の陣地に送り込む

怪獣タワーディフェンス


いいなと思ったら応援しよう!