2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
11 #ifndef XCHESS__ANIMATOR_IMPL_H
12 #define XCHESS__ANIMATOR_IMPL_H
15 #include "animationfactory.h"
16 #include "namedsprite.h"
19 template <typename Variant
>
20 AnimationGroupPtr BaseAnimator
<Variant
>::warp(const Position
& final
) {
21 const Position
* current
= m_cinterface
->position();
22 AnimationFactory
res(m_cinterface
->inner());
24 for (Point i
= current
->first(); i
<= current
->last(); i
= current
->next(i
)) {
25 Piece c
= current
->get(i
);
26 Piece f
= final
.get(i
);
30 NamedSprite sprite
= m_cinterface
->setPiece(i
, f
, false);
31 res
.addPreAnimation(Animate::appear(sprite
), Animate::Instant
);
34 NamedSprite old_sprite
= m_cinterface
->takeSprite(i
);
35 res
.addPreAnimation(Animate::disappear(old_sprite
), Animate::Instant
);
37 else if(c
&& f
&& !(c
== f
) ) {
38 NamedSprite old_sprite
= m_cinterface
->takeSprite(i
);
39 NamedSprite sprite
= m_cinterface
->setPiece(i
, f
, false);
40 res
.addPreAnimation(Animate::morph(old_sprite
, sprite
), Animate::Instant
);
47 template <typename Variant
>
48 AnimationGroupPtr BaseAnimator
<Variant
>::forward(const Position
& final
, const Move
&) {
53 template <typename Variant
>
54 AnimationGroupPtr BaseAnimator
<Variant
>::back(const Position
& final
, const Move
&) {
58 template <typename Variant
>
59 AnimationGroupPtr SimpleAnimator
<Variant
>::warp(const Position
& final
) {
60 AnimationFactory
res(m_cinterface
->inner());
62 res
.setGroup(Base::warp(final
));
67 template <typename Variant
>
68 SchemePtr SimpleAnimator
<Variant
>::movement(const NamedSprite
& sprite
, const Point
& from
, const Point
& to
) {
69 bool knight
= m_cinterface
->position()->get(from
).type() == KNIGHT
;
71 ? Animate::move::LShaped
| Animate::move::Rotating
72 : Animate::move::Straight
;
73 return SchemePtr(new Animate::move(sprite
, to
, mtype
));
76 template <typename Variant
>
77 AnimationGroupPtr SimpleAnimator
<Variant
>::forward(const Position
& final
, const Move
& move
) {
78 AnimationFactory
res(m_cinterface
->inner());
80 NamedSprite piece
= m_cinterface
->takeSprite(move
.from
);
81 NamedSprite captured
= m_cinterface
->takeSprite(move
.to
);
82 m_cinterface
->setSprite(move
.to
, piece
);
85 res
.addPreAnimation(*movement(piece
, move
.from
, move
.to
));
90 res
.addPostAnimation(Animate::destroy(captured
));
92 if (move
.type() == Move::EnPassantCapture
) {
93 Point
phantom(move
.to
.x
, move
.from
.y
);
94 NamedSprite capturedPawn
= m_cinterface
->takeSprite(phantom
);
97 QPoint real
= m_cinterface
->converter()->toReal(phantom
);
98 res
.addPostAnimation(Animate::disappear(capturedPawn
));
103 else if (move
.type() == Move::Promotion
) {
104 Piece promoted
= final
.get(move
.to
);
107 QPoint real
= m_cinterface
->converter()->toReal(move
.to
);
108 NamedSprite old_sprite
= m_cinterface
->getSprite(move
.to
);
109 NamedSprite new_sprite
= m_cinterface
->setPiece(move
.to
, promoted
, /*false,*/ false);
111 res
.addPostAnimation(Animate::morph(old_sprite
, new_sprite
));
116 else if (move
.type() == Move::KingSideCastling
) {
117 Point rookSquare
= move
.to
+ Point(1,0);
118 Point rookDestination
= move
.from
+ Point(1,0);
120 NamedSprite rook
= m_cinterface
->takeSprite(rookSquare
);
121 m_cinterface
->setSprite(rookDestination
, rook
);
122 res
.addPreAnimation(Animate::move(rook
, rookDestination
));
124 else if (move
.type() == Move::QueenSideCastling
) {
125 Point rookSquare
= move
.to
+ Point(-2,0);
126 Point rookDestination
= move
.from
+ Point(-1,0);
128 NamedSprite rook
= m_cinterface
->takeSprite(rookSquare
);
129 m_cinterface
->setSprite(rookDestination
, rook
);
130 res
.addPreAnimation(Animate::move(rook
, rookDestination
));
136 template <typename Variant
>
137 AnimationGroupPtr SimpleAnimator
<Variant
>::back(const Position
& final
, const Move
& move
) {
138 AnimationFactory
res(m_cinterface
->inner());
140 NamedSprite piece
= m_cinterface
->takeSprite(move
.to
);
141 NamedSprite captured
;
142 if (Piece captured_piece
= final
.get(move
.to
)) {
143 captured
= m_cinterface
->setPiece(move
.to
, captured_piece
, false);
144 res
.addPreAnimation(Animate::appear(captured
));
148 piece
= m_cinterface
->createPiece(move
.to
, final
.get(move
.from
), false);
149 res
.addPreAnimation(Animate::appear(piece
));
152 m_cinterface
->setSprite(move
.from
, piece
);
155 if (move
.type() == Move::EnPassantCapture
) {
156 Point
phantom(move
.to
.x
, move
.from
.y
);
158 if (Piece pawn_piece
= final
.get(phantom
)) {
159 NamedSprite captured_pawn
= m_cinterface
->setPiece(phantom
, pawn_piece
, false);
160 res
.addPreAnimation(Animate::appear(captured_pawn
));
163 else if (move
.type() == Move::Promotion
) {
164 Piece pawn_piece
= final
.get(move
.from
);
166 NamedSprite pawn
= m_cinterface
->createPiece(move
.to
, pawn_piece
, false);
167 res
.addPreAnimation(Animate::morph(piece
, pawn
));
169 // replace piece with pawn
170 m_cinterface
->setSprite(move
.from
, pawn
);
174 else if (move
.type() == Move::KingSideCastling
) {
175 Point rookSquare
= move
.to
+ Point(1,0);
176 Point rookDestination
= move
.from
+ Point(1,0);
178 NamedSprite rook
= m_cinterface
->takeSprite(rookDestination
);
179 m_cinterface
->setSprite(rookSquare
, rook
);
181 res
.addPreAnimation(Animate::move(rook
, rookSquare
));
183 else if (move
.type() == Move::QueenSideCastling
) {
184 Point rookSquare
= move
.to
+ Point(-2,0);
185 Point rookDestination
= move
.from
+ Point(-1,0);
187 NamedSprite rook
= m_cinterface
->takeSprite(rookDestination
);
188 m_cinterface
->setSprite(rookSquare
, rook
);
190 res
.addPreAnimation(Animate::move(rook
, rookSquare
));
193 res
.addPreAnimation(*movement(piece
, move
.to
, move
.from
));
199 #endif // XCHESS__ANIMATOR_IMPL_H