imagireshop.hamazo.tv夢で出てきた言葉を検索したら本当にあった。
今日はメインフェーズをopponent仕様にしていこうと思う。
その前に、いくつかのプラグインに分けようと思う。

pub fn situation_log(
mut player1_hand: ResMut<Player1Hand>,
mut player1_szone: ResMut<Player1SZone>,
mut player1_fzone: ResMut<Player1FZone>,
mut player2_szone: ResMut<Player2SZone>,
mut player2_fzone: ResMut<Player2FZone>,
mut player1_xzone: ResMut<Player1XZone>,
mut player2_xzone: ResMut<Player2XZone>,
query: Query<(Entity, &Card, &Location), With<Player1>>,
query_opponent: Query<(Entity, &Card, &Location), With<Player2>>,
query_first_energy: Query<(Entity, &Card), (With<Player1>, With<FirstEnergy>)>,
query_first_energy_opponent: Query<(Entity, &Card), (With<Player2>, With<FirstEnergy>)>,
mut next_state: ResMut<NextState<GameState>>,
mut check_event_reader: EventReader<CheckCard>,
mut start_free_event_writer: EventWriter<StartFree>,
mut game_over_event_writer: EventWriter<GameOver>,
mut commands: Commands,
) {
for _event in check_event_reader.read() {
// プレイヤー1の手札をチェック
player1_hand.cards.clear();
player1_fzone.cards.clear();
player1_szone.cards.clear();
player1_xzone.cards.clear();
if let Location::InHand = location {
player1_hand.cards.push(entity);
}
if let Location::SZone = location {
player1_szone.cards.push(entity);
}
if let Location::FZone = location {
player1_fzone.cards.push(entity);
}
if let Location::XZone = location {
player1_xzone.cards.push(entity);
}
}
// プレイヤー2のSゾーンとFゾーンをチェック
player2_szone.cards.clear();
player2_fzone.cards.clear();
player2_xzone.cards.clear();
if let Location::SZone = location {
player2_szone.cards.push(entity);
}
if let Location::FZone = location {
player2_fzone.cards.push(entity);
}
if let Location::XZone = location {
player2_xzone.cards.push(entity);
}
}
println!("--- フィールド情報 ---");
println!("プレイヤー1の手札: {:?}", player1_hand.cards);
println!("プレイヤー1のSゾーン: {:?}", player1_szone.cards);
println!("プレイヤー1のFゾーン: {:?}", player1_fzone.cards);
println!("プレイヤー1のXゾーン: {:?}", player1_xzone.cards);
println!("プレイヤー2のSゾーン: {:?}", player2_szone.cards);
println!("プレイヤー2のFゾーン: {:?}", player2_fzone.cards);
println!("プレイヤー2のXゾーン: {:?}", player2_xzone.cards);
if player1_xzone.cards.len() >= 6 {
println!("プレイヤー1のXゾーンには6枚以上のカードがあります。");
commands.entity(entity).insert(Location::XZone);
println!("プレイー1の{}がXゾーンに置かれました。", card.name);
}
game_over_event_writer.send(GameOver {
winner_id: 2,
});
next_state.set(GameState::GameOver);
}
if player2_xzone.cards.len() >= 6 {
println!("プレイヤー2のXゾーンには6枚以上のカードがあります。");
commands.entity(entity).insert(Location::XZone);
println!("プレイー2の{}がXゾーンに置かれました。", card.name);
}
game_over_event_writer.send(GameOver {
winner_id: 1,
});
next_state.set(GameState::GameOver);
}
println!("フィールド情報の更新をしました");
start_free_event_writer.send(StartFree);
}
}
pub fn check_the_will_of_battle_or_play() -> i32 {
loop {
println!("[1]:ファイターで攻撃する [2]:カードをプレイする [0]:メインフェーズ終了する");
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.expect("Failed to read line");
// 入力を整数に変換し、結果を返す
match input.trim().parse::<i32>() {
Ok(choice) if choice == 1 || choice == 0 || choice == 2 => return choice,
_ => println!("無効な選択です。もう一度入力してください。"),
}
}
}
pub fn transition_battle_or_play(
mut next_state: ResMut<NextState<PlayState>>,
mut select_attacker_event_writer: EventWriter<SelectAttacker>,
mut select_hand_event_writer: EventWriter<SelectHand>,
mut state_move_event_reader: EventReader<StateMove>,
) {
for event in state_move_event_reader.read() {
let choice = check_the_will_of_battle_or_play();
match choice {
1 => {
println!("バトルに移行します");
select_attacker_event_writer.send(SelectAttacker);
}
2 => {
println!("カードプレイに移行します");
select_hand_event_writer.send(SelectHand);
}
0 => {
println!("メインフェーズ終了しました");
next_state.set(PlayState::TurnEnd);
}
_ => {}
}
}
}
pub fn check_the_will_of_turn_end() -> i32 {
loop {
println!("[1]:メインフェーズを続ける [0]:ターンエンドする");
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.expect("Failed to read line");
// 入力を整数に変換し、結果を返す
match input.trim().parse::<i32>() {
Ok(choice) if choice == 1 || choice == 0 => return choice,
_ => println!("無効な選択です。もう一度入力してください。"),
}
}
}
pub fn transition_turn_end(
mut next_state: ResMut<NextState<PlayState>>,
mut start_free_event_reader: EventReader<StartFree>,
mut state_move_event_writer: EventWriter<StateMove>,
) {
for event in start_free_event_reader.read() {
let choice = check_the_will_of_turn_end();
match choice {
1 => {
state_move_event_writer.send(StateMove);
}
0 => {
println!("ターンエンドしました");
next_state.set(PlayState::TurnEnd);
}
_ => {}
}
}
}
この3つが、基本的なマリガンマネジメント関数になっている。
それ以外は、バトルや、プレイに関する関数である。
pub fn check_situation(mut check_card_event_writer: EventWriter<CheckCard>) {
check_card_event_writer.send(CheckCard);
}
これもあったわ。
これらを改造して、イベントの名前とかを分かりやすくする。
check situation は、メインスタートであるべきだし、発信するイベントの名前も書き換えた。
.add_systems(OnEnter(PlayState::MainPhase), main_phase_start)
.add_systems(Update, (situation_log, main_phase_management, continue_main_phase))
これで、とりあえずインサートした。

choose being attackedがリスピンファイターも殴れるバグに気付いたが、ちょっと待って。
pub fn main_phase_management(
mut next_state: ResMut<NextState<PlayState>>,
mut select_attacker_event_writer: EventWriter<SelectAttacker>,
mut select_hand_event_writer: EventWriter<SelectHand>,
mut main_phase_management_event_reader: EventReader<MainPhaseManagement>,
mut attack_start_event_writer: EventWriter<AttackStart>,
mut play_start_event_writer: EventWriter<PlayStart>,
) {
for event in main_phase_management_event_reader.read() {
let choice = check_the_will_of_battle_or_play();
match choice {
1 => {
attack_start_event_writer.send(AttackStart);
}
2 => {
play_start_event_writer.send(PlayStart);
}
0 => {
println!("メインフェーズ終了しました");
next_state.set(PlayState::TurnEnd);
}
_ => {}
}
}
}
最後の関数を分かりやすくした、
use bevy::prelude::*;
pub mod systems;
use systems::*;
pub struct FreePlugin;
impl Plugin for FreePlugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, (situation_log, main_phase_management, continue_main_phase));
}
}
こういう風にプラグインを作った。

pub struct MainPhasePlugin;
impl Plugin for MainPhasePlugin {
fn build(&self, app: &mut App) {
app.insert_resource(Player1FZone::default())
.insert_resource(Player2FZone::default())
.insert_resource(Player1SZone::default())
.insert_resource(Player2SZone::default())
.insert_resource(Player1XZone::default())
.insert_resource(Player2XZone::default())
.insert_resource(Player1Hand::default())
.insert_resource(Player2Hand::default())
.init_state::<MainPhaseState>()
.add_systems(OnEnter(PlayState::MainPhase), main_phase_start)
.add_plugins(FreePlugin)
.add_plugins(BattlePlugin)
.add_plugins(CardPlayPlugin);
}
}
こういう風に3つのプラグインに分けて、何とかきれいにした。
キレイにしてから、鏡で合わせる。
つく負行ってきたけど、教員とのコミュニケーションの負荷が大きい
というのも、教員が私にしてくる質問が全部情報収集のための質問で意図をつかめないと苦しい
美人のおばちゃんがいるし、セルフレジでウォーターサーバーがある。
土地がキラキラしてる
こんな高校で過ごしてたら、もっと健常な発達ができたような気もするし、開成の深淵からの回収で自分がハマったような気もするし、どちらが良いとは言えないなぁ