Create dynamically named sliders - c#

This question got marked as duplicate as it involves creating dynamically named variables.
But the thing that I'm after is to create a number of dynamic sliders, so those .net answers aren't helping me.
The sliders are the same physical size and their names are held within an array, and their number is known. However, it could be one it could be twent, hence the need for dynamic slider creation.
This doesn't work:
for (int i = 0; i < numOfCheeseMonkeys; i++)
{
slider + i = GUI.HorizontalSlider(new Rect(25, 50 + (i * 30), 150, 25), slider + i, 0.0F, 100.0F);
}
...this will, but it's stoopid:
sliderA = GUI.HorizontalSlider(new Rect(25, 50 + (i * 30), 150, 25), sliderA, 0.0F, 100.0F);
sliderB = GUI.HorizontalSlider(new Rect(25, 50 + (i * 30), 150, 25), sliderB, 0.0F, 100.0F);

Use an array or some kind of collection. It would look something like this:
Slider[] sliders = new Slider[numOfCheeseMonkeys];
for (int i =0; i < numOfCheeseMonkeys; i++)
{
sliders[i] = GUI.HorizontalSlider(new Rect(25, 50+(i*30), 150, 25), slider[i], 0.0F, 100.0F); // yeah, this doesn't work
}

Related

Skisharp ColorMatrix Invert black/white

I try to draw an image and after the first drawing i want invert the color of the drawing.
If the background of my new square is black i need white and if it white i need black.
In my example i draw 3 squares and make a offset of 10 pixel in the x.
Unfortunately, it does not produce the wanted result.
using var skBitmap = new SKBitmap(100, 40);
using var skCanvas = new SKCanvas(skBitmap);
skCanvas.Clear(SKColors.White);
var color = SKColors.Black;
float[] invertMatrix = {
-1.0f, 0.0f, 0.0f, 0.0f, 255.0f,
0.0f, -1.0f, 0.0f, 0.0f, 255.0f,
0.0f, 0.0f, -1.0f, 0.0f, 255.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f
};
using var skPaint = new SKPaint();
skPaint.Color = color;
skPaint.Style = SKPaintStyle.Fill;
skCanvas.DrawRect(10, 10, 20, 20, skPaint);
skPaint.ColorFilter = SKColorFilter.CreateColorMatrix(invertMatrix);
//move +10 in x
skCanvas.DrawRect(20, 10, 20, 20, skPaint);
//move +10 in x
skCanvas.DrawRect(30, 10, 20, 20, skPaint);
It looks like after making your second call to skCanvas.DrawRect you are not updating the colour.
Further, in your drawing 20 pixel wide rectangles, and overlapping them, as your only shifting your new rectangle 10 pixels to the right.
Following your wanted example, your need to make the 4th call to changing the colour back to black, then make a call to skCanvas.DrawRect(40, 10, 20, 20, skPaint).
Given that you are shifting your rectangles by 10 pixels and overlapping them, I suggest you update your calls to produce a thinner initial rectangle at 10 pixels wide.
I have found a solution for my problem unfortunately without a matrix.
using var skBitmap = new SKBitmap(100, 40);
using var skCanvas = new SKCanvas(skBitmap);
skCanvas.Clear(SKColors.White);
var color = SKColors.Black;
using var skPaint = new SKPaint();
skPaint.Color = color;
skPaint.Style = SKPaintStyle.Fill;
skCanvas.DrawRect(10, 10, 20, 20, skPaint);
DrawInvertRectangle(20, 10, 20, 20, skBitmap);
DrawInvertRectangle(30, 10, 20, 20, skBitmap);
private static void DrawInvertRectangle(int x, int y, int width, int height, SKBitmap skBitmap)
{
using var skPaint = new SKPaint();
skPaint.Color = SKColors.Black;
skPaint.Style = SKPaintStyle.Fill;
using var skBitmapInvert = new SKBitmap(skBitmap.Width, skBitmap.Height);
using var skCanvas = new SKCanvas(skBitmapInvert);
skCanvas.DrawRect(x, y, width, height, skPaint);
for (var row = 0; row < skBitmapInvert.Height; row++)
{
for (var column = 0; column < skBitmapInvert.Width; column++)
{
var pixel = skBitmap.GetPixel(column, row);
var pixelInvert = skBitmapInvert.GetPixel(column, row);
if (pixelInvert.Alpha == 255 && pixelInvert.Blue == 0 && pixel.Blue == 255)
{
skBitmap.SetPixel(column, row, SKColors.Black);
}
if (pixelInvert.Alpha == 255 && pixelInvert.Blue == 0 && pixel.Blue == 0)
{
skBitmap.SetPixel(column, row, SKColors.White);
}
}
}
}

