Teoria
Como você não especificou em qual plataforma está implementando isso, darei uma descrição do algoritmo de maneira independente da linguagem:
- Primeiro empilhe todas as cartas umas sobre as outras, dando-lhes a mesma posição inicial.
- Em seguida, para cada cartão, aplique uma rotação (geralmente centralizada em torno de um dos cantos inferiores , mas mover essa origem permitirá essencialmente que você ajuste a aparência do ventilador).
- Aumente o ângulo de rotação entre cada chamada , dependendo do número de cartões e quanto você deseja que eles sejam distribuídos.
Que a rotação esteja centrada em torno de um dos cantos inferiores do cartão (ou próximo ao canto), deve ser evidente olhando para ele:
Implementação
Quanto à forma de implementar isso, isso depende da sua plataforma. No XNA, você pode simplesmente usar o parâmetro Origin SpriteBatch.Draw
para alterar o centro de sua rotação.
Aqui está o que obtive com o código a seguir (com alguns ajustes na origem para torná-la melhor - basicamente a origem começa no canto direito e termina no canto esquerdo):
int cards = 20;
float range = MathHelper.ToRadians(90);
float initialAngle = MathHelper.ToRadians(-45);
float increment = range / cards;
Vector2 leftCorner = new Vector2(0, texture.Height * 0.9f);
Vector2 rightCorner = new Vector2(texture.Width, texture.Height * 0.9f);
Vector2 fanPosition = new Vector2(400, 300);
spriteBatch.Begin();
for (float angle = 0; angle < range; angle+=increment)
{
float cardAngle = initialAngle + angle;
Vector2 cardOrigin = Vector2.Lerp(rightCorner, leftCorner, angle / range);
spriteBatch.Draw(texture, fanPosition, null, Color.White, cardAngle, cardOrigin, 1f, SpriteEffects.None, 0f);
}
spriteBatch.End();
E o resultado: