/// <summary> /// Obtient le tile à l'index spécifié sur la texture donnée /// </summary> /// <param name="tileIndex">L'index du tile</param> /// <param name="texture">La texture</param> /// <returns>Le tile</returns> private Bitmap GetCroppedTexture(int tileIndex, string textureName) { if (tileIndex == GameMapTile.EMPTY) { return(null); } int textureIndex = this.RetrieveTextureIndex(textureName); string croppedKey = RetrieveCroppedKey(tileIndex, textureIndex); // Si le tile n'est pas en dictionnaire de données, on l'ajoute pour une utilisation future (évite de recharger la même texture) if (!CroppedTextures.ContainsKey(croppedKey)) { Bitmap texture = this.GetTexture(textureName); Bitmap croppedTexture = new Bitmap(GlobalData.TileSize.Width, GlobalData.TileSize.Height); Graphics graphics = Graphics.FromImage(croppedTexture); GameVector2 vector = GameMapTile.DecodeFormattedIndex(tileIndex, texture.Width / GlobalData.TileSize.Width) * GlobalData.TileSize; Rectangle section = new Rectangle(vector.X, vector.Y, GlobalData.TileSize.Width, GlobalData.TileSize.Height); graphics.DrawImage(texture, DESTINATION_RECT_32, section, GraphicsUnit.Pixel); CroppedTextures.Add(croppedKey, croppedTexture); } Bitmap resultBitmap; if (CroppedTextures.TryGetValue(croppedKey, out resultBitmap)) { return(resultBitmap); } return(null); }
/// <summary> /// Dessine la map sur le controle de dessin à l'origine spécifiée /// </summary> /// <param name="origin">L'origine de dessin, définie par le point supérieur gauche</param> /// <param name="e">L'évènement du control de dessin</param> public void Draw(GameVector2 origin, PaintEventArgs e) { for (int i = this.layers.Count - 1; i >= 0; i--) { this.layers.ElementAt(i).Draw(origin, e); } }
/// <summary> /// Initialise tous les attributs de l'objet et créer les liens /// </summary> private void Initialize() { this.InitializeComponent(); this.HideOnClose = false; this.AllowEndUserDocking = false; this.mapOrigin = new GameVector2(); this.IsGridActived = true; this.IsSaved = false; this.IsTilesetSelectionShown = true; this.State = GameEditorState.Default; this.gridColor = GridPenColor; this.gridColor.DashStyle = DashStyle.Dash; this.gridColor.Alignment = PenAlignment.Center; this.gridColor.DashOffset = 3.4f; this.mouseLocation = new Point(); this.location = new GameVector2(); this.oldLocation = new Point(); this.selectedLayerIndex = 0; this.mouseReleased = true; this.undoRedoManager = new UndoRedoManager <MemoryStream>(); this.undoRedoManager.UndoHappened += UndoRedoSystem_UndoHappened; this.undoRedoManager.RedoHappened += UndoRedoSystem_RedoHappened; this.RefreshScrollComponents(); }
/// <summary> /// Dessine le layer sur le controle de dessin à l'origine spécifiée /// </summary> /// <param name="origin">L'origine de dessin, définie par le point supérieur gauche</param> /// <param name="e">L'évènement du control de dessin</param> public void Draw(GameVector2 origin, PaintEventArgs e) { if (this.visible) { this.tiles.ForEach(tile => tile.Draw(origin, e)); } }
/// <summary> /// Dessine le tile sur le controle de dessin à l'origine spécifiée /// </summary> /// <param name="origin">L'origine de dessin, définie par le point supérieur gauche</param> /// <param name="e">L'évènement du control de dessin</param> public void Draw(GameVector2 origin, PaintEventArgs e) { if (this.Texture != null) { e.Graphics.DrawImage(this.Texture, new Rectangle( this.Position.X * GlobalData.TileSize.Width - origin.X, this.Position.Y * GlobalData.TileSize.Height - origin.Y, GlobalData.TileSize.Width, GlobalData.TileSize.Height)); } }
private void picMap_MouseMove(object sender, MouseEventArgs e) { this.mouseLocation = e.Location; this.location = this.GetTilePosition(e.Location.X + this.mapOrigin.X, e.Location.Y + this.mapOrigin.Y); // Si la position de la souris à évolué (ref : tile) if (oldLocation.X != location.X || oldLocation.Y != location.Y) { this.oldLocation.X = this.location.X; this.oldLocation.Y = this.location.Y; this.DoTileEdition(e); } this.picMap.Invalidate(); }
public override bool Equals(object obj) { if (!(obj is GameVector2)) { return(false); } if (obj == this) { return(true); } GameVector2 vector = obj as GameVector2; if (vector.X == this.X && this.Y == vector.Y) { return(true); } return(false); }
/// <summary> /// Obtient la position relative en nombre de tiles depuis la position absolue en pixel /// </summary> /// <param name="absoluteX">La position absolue verticale</param> /// <param name="absoluteY">La position absolue horizontale</param> /// <returns>La position relative calculée</returns> private GameVector2 GetTilePosition(int absoluteX, int absoluteY) { GameVector2 vector = new GameVector2(); if (absoluteX < 0) { vector.X = (int)Math.Floor(absoluteX / (GlobalData.TileSize.Width * 1f)); } else { vector.X = absoluteX / GlobalData.TileSize.Width; } if (absoluteY < 0) { vector.Y = (int)Math.Floor(absoluteY / (GlobalData.TileSize.Height * 1f)); } else { vector.Y = absoluteY / GlobalData.TileSize.Height; } return(vector); }
public static bool InBounds(GameVector2 relativePosition) { return relativePosition.X >= 0 && relativePosition.X < GlobalData.MapSize.Width && relativePosition.Y >= 0 && relativePosition.Y < GlobalData.MapSize.Height; }
// TODO : Optimisation requise (Division en sous-methodes, calculs et déroulement impératif unique) /// <summary> /// Modifie de façon intelligente les données de la carte selon la selection du tileset, à partir de la position donnée /// </summary> /// <param name="position">La position du premier tile en haut à gauche à modifier</param> public void SetTiles(int layerIndex, GameVector2 position, TextureInfo texture, bool raiseChanged = true) { #if DEBUG Stopwatch watch = new Stopwatch(); watch.Start(); #endif if (layerIndex >= 0 && layerIndex < this.layers.Count) { if (texture != null && texture.BitmapSelection != null && texture.BitmapSource != null) { int tmpWidth = texture.BitmapSelection.Width / GlobalData.TileSize.Width; int tmpHeight = texture.BitmapSelection.Height / GlobalData.TileSize.Height; int tilesCount = texture.BitmapSource.Width / GlobalData.TileSize.Width; for (int x = 0; x < tmpWidth; x++) { for (int y = 0; y < tmpHeight; y++) { GameMapTile tile = this.layers.ElementAt(layerIndex)[position.X + x, position.Y + y]; if (tile != null) { Rectangle selection = new Rectangle( GlobalData.TileSize.Width * x, GlobalData.TileSize.Height * y, GlobalData.TileSize.Width, GlobalData.TileSize.Height); GraphicsUnit unit = GraphicsUnit.Pixel; RectangleF bounds = texture.BitmapSource.GetBounds(ref unit); if (bounds.Contains(selection)) { // OutOfMemory eventuel, par usage de textures inexistantes (OutOfRange extension) tile.Texture = texture.BitmapSelection.Clone(selection, PixelFormat.DontCare); Point location = new Point( (selection.Location.X + texture.Selection.X) / GlobalData.TileSize.Width, (selection.Location.Y + texture.Selection.Y) / GlobalData.TileSize.Height); tile.FormattedIndex = GameMapTile.EncodeFormattedIndex(location, tilesCount); tile.TextureIndex = this.RetrieveTextureIndex(texture.Path); } } } } } else { GameMapTile tile = this.layers.ElementAt(layerIndex)[position.X, position.Y]; if (tile != null) { tile.FormattedIndex = GameMapTile.EMPTY; tile.Texture = null; } } if(raiseChanged) this.MapChanged?.Invoke(this); } #if DEBUG watch.Stop(); Console.WriteLine($"SetTile : {watch.ElapsedMilliseconds.ToString()} ms"); #endif }
/// <summary> /// Dessine la map sur le controle de dessin à l'origine spécifiée /// </summary> /// <param name="origin">L'origine de dessin, définie par le point supérieur gauche</param> /// <param name="e">L'évènement du control de dessin</param> public void Draw(GameVector2 origin, PaintEventArgs e) { for(int i = this.layers.Count - 1; i >= 0; i--) { this.layers.ElementAt(i).Draw(origin, e); } }
/// <summary> /// Initialise tous les attributs de l'objet et créer les liens /// </summary> private void Initialize() { this.InitializeComponent(); this.HideOnClose = false; this.AllowEndUserDocking = false; this.mapOrigin = new GameVector2(); this.IsGridActived = true; this.IsSaved = false; this.IsTilesetSelectionShown = true; this.State = GameEditorState.Default; this.gridColor = GridPenColor; this.gridColor.DashStyle = DashStyle.Dash; this.gridColor.Alignment = PenAlignment.Center; this.gridColor.DashOffset = 3.4f; this.mouseLocation = new Point(); this.location = new GameVector2(); this.oldLocation = new Point(); this.selectedLayerIndex = 0; this.mouseReleased = true; this.undoRedoManager = new UndoRedoManager<MemoryStream>(); this.undoRedoManager.UndoHappened += UndoRedoSystem_UndoHappened; this.undoRedoManager.RedoHappened += UndoRedoSystem_RedoHappened; this.RefreshScrollComponents(); }
/// <summary> /// Obtient la position relative en nombre de tiles depuis la position absolue en pixel /// </summary> /// <param name="absoluteX">La position absolue verticale</param> /// <param name="absoluteY">La position absolue horizontale</param> /// <returns>La position relative calculée</returns> private GameVector2 GetTilePosition(int absoluteX, int absoluteY) { GameVector2 vector = new GameVector2(); if (absoluteX < 0) vector.X = (int)Math.Floor(absoluteX / (GlobalData.TileSize.Width * 1f)); else vector.X = absoluteX / GlobalData.TileSize.Width; if (absoluteY < 0) vector.Y = (int)Math.Floor(absoluteY / (GlobalData.TileSize.Height * 1f)); else vector.Y = absoluteY / GlobalData.TileSize.Height; return vector; }
/// <summary> /// Dessine la selection du tileset si l'état du document est par défaut, sinon dessine l'effet de l'état courant du document /// </summary> /// <param name="state">L'état de dessin</param> /// <param name="e">Les données de dessin</param> private void DrawSelection(bool state, PaintEventArgs e) { if (state) { GameVector2 location = this.GetTilePosition(this.mouseLocation.X + this.mapOrigin.X, this.mouseLocation.Y + this.mapOrigin.Y); if (this.State == GameEditorState.Default) { if (this.texture?.BitmapSelection != null) { ImageAttributes attributes = new ImageAttributes(); attributes.SetOpacity(0.5f); /*************** Affichage uniquement à l'interieur de la carte *****************/ /*int limitX = this.texture.BitmapSelection.Width / GlobalData.TileSize.Width; * int limitY = this.texture.BitmapSelection.Height / GlobalData.TileSize.Height; * * for (int x = 0; x < limitX; x++) * { * for (int y = 0; y < limitY; y++) * { * if (location.X + x >= 0 && location.X + x < GlobalData.MapSize.Width && * location.Y + y >= 0 && location.Y + y < GlobalData.MapSize.Height) * { * e.Graphics.DrawImage(this.texture.BitmapSelection, * new Rectangle( * (location.X + x) * GlobalData.TileSize.Width - this.mapOrigin.X, * (location.Y + y) * GlobalData.TileSize.Height - this.mapOrigin.Y, * GlobalData.TileSize.Width, * GlobalData.TileSize.Height), * x * GlobalData.TileSize.Width, * y * GlobalData.TileSize.Height, * GlobalData.TileSize.Width, * GlobalData.TileSize.Height, * GraphicsUnit.Pixel, * attributes); * } * } * }*/ /*************** Affichage possible à l'exterieur de la carte *****************/ e.Graphics.DrawImage(this.texture.BitmapSelection, new Rectangle( location.X * GlobalData.TileSize.Width - this.mapOrigin.X, location.Y * GlobalData.TileSize.Height - this.mapOrigin.Y, this.texture.BitmapSelection.Width, this.texture.BitmapSelection.Height), 0, 0, this.texture.BitmapSelection.Width, this.texture.BitmapSelection.Height, GraphicsUnit.Pixel, attributes); } } else if (this.State == GameEditorState.Erase && GameMap.InBounds(location)) { e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(100, 255, 45, 45)), location.X * GlobalData.TileSize.Width - this.mapOrigin.X, location.Y * GlobalData.TileSize.Height - this.mapOrigin.Y, GlobalData.TileSize.Width, GlobalData.TileSize.Height); } } }
// TODO : Optimisation requise (Division en sous-methodes, calculs et déroulement impératif unique) /// <summary> /// Modifie de façon intelligente les données de la carte selon la selection du tileset, à partir de la position donnée /// </summary> /// <param name="position">La position du premier tile en haut à gauche à modifier</param> public void SetTiles(int layerIndex, GameVector2 position, TextureInfo texture, bool raiseChanged = true) { #if DEBUG Stopwatch watch = new Stopwatch(); watch.Start(); #endif if (layerIndex >= 0 && layerIndex < this.layers.Count) { if (texture != null && texture.BitmapSelection != null && texture.BitmapSource != null) { int tmpWidth = texture.BitmapSelection.Width / GlobalData.TileSize.Width; int tmpHeight = texture.BitmapSelection.Height / GlobalData.TileSize.Height; int tilesCount = texture.BitmapSource.Width / GlobalData.TileSize.Width; for (int x = 0; x < tmpWidth; x++) { for (int y = 0; y < tmpHeight; y++) { GameMapTile tile = this.layers.ElementAt(layerIndex)[position.X + x, position.Y + y]; if (tile != null) { Rectangle selection = new Rectangle( GlobalData.TileSize.Width * x, GlobalData.TileSize.Height * y, GlobalData.TileSize.Width, GlobalData.TileSize.Height); GraphicsUnit unit = GraphicsUnit.Pixel; RectangleF bounds = texture.BitmapSource.GetBounds(ref unit); if (bounds.Contains(selection)) { // OutOfMemory eventuel, par usage de textures inexistantes (OutOfRange extension) tile.Texture = texture.BitmapSelection.Clone(selection, PixelFormat.DontCare); Point location = new Point( (selection.Location.X + texture.Selection.X) / GlobalData.TileSize.Width, (selection.Location.Y + texture.Selection.Y) / GlobalData.TileSize.Height); tile.FormattedIndex = GameMapTile.EncodeFormattedIndex(location, tilesCount); tile.TextureIndex = this.RetrieveTextureIndex(texture.Path); } } } } } else { GameMapTile tile = this.layers.ElementAt(layerIndex)[position.X, position.Y]; if (tile != null) { tile.FormattedIndex = GameMapTile.EMPTY; tile.Texture = null; } } if (raiseChanged) { this.MapChanged?.Invoke(this); } } #if DEBUG watch.Stop(); Console.WriteLine($"SetTile : {watch.ElapsedMilliseconds.ToString()} ms"); #endif }
public static bool InBounds(GameVector2 relativePosition) { return(relativePosition.X >= 0 && relativePosition.X < GlobalData.MapSize.Width && relativePosition.Y >= 0 && relativePosition.Y < GlobalData.MapSize.Height); }