minimap Drawing issue with graphics in thread

I am attempting to create a minimap for an overlay. Currently the radar portion is working, targets rotate around the center point at the correct distance. I am having trouble printing the graphic that holds the minimap to screen. Everything other than the map prints to screen using the SlimDx.Direct3D9 library but based on my research the best way to create sub images based on player location was with graphics and this method avoids the OutOfMemory exception with cloning bitmaps and is more efficient.
if (ShowRadar)
{
//Draw background
//DrawFilledBox(this.GameWindowRect.Right - 225, this.GameWindowRect.Top + 50, 201f, 201f, Color.DarkOliveGreen, RadarTransparency);
RadarCenter = new Vector2(this.GameWindowRect.Right - 125, this.GameWindowRect.Top + 125 + 25);
if (DXTextrureMap != null)
{
//Transpose player posistion to map position and create the current mini map image
x = (int)player_X / 8;// +/- 4000 is max player range /8 = 500 = max map range
z = (int)player_Z / 8;
mini = new Rectangle(x, z, 100, 100);
Graphics g = Graphics.FromImage(originalBitmap);
g.DrawImage(originalBitmap, mini, new Rectangle((int)this.GameWindowRect.Right - 125, (int)this.GameWindowRect.Top + 125, 100, 100), System.Drawing.GraphicsUnit.Pixel);
}//the rest works as it should and displays on screen
if (RadarCenter.Length() > 0f)
{
//Display each entity in correct relational position
foreach (ENTITY entity in Entity)
{
Vector2 pointToRotate = new Vector2(entity.Pos.X, entity.Pos.Z);
Vector2 vector3 = new Vector2(player_X, player_Z);
pointToRotate = vector3 - pointToRotate;
float num30 = pointToRotate.Length() * 0.5f;
num30 = Math.Min(num30, 90f);
pointToRotate.Normalize();
pointToRotate = (Vector2)(pointToRotate * num30);
pointToRotate += RadarCenter;
pointToRotate = RotatePoint(pointToRotate, RadarCenter, player_D, true);
if (entity.Type == 0x04 && RadarPlayers)
{
DrawFilledBox(pointToRotate.X, pointToRotate.Y, 3f, 3f, Color.SkyBlue);
}
if ((entity.Type == 0x0C || entity.Type == 0x14 || entity.Type == 0x50 || entity.Type == 0x5b) && RadarAggressive)
{
DrawFilledBox(pointToRotate.X, pointToRotate.Y, 3f, 3f, Color.Red);
}
if ((entity.Type == 0x13 || entity.Type == 0x55) && RadarAnimals)
{
DrawFilledBox(pointToRotate.X, pointToRotate.Y, 3f, 3f, Color.LightGreen);
}
if ((entity.Type == 0x11 || entity.Type == 0x72 || entity.Type == 0x76) && RadarVehicles)
{
DrawFilledBox(pointToRotate.X, pointToRotate.Y, 3f, 3f, Color.HotPink);
}
}
}
//Draw radar border
DrawBoxAbs(this.GameWindowRect.Right - 225, this.GameWindowRect.Top + 50, 201f, 201f, 1f, Color.Black);
//Draw radar axis
DrawLine(this.GameWindowRect.Right - 125, this.GameWindowRect.Top + 50, this.GameWindowRect.Right - 125, this.GameWindowRect.Top + 251, 1f, Color.Black);
DrawLine(this.GameWindowRect.Right - 225, this.GameWindowRect.Top + 150, this.GameWindowRect.Right - 24, this.GameWindowRect.Top + 150, 1f, Color.Black);
//Center point
DrawFilledBox(RadarCenter.X - 1f, RadarCenter.Y - 1f, 3f, 3f, Color.White);
}
What is the correct way to print my graphic?
Makes more sense when you realize a graphic draws on the image it grabs, also had to dispose of some elements. Time to make it rotate then perhaps add headings.
if (DXTextrureMap != null)
{
DXSprite.Begin(SpriteFlags.None);
//Transpose player posistion to map position and create the current mini map image
x = (int)player_X / 4;// +/- 4000 is max player range and /4 = 1000 = max map range
z = (int)player_Z / 4;
mini = new Rectangle(x-78, z-78, 157, 157);
croppedBitmap = new Bitmap(200, 200);
using (Graphics grD = Graphics.FromImage(croppedBitmap))
{
grD.DrawImage(originalBitmap, new Rectangle(0, 0, 157, 157), mini, GraphicsUnit.Pixel);
}
//croppedBitmap = Copy(originalBitmap, mini);
using (MemoryStream s = new MemoryStream())//s is a MemoryStream
{
croppedBitmap.Save(s, System.Drawing.Imaging.ImageFormat.Png);
s.Seek(0, SeekOrigin.Begin); //must do this, or error is thrown in next line
currentMinimap = Texture.FromStream(DXDevice, s);
s.Dispose();
}
//croppedImage.Dispose();
DXSprite.Draw(currentMinimap, new Vector3(100f, 100f, 0f), new Vector3(this.GameWindowRect.Right - 125, this.GameWindowRect.Top + 135, 0f), Color.White);
DXSprite.End();
currentMinimap.Dispose();
}

