引っ越しがあるので、今日で当分戦いは禁止になってしまう
兎に角、メインフェーズ完成させたいな。
昨日の続き、
アタック4パターンのうち、ファーストエナジーに対してだけ一つを終わらせた。
残りの3パターンをやっていく。
pub fn handle_being_attacked(
query: Query<
(
Entity,
&Card,
Option<&Fighter>,
&Location,
Option<&FirstEnergy>,
),
With<Player2>,
>,
mut being_attacked_event_reader: EventReader<BeingAttacked>,
mut first_energy_penalty_event_writer: EventWriter<FirstEnergyPenalty>,
mut commands: Commands,
) {
for event in being_attacked_event_reader.read() {
query.get(event.attacked_card_id)
{
match *location {
Location::FZone => {
// Fゾーンにいる場合の処理
println!("{} は Fゾーンにいます", card.name);
// 追加の処理をここに記述する
}
Location::SZone => {
// Sゾーンにいる場合の処理
if let Some(_) = fighter_option {
println!("{} は Sゾーンにいるファイターです", card.name);
// ファイターの特殊な処理をここに記述する
}
}
_ => {}
}
if first_energy_option.is_some() {
println!("{} は ファーストエナジー です", card.name);
first_energy_penalty_event_writer.send(FirstEnergyPenalty);
// FirstEnergy に関連する処理をここに記述する
}
println!("{} は タクティクスです", card.name);
}
} else {
println!(
"攻撃対象の情報を取得できませんでした。エンティティID: {:?}",
event.attacked_card_id
);
}
}
}
バトルFゾーンファイター
- パワー比べを行う(バトル)
- バトル終了時効果や破壊時効果を発動させる
- 撤退と墓地移動選択を行う。
- リセットして、フリーステートに戻る
バトルSゾーンファイター
- 緩いパワー比べを行う(バトル)
- バトル終了時効果や破壊時効果を発動させる
- ペナルティを行う。
- リセットして、フリーステートに戻る
バトルタクティクス
- 必ずバトルに勝つ
- バトル終了時効果や破壊時効果を発動させる
- ペナルティを行う
- リセットして、フリーステートに戻る
撤退の選択が無い、
バトルSゾーンとタクティクスから実装していく。 取り敢えず、
mut attack_tactics_event_reader: EventReader<AttackTactics>,
mut battle_tactics_win_event_writer: EventWriter<BattleTacticsWin>,
mut destroyed_tactics_event_writer: EventWriter<DestroyedTactics>,
mut attack_end_event_writer: EventWriter<AttackEnd>,
mut commands: Commands,
) {
for event in attack_tactics_event_reader.read() {
battle_tactics_win_event_writer.send(BattleTacticsWin {
attacker_id: event.attacker_id,
});
println!("{:?}はバトルに勝利しました", event.attacker_id);
commands
.entity(event.attacked_card_id)
.insert(FaceCondition::Facedown);
commands
.entity(event.attacked_card_id)
.insert(Location::XZone);
println!("{:?}は裏向きで、Xゾーンに送られました。ペナルティです。", event.attacked_card_id);
destroyed_tactics_event_writer.send(DestroyedTactics {
destroyed_tactics_id: event.attacked_card_id,
});
println!("{:?}は破壊されました。Xゾーンに送られます。", event.attacked_card_id);
attack_end_event_writer.send(AttackEnd {
attacker_id: event.attacker_id,
});
}
}
タクティクスとバトルする処理はできた。
pub fn attack_szone(
mut attack_szone_event_reader: EventReader<AttackSZone>,
mut battle_fighter_win_event_writer: EventWriter<BattleFighterWin>,
mut destroyed_fighter_event_writer: EventWriter<DestroyedFighter>,
mut attack_end_event_writer: EventWriter<AttackEnd>,
query: Query<(Entity, &Card, &Fighter), With<Location>>,
mut commands: Commands,
) {
for event in attack_szone_event_reader.read() {
// クエリから攻撃者と攻撃対象の情報を取得
let attacker_query = query.get(event.attacker_id);
let attacked_query = query.get(event.attacked_card_id);
match (attacker_query, attacked_query) {
(
) => {
let attacker_power = attacker_fighter.power; // 攻撃者のパワーを取得
let attacked_power = attacked_fighter.power; // 攻撃対象のパワーを取得
// 攻撃者のパワーが攻撃対象のパワーより大きい場合
if attacker_power > attacked_power {
println!(
"{:?} は {:?} に勝利しました",
attacker_card.name, attacked_card.name
);
// 勝利イベントを発行
battle_fighter_win_event_writer.send(BattleFighterWin {
winner_id: event.attacker_id,
});
// 攻撃対象を破壊するイベントを発行
destroyed_fighter_event_writer.send(DestroyedFighter {
destroyed_fighter_id: event.attacked_card_id,
});
commands
.entity(event.attacked_card_id)
.insert(SpinCondition::ReSpin);
commands
.entity(event.attacked_card_id)
.insert(Location::XZone);
commands
.entity(event.attacked_card_id)
.insert(FaceCondition::Facedown);
println!(
"{:?}は破壊されました。Xゾーンに送られます。",
event.attacked_card_id
);
} else {
// 攻撃者のパワーが攻撃対象のパワー以下の場合
println!("何も起きませんでした");
}
// 攻撃終了イベントを発行
attack_end_event_writer.send(AttackEnd {
attacker_id: event.attacker_id,
});
}
_ => {
// もしいずれかのエンティティが見つからない場合のエラーログ
println!("攻撃者または攻撃対象の情報が見つかりません。");
}
}
}
}
SZoneのファイターとバトルするのもそんなに難しくなかった。
問題は相手の入力を受け付ける必要がある、ファイターに攻撃した場合だ。
pub fn attack_szone(
mut attack_szone_event_reader: EventReader<AttackSZone>,
mut battle_fighter_win_event_writer: EventWriter<BattleFighterWin>,
mut destroyed_fighter_event_writer: EventWriter<DestroyedFighter>,
mut attack_end_event_writer: EventWriter<AttackEnd>,
query: Query<(Entity, &Card, &Fighter), With<Location>>,
mut commands: Commands,
) {
for event in attack_szone_event_reader.read() {
// クエリから攻撃者と攻撃対象の情報を取得
let attacker_query = query.get(event.attacker_id);
let attacked_query = query.get(event.attacked_card_id);
match (attacker_query, attacked_query) {
(
) => {
let attacker_power = attacker_fighter.power; // 攻撃者のパワーを取得
let attacked_power = attacked_fighter.power; // 攻撃対象のパワーを取得
// 攻撃者のパワーが攻撃対象のパワーより大きい場合
if attacker_power > attacked_power {}
if attacker_power == attacked_power {
} else {
}
// 攻撃終了イベントを発行
attack_end_event_writer.send(AttackEnd {
attacker_id: event.attacker_id,
});
}
_ => {
// もしいずれかのエンティティが見つからない場合のエラーログ
println!("攻撃者または攻撃対象の情報が見つかりません。");
}
}
}
}
これでいいだろう。実際できた。
pub fn attack_fzone(
mut attack_fzone_event_reader: EventReader<AttackFZone>,
mut battle_fighter_win_event_writer: EventWriter<BattleFighterWin>,
mut attack_end_event_writer: EventWriter<AttackEnd>,
mut choose_withdraw_event_writer: EventWriter<ChooseWithdrawOrGY>,
query: Query<(Entity, &Card, &Fighter), With<Location>>,
) {
for event in attack_fzone_event_reader.read() {
// クエリから攻撃者と攻撃対象の情報を取得
let attacker_query = query.get(event.attacker_id);
let attacked_query = query.get(event.attacked_card_id);
match (attacker_query, attacked_query) {
(
) => {
let attacker_power = attacker_fighter.power; // 攻撃者のパワーを取得
let attacked_power = attacked_fighter.power; // 攻撃対象のパワーを取得
// 攻撃者のパワーが攻撃対象のパワーより大きい場合
if attacker_power > attacked_power {
battle_fighter_win_event_writer.send(BattleFighterWin { winner_id: event.attacker_id });
choose_withdraw_event_writer.send(ChooseWithdrawOrGY { destroyed_fighter_id: event.attacked_card_id });
} if attacker_power == attacked_power{
choose_withdraw_event_writer.send(ChooseWithdrawOrGY { destroyed_fighter_id: event.attacked_card_id });
choose_withdraw_event_writer.send(ChooseWithdrawOrGY { destroyed_fighter_id: event.attacker_id });
}
else {
battle_fighter_win_event_writer.send(BattleFighterWin { winner_id: event.attacked_card_id });
choose_withdraw_event_writer.send(ChooseWithdrawOrGY { destroyed_fighter_id: event.attacker_id });
}
// 攻撃終了イベントを発行
attack_end_event_writer.send(AttackEnd {
attacker_id: event.attacker_id,
});
}
_ => {
// もしいずれかのエンティティが見つからない場合のエラーログ
println!("攻撃者または攻撃対象の情報が見つかりません。");
}
}
}
}
最後の難関なんだけど、攻撃力の比較に応じて、必ず撤退か墓地送りかを選ばないといけないので、このようにした。
2択なので、いつも通り、check will of 関数を改造して作ることにした。
だけど、よく考えたら、プレイヤーを分けるのがめんどくさいので、ChooseWithdrawOrGY関数は二つ作って、イベントも分けた方がいい。
pub fn attack_fzone(
mut attack_fzone_event_reader: EventReader<AttackFZone>,
mut battle_fighter_win_event_writer: EventWriter<BattleFighterWin>,
mut attack_end_event_writer: EventWriter<AttackEnd>,
mut choose_withdraw_event_writer: EventWriter<ChooseWithdrawOrGY>,
mut opponent_choose_withdraw_event_writer: EventWriter<OpponentWithdrawOrGY>,
query: Query<(Entity, &Card, &Fighter), With<Location>>,
) {
for event in attack_fzone_event_reader.read() {
// クエリから攻撃者と攻撃対象の情報を取得
let attacker_query = query.get(event.attacker_id);
let attacked_query = query.get(event.attacked_card_id);
match (attacker_query, attacked_query) {
(
) => {
let attacker_power = attacker_fighter.power; // 攻撃者のパワーを取得
let attacked_power = attacked_fighter.power; // 攻撃対象のパワーを取得
// 攻撃者のパワーが攻撃対象のパワーより大きい場合
if attacker_power > attacked_power {
battle_fighter_win_event_writer.send(BattleFighterWin {
winner_id: event.attacker_id,
});
opponent_choose_withdraw_event_writer.send(OpponentWithdrawOrGY {
destroyed_fighter_id: event.attacked_card_id,
});
}
if attacker_power == attacked_power {
opponent_choose_withdraw_event_writer.send(OpponentWithdrawOrGY {
destroyed_fighter_id: event.attacked_card_id,
});
choose_withdraw_event_writer.send(ChooseWithdrawOrGY {
destroyed_fighter_id: event.attacker_id,
});
} else {
battle_fighter_win_event_writer.send(BattleFighterWin {
winner_id: event.attacked_card_id,
});
choose_withdraw_event_writer.send(ChooseWithdrawOrGY {
destroyed_fighter_id: event.attacker_id,
});
}
// 攻撃終了イベントを発行
attack_end_event_writer.send(AttackEnd {
attacker_id: event.attacker_id,
});
}
_ => {
// もしいずれかのエンティティが見つからない場合のエラーログ
println!("攻撃者または攻撃対象の情報が見つかりません。");
}
}
}
}
これでいいよ。 てかよく考えたら、LocationコンポーネントにGraveYardなかったわ。
追加と、 追記、elseが上手くいっていないので、3つともifの条件にした。
#[derive(Component, Default)]
InHand,
SZone,
XZone,
FZone,
GraveYard,
#[default]
InLibrary,
}
pub fn show_information(query: Query<(&Card, &Location)>) {
for (card, location) in query.iter() {
let location_str = match location {
Location::InHand => "InHand",
Location::SZone => "SZone",
Location::XZone => "XZone",
Location::FZone => "FZone",
Location::InLibrary => "InLibrary",
Location::GraveYard => "GraveYard"
};
println!(
"Card Name: {}, Energy: {}, Location:{}",
card.name, card.energy, location_str
);
}
}
ちょこっと修正した。
取り敢えず、szoneリストのカードリストから、合計エナジーを取得する処理を書いて。 場合分け
pub fn check_the_will_of_withdraw_or_gy() -> i32 {
loop {
println!("[1]:撤退させる [2]:墓地に送る ");
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 == 2 => return choice,
_ => println!("無効な選択です。もう一度入力してください。"),
}
}
}
pub fn choose_withdraw_or_gy(
mut choose_withdraw_event_writer: EventReader<ChooseWithdrawOrGY>,
mut commands: Commands,
query: Query<(Entity, &Card, &Location)>,
player1_szone: ResMut<Player1SZone>,
) {
for event in choose_withdraw_event_writer.read() {
let mut total_energy = 0;
for entity in player1_szone.cards.iter() {
if let Ok*10 = query.get(*entity) {
total_energy += card.energy;
}
}
println!("合計エナジーは現在:{}", total_energy);
if let Ok*11 = query.get(event.destroyed_fighter_id) {
println!("{}はエナジー:{}", card.name, card.energy);
total_energy += card.energy;
}
let choice = check_the_will_of_withdraw_or_gy();
match choice {
1 => {
if total_energy > 10 {
println!(
"このカードはエナジーが大きすぎて、撤退できません。自動的に墓地に行きます。"
);
commands
.entity(event.destroyed_fighter_id)
.insert(Location::GraveYard);
commands
.entity(event.destroyed_fighter_id)
.insert(SpinCondition::ReSpin);
} else {
println!("撤退させました");
commands.entity(event.destroyed_fighter_id)
.insert(Location::SZone);
}
}
2 => {
println!("墓地に行きました");
commands
.entity(event.destroyed_fighter_id)
.insert(Location::GraveYard);
commands
.entity(event.destroyed_fighter_id)
.insert(SpinCondition::ReSpin);
}
_ => {}
}
}
}
pub fn opponent_choose_withdraw_or_gy(
mut opponent_choose_withdraw_event_writer: EventReader<OpponentWithdrawOrGY>,
mut commands: Commands,
query: Query<(Entity, &Card, &Location)>,
player2_szone: ResMut<Player2SZone>,
) {
for event in opponent_choose_withdraw_event_writer.read() {
let mut total_energy = 0;
for entity in player2_szone.cards.iter() {
if let Ok*12 = query.get(*entity) {
total_energy += card.energy;
}
}
println!("合計エナジーは現在:{}", total_energy);
if let Ok*13 = query.get(event.destroyed_fighter_id) {
println!("{}はエナジー:{}", card.name, card.energy);
total_energy += card.energy;
}
let choice = check_the_will_of_withdraw_or_gy();
match choice {
1 => {
if total_energy > 10 {
println!(
"このカードはエナジーが大きすぎて、撤退できません。自動的に墓地に行きます。"
);
commands
.entity(event.destroyed_fighter_id)
.insert(Location::GraveYard);
commands
.entity(event.destroyed_fighter_id)
.insert(SpinCondition::ReSpin);
} else {
println!("撤退させました");
commands.entity(event.destroyed_fighter_id)
.insert(Location::SZone);
}
}
2 => {
println!("墓地に行きました");
commands
.entity(event.destroyed_fighter_id)
.insert(Location::GraveYard);
commands
.entity(event.destroyed_fighter_id)
.insert(SpinCondition::ReSpin);
}
_ => {}
}
}
}
こんなんでいいかなぁ

