Development: engine 4.0.0 - still almost there: a lot of creatures, items and player improvements
Sorry, still no new release... But, as usual, we have many new features to announce for the upcoming Castle Game Engine 4.0.0 :) For starters, a little movie with explosions fun:
Creatures/items (commonly called "resources" in many places) improvements:
New example program:
resource_animations. Demonstrates how to define creature/item animations in
resource.xml files, from KAnim and/or X3D animations. Can be also used to preview animations from any
resource.xml files, e.g. you can try it on castle1 creatures and items. See DRAFT.modeling_tutorial.txt (will be moved to nicer HTML page later) for notes about how to design your creatures/items.
Defining short-range creature attack and/or firing a missile are trivial now. See
TWalkAttackCreatureKind.FireMissileXxx properties, and
<attack> elements in
What actually happens is configurable by overriding methods
TWalkAttackCreature.FireMissile. So, while you can think that <attack> is "short-range attack" and <fire_missile> is "firing a missile", in reality it's more like <attack> is "1st configurable attack-like action" and <fire_missile> is "2nd configurable attack-like action".
You still can use extra states for special purposes in TWalkAttackCreature (
csMax+2 etc.), so it's possible to add even more kinds of attack (or really anything else) by overriding appropriate methods.
resource.xmlfile), no need for a single line of code.
Die animations, and configurable RemoveDead, are also available for Still and Missile creatures. Die animation allows e.g. to make exploding animations for missiles and immobile objects (like barrel in the movie above).
RemoveDead allows to keep the corpse on the level, with special twists for missiles. Your missiles, like arrows, can be left "stuck" in the wall. (This mechanism should be better and more intelligent in the future, as part of the "decal" system. For now, at least it basically works for some cases.)
ReceiveShadowVolumes, default true, configurable for every item and creature (
TItemOnWorld.AutoPickproperty, to control automatic picking of items by player, and
TItemOnWorld.ExtractItemmethod to implement picking yourself.
TItemOnWorld.RotationSpeedproperty, to control the speed of rotation of items (set to 0 to disable rotating).
TInventoryItem.Stackmethod to override, to affect how items stacking works.
T3DCustomTransform.PreferredHeight). Unified gravity on items and creatures, with new comfortable properties (see
T3DCustomTransform.GrowSpeed). More configurable from
direction_fall_speed— see creating_data_resources).
T3D.PointingDeviceActivate, like before.
Our Blender X3D exporter updated for Blender 2.64a.
New KAnim exporter for Blender 2.64a added. For the same reason as a couple of years ago (Blender standard X3D exporter still cannot export animations) we still need it.
Placeholders are nicer. You can indicate in
level.xml how to detect placeholder names in 3D level file, for example use
placeholders="blender" to use object names set in Blender. You configure it now nicely to support any other modeler. Also, we now make clear that this detection dependent on modeler is only for
TGameSceneManager.LoadLevel placeholders, nothing else. See level.xml and resource.xml files documentation.
You can register own callbacks, see
PlaceholdersNames and docs of
TGameSceneManager.LoadLevelfor developer docs.
placeholder_default_directionin creating_data_levels docs.
TCastleSceneManager.OnMoveAllowedcallback, to control how the algorithm described at
TCastleSceneManager.MoveLimitworks — allows to limit the working of gravity and/or movement to some 3D space.
T3DOrientinstance has automatically a synchronized
T3DOrient.Camerainstance inside. This makes Player<->Camera synchronization work without any fuss. It also allows to switch your view into a computer-controlled creature, which is quite fun. In network games, other players will also be creatures (with data synchronized from network), so this will also allow observing other players when in "spectator" mode — I saw this feature in Tremulous, it's quite cool.
TPlayer.FlyingTimeOut, a simpler and more flexible properties to control player flying (replace previous
Image API improvements:
AlphaChanneldetection, code simplified (and much shortened). Our alphaChannel extension is now available for all X3DTextureNode.
GLImagesunit, for drawing images on 2D screen. This encapsulates a display list, and in the future will be seamlessly changed to PBO for modern OpenGL versions.
LoadImageremoved, along with
TImageLoadConversionsand friends. They were complicated, and not really useful in practice. (If you're really paranoid about conversions, you can use
LoadImageto any class and make conversions yourself, honoring any order/limits as you desire.)
CastleGameCacheremoved. We automatically use the global
GLContextCachenow, this makes things trivial to use and automatically optimal. If you really, really want to use a separate cache for some stuff, you can still do it by
TCastlePrecalculatedAnimation.CreateCustomCache— but, aside from debugging, it's hard to imagine why you would need it now :)
Idlefixes for multiple
TCastleControlin a single application.
X3DTriangles. New unit
VectorMath(to make a huge
VectorMathunit at least a little slimmer).
Large press / release callbacks and virtual methods rearrangement: all presses (
MouseWheel) now go to a single
Press method (with
TInputPressRelease param). Likewise, all releases (
MouseUp (we didn't implement mouse wheel releases yet)) go to
Release. Same goes for callbacks, now you have
This allows a huge code cleanup (and shortening) in a lot of places. Since our engine concentrates input processing on
TInputShortcut, where you can customize whether it's key and/or mouse button and/or mouse wheel, it makes sense to store "press" and "release" as a single
TInputPressRelease value. Previously, a lot of code was complicated because of this, and also some methods had a lot of parameters to pass all key/mouse information in separate variables.
If you want to add some key/mouse shortcut to your game, you can now do it easily:
Create it, like this:
Input_UseLifePotion := TInputShortcut.Create(nil, 'Use life potion', 'life_potion_use', igItems); Input_UseLifePotion.Assign(K_L, K_None, #0, false, mbLeft);
Then use it in
TCastleControl.OnPress callback, or in an overridden
TInputListener.Press method (
TInputListener is an ancestor for many things, like
procedure Press(Window: TCastleWindow; const Event: TInputPressRelease); begin if Input.IsEvent(Event) then ... end;
The keymap management in
CastleInputs unit cooperates with it nicely. For example you can check which shortcut matches by
InputsAll.SeekMatchingShortcut. You can get an input from user by
CastleMessages.MessageKeyMouse. This is great for games where you want to allow user to customize inputs. See
GameControlsMenu in castle1 source for a working example of it, with
You can of course still hardcode the particular keys/mouse buttons etc., if you want. It's still simple as the
TInputPressRelease is a pretty trivial structure, it has
EventType field, and even helpers like
IsKey. So you can do
procedure Press(Window: TCastleWindow; const Event: TInputPressRelease); begin if Input.IsKey(CharEscape) then ... if Input.IsMouseButton(mbLeft) then ... end;