I am making a 2D game in windows form and I have a problem... So, I have a Panel where all the "Ground" Tiles (PictureBox[]) are... But instead of just setting the PictureBox.Image, i need to have another Panel above the "Ground Tiles" one, so it can looks like the player is behind something... But that panel needs to be transparent, and its Picture boxes need to appear to make the effect, yet it doesnt... The reason why I put the Tiles (PictureBox) inside a Panel, it is because i want to make the illusion that the camera is focused on the player (meaning the player doesnt really moves, its the Panels that moves).
Can anyone help me please? I know it looks complex... Sorry...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using World;
namespace World
{
public partial class LoadWorld : Form
{
public int TileSizeX = 30;
public int TileSizeY = 30;
public int TileT = 2500;
public int TileX = 49;
public int TileY = 49
//Here's the problematic panel
public Panel PropPanel = new Panel();
public PictureBox[] WorldTile = new PictureBox[2500];
public PictureBox[] PropTile = new PictureBox[2500];
public static Dictionary<PictureBox, int[]> tileProp = new Dictionary<PictureBox, int[]>();
public LoadWorld()
{
InitializeComponent();
}
private void LoadWorld_Load(object sender, EventArgs e)
{
//settings of the PropPanel
PropPanel.BorderStyle = BorderStyle.None;
PropPanel.BringToFront();
PropPanel.BackColor = Color.Transparent;
PropPanel.Visible = true;
PropPanel.Name = "PropPanel";
PropPanel.TabIndex = 0;
int valueA = 0;
int valueX = 0;
int valueY = 0;
foreach (PictureBox pictureBoxValue in WorldTile)
{
if(valueY < TileY)
{
if(valueX < TileX)
{
WorldTile[valueA] = new PictureBox()
{
Size = new Size(TileSizeX, TileSizeY),
Location = new Point(valueX * 30, valueY * 30),
BackgroundImage = new Bitmap("Sprites/null.png"),
Visible = true,
Name = "tile" + valueA
};
WorldMap.Controls.Add(WorldTile[valueA]);
valueA = valueA + 1;
valueX = valueX + 1;
}
else if(valueX == TileX)
{
WorldTile[valueA] = new PictureBox()
{
Size = new Size(TileSizeX, TileSizeY),
Location = new Point(valueX * 30, valueY * 30),
BackgroundImage = new Bitmap("Sprites/null.png"),
Visible = true,
Name = "tile" + valueA,
};
WorldMap.Controls.Add(WorldTile[valueA]);
valueA = valueA + 1;
valueY = valueY + 1;
valueX = 0;
}
}
else if(valueY == TileY)
{
if (valueX < TileX)
{
WorldTile[valueA] = new PictureBox()
{
Size = new Size(TileSizeX, TileSizeY),
Location = new Point(valueX * 30, valueY * 30),
BackgroundImage = new Bitmap("Sprites/null.png"),
Visible = true,
Name = "tile" + valueA,
};
WorldMap.Controls.Add(WorldTile[valueA]);
valueX = valueX + 1;
valueA = valueA + 1;
}
else if (valueX == TileX)
{
WorldTile[valueA] = new PictureBox()
{
Size = new Size(TileSizeX, TileSizeY),
Location = new Point(valueX * 30, valueY * 30),
BackgroundImage = new Bitmap("Sprites/null.png"),
Visible = true,
Name = "tile" + valueA,
};
WorldMap.Controls.Add(WorldTile[valueA]);
}
}
}
SetGroundTiles();
SetPropTiles();
}
public void SetGroundTiles()
{
SGT(1, "grass");
SGT(2, "DirtPathVSideL");
SGT(3, "DirtPathCenter");
SGT(4, "DirtPathVSideR");
//Road
SGT(9, "SidewalkMiddle");
SGT(10, "Asphalt");
SGT(11, "Asphalt");
SGT(12, "Asphalt2YL");
SGT(13, "Asphalt");
SGT(14, "Asphalt");
SGT(15, "GrassConcreteHL");
SGT(59, "SidewalkMiddle");
SGT(60, "Asphalt");
SGT(61, "Asphalt");
SGT(62, "Asphalt2YL");
SGT(63, "Asphalt");
SGT(64, "Asphalt");
SGT(65, "GrassConcreteHL");
SGT(109, "SidewalkMiddle");
SGT(110, "Asphalt");
SGT(111, "Asphalt");
SGT(112, "Asphalt2YL");
SGT(113, "Asphalt");
SGT(114, "Asphalt");
SGT(115, "GrassConcreteHL");
}
public void SetPropTiles()
{
SPT(9, "SmallTree2", true, false);
SPT(60, "SmallTree1", false, true);
}
public void SGT (int valueA, string texture)
{
WorldTile[valueA].BackgroundImage = new Bitmap("Sprites/" + texture + ".png");
}
public void SPT(int valueA, string texture, bool Collide, bool IsOverlaying)
{
PropTile[valueA] = new PictureBox
{
Name = "Panel" + valueA,
Image = new Bitmap("Sprites/" + texture + ".png"),
Location = WorldTile[valueA].Location,
Size = WorldTile[valueA].Size,
Visible = true,
BackColor = Color.Transparent,
};
//Where PropPanel is being used
PropTile[valueA].BorderStyle = BorderStyle.None;
PropPanel.BringToFront();
PropPanel.Controls.Add(PropTile[valueA]);
WorldMap.Controls.Add(PropPanel);
}
}
}
Its like overlaying a transparent panel on another panel... i have tried to put the 2nd panel transparent but its images just didnt appear.
This may help you to understand
what i want to do is basically 3 layers of panel...
PropTextures (like if the player was behind something)
Player Texture / PropTextures (Collision with objects)
Ground Textures (where the player can or not walk)
Transparency, the way you are trying to use it, is not provided by the PictureBox control. I don't think you're going to have much luck if you continue with your current approach.
So here is a tip for an alternate approach. If you're having difficulty doing this with PictureBox controls and such, then you could do the rendering yourself. Create a UserControl that is DoubleBuffered, and in the Paint event, for each sprite, call Graphics.DrawImage to render each image to the correct spot. The nice thing about this technique is that you will get proper alpha-correct compositing when drawing the sprites this way. Just be sure to sort them so that you draw them from back to front and "paint over" the background sprites using the foreground sprites.