I am working on a project for school, we need to make a basic top down race game in C# without using XNA. First of all let me tell you that the stuff we have learned about programming so far has little to do with making something that even remotely looks like a racegame. It didn't get any more difficult than array's, loops etc. So we didn't learn about graphics or anything like that.
Having said all that I am having the following problem.
We have created a Graphics object, and then use DrawImage and use a bitmap from a car.jpg.
graphics = e.Graphics;
graphics.RotateTransform(angle);
graphics.DrawImage(car, xPos, yPos, car.Width, car.Height);
Then we wait for a key press e.g Right
case Keys.Right:
if (angle != 360)
{
angle += 10;
}
else
{
angle = 0;
}
this.Refresh();
break;
The problem we have is that the pivot point for the rotation is in the top left corner. So as soon as we move the car to something like (20,25)
and start to rotate it, it will use (0,0)
as the center of rotation. What we want to achieve is to have the center point of rotation at the center of our car.
We have tried looking for ways to change the centerX
and centerY
of the RotateTransform
but have come to the conclusion that this isn't possible with the bitmap.
We have been struggling with this problem for over 2 days and can't seem to find any solution for achieving the thing we want.
Is there something we are doing wrong creating the Graphics object, or is there a totally different way to change centerX
and centerY
for the car?
To draw a rotated Bitmap
you need to do a few steps to prepare the Graphics
object:
Bitmap
Graphics
This needs to be done for each bitmap.
Here are the steps in code to draw a Bitmap bmp
at position (xPos, yPos
):
float moveX = bmp.Width / 2f + xPos;
float moveY = bmp.Height / 2f+ xPos;
e.Graphics.TranslateTransform(moveX , moveY );
e.Graphics.RotateTransform(angle);
e.Graphics.TranslateTransform(-moveX , -moveY );
e.Graphics.DrawImage(bmp, xPos, yPos);
e.Graphics.ResetTransform();
There is one possible complication: If your Bitmap
has different dpi
resolution than the screen i.e. than the Graphics
you must first adapt the Bitmap
's dpi
setting!
To adapt the Bitmap
to the usual 96dpi
you can simply do a
bmp.SetResolution(96,96);
To be prepared for future retina-like displays you can create a class variable you set at startup:
int ScreenDpi = 96;
private void Form1_Load(object sender, EventArgs e)
{
using (Graphics G = this.CreateGraphics()) ScreenDpi = (int)G.DpiX;
}
and use it after loading the Bitmap
:
bmp.SetResolution(ScreenDpi , ScreenDpi );
As usual the DrawImage
method uses the top left corner of the Bitmap
. You may need to use different Points
for the rotation point and possibly also for the virtual position of your car, maybe in the middle of its front..