How to move a Rectangle by MouseClick

heater19

Newcomer
Joined
Apr 15, 2011
I'm starting out with learning C# and GDI+; and was trying to come up with ways of implementing mouseclick movement for a game. The method I came up with is below.

Would welcome any suggestions for making it better.

Relevant code:---


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace clickmoveproject
{
public partial class Form1 : Form
{
Bitmap backup;
Graphics gfx, fgfx;

PointF charloc;

private bool mclick;

float speed = 3f;
float dx = 0f;
float dy = 0f;
float mX, mY;

float ddx = 0f;
float ddy = 0f;


public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
backup = new Bitmap(640, 480);

gfx = Graphics.FromImage(backup);
gfx.FillRectangle(Brushes.Black, this.ClientRectangle);

fgfx = this.CreateGraphics();
//*2**

charloc = new Point(4, 4);
}

void Present()
{
fgfx.DrawImage(backup, 0, 0);
}

private void movement()
{
if (mclick)
{
charloc.X += ddx;
charloc.Y += ddy;
}
}

private void timer1_Tick_1(object sender, EventArgs e)
{
//*5**
movement();

//*6**
gfx.FillRectangle(Brushes.Black, this.ClientRectangle);

gfx.DrawRectangle(Pens.Green, charloc.X, charloc.Y, 30, 30);

gfx.DrawLine(Pens.Aqua, charloc.X, charloc.Y, mX, mY);

Present();
}

private void Form1_MouseClick(object sender, MouseEventArgs e)
{
mclick = true;
mX = e.X;
mY = e.Y;

dx = mX - charloc.X;
dy = mY - charloc.Y;

double dist = Math.Sqrt((double)(dx * dx) + (double)(dy * dy));

ddx = (dx / (float)dist) * speed;
ddy = (dy / (float)dist) * speed;
}
}
}
----- end of code ----

thanks to IcePlug for his help
www.Iceplug.us
 

EFileTahi-A

Contributor
Joined
Aug 8, 2004
Location
Portugal / Barreiro
I've made some changes towards the way you draw things onto the screen:

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        PointF charloc = new PointF(4,4);

        private bool mclick;

        float speed = 3f;
        float dx = 0f;
        float dy = 0f;
        float mX, mY;

        float ddx = 0f;
        float ddy = 0f;

        public Form1()
        {
            InitializeComponent();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
[COLOR="Red"]            //Here we clear the screen with a chosen color. No need to use FillRectangle.
            e.Graphics.Clear(Color.Black);[/COLOR]

            movement();

            e.Graphics.DrawRectangle(Pens.Green, charloc.X, charloc.Y, 30, 30);
            e.Graphics.DrawLine(Pens.Aqua, charloc.X, charloc.Y, mX, mY);
        }

        private void movement()
        {
            if (mclick)
            {
                charloc.X += ddx;
                charloc.Y += ddy;
            }
        }

        private void Form1_MouseClick(object sender, MouseEventArgs e)
        {
            mclick = true;
            mX = e.X;
            mY = e.Y;

            dx = mX - charloc.X;
            dy = mY - charloc.Y;

            double dist = Math.Sqrt((double)(dx * dx) + (double)(dy * dy));

            ddx = (dx / (float)dist) * speed;
            ddy = (dy / (float)dist) * speed;
        }

        private void timer1_Tick_1(object sender, EventArgs e)
        {
            this.Invalidate();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}

By using the "protected override OnPaint" event, drawing speed will be drastically increased. Simply use its built in graphics object to draw all that is needed. Don't forget to turn the form's DoubleBuffer On to avoid flicker.

The Invalidate() forces the window to refresh by calling the OnPaint event.

I hope this helps.
 
Top Bottom