✨
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
.vscode/
|
@ -13,3 +13,27 @@
|
|||||||
|
|
||||||
#---------------------------------- Content ---------------------------------#
|
#---------------------------------- Content ---------------------------------#
|
||||||
|
|
||||||
|
#begin playing cards.png
|
||||||
|
/importer:TextureImporter
|
||||||
|
/processor:TextureProcessor
|
||||||
|
/processorParam:ColorKeyColor=255,0,255,255
|
||||||
|
/processorParam:ColorKeyEnabled=True
|
||||||
|
/processorParam:GenerateMipmaps=False
|
||||||
|
/processorParam:PremultiplyAlpha=True
|
||||||
|
/processorParam:ResizeToPowerOfTwo=False
|
||||||
|
/processorParam:MakeSquare=False
|
||||||
|
/processorParam:TextureFormat=Color
|
||||||
|
/build:playing cards.png
|
||||||
|
|
||||||
|
#begin playing cards.png
|
||||||
|
/importer:TextureImporter
|
||||||
|
/processor:TextureProcessor
|
||||||
|
/processorParam:ColorKeyColor=255,0,255,255
|
||||||
|
/processorParam:ColorKeyEnabled=True
|
||||||
|
/processorParam:GenerateMipmaps=False
|
||||||
|
/processorParam:PremultiplyAlpha=True
|
||||||
|
/processorParam:ResizeToPowerOfTwo=False
|
||||||
|
/processorParam:MakeSquare=False
|
||||||
|
/processorParam:TextureFormat=Color
|
||||||
|
/build:playing cards.png
|
||||||
|
|
||||||
|
BIN
Content/playing cards.png
Normal file
BIN
Content/playing cards.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
308
Entities/Card.cs
Normal file
308
Entities/Card.cs
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Solitaire.Graphics;
|
||||||
|
|
||||||
|
namespace Solitaire.Entities {
|
||||||
|
public class Card: CardPosition {
|
||||||
|
const int SelectedOffset = 3;
|
||||||
|
public int DefaultX;
|
||||||
|
|
||||||
|
public Sprite Sprite {get; private set;}
|
||||||
|
public Sprite BackSprite {get; private set;}
|
||||||
|
public Sprite FrontSprite {get; private set;}
|
||||||
|
public int Value;
|
||||||
|
public bool Hidden {get; private set;}
|
||||||
|
private bool Selected;
|
||||||
|
public CardPosition parent = null;
|
||||||
|
|
||||||
|
private double lastClicked;
|
||||||
|
|
||||||
|
public void setSprite() {
|
||||||
|
if (Hidden) {
|
||||||
|
Sprite = BackSprite;
|
||||||
|
} else {
|
||||||
|
Sprite = FrontSprite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Card(int value, bool hidden, Vector2 position, Texture2D spriteSheet): base(position) {
|
||||||
|
Offset = 13;
|
||||||
|
Value = value;
|
||||||
|
Hidden = hidden;
|
||||||
|
if (Hidden) {
|
||||||
|
Offset = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
Position = position;
|
||||||
|
DefaultX = (int)position.X;
|
||||||
|
|
||||||
|
Stationary = true;
|
||||||
|
|
||||||
|
BackSprite = new Sprite(spriteSheet, 320, 192, 32, 48);
|
||||||
|
FrontSprite = new Sprite(
|
||||||
|
spriteSheet,
|
||||||
|
(value % 11) * 32,
|
||||||
|
(value / 11) * 48,
|
||||||
|
32,
|
||||||
|
48
|
||||||
|
);
|
||||||
|
|
||||||
|
setSprite();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NewPosition(Vector2 position) {
|
||||||
|
Position = position;
|
||||||
|
DefaultX = (int)position.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Hide() {
|
||||||
|
Hidden = true;
|
||||||
|
setSprite();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnHide() {
|
||||||
|
Hidden = false;
|
||||||
|
setSprite();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(SpriteBatch spriteBatch, GameTime gameTime) {
|
||||||
|
Sprite.Draw(spriteBatch, Position);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool inRectangle(Vector2 point, Rectangle rectangle) {
|
||||||
|
return (
|
||||||
|
point.X >= rectangle.Left &&
|
||||||
|
point.X <= rectangle.Right &&
|
||||||
|
point.Y > rectangle.Top &&
|
||||||
|
point.Y < rectangle.Bottom
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSelected(Vector2 mPosition, bool mHolding) {
|
||||||
|
int height = 40;
|
||||||
|
if (child != null) {
|
||||||
|
height = Offset;
|
||||||
|
} else if (Selected) {
|
||||||
|
height += SelectedOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle spritePosition = new Rectangle(
|
||||||
|
(int)Position.X, (int)Position.Y, 32, height
|
||||||
|
);
|
||||||
|
if ((!Hidden || child == null) && !mHolding && !Following && inRectangle(mPosition, spritePosition) && !Selected && (child == null || !((Card)child).Selected) && (Offset > 0 || child == null)) {
|
||||||
|
Selected = true;
|
||||||
|
} else if (!inRectangle(mPosition, spritePosition) && Selected) {
|
||||||
|
Selected = false;
|
||||||
|
if (child != null) {
|
||||||
|
((Card)child).SetSelected(mPosition, mHolding);
|
||||||
|
if (((Card)child).Selected) {
|
||||||
|
((Card)child).SetPosition(mPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parent != null) {
|
||||||
|
if (parent is Card) {
|
||||||
|
((Card)parent).SetSelected(mPosition, mHolding);
|
||||||
|
if (((Card)parent).Selected) {
|
||||||
|
((Card)parent).SetPosition(mPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPosition(Vector2 mPosition) {
|
||||||
|
int X;
|
||||||
|
int Y;
|
||||||
|
|
||||||
|
if (Following) {
|
||||||
|
X = (int)mPosition.X - 16;
|
||||||
|
Y = (int)mPosition.Y - 16;
|
||||||
|
} else {
|
||||||
|
X = (int)parent.Position.X;
|
||||||
|
Y = (int)parent.Position.Y + parent.Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Selected && !Following) {
|
||||||
|
Y -= SelectedOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
Position = new Vector2(X, Y);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetStationary(bool stationary) {
|
||||||
|
Stationary = stationary;
|
||||||
|
if (child != null) {
|
||||||
|
((Card)child).SetStationary(stationary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsCloser(CardPosition other, CardPosition closest) {
|
||||||
|
return (
|
||||||
|
other.Stationary &&
|
||||||
|
other.child == null &&
|
||||||
|
(
|
||||||
|
closest == null ||
|
||||||
|
Vector2.Distance(closest.Position, Position) > Vector2.Distance(other.Position, Position)
|
||||||
|
) &&
|
||||||
|
ValidPlacement(other)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ValidPlacement(CardPosition other) {
|
||||||
|
return (
|
||||||
|
other == parent ||
|
||||||
|
(
|
||||||
|
!(other is Card) &&
|
||||||
|
(
|
||||||
|
(
|
||||||
|
!other.TopPile &&
|
||||||
|
(
|
||||||
|
(
|
||||||
|
Deck && other.Deck
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
!other.Deck &&
|
||||||
|
Value % 13 == 12
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
other.TopPile &&
|
||||||
|
Value % 13 == 0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
other is Card &&
|
||||||
|
(
|
||||||
|
(
|
||||||
|
!other.Deck &&
|
||||||
|
(
|
||||||
|
(
|
||||||
|
other.TopPile &&
|
||||||
|
Value / 13 == ((Card)other).Value / 13 &&
|
||||||
|
Value - 1 == ((Card)other).Value
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
(Value % 13 + 1 == ((Card)other).Value % 13) &&
|
||||||
|
((Value / 13) % 2 != (((Card)other).Value / 13) % 2)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
Deck && other.Deck && !((Card)other).Hidden
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(GameTime gameTime, Vector2 mPosition, bool mReleased, bool mHolding, List<IGameEntity> entities) {
|
||||||
|
SetSelected(mPosition, mHolding);
|
||||||
|
|
||||||
|
if (parent != null && !Following) {
|
||||||
|
DrawOrder = parent.DrawOrder + 1;
|
||||||
|
} else if (!Following) {
|
||||||
|
DrawOrder = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Selected && mReleased && !Following) {
|
||||||
|
if (!Hidden) {
|
||||||
|
lastClicked = gameTime.TotalGameTime.TotalSeconds;
|
||||||
|
Following = true;
|
||||||
|
SetStationary(false);
|
||||||
|
Selected = false;
|
||||||
|
DrawOrder = 1000;
|
||||||
|
} else {
|
||||||
|
UnHide();
|
||||||
|
if (Deck) {
|
||||||
|
parent.child = null;
|
||||||
|
Selected = false;
|
||||||
|
SolitaireGame.logic.DeckRevealed.Last().child = this;
|
||||||
|
parent = SolitaireGame.logic.DeckRevealed.Last();
|
||||||
|
SolitaireGame.logic.DeckRevealed.Add(this);
|
||||||
|
SolitaireGame.logic.DeckHidden.Remove(this);
|
||||||
|
parent.Offset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (Following && mReleased) {
|
||||||
|
CardPosition closest = null;
|
||||||
|
CardPosition oldPosition = parent;
|
||||||
|
|
||||||
|
parent.child = null;
|
||||||
|
|
||||||
|
foreach (IGameEntity entity in entities) {
|
||||||
|
if (entity is CardPosition) {
|
||||||
|
if (IsCloser((CardPosition)entity, closest)) {
|
||||||
|
closest = (CardPosition)entity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (closest != null && Vector2.Distance(closest.Position, Position) < 50) {
|
||||||
|
if (ValidPlacement(closest)) {
|
||||||
|
Following = false;
|
||||||
|
SetStationary(true);
|
||||||
|
closest.child = this;
|
||||||
|
parent = closest;
|
||||||
|
if (parent is Card && !((Card)parent).Hidden){
|
||||||
|
parent.Offset = 13;
|
||||||
|
}
|
||||||
|
if (parent.TopPile) {
|
||||||
|
TopPile = true;
|
||||||
|
parent.Offset = 0;
|
||||||
|
} else {
|
||||||
|
TopPile = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Deck && !closest.Deck) {
|
||||||
|
Deck = false;
|
||||||
|
SolitaireGame.logic.DeckRevealed.Remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Deck) {
|
||||||
|
parent.Offset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Following = false;
|
||||||
|
SetStationary(true);
|
||||||
|
oldPosition.child = this;
|
||||||
|
parent = oldPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gameTime.TotalGameTime.TotalSeconds - lastClicked < 0.3 && parent == oldPosition) {
|
||||||
|
foreach (IGameEntity entity in SolitaireGame.entities) {
|
||||||
|
if (entity is CardPosition && ((CardPosition)entity).TopPile && ((CardPosition)entity).child == null) {
|
||||||
|
if (
|
||||||
|
(entity is Card && ((Card)entity).Value % 13 == Value % 13 - 1 && ((Card)entity).Value / 13 == Value / 13) ||
|
||||||
|
(!(entity is Card) && Value % 13 == 0)
|
||||||
|
) {
|
||||||
|
parent.child = null;
|
||||||
|
((CardPosition)entity).child = this;
|
||||||
|
parent = ((CardPosition)entity);
|
||||||
|
TopPile = true;
|
||||||
|
parent.Offset = 0;
|
||||||
|
|
||||||
|
if (Deck) {
|
||||||
|
Deck = false;
|
||||||
|
SolitaireGame.logic.DeckRevealed.Remove(this);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (Following && (mPosition.X < 0 || mPosition.X > SolitaireGame.gameWidth || mPosition.Y < 0 || mPosition.Y > SolitaireGame.gameHeight)) {
|
||||||
|
Following = false;
|
||||||
|
SetStationary(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetPosition(mPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
Entities/CardPosition.cs
Normal file
30
Entities/CardPosition.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Solitaire.Entities {
|
||||||
|
public class CardPosition: IGameEntity {
|
||||||
|
const int SelectedOffset = 0;
|
||||||
|
public int Offset {get; set;} = 0;
|
||||||
|
|
||||||
|
public bool TopPile = false;
|
||||||
|
public bool Deck = false;
|
||||||
|
|
||||||
|
public Vector2 Position {get; set;}
|
||||||
|
public CardPosition child = null;
|
||||||
|
public bool Stationary = true;
|
||||||
|
|
||||||
|
public int DrawOrder {get; set;}
|
||||||
|
public bool Following {get; set;} = false;
|
||||||
|
|
||||||
|
public CardPosition(Vector2 position) {
|
||||||
|
Position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Draw(SpriteBatch spriteBatch, GameTime gameTime) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Update(GameTime gameTime, Vector2 mPosition, bool mReleased, bool mHolding, List<IGameEntity> entities) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
Entities/EmptyDeck.cs
Normal file
43
Entities/EmptyDeck.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Solitaire.Entities {
|
||||||
|
public class EmptyDeck: CardPosition {
|
||||||
|
public bool Selected;
|
||||||
|
|
||||||
|
public EmptyDeck(Vector2 position): base(position) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool inRectangle(Vector2 point, Rectangle rectangle) {
|
||||||
|
return (
|
||||||
|
point.X >= rectangle.Left &&
|
||||||
|
point.X <= rectangle.Right &&
|
||||||
|
point.Y > rectangle.Top &&
|
||||||
|
point.Y < rectangle.Bottom
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSelected(Vector2 mPosition, bool mHolding) {
|
||||||
|
int height = 48;
|
||||||
|
|
||||||
|
Rectangle spritePosition = new Rectangle(
|
||||||
|
(int)Position.X, (int)Position.Y, 32, height
|
||||||
|
);
|
||||||
|
if (child == null && inRectangle(mPosition, spritePosition) && !mHolding) {
|
||||||
|
Selected = true;
|
||||||
|
} else if ((!inRectangle(mPosition, spritePosition) && Selected) || child != null) {
|
||||||
|
Selected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(GameTime gameTime, Vector2 mPosition, bool mReleased, bool mHolding, List<IGameEntity> entities) {
|
||||||
|
SetSelected(mPosition, mHolding);
|
||||||
|
|
||||||
|
if (Selected && mReleased) {
|
||||||
|
SolitaireGame.logic.FlipDeck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
15
Entities/IGameEntity.cs
Normal file
15
Entities/IGameEntity.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Solitaire.Entities {
|
||||||
|
public interface IGameEntity {
|
||||||
|
int DrawOrder {get;}
|
||||||
|
bool Following {get;}
|
||||||
|
Vector2 Position {get;}
|
||||||
|
int Offset {get; set;}
|
||||||
|
|
||||||
|
void Update(GameTime gameTime, Vector2 mPosition, bool mReleased, bool mHolding, List<IGameEntity> entities);
|
||||||
|
void Draw(SpriteBatch spriteBatch, GameTime gameTime);
|
||||||
|
}
|
||||||
|
}
|
52
Game1.cs
52
Game1.cs
@ -1,52 +0,0 @@
|
|||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
using Microsoft.Xna.Framework.Input;
|
|
||||||
|
|
||||||
namespace Solitaire
|
|
||||||
{
|
|
||||||
public class Game1 : Game
|
|
||||||
{
|
|
||||||
private GraphicsDeviceManager _graphics;
|
|
||||||
private SpriteBatch _spriteBatch;
|
|
||||||
|
|
||||||
public Game1()
|
|
||||||
{
|
|
||||||
_graphics = new GraphicsDeviceManager(this);
|
|
||||||
Content.RootDirectory = "Content";
|
|
||||||
IsMouseVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
// TODO: Add your initialization logic here
|
|
||||||
|
|
||||||
base.Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadContent()
|
|
||||||
{
|
|
||||||
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
|
||||||
|
|
||||||
// TODO: use this.Content to load your game content here
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update(GameTime gameTime)
|
|
||||||
{
|
|
||||||
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
|
|
||||||
Exit();
|
|
||||||
|
|
||||||
// TODO: Add your update logic here
|
|
||||||
|
|
||||||
base.Update(gameTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Draw(GameTime gameTime)
|
|
||||||
{
|
|
||||||
GraphicsDevice.Clear(Color.CornflowerBlue);
|
|
||||||
|
|
||||||
// TODO: Add your drawing code here
|
|
||||||
|
|
||||||
base.Draw(gameTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
35
Graphics/Sprite.cs
Normal file
35
Graphics/Sprite.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Solitaire.Graphics {
|
||||||
|
public class Sprite {
|
||||||
|
public Texture2D Texture {get; private set;}
|
||||||
|
|
||||||
|
public int X { get; set; }
|
||||||
|
public int Y { get; set; }
|
||||||
|
|
||||||
|
public int Width {get; set; }
|
||||||
|
public int Height { get; set; }
|
||||||
|
|
||||||
|
public Color TintColor { get; set; } = Color.White;
|
||||||
|
|
||||||
|
public Sprite(Texture2D texture, int x, int y, int width, int height) {
|
||||||
|
Texture = texture;
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Width = width;
|
||||||
|
Height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Draw(SpriteBatch spriteBatch, Vector2 position) {
|
||||||
|
spriteBatch.Draw(
|
||||||
|
Texture,
|
||||||
|
position,
|
||||||
|
new Rectangle(X, Y, Width, Height),
|
||||||
|
TintColor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
117
Logic/GameLogic.cs
Normal file
117
Logic/GameLogic.cs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Solitaire.Entities;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Solitaire.Logic {
|
||||||
|
public class GameLogic {
|
||||||
|
public List<int> deck;
|
||||||
|
public List<IGameEntity> Entities;
|
||||||
|
private Texture2D _SpriteSheet;
|
||||||
|
|
||||||
|
public List<CardPosition> DeckHidden = new List<CardPosition>();
|
||||||
|
public List<CardPosition> DeckRevealed = new List<CardPosition>();
|
||||||
|
|
||||||
|
private void Shuffle<T>(List<T> list) {
|
||||||
|
System.Random random = new System.Random();
|
||||||
|
int n = list.Count;
|
||||||
|
while (n > 1) {
|
||||||
|
int k = random.Next(n);
|
||||||
|
n--;
|
||||||
|
T temp = list[k];
|
||||||
|
list[k] = list[n];
|
||||||
|
list[n] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<int> GenerateDeck() {
|
||||||
|
List<int> newDeck = new List<int>();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (i < 52)
|
||||||
|
{
|
||||||
|
newDeck.Add(i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shuffle(newDeck);
|
||||||
|
return newDeck;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Card DrawCard() {
|
||||||
|
Card card = new Card(
|
||||||
|
deck[0], true, new Vector2(0,0), _SpriteSheet
|
||||||
|
);
|
||||||
|
|
||||||
|
deck.RemoveAt(0);
|
||||||
|
|
||||||
|
return card;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PlayCards() {
|
||||||
|
Card card;
|
||||||
|
CardPosition lastCard;
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
card = null;
|
||||||
|
lastCard = new CardPosition(new Vector2(14 + (i * 40),60));
|
||||||
|
Entities.Add(lastCard);
|
||||||
|
for (int n = 0; n <= i; n ++) {
|
||||||
|
card = DrawCard();
|
||||||
|
card.parent = lastCard;
|
||||||
|
lastCard.child = card;
|
||||||
|
Entities.Add((Card)card);
|
||||||
|
lastCard = card;
|
||||||
|
}
|
||||||
|
card.UnHide();
|
||||||
|
}
|
||||||
|
CardPosition topPile;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
topPile = new CardPosition(new Vector2(134 + (i * 40),8));
|
||||||
|
topPile.TopPile = true;
|
||||||
|
Entities.Add(topPile);
|
||||||
|
}
|
||||||
|
|
||||||
|
CardPosition deckHidden = new EmptyDeck(new Vector2(14, 8));
|
||||||
|
deckHidden.Deck = true;
|
||||||
|
deckHidden.DrawOrder = 100;
|
||||||
|
DeckHidden.Add(deckHidden);
|
||||||
|
Entities.Add(deckHidden);
|
||||||
|
CardPosition deckRevealed = new CardPosition(new Vector2(54, 8));
|
||||||
|
deckRevealed.Deck = true;
|
||||||
|
DeckRevealed.Add(deckRevealed);
|
||||||
|
|
||||||
|
while (deck.Count() > 0) {
|
||||||
|
card = DrawCard();
|
||||||
|
card.parent = DeckHidden.Last();
|
||||||
|
card.Offset = 0;
|
||||||
|
card.Deck = true;
|
||||||
|
DeckHidden.Last().child = card;
|
||||||
|
DeckHidden.Add(card);
|
||||||
|
Entities.Add(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FlipDeck() {
|
||||||
|
CardPosition card;
|
||||||
|
while (DeckRevealed.Count() > 1) {
|
||||||
|
card = DeckRevealed.Last();
|
||||||
|
card.child = null;
|
||||||
|
((Card)card).parent = DeckHidden.Last();
|
||||||
|
DeckHidden.Last().child = card;
|
||||||
|
DeckRevealed.Remove(card);
|
||||||
|
DeckHidden.Add(card);
|
||||||
|
((Card)card).Hide();
|
||||||
|
((Card)card).SetPosition(new Vector2(0,0));
|
||||||
|
card.DrawOrder = ((Card)card).parent.DrawOrder + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameLogic(List<IGameEntity> entities, Texture2D _spriteSheet) {
|
||||||
|
deck = GenerateDeck();
|
||||||
|
Entities = entities;
|
||||||
|
|
||||||
|
_SpriteSheet = _spriteSheet;
|
||||||
|
PlayCards();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ namespace Solitaire
|
|||||||
[STAThread]
|
[STAThread]
|
||||||
static void Main()
|
static void Main()
|
||||||
{
|
{
|
||||||
using (var game = new Game1())
|
using (var game = new SolitaireGame())
|
||||||
game.Run();
|
game.Run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
166
Solitaire.cs
Normal file
166
Solitaire.cs
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
using Solitaire.Entities;
|
||||||
|
using Solitaire.Logic;
|
||||||
|
|
||||||
|
namespace Solitaire
|
||||||
|
{
|
||||||
|
public class SolitaireGame : Game
|
||||||
|
{
|
||||||
|
public const int gameWidth = 300;
|
||||||
|
public const int gameHeight = 300;
|
||||||
|
|
||||||
|
private GraphicsDeviceManager _graphics;
|
||||||
|
private SpriteBatch _spriteBatch;
|
||||||
|
private SpriteBatch _renderTargetBatch;
|
||||||
|
private RenderTarget2D renderTarget;
|
||||||
|
private Rectangle renderTargetRectangle;
|
||||||
|
|
||||||
|
private float renderRatio;
|
||||||
|
|
||||||
|
private MouseState mState;
|
||||||
|
public Vector2 mPosition;
|
||||||
|
public bool mClicked;
|
||||||
|
public bool mReleased;
|
||||||
|
public bool mHolding;
|
||||||
|
|
||||||
|
private Texture2D _spriteSheet;
|
||||||
|
|
||||||
|
public static GameLogic logic;
|
||||||
|
|
||||||
|
|
||||||
|
public static List<IGameEntity> entities;
|
||||||
|
|
||||||
|
private void setRenderRatio() {
|
||||||
|
float wRatio = Window.ClientBounds.Width / (float)gameWidth;
|
||||||
|
float hRatio = Window.ClientBounds.Height / (float)gameHeight;
|
||||||
|
|
||||||
|
if (wRatio > hRatio) {
|
||||||
|
renderRatio = hRatio;
|
||||||
|
} else {
|
||||||
|
renderRatio = wRatio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rectangle renderRectangle() {
|
||||||
|
float drawnWidth = gameWidth * renderRatio;
|
||||||
|
float drawnHeight = gameHeight * renderRatio;
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle rect = new Rectangle(
|
||||||
|
(int)((Window.ClientBounds.Width - drawnWidth)/2),
|
||||||
|
(int)((Window.ClientBounds.Height - drawnHeight)/2),
|
||||||
|
(int)drawnWidth,
|
||||||
|
(int)drawnHeight
|
||||||
|
);
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SolitaireGame()
|
||||||
|
{
|
||||||
|
_graphics = new GraphicsDeviceManager(this);
|
||||||
|
Content.RootDirectory = "Content";
|
||||||
|
IsMouseVisible = true;
|
||||||
|
this.Window.AllowUserResizing = true;
|
||||||
|
this.Window.ClientSizeChanged += new EventHandler<EventArgs>(Window_ClientSizeChanged);
|
||||||
|
|
||||||
|
void Window_ClientSizeChanged(object sender, EventArgs e) {
|
||||||
|
setRenderRatio();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Initialize()
|
||||||
|
{
|
||||||
|
_graphics.PreferredBackBufferWidth = gameWidth * 2;
|
||||||
|
_graphics.PreferredBackBufferHeight = gameHeight * 2;
|
||||||
|
_graphics.ApplyChanges();
|
||||||
|
|
||||||
|
setRenderRatio();
|
||||||
|
|
||||||
|
base.Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadContent()
|
||||||
|
{
|
||||||
|
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
||||||
|
_renderTargetBatch = new SpriteBatch(GraphicsDevice);
|
||||||
|
renderTarget = new RenderTarget2D(
|
||||||
|
GraphicsDevice, gameWidth, gameHeight
|
||||||
|
);
|
||||||
|
|
||||||
|
_spriteSheet = Content.Load<Texture2D>("playing cards");
|
||||||
|
|
||||||
|
entities = new List<IGameEntity>();
|
||||||
|
logic = new GameLogic(entities, _spriteSheet);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update(GameTime gameTime)
|
||||||
|
{
|
||||||
|
renderTargetRectangle = renderRectangle();
|
||||||
|
|
||||||
|
mState = Mouse.GetState();
|
||||||
|
mPosition = mState.Position.ToVector2();
|
||||||
|
mPosition.X -= renderTargetRectangle.Left;
|
||||||
|
mPosition.Y -= renderTargetRectangle.Top;
|
||||||
|
mPosition /= renderRatio;
|
||||||
|
|
||||||
|
if (mReleased) {
|
||||||
|
mReleased = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mState.LeftButton == ButtonState.Pressed && !mClicked) {
|
||||||
|
mClicked = true;
|
||||||
|
} else if (mState.LeftButton == ButtonState.Released && mClicked) {
|
||||||
|
mClicked = false;
|
||||||
|
mReleased = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
entities.Sort(delegate(IGameEntity a, IGameEntity b) {
|
||||||
|
return a.DrawOrder.CompareTo(b.DrawOrder);
|
||||||
|
});
|
||||||
|
|
||||||
|
mHolding = false;
|
||||||
|
foreach (IGameEntity entity in entities) {
|
||||||
|
if (entity is Card && entity.Following) {
|
||||||
|
mHolding = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (IGameEntity entity in entities) {
|
||||||
|
entity.Update(gameTime, mPosition, mReleased, mHolding, entities);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
base.Update(gameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void Draw(GameTime gameTime)
|
||||||
|
{
|
||||||
|
GraphicsDevice.Clear(Color.Black);
|
||||||
|
|
||||||
|
GraphicsDevice.SetRenderTarget(renderTarget);
|
||||||
|
GraphicsDevice.Clear(Color.Green);
|
||||||
|
_spriteBatch.Begin();
|
||||||
|
foreach (IGameEntity entity in entities) {
|
||||||
|
entity.Draw(_spriteBatch, gameTime);
|
||||||
|
}
|
||||||
|
_spriteBatch.End();
|
||||||
|
GraphicsDevice.SetRenderTarget(null);
|
||||||
|
|
||||||
|
_renderTargetBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone);
|
||||||
|
_renderTargetBatch.Draw(
|
||||||
|
renderTarget,
|
||||||
|
renderTargetRectangle,
|
||||||
|
Color.White
|
||||||
|
);
|
||||||
|
_renderTargetBatch.End();
|
||||||
|
|
||||||
|
base.Draw(gameTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user