OnGUI Health Bar Scaling

I am trying to set up a health bar for a 2D game using OnGUI. I have an outside texture and an inside texture for the meter. The set up I have now works partially. I am able to change the scale of the inside meter so it looks like it is depleting, however the position along the x is changing as well. This causes an awkward effect as well as the meter moving outside its container.
void Update ()
{
score = EnemyScript.killCount * 100;
powerScale -= 1;
}
void OnGUI()
{
//Score and Power Containter
GUILayout.BeginArea(new Rect(Screen.width/8, Screen.height/8, 500, 200));
GUILayout.Label("Score: " + score, style);
GUI.DrawTexture(new Rect(-10,20,200,80),powerBoundry);
GUILayout.EndArea();
//Power Meter
GUILayout.BeginArea(new Rect(Screen.width/8, Screen.height/8, 450, 200));
GUI.DrawTexture(new Rect(-10,20,powerScale,80),powerFill, ScaleMode.ScaleAndCrop);
GUILayout.EndArea();
}
Is it possible to anchor it in place? Or perhaps make it a child of a game object to anchor it?
try using DrawTextureWithTexCoords.
void OnGUI()
{
GUILayout.BeginArea(new Rect(Screen.width / 8, Screen.height / 8, 500, 200));
GUI.DrawTexture(new Rect(-10, 20, 200, 80), powerBoundry);
GUI.DrawTextureWithTexCoords(new Rect(-10, 20, powerScale, 80), powerFill, new Rect(0f, 0f, (float)powerScale / 200f, 1f));
GUILayout.EndArea();
}

directx transformedcolored color field alpha value

I am using C #. I need to draw points using DirectX and they should be semitransparent. I declared vertices to be transformedColored and set the color value to be:
vertices[i].Color = Color.FromArgb(20,0,0,255).ToArgb();
This should be quite transparent blue but what I got was opaque blue. Whatever value I use for the alpha value, it always gets fully opaque.
Any ideas why? I hope the transformedcolored color field supports alpha value.
Thanks in advance.
The drawing code is:
device.Clear(ClearFlags.Target, System.Drawing.Color.White, 1.0f, 0);
device.RenderState.AlphaBlendEnable = true;
device.RenderState.AlphaSourceBlend = Blend.SourceAlpha;
device.RenderState.AlphaDestinationBlend = Blend.InvSourceAlpha;
device.RenderState.BlendOperation = BlendOperation.Add;
CustomVertex.TransformedColored[] vertices = new CustomVertex.TransformedColored[N];
for (int i = 0; i < N; i++)
{
vertices[i].Position = new Vector4(2.5f + (g_embed[i, 0] - minx) * (width - 5.0f) / maxx, 2.5f + (g_embed[i, 1] - miny) * (height - 5.0f) / maxy, 0f, 1f);//g_embed, minx, width,maxx, miny,height, maxy are all predifined
vertices[i].Color = Color.FromArgb(20, 0, 0, 255).ToArgb();
}
device.BeginScene();
device.VertexFormat = CustomVertex.TransformedColored.Format;
device.DrawUserPrimitives(PrimitiveType.PointList, N, vertices);
device.EndScene();
device.Present();
this.Invalidate();
Your renderstates are used for premultiplied alpha. Using a real alpha-channel needs the following settings (Blendenumerationdoc):
graphics.GraphicsDevice.RenderState.AlphaBlendEnable = true;
graphics.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
graphics.GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
graphics.GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add;
It creates following the formular, where a is your alpha of the color: a * SourceColor + (1-a) * DestColor

Performance difference between different ways to draw rectangles from textures in xna?

I am trying to developing p a JRPG/dungeon crawler as a summer project and I am atm cleaning up in my code. In the combat it exists "healthbars" and one healthbar consists of 3 rectangles that need to be drawn for each character (2-8 characters in total depending on the context means up to 24 healbar rectangles at one time).
My old way to draw the healbar was based on 1 texture where i took a single pixel from
and draw over a rectangle shaped area. Basicly i used the "HealtBar" texture as a color palet... for example if the source rectangle was (0, 0, 1, 1) it represented to draw a black rectangle.
Texture2D mHealthBar;
mHealthBar = theContentManager.Load<Texture2D>("HealthBar");
public override void Draw(SpriteBatch theSpriteBatch)
{
//draw healtbar
theSpriteBatch.Draw(mHealthBar, new Rectangle((int)Position.X+5,
(int)(Position.Y - 20), (MaxHealth * 5)+7, 15),
new Rectangle(0, 0, 1, 1), Color.Black);
theSpriteBatch.Draw(mHealthBar, new Rectangle((int)(Position.X + 8),
(int)(Position.Y - 17), ((MaxHealth * 5)), (mHealthBar.Height) - 2),
new Rectangle(2, 2, 1, 1), Color.White);
theSpriteBatch.Draw(mHealthBar, new Rectangle((int)(Position.X + 8),
(int)(Position.Y - 17), ((Health * 5)), (mHealthBar.Height) - 2),
new Rectangle(3, 2, 1, 1), Color.Red);
}
this aint a good looking solution... so instead i tried to create an abstract class that would reduce the amount of code and increase the amount of clarity in the code.
abstract class Drawer
{
static private Texture2D _empty_texture;
static public void DrawRect(SpriteBatch batch, Color color, Rectangle rect)
{
_empty_texture = new Texture2D(batch.GraphicsDevice, 1, 1);
_empty_texture.SetData(new[] { Color.White });
batch.Draw(_empty_texture, rect, color);
}
}
With the new Drawer class I could throw away the "mHealthBar" variable and draw the rectangles in a more nice looking code way. But when I started to use the new way to draw the game started to have frame Rate problems, the old way was smooth...what is the reason to the frame rate problems?
Drawer.DrawRect(theSpriteBatch, Color.Black, new Rectangle((int)Position.X+5,
(int)(Position.Y - 20), (MaxHealth * 5)+7, 15));
Drawer.DrawRect(theSpriteBatch, Color.White, new Rectangle((int)(Position.X + 8),
(int)(Position.Y - 17), (MaxHealth * 5), 9));
Drawer.DrawRect(theSpriteBatch, Color.Red, new Rectangle((int)(Position.X + 8),
(int)(Position.Y - 17), (Health * 5), 9));
The issue is that you're creating a new texture and setting the colour every time you want to draw.
What you should do is only create the texture once (when loading your other content).

Categories