きつぁぁぁぁぁぁぁぁっぁあぁあ
後はガード実装だけかな。
最終的にこうでした。
pub fn attack_fzone(
mut attack_fzone_event_reader: EventReader<AttackFZone>,
mut battle_fighter_win_event_writer: EventWriter<BattleFighterWin>,
mut attack_end_event_writer: EventWriter<AttackEnd>,
mut choose_withdraw_event_writer: EventWriter<ChooseWithdrawOrGY>,
mut opponent_choose_withdraw_event_writer: EventWriter<OpponentWithdrawOrGY>,
query: Query<(Entity, &Card, &Fighter), With<Location>>,
) {
for event in attack_fzone_event_reader.read() {
// クエリから攻撃者と攻撃対象の情報を取得
let attacker_query = query.get(event.attacker_id);
let attacked_query = query.get(event.attacked_card_id);
match (attacker_query, attacked_query) {
(
) => {
let attacker_power = attacker_fighter.power; // 攻撃者のパワーを取得
let attacked_power = attacked_fighter.power; // 攻撃対象のパワーを取得
// 攻撃者のパワーが攻撃対象のパワーより大きい場合
if attacker_power > attacked_power {
println!("バトルに勝ちました。");
battle_fighter_win_event_writer.send(BattleFighterWin {
winner_id: event.attacker_id,
});
opponent_choose_withdraw_event_writer.send(OpponentWithdrawOrGY {
attacker_id: event.attacker_id,
attacked_card_id: event.attacked_card_id,
});
}
if attacker_power == attacked_power {
println!("相打ちです");
opponent_choose_withdraw_event_writer.send(OpponentWithdrawOrGY {
attacker_id: event.attacker_id,
attacked_card_id: event.attacked_card_id,
});
choose_withdraw_event_writer.send(ChooseWithdrawOrGY {
attacker_id: event.attacker_id,
attacked_card_id: event.attacked_card_id,
});
}
if attacker_power < attacked_power {
println!("バトルに負けました");
battle_fighter_win_event_writer.send(BattleFighterWin {
winner_id: event.attacked_card_id,
});
choose_withdraw_event_writer.send(ChooseWithdrawOrGY {
attacker_id: event.attacker_id,
attacked_card_id: event.attacked_card_id,
});
}
// 攻撃終了イベントを発行
}
_ => {
// もしいずれかのエンティティが見つからない場合のエラーログ
println!("攻撃者または攻撃対象の情報が見つかりません。");
}
}
}
}
pub fn check_the_will_of_withdraw_or_gy() -> i32 {
loop {
println!("[1]:撤退させる [2]:墓地に送る ");
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 == 2 => return choice,
_ => println!("無効な選択です。もう一度入力してください。"),
}
}
}
pub fn choose_withdraw_or_gy(
mut choose_withdraw_event_writer: EventReader<ChooseWithdrawOrGY>,
mut commands: Commands,
query: Query<(Entity, &Card, &Location)>,
player1_szone: ResMut<Player1SZone>,
mut attack_end_event_writer: EventWriter<AttackEnd>,
) {
for event in choose_withdraw_event_writer.read() {
let mut total_energy = 0;
for entity in player1_szone.cards.iter() {
if let Ok*16 = query.get(*entity) {
total_energy += card.energy;
}
}
println!("合計エナジーは現在:{}", total_energy);
if let Ok*17 = query.get(event.attacker_id) {
println!("{}はエナジー:{}", card.name, card.energy);
total_energy += card.energy;
}
let choice = check_the_will_of_withdraw_or_gy();
match choice {
1 => {
if total_energy > 10 {
println!(
"このカードはエナジーが大きすぎて、撤退できません。自動的に墓地に行きます。"
);
commands
.entity(event.attacker_id)
.insert(Location::GraveYard);
commands
.entity(event.attacker_id)
.insert(SpinCondition::ReSpin);
} else {
println!("撤退させました");
commands
.entity(event.attacker_id)
.insert(Location::SZone);
}
}
2 => {
println!("墓地に行きました");
commands
.entity(event.attacker_id)
.insert(Location::GraveYard);
commands
.entity(event.attacker_id)
.insert(SpinCondition::ReSpin);
}
_ => {}
}
attack_end_event_writer.send(AttackEnd {
attacker_id: event.attacker_id,
});
}
}
pub fn opponent_choose_withdraw_or_gy(
mut opponent_choose_withdraw_event_writer: EventReader<OpponentWithdrawOrGY>,
mut commands: Commands,
query: Query<(Entity, &Card, &Location)>,
player2_szone: ResMut<Player2SZone>,
mut attack_end_event_writer: EventWriter<AttackEnd>,
) {
for event in opponent_choose_withdraw_event_writer.read() {
let mut total_energy = 0;
for entity in player2_szone.cards.iter() {
if let Ok*18 = query.get(*entity) {
total_energy += card.energy;
}
}
println!("合計エナジーは現在:{}", total_energy);
if let Ok*19 = query.get(event.attacked_card_id) {
println!("{}はエナジー:{}", card.name, card.energy);
total_energy += card.energy;
}
let choice = check_the_will_of_withdraw_or_gy();
match choice {
1 => {
if total_energy > 10 {
println!(
"このカードはエナジーが大きすぎて、撤退できません。自動的に墓地に行きます。"
);
commands
.entity(event.attacked_card_id)
.insert(Location::GraveYard);
commands
.entity(event.attacked_card_id)
.insert(SpinCondition::ReSpin);
} else {
println!("撤退させました");
commands
.entity(event.attacked_card_id)
.insert(Location::SZone);
}
}
2 => {
println!("墓地に行きました");
commands
.entity(event.attacked_card_id)
.insert(Location::GraveYard);
commands
.entity(event.attacked_card_id)
.insert(SpinCondition::ReSpin);
}
_ => {}
}
attack_end_event_writer.send(AttackEnd {
attacker_id: event.attacker_id,
});
}
}
なんか、attack fzone関数に、attack endイベントを送信させてたら、処理が上手くいかなかったので、結局、撤退の後に送るようにした。そしたらCheckの前に表示されてしまう問題などが色々解決した。
イベントに攻撃と攻撃される側を常に格納し続けるのがいいような気がした。
それなら、リソースにした方がいいかと思ったけど、イベントでカード効果を処理するなら、こっちでもいいかという発想に至った。
あとは、ガードファイターの実装