Initial implementation of the new abstraction architecture.
[tagua/yd.git] / src / variants / xchess / animator.impl.h
blob6db55cc2275c9c8d2eab2d205c332a73e40f7dda
1 /*
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.
9 */
11 #if 0
12 #include <iostream>
13 #include <memory>
15 #include "variants/xchess/animator.h"
16 #include "variants/xchess/move.h"
17 #include "animation.h"
18 #include "graphicalposition.h"
19 #include "piecesprite.h"
20 #include "kboard.h"
21 #include "pointconverter.h"
22 #include "position.h"
24 using namespace boost;
26 template <typename Variant>
27 SimpleAnimator<Variant>::SimpleAnimator(PointConverter* converter,
28 const shared_ptr<GPosition>& position)
29 : m_converter(converter)
30 , m_position(position) {
31 if(position->getBoolSetting("animations", true)) {
32 m_anim_movement = (bool)position->getBoolSetting("animations.movement", true);
33 m_anim_explode = (bool)position->getBoolSetting("animations.explode", true);
34 m_anim_fade = (bool)position->getBoolSetting("animations.fading", true);
35 m_anim_rotate = (bool)position->getBoolSetting("animations.transform", true);
39 template <typename Variant>
40 shared_ptr<AnimationGroup> SimpleAnimator<Variant>::warp(const Position& final) {
41 AnimationPtr res(new AnimationGroup);
42 // for each point
43 for (Point i = m_position->first(); i <= m_position->last(); i = m_position->next(i)) {
44 QPoint real = m_converter->toReal(i);
46 // retrieve graphical element
47 GElement p = m_position->getElement(i);
49 // retrieve piece
50 const Piece* q = final.get(i);
52 // create animation
53 shared_ptr<Animation> a;
55 // if the graphical element is valid
56 if (p) {
57 // assert that its sprite is valid as well
58 shared_ptr<PieceSprite> sprite = p.sprite();
59 Q_ASSERT(sprite);
61 // if the piece differs
62 if (!p.piece().equals(q)) {
63 shared_ptr<PieceSprite> sprite = p.sprite();
65 if (q) {
66 // replace sprite
67 a = shared_ptr<Animation>(new PromotionAnimation( sprite,
68 m_position->setPiece(i, *q, false, false) ));
70 else {
71 // remove it
72 m_position->removeElement(i);
73 a = shared_ptr<Animation>(new CaptureAnimation(sprite));
77 // if there is no graphical element, simply add it
78 else if (q) {
79 a = shared_ptr<Animation>(new DropAnimation( m_position->setPiece(i, *q, false, false) ));
82 // add animation to the group
83 if (a) res->addPreAnimation(a);
86 return res;
89 template <typename Variant>
90 shared_ptr<MovementAnimation> SimpleAnimator<Variant>::createMovementAnimation(
91 const GElement& element,
92 const QPoint& destination) {
93 return shared_ptr<MovementAnimation>(new MovementAnimation(element.sprite(),
94 destination, 1.0));
98 template <typename Variant>
99 shared_ptr<Animation> SimpleAnimator<Variant>::createCapture(const Point& p,
100 const GElement& /*piece*/,
101 const GElement& captured,
102 const Position& /*pos*/) {
103 if (!captured)
104 return shared_ptr<Animation>();
105 else if(m_anim_explode)
106 return shared_ptr<Animation>(new ExplodeAnimation(captured.sprite(), m_random));
107 else if(m_anim_fade)
108 return shared_ptr<Animation>(new FadeAnimation(captured.sprite(),
109 m_converter->toReal(p), 255, 0));
110 else
111 return shared_ptr<Animation>(new CaptureAnimation(captured.sprite()));
114 template <typename Variant>
115 shared_ptr<AnimationGroup> SimpleAnimator<Variant>::forward(const Position& final,
116 const Move& move) {
117 Q_ASSERT(m_position->consistent());
119 AnimationPtr res(new AnimationGroup);
121 GElement piece = m_position->getElement(move.from);
123 if (piece) {
124 m_position->removeElement(move.from);
125 Q_ASSERT(m_position->consistent());
127 if (move.to.valid()) {
128 GElement captured = m_position->getElement(move.to);
130 m_position->setElement(move.to, piece);
131 Q_ASSERT(m_position->consistent());
133 shared_ptr<Animation> mainAnimation;
134 QPoint hotSpot = piece.sprite()->pos();
135 hotSpot += QPoint(piece.sprite()->pixmap().width() / 2, piece.sprite()->pixmap().height() / 2);
137 // do not animate forward
138 if (!m_anim_movement) {
139 mainAnimation = shared_ptr<InstantAnimation>(
140 new InstantAnimation(piece.sprite(), m_converter->toReal(move.to))
143 // the piece is already on the destination square:
144 // do a direct animation
145 else if (m_converter->toLogical(hotSpot) == move.to) {
146 mainAnimation = shared_ptr<MovementAnimation>(
147 new MovementAnimation(piece.sprite(), m_converter->toReal(move.to))
150 else
151 // do an animation according to preferences
152 mainAnimation = createMovementAnimation(piece, m_converter->toReal(move.to));
154 res->addPreAnimation(mainAnimation);
155 res->addPostAnimation(createCapture(move.to, piece, captured, final));
158 // if it is a one-click move, do nothing
159 // the warping animation will adjust everything
161 // add main animation
162 // the animation must be direct when the piece is already
163 // near the destination square
165 Q_ASSERT(m_position->consistent());
167 finalizeForwardAnimation(res, final, move);
169 AnimationPtr warpingAnimation(new AnimationGroup);
170 warpingAnimation->addPreAnimation(res);
171 warpingAnimation->addPostAnimation(warp(final));
173 return warpingAnimation;
177 template <typename Variant>
178 shared_ptr<AnimationGroup> SimpleAnimator<Variant>::back(const Position& final,
179 const Move& move) {
180 AnimationPtr res(new AnimationGroup);
181 const Piece* captured = final.get(move.to);
182 GElement piece = m_position->getElement(move.to);
184 // the piece could have disappeared
185 // make it reappear!
186 if (!piece) {
187 Q_ASSERT(final.get(move.from));
188 const Piece* disappeared = final.get(move.from);
189 shared_ptr<PieceSprite> sprite = m_position->setPiece(move.to, *disappeared, false, false);
190 res->addPreAnimation(shared_ptr<Animation>(new DropAnimation(sprite)));
191 piece = m_position->getElement(move.to);
194 m_position->setElement(move.from, piece);
196 if (captured) {
197 // recreate captured piece sprite
198 QPoint real = m_converter->toReal(move.to);
199 if(m_anim_fade)
200 res->addPreAnimation( shared_ptr<Animation>(new FadeAnimation(
201 m_position->setPiece(move.to, *captured, false, false), real, 0, 255 ) ));
202 else
203 res->addPreAnimation( shared_ptr<Animation>(new DropAnimation(
204 m_position->setPiece(move.to, *captured, false, false) ) ));
206 else
207 m_position->removeElement(move.to);
209 res->addPreAnimation(
210 m_anim_movement
211 ? shared_ptr<Animation>(createMovementAnimation(piece, m_converter->toReal(move.from)))
212 : shared_ptr<Animation>(new InstantAnimation(piece.sprite(), m_converter->toReal(move.from)))
215 finalizeBackAnimation(res, final, move);
217 AnimationPtr warpingAnimation(new AnimationGroup);
218 warpingAnimation->addPreAnimation(res);
219 warpingAnimation->addPostAnimation(warp(final));
221 return warpingAnimation;
224 #endif