Form not showing after Invalidate() - c#

For some reason, this code does not actually draw my bitmap file... or show the form.
namespace GraphicsEngine
{
public partial class Form1 : Form
{
Bitmap[] dude = new Bitmap[3];
Bitmap dude0 = new Bitmap(#"C:\Directory.bmp");
Point renderpoint = new Point(1, 1);
public Form1()
{
dude[0] = new Bitmap(#"C:\Directory.bmp");
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
MainLoop();
}
private void MainLoop()
{
double FPS = 30.0;
long ticks1 = 0;
long ticks2 = 0;
double interval = (double)Stopwatch.Frequency / FPS;
while (!this.IsDisposed)
{
ticks2 = Stopwatch.GetTimestamp();
if (ticks2 >= ticks1 + interval)
{
ticks1 = Stopwatch.GetTimestamp();
this.Invalidate();
}
Thread.Sleep(1);
}
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawImage(dude0, renderpoint);
}
}
}
Any ideas?

Your problem ought to be a bit more obvious than not seeing the bitmap, you should not see the form either. That's because you never complete the Load event. You could use the Shown event instead.
Check this thread for the code for a true game loop.

Try replacing your call to this.Invalidate(); with this.Refresh();.

Looks like your MainLoop() could be an infinite loop. You can put Console.Out.WriteLine(ticks1); in your while loop to validate this.
It gets stuck in the Load event handler and none of the main form validation occurs. It definitely draws the picture if you comment out the call to MainLoop().

Form1_Paint is not called unless if you have UserPaint set to true. Try this as your constructor
public Form1() {
dude[0] = new Bitmap(#"C:\Directory.bmp");
InitializeComponent();
this.SetStyle( System.Windows.Forms.ControlStyles.UserPaint, true );
this.SetStyle( System.Windows.Forms.ControlStyles.AllPaintingInWmPaint, true );
this.SetStyle( System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer, true );
}
Just beware, when you do this, you may be responsible for all the paints on the form.

Related

Moving a picture box in timer C# Winforms

Ok so please keep answers very direct and i must say i am very new to C#, i don't know a lot of stuff. Without further adieu my problem.
I am trying to move a picture box horizontally across the screen on a timer.The timer must go infinitely. I have tried all i currently know in C# and searched around quite a lot but nothing answered my exact question which is what i need because of my lesser knowledge of C#. For the last two weeks i worked on graphics mostly and the rest of that was trying to get this to work, So i have no code in my game. This is because for anything to work i need this part to be working. My game is 2D topdown. Any and all help is appreciated.
Thank you for taking the time to read.
Edit
No more answers needed, Thank you Odrai for the answer, it helped me a lot.
Use pictureBox.Location = new Point(x, y) or set pictureBox.Left/Top/Right. You can define x and y as variabels and initialize them with a default value. Increment x on timer tick.
Sample 1:
public partial class Form1 : Form
{
private Random _random
public Form1()
{
InitializeComponent();
_random = new Random();
}
private void timer1_Tick(object sender, EventArgs e)
{
int x = _random.Next(0, 500);
int y = _random.Next(0, 500);
pictureBox1.Top += y;
pictureBox1.Left += x;
}
}
Sample 2:
private void timer1_Tick(object sender, EventArgs e)
{
this.SuspendLayout();
pictureBox.Location = new Point(picust.Location.X + 10, picust.Location.Y);
this.ResumeLayout();
}
Add two buttons with title LEFT and RIGHT to a form and write the following code.
It might give you an idea, how to do simple moving animations.
public partial class Form1 : Form
{
int difference = 0;
Timer timer = new Timer();
public Form1()
{
InitializeComponent();
timer.Interval = 15;
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
pictureBox1.Left += difference;
}
private void btnLeft_Click(object sender, EventArgs e)
{
difference = -2;
}
private void btnRight_Click(object sender, EventArgs e)
{
difference = 2;
}
}
Try This Code it will work :
private void timer1_Tick(object sender, EventArgs e)
{
int width = this.Width; // get the width of Form.
if(pictureBox1.Location.X > width - pictureBox1.Width) //to check condition if pic box is touch the boundroy of form width
{
pictureBox1.Location = new Point(1, pictureBox1.Location.Y); // pic box is set to the new point. here 1 is indicate of X coordinate.
}
else
{
pictureBox1.Location = new Point(pictureBox1.Location.X + 100, pictureBox1.Location.Y); // to move picture box from x coordinate by 100 Point.
}
}
//Try This //
picturebox1.Location = 0,0;

Fading an Image - C# WPF

I don't quite understand why it is so complicated as in a standard windows form the code below works just fine. But anyway.
I am trying to just fade an image in, and then fade it back out. At the moment I can't even get it to fade in, I feel pretty dumb because I'm sure there is something I am doing wrong. The for loop works but the image opacity does not change until it gets to 99 and then it suddenly changes. Please help because this is driving me mad.
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
for (int i = 1; i <+ 100; i++)
{
Logo.Opacity = i;
label1.Content = i;
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 10);
dispatcherTimer.Start();
}
}
}
I don't know exactly what behaviour you want to get, but in WPF you should use animations. Probably you have to adapt the parameters:
private void Button_Click(object sender, RoutedEventArgs e)
{
DoubleAnimation da = new DoubleAnimation
{
From = 0,
To = 1,
Duration = new Duration(TimeSpan.FromSeconds(1)),
AutoReverse = true
};
Logo.BeginAnimation(OpacityProperty, da);
}
Opacity is double with 0.0 - 1.0 range. So the loop should be something like this.
for (double i = 0.0; i <= 1.0; i+=0.01)
{
Logo.Opacity = i;
label1.Content = i;
}
But as Clemens pointed out it also won't work. You're doing entire loop in one short burst. You should do one increment per timer tick:
double CurrentOpacity = 0.0;
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
CurrentOpacity += 0.01;
if(CurrentOpacity <= 1.0)
{
Logo.Opacity = CurrentOpacity;
label1.Content =CurrentOpacity;
}
else
{
dispatcherTimer.Stop();
}
}

How to animate a PictureBox in a Win Forms application?

I have a windows form application with a PictureBox control containing an image. I want to move the PictureBox control to the right in a slow movement. Here is my code:
Point currentPoint = pictureBox_Logo.Location;
for (int i = 0; i < 25; i++)
{
pictureBox_Logo.Location = new Point(pictureBox_Logo.Location.X + 1, pictureBox_Logo.Location.Y);
Thread.Sleep(30);
}
The problem here is that when the code executes instead of seeing the picture move, I see a white picture move and the moving stops until the picture appears.
What am I missing and what can I do about it?
Code:
public partial class Form1 : Form
{
void timer_Tick(object sender, EventArgs e)
{
int x = pictureBox1.Location.X;
int y = pictureBox1.Location.Y;
pictureBox1.Location = new Point(x+25, y);
if (x > this.Width)
timer1.Stop();
}
public Form1()
{
InitializeComponent();
timer1.Interval = 10;
timer1.Tick += new EventHandler(timer_Tick);
}
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Show();
timer1.Start();
}
}
original thread is here Move images in C#
Try to use pictureBox_Logo.Refresh() after Thread.Sleep(30);
Or look for standard Timer control.
My code is good written, but what I did wrong was putting the code in an event:
private void Form1_Shown(object sender, EventArgs e);
But when I put my code in a button it works without any problems.

Drawing to a panel using a bitmap as a buffer

I have been learning about drawing to panels using bitmaps. I thought I would run a trial program to simply turn a white panel black. (May seem a complicated way of doing it but this is just to test the basics) My program is as follows:
public partial class Form1 : Form
{
private Bitmap buffer = new Bitmap(100,100);
public Form1()
{
InitializeComponent();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImageUnscaled(buffer, Point.Empty);
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
buffer.SetPixel(i, j, Color.Black);
}
}
}
}
When I run it and press the button the panel does not seem to change. Any Idea where I am going wrong. Thank you in advance.
You have to invalidate the panel's client area so that Windows will force a repaint. But there are some other issues:
FillRectangle will do a much more efficient job than painting each pixel in a loop, as #Tony suggested.
You might hit concurrency issues if the panel is invalidated before buffer is ready to be displayed. Be sure that the bitmap generation is isolated from its presentation.
These suggestions are summarized (but not tested) as follows:
private void button1_Click(object sender, EventArgs e)
{
Bitmap tempBuffer = new Bitmap(100, 100);
using (Graphics g = Graphics.FromImage(tempBuffer))
using (SolidBrush blackBrush = new SolidBrush(Color.Black))
{
g.FillRectangle(blackBrush, new Rectangle(0, 0, tempBuffer.Width-1, tempBuffer.Height-1);
}
buffer = tempBuffer;
panel1.Invalidate();
}
In addition to invalidating the panel's client area, if you're wanting it to paint when you click the button you'll want to wire up the paint event in the button's click event. Give this a shot:
public partial class Form1 : Form
{
private bool _paintWired;
public Form1()
{
InitializeComponent();
}
private void PanelPaint(object sender, PaintEventArgs e)
{
using (Graphics g = this.panel1.CreateGraphics())
{
g.FillRectangle(Brushes.Black, this.panel1.Bounds);
}
}
private void button1_Click(object sender, EventArgs e)
{
if(!_paintWired)
{
this.panel1.Paint += new PaintEventHandler(PanelPaint);
_paintWired = true;
}
this.panel1.Invalidate();
}
}
UPDATE: Sorry, I missed the point about using a bitmap.
try this example
I use it for something like what you want to do and it worked.
I hope to help you
example_1

C# - Make form semi-transparent while moving

Is there any way to make the form semi-transparent while it is being moved and then become opaque when it's not being moved anymore? I have tried the Form_Move event with no luck.
I'm stuck, any help?
The reason the form loads as semi-transparent is because the form has to be moved into the starting position, which triggers the Move event. You can overcome that by basing whether the opacity is set, on whether the form has fully loaded.
The ResizeEnd event fires after a form has finished moving, so something like this should work:
bool canMove = false;
private void Form1_Load(object sender, EventArgs e)
{
canMove = true;
}
private void Form1_Move(object sender, EventArgs e)
{
if (canMove)
{
this.Opacity = 0.5;
}
}
private void Form1_ResizeEnd(object sender, EventArgs e)
{
this.Opacity = 1;
}
To do it properly I expect you'd need to override the message processing to respond to the title bar being held, etc. But you could cheat, and just use a timer so that you make it opaque for a little while when moved, so continuous movement works:
[STAThread]
static void Main()
{
using (Form form = new Form())
using (Timer tmr = new Timer())
{
tmr.Interval = 500;
bool first = true;
tmr.Tick += delegate
{
tmr.Stop();
form.Opacity = 1;
};
form.Move += delegate
{
if (first) { first = false; return; }
tmr.Stop();
tmr.Start();
form.Opacity = 0.3;
};
Application.Run(form);
}
}
Obviously you could tweak this to fade in/out, etc - this is just to show the overall concept.

Categories