using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Input; using tAC_Engine.Graphics.Cameras; using tAC_Engine.Graphics.Entities; using tAC_Engine.Graphics; using Util; namespace FaceOff { class FaceTray : GameObject { private int traySize = GameConfig.FaceTraySize; private Texture2D mPixel; private Texture2D preloadedTex; private Texture2D loadingTex; private Texture2D undoTex; private Texture2D blankTex; private Logger mLogger; private List mCells; private int borderWidth; private int cellSpace; private int trayWidth; public int Width { get { return trayWidth; } } private int viewWidth; private int lineWidth; private float jitter; private int convertJitter; private System.Random random; private bool completed = false; public bool Completed { get { return completed; } set { completed = value; } } private bool loading = false; public bool Loading { get { return loading; } set { loading = value; } } public FaceTray(int cellSize, Logger logger) { viewWidth = 800; mLogger = logger; mCells = new List(); random = new System.Random(); cellSpace = cellSize; } public void initialize() { lineWidth = mPixel.Width; trayWidth = cellSpace * traySize; borderWidth = (viewWidth - trayWidth) / 2; Position = new Vector2(borderWidth, GameConfig.DesiredBoardHeight + GameConfig.VerticalOffsetTray); mCells = new List(); } public void LoadContent(ContentManager content) { mPixel = content.Load(@"Texture\pixel"); preloadedTex = content.Load(@"Texture\Preload"); loadingTex = content.Load(@"Texture\temp_loading"); undoTex = content.Load(@"Texture\temp_undo"); blankTex = content.Load(@"Texture\Blank"); } public void PopulateTray(int[] categories) { int category; for (int i = 0; i < traySize; ++i) { category = categories[i]; TrayCell tempCell = new TrayCell(mLogger); //this is the texture drawn tempCell.Texture = preloadedTex; tempCell.Category = category; //this is the texture that holds the face //this will only be shown after the user loads the face tempCell.FaceTexture = FaceLoader.GetRandomTexture(category); tempCell.PreLoad = true; tempCell.Loading = false; tempCell.Visible = true; tempCell.Placed = false; tempCell.Reference = i+1; tempCell.Size = cellSpace - lineWidth; //set the position that the image will be drawn int x = lineWidth + borderWidth + (cellSpace * i) - 1; int y = GameConfig.VerticalOffsetTray + GameConfig.DesiredBoardHeight; tempCell.DrawPosition = new Vector2(x, y); tempCell.OriginalPosition = tempCell.DrawPosition; //scale the image to fit the cell tempCell.Scale(); //convert float jitter to int and multiply by 10 so that it //works with the random number generator convertJitter = (int)(GameConfig.MaxJitter * 10f); jitter = random.Next(convertJitter) * 0.1f; tempCell.ApplyJitter(jitter); //add cell to the list of cells mCells.Add(tempCell); } } void DrawTray(SpriteBatch spriteBatch) { //draw the top and bottom line in the faceTray for (int i = 0; i < 2; ++i) { DrawLine(spriteBatch, new Vector2(borderWidth, GameConfig.DesiredBoardHeight + GameConfig.VerticalOffsetTray + (cellSpace * i)), new Vector2(viewWidth - borderWidth, GameConfig.DesiredBoardHeight + GameConfig.VerticalOffsetTray + (cellSpace * i)), GameConfig.FaceOffGreen); } //draw the columns depending on how many cells for (int i = 0; i < (traySize+1); ++i) { DrawLine(spriteBatch, new Vector2(borderWidth + (cellSpace * i), GameConfig.DesiredBoardHeight + GameConfig.VerticalOffsetTray - lineWidth), new Vector2(borderWidth + (cellSpace * i), cellSpace + GameConfig.DesiredBoardHeight + GameConfig.VerticalOffsetTray), GameConfig.FaceOffGreen); } } void DrawLine(SpriteBatch spriteBatch, Vector2 a, Vector2 b, Color col) { Vector2 Origin = new Vector2(0.5f, 0.0f); Vector2 diff = b - a; float angle; Vector2 Scale = new Vector2(1.0f, diff.Length() / mPixel.Height); angle = (float)(Math.Atan2(diff.Y, diff.X)) - MathHelper.PiOver2; spriteBatch.Draw(mPixel, a, null, col, angle, Origin, Scale, SpriteEffects.None, 1.0f); } public void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch) { DrawTray(spriteBatch); TrayCell onTop = null; foreach (TrayCell cell in mCells) { if (!cell.Clicked) { cell.Draw(spriteBatch); } else { onTop = cell; } } //draw the cell being dragged last so that appears on top of everything else if (onTop != null) { onTop.Draw(spriteBatch); } } public int checkClick(Vector2 clickPos) { int retVal = -1; //if another cell is loading than no other cell may be clicked foreach (TrayCell cell in mCells) { if (cell.Loading) { return retVal; } } //if no cells are loading then look to see if the users click was on a cell in the tray foreach (TrayCell cell in mCells) { if ((clickPos.X >= cell.DrawPosition.X) && (clickPos.Y >= cell.DrawPosition.Y) && (clickPos.X <= (cell.DrawPosition.X + cellSpace)) && (clickPos.Y <= (cell.DrawPosition.Y + cellSpace))) { cell.Clicked = true; //start laoding the cell's image if (cell.PreLoad) { mLogger.Write((int)EventCode.FO_STARTFACELOAD + cell.Reference - 1, "FO_STARTFACELOAD Cell=" + cell.Reference); cell.Loading = true; cell.PreLoad = false; cell.Clicked = false; cell.Texture = loadingTex; cell.Scale(); } // if the cell is loading or placed, then it cannot be clicked else if (cell.Loading || cell.Placed || !(cell.Visible)) { cell.Clicked = false; } //if the cell is done loading then it can be dragged else if (!(cell.PreLoad) && !(cell.Loading) && cell.Visible) { mLogger.Write((int)EventCode.FO_FACEDRAG, typeof(EventCode), "X=" + clickPos.X + "_Y="+clickPos.Y); cell.DrawPosition = clickPos; retVal = 0; return retVal; } } } return retVal; } //put a cell back into the facetray that was previously placed onto the board public void undo(int cellReference) { foreach (TrayCell cell in mCells) { if (cell.Reference == cellReference) { cell.Clicked = false; cell.Placed = false; cell.DrawPosition = cell.OriginalPosition; cell.Texture = cell.FaceTexture; cell.Scale(); } } } //put multiple cells back into the facetray that was previously placed onto the board public void undo(List cells) { foreach (TrayCell cell in mCells) { foreach (int cellReference in cells) { //if the cell was incorrect and needs to be undone if (cell.Reference == cellReference) { cell.Clicked = false; cell.Placed = false; cell.DrawPosition = cell.OriginalPosition; cell.Texture = cell.FaceTexture; cell.Scale(); } } } } public void removeFromTray(List cells) { foreach (TrayCell cell in mCells) { foreach (int cellReference in cells) { //if the cell was placed and correct, remove it from the board if (cell.Reference == cellReference) { cell.Visible = false; } } } } //return the cell which is clicked and being dragged public TrayCell getClickedCell() { TrayCell retCell = null; foreach (TrayCell cell in mCells) { if (cell.Clicked) { retCell = cell; //return the cell which is currently clicked return retCell; } } return retCell; } public void cellRelease(bool placed) { foreach (TrayCell cell in mCells) { if (cell.Clicked) { //if the cell was placed on a blank if (placed) { cell.Placed = true; cell.Texture = undoTex; cell.Scale(); } cell.DrawPosition = cell.OriginalPosition; cell.Clicked = false; } } } /// /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// /// Provides a snapshot of timing values. public void Update(GameTime gameTime, Vector2 mousePos) { loading = false; //check to see if the facetray is complete while updating cells completed = true; foreach (TrayCell cell in mCells) { cell.Update(gameTime, mousePos); if (cell.Loading) { loading = true; } if (cell.Visible) { completed = false; } } } } }