Games with FMX!
Is Firemonkey ready for game development - of course! There are many games out in the wild written with Delphi and also with FMX.
Why this blogpost? Because in the last weeks there are so many questions in forums or FB about this topic.
But where to start?
Do you want to go 2D?
Great simple answer:
1.) Use a TRectangle with a PNG for your sprite(s).
2.) Use a Timer with 16ms for your game-loop.
Go and write - like me in 2015 - funny games like this:
Perhaps sometime in the future, I will release this game, if I find the time and change the stolen ROM-Images with new creations. ;-)
Then you might want to use a "3D Engine". Why an engine, because you do not want to do the hard work for all platforms by hand. Or you just use FMX as your engine.
This could look like this:
Do you want 3D?
Then you might want to use a "3D Engine". Why an engine, because you do not want to do the hard work for all platforms by hand. Or you just use FMX as your engine.
This could look like this:
- Create a new FMX 3D application.
- Put a dummy object on the form
- Put a camera on the form
- Put a light on the form
- Place the camera at 0,0,-20
- Set the light to Point
- Place the light at 0,0,-20
- Put a Timer on the form and set it to 16ms
- In the onTimer event call Invalidate;
- In the onRender event call your 3D stuff.
The Form should look like this:
type
THello3DWorld = class(TForm3D)
Dummy1: TDummy;
Camera1: TCamera;
Timer1: TTimer;
Light1: TLight;
procedure Timer1Timer(Sender: TObject);
procedure Form3DCreate(Sender: TObject);
procedure Form3DDestroy(Sender: TObject);
procedure Form3DRender(Sender: TObject; Context: TContext3D);
private
{ Private-Deklarationen }
fColorMaterial : TColorMaterial;
fModelMatrix,
fRotate : TMatrix3D;
fVertexBuffer : TVertexBuffer;
fIndexBuffer : TIndexBuffer;
Procedure DoInit;
Procedure DoRotate;
public
{ Public-Deklarationen }
end;
In the FormCreate you can create, like in the example - a 3D object. I use a simple Triangle, but you can, of course, create any 3D Mesh or object. You also have to create Material. You can use your own Material (shader) or use the build-in.
This looks like this:
In the on Form3DRender event you can provide all your generated objects to the renderer.
That's it. Now your FMX program could render any 3D object to the scene.
For entertainment, the object should rotate or do whatever you like. That's why this demo has a DoRotate method.
This looks like this:
procedure THello3DWorld.Form3DCreate(Sender: TObject);
begin
fColorMaterial := TColorMaterial.Create;
fModelMatrix := TMatrix3D.Identity;
// 3 for a Triangle
fVertexBuffer := TVertexBuffer.Create([TVertexFormat.Vertex],3);
fIndexBuffer := TIndexBuffer.Create(3,TIndexFormat.UInt16);
DoInit;
Timer1.Enabled := true;
end;
In the DoInit, I setup a triangle for this little demo:
procedure THello3DWorld.DoInit;
var
lVector : TVector3D;
lMatrix : TMatrix3D;
begin
// Create a Rotation Matrix for a equilateral triangle
lMatrix := TMatrix3D.CreateRotationZ(120*Pi/180);
LVector := TVector3D.Create(3,0,0); // Size 3
fVertexBuffer.Vertices[0] := LVector;
LVector := LVector * LMatrix; // Rotate to next point
fVertexBuffer.Vertices[1] := LVector;
LVector := LVector * LMatrix; // Rotate to next point
fVertexBuffer.Vertices[2] := LVector;
// Draw Clockwise
fIndexBuffer.Indices[0] := 0;
fIndexBuffer.Indices[1] := 1;
fIndexBuffer.Indices[2] := 2;
// Create Rotation Matrix for later use
fRotate := TMatrix3D.CreateRotationZ(3*Pi/180);
end;
In the on Form3DRender event you can provide all your generated objects to the renderer.
procedure THello3DWorld.Form3DRender(Sender: TObject; Context: TContext3D);
begin
if ( Context = nil ) or not( Context.BeginScene ) then
exit;
try
Context.SetContextState( TContextState.cs3DScene );
Context.Clear( TAlphaColorRec.Black ); // or any Color
// Set ModelMatrix
Context.SetMatrix( fModelmatrix );
fColorMaterial.Color := TAlphaColorRec.Yellow;
// Render Model
Context.DrawTriangles( fVertexBuffer, fIndexBuffer,
fColorMaterial, 1 );
finally
Context.EndScene;
end;
end;
For entertainment, the object should rotate or do whatever you like. That's why this demo has a DoRotate method.
procedure THello3DWorld.DoRotate;
begin
fModelMatrix := fModelMatrix * fRotate;
end;
This is a simple Matrix3D rotation. To use this rotation just call DoRotate before you call the invalidate. Normally you would measure the time difference between two frames and do the calculation for this deltaT to get even rotation speeds on all platform / CPUs. But with our timer we are fine for this demo.
With a collection of elements and some logic you can build your own 3D Engine and create some nice 3D stuff or games.
If you like to see more 3D Stuff write me a message.
With a collection of elements and some logic you can build your own 3D Engine and create some nice 3D stuff or games.
If you like to see more 3D Stuff write me a message.
No comments:
Post a Comment