[Mono-winforms-list] simple animation

Jon Heiner jon.heiner@gmail.com
Sun, 10 Apr 2005 14:29:24 -0700


Excellent. That did it. Thanks for the assistance.

Now to remove the bugs and get rid of the flickering.

I noticed that the timer object "should" be triggering at 60 FPS, but  
it's not even close. Is there some considerable overhead to using  
timers? Down the line, I'm planning on running the updates in a  
separate thread and simply putting it to sleep when it's not drawing,  
but i'm a little worried about this overhead. Any thoughts on  
optimizing animation would be great. I'll see what I can do here and  
repost later.

-heina

On Apr 10, 2005, at 1:17 PM, kangaroo wrote:

Jon,

   The problem is currently you need to Flush() any graphics context  
that you use on OSX.  Just add a clientDC.Flush (); after your  
_ball.Draw (); and this will start working.

-kangaroo

On 10-Apr-05, at 1:12 AM, Jon Heiner wrote:

> Is there a problem with the Graphics Device not being invalidated  
> properly? Here is some simple code that animates a sprite moving  
> around. The only way I can see anything is if I toggle the mono window  
> underneath another window, like the Finder. This is adapted from some  
> animation code I picked up that renders to an Image and then uses the  
> Graphic DrawImage call. No matter how I do it, my Form does not  
> invalidate and update on the timer ticks. Any thoughts?
>
> system: MacOSX 10.3.8 w/ mono1.1.5
>
> code:
> _______________________________________________________________________ 
> ___________________________________
> using System;
> using System.Drawing;
> using System.Collections;
> using System.ComponentModel;
> using System.Windows.Forms;
> using System.Runtime.InteropServices;
>
> namespace Bouncy
> {
> 	/ 
> /---------------------------------------------------------------------- 
> --------
> 	// Ball
> 	/ 
> /---------------------------------------------------------------------- 
> --------
> 	public class Ball
> 	{
> 		public Ball( System.Drawing.Size bounds )
> 		{
> 			_armPen   = new Pen(Color.Red, (float)3.0);
> 			_center   = new Point(3,3);
> 			_size     = new Size( bounds.Width + 5, bounds.Height + 5);
> 			_velocity = new Point(1,1);
> 		}
>
> 		// bounce the ball around in a bounded rectangle
> 		public void Update( System.Drawing.Size bounds )
> 		{
> 			_center.X += _velocity.X;
> 			if( _center.X < 0 )             { _center.X = 0; _velocity.X =  
> -_velocity.X; }
> 			if( _center.X > bounds.Width )  { _center.X = bounds.Width;  
> _velocity.X = -_velocity.X; }
> 			_center.Y += _velocity.Y;
> 			if( _center.Y < 0 )             { _center.Y = 0; _velocity.Y =  
> -_velocity.Y; }
> 			if( _center.Y > bounds.Height ) { _center.Y = bounds.Height;  
> _velocity.Y = -_velocity.Y; }
> 		}
>
> 		// draw the 'ball'
> 		public void Draw(Graphics g)
> 		{
> 			g.DrawRectangle( _armPen, new Rectangle( _center, _size) );
> 		}
>
> 		private Color _ballColor;
> 		private Pen   _armPen;
> 		private Size  _size;
> 		private Point _velocity;
> 		private Point _center;
> 	}
>
> 	/ 
> /---------------------------------------------------------------------- 
> --------
> 	// MainForm
> 	/ 
> /---------------------------------------------------------------------- 
> --------
> 	public class MainForm : System.Windows.Forms.Form
> 	{
> 		[STAThread]
> 		static void Main()
> 		{
> 			Application.Run(new MainForm());
> 		}
>
> 		public MainForm()
> 		{
> 			InitializeComponent();
> 		}
>
> 		protected override void Dispose( bool disposing )
> 		{
> 			if( disposing )
> 			{
> 				if (components != null)
> 				{
> 					components.Dispose();
> 				}
> 			}
> 			base.Dispose( disposing );
> 		}
>
> 		private void InitializeComponent()
> 		{
> 			this.components = new System.ComponentModel.Container();
> 			this.timer1 = new System.Windows.Forms.Timer(this.components);
> 			this.drawBox = new System.Windows.Forms.GroupBox();
> 			this.SuspendLayout();
>
> 			// timer1
> 			this.timer1.Enabled = true;
> 			this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
> 			this.timer1.Interval = 1000/60;
>
> 			// drawBox
> 			this.drawBox.Location = new System.Drawing.Point(120, 60);
> 			this.drawBox.Name = "drawBox";
> 			this.drawBox.Size = new System.Drawing.Size(400, 200);
> 			this.drawBox.TabIndex = 3;
> 			this.drawBox.TabStop = false;
> 			this.drawBox.Text = "Drawing Area";
> 			this.drawBox.Visible = false;
>
> 			// MainForm
> 			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
> 			this.BackColor = System.Drawing.Color.LightBlue;
> 			this.ClientSize = new System.Drawing.Size(640, 320);
> 			this.Controls.AddRange(new System.Windows.Forms.Control[] {  
> this.drawBox });
> 			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
> 			this.MaximizeBox = false;
> 			this.Name = "MainForm";
> 			this.Text = "MainForm";
> 			this.Load += new System.EventHandler(this.OnLoad);
> 			this.ResumeLayout(false);
>
> 		}
>
> 		private void OnLoad(object sender, System.EventArgs e)
> 		{
> 			_ball = new Ball( drawBox.Size );
>
> 			backBrush = new SolidBrush(Color.Black);
>
> 			InitForSimpleDrawing();
> 		}
>
> 		private void timer1_Tick(object sender, System.EventArgs e)
> 		{
> 			// redraw the whole form
> 			_ball.Update( this.drawBox.Size );
> 			DrawSimple();
> 		}
>
> 		private void DrawSimple()
> 		{
> 			Graphics clientDC = this.CreateGraphics();
>
> 			clientDC.FillRectangle(backBrush, drawBox.Left, drawBox.Top,  
> drawBox.Width, drawBox.Height);
> 			_ball.Draw(clientDC);
> 			drawBox.Invalidate();
> 		}
> 		
> 		private System.ComponentModel.IContainer components;
> 		private System.Windows.Forms.Timer       timer1;
>
> 		private System.Windows.Forms.GroupBox    drawBox;
> 		private SolidBrush                       backBrush;
> 		private Ball                             _ball;
> 	}
> }
>
> _______________________________________________
> Mono-winforms-list maillist  -  Mono-winforms-list@lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-winforms-list
>
>
> !DSPAM:4258b64b310886250714568!
>