mchess-client/lib/chess_bloc/tap_bloc.dart
Marco 200393ac76 Fix tapping on opponent's piece
With the previous change of starting a tap on a drag,
we removed the GestureDetector from all squares with any pieces.

This included the opponent's pieces. Tapping and taking an opponent's
piece was not possible anymore.

This was a bug, since we still want to detect a tap and take an opponent's piece.
2024-02-01 11:37:00 +01:00

110 lines
3.0 KiB
Dart

import 'dart:developer';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mchess/chess_bloc/chess_bloc.dart';
import 'package:mchess/chess_bloc/chess_events.dart';
import 'package:mchess/chess_bloc/promotion_bloc.dart';
import 'package:mchess/utils/chess_utils.dart';
class TapBloc extends Bloc<TapEvent, TapState> {
static final TapBloc _instance = TapBloc._internal();
static TapBloc getInstance() {
return _instance;
}
factory TapBloc() {
return _instance;
}
TapBloc._internal() : super(TapState.init()) {
on<SquareTappedEvent>(handleTap);
on<CancelTapEvent>(cancelTap);
}
void handleTap(SquareTappedEvent event, Emitter<TapState> emit) {
ChessCoordinate? firstTappedSquare, secondTappedSquare;
ChessPiece? piece;
if (ChessBloc.myColor != ChessBloc.turnColor) return;
if (state.firstSquareTapped == null) {
//first tap
if (event.pieceOnSquare == null) return;
if (event.pieceOnSquare != null &&
ChessBloc.myColor != event.pieceOnSquare!.color) return;
firstTappedSquare = event.tapped;
piece = event.pieceOnSquare;
} else {
//second tap
if (event.pieceOnSquare?.color == ChessBloc.myColor) {
emit(TapState(
firstSquareTapped: event.tapped,
pieceOnFirstTappedSquare: event.pieceOnSquare,
secondSquareTapped: null));
return;
}
secondTappedSquare = event.tapped;
}
if (state.firstSquareTapped != null &&
state.firstSquareTapped != event.tapped) {
if (isPromotionMove(
state.pieceOnFirstTappedSquare!.pieceClass,
ChessBloc.myColor,
event.tapped,
)) {
PromotionBloc().add(PawnMovedToPromotionField(
move: ChessMove(from: state.firstSquareTapped!, to: event.tapped),
colorMoved: ChessBloc.myColor));
emit(TapState.init());
return;
} else {
ChessBloc().add(OwnPieceMoved(
startSquare: state.firstSquareTapped!, endSquare: event.tapped));
emit(TapState.init());
return;
}
}
log("handleTap() in TapBloc is called");
emit(TapState(
firstSquareTapped: firstTappedSquare,
pieceOnFirstTappedSquare: piece,
secondSquareTapped: secondTappedSquare));
}
void cancelTap(CancelTapEvent event, Emitter<TapState> emit) {
emit(TapState.init());
}
}
abstract class TapEvent {}
class SquareTappedEvent extends TapEvent {
ChessCoordinate tapped;
ChessPiece? pieceOnSquare;
SquareTappedEvent({required this.tapped, required this.pieceOnSquare});
}
class CancelTapEvent extends TapEvent {}
class TapState {
ChessCoordinate? firstSquareTapped;
ChessPiece? pieceOnFirstTappedSquare;
ChessCoordinate? secondSquareTapped;
TapState(
{required this.firstSquareTapped,
required this.pieceOnFirstTappedSquare,
required this.secondSquareTapped});
factory TapState.init() {
return TapState(
firstSquareTapped: null,
pieceOnFirstTappedSquare: null,
secondSquareTapped: null);
}
}