AppEasy Core SDK
1.5.0
Cross platform mobile and desktop app and game development SDK - The easy way to make apps
|
00001 // 00002 // 00003 // AppEasy SDK - Cross Platform Multi-purpose Game and App Engine 00004 // 00005 // Developed by Matthew Hopwood of Pocketeers Limited - www.pocketeers.co.uk 00006 // 00007 // For updates, tutorials and more details check out www.appeasymobile.com 00008 // 00009 // This code is provided free of charge and without any warranty whatsoever. You must ensure that this whole notice is present in all files and derivatives, so the reader knows its origin. 00010 // If you use this SDK in your product then please ensure that you credit AppEasy's usage appropriately. Please see www.appeasymobile.com for licensing details and support 00011 // 00012 // 00013 00014 #if !defined(_CZ_ACTOR_H_) 00015 #define _CZ_ACTOR_H_ 00016 00017 #include "CzUtil.h" 00018 #include "CzScene.h" 00019 #include "CzSprite.h" 00020 #include "CzAnim.h" 00021 #include "CzString.h" 00022 #include "CzXoml.h" 00023 #include "CzBox2d.h" 00024 #include "CzShapes.h" 00025 #include "CzActions.h" 00026 #include "CzEvents.h" 00027 #include "CzModifier.h" 00028 #include "CzUserProperty.h" 00029 #include "CzTimer.h" 00030 00031 00032 /** 00033 @addtogroup Actors 00034 @{ 00035 */ 00036 00037 /** 00038 @class CzActor 00039 00040 @brief A basic actor. We derive different types of game / app objects from this type and add them to be processed and rendered 00041 00042 <h1>Introduction</h1> 00043 00044 In the CzScene section we talked about scenes and compared them to the scenes of a movie set. Carrying on from our movie business analogy we can think of 00045 Actors as the actors and scenery objects that make up the movie scene with each actor having its own function and purpose within the scene. Actors are 00046 the central focus of all AppEasy development as they provide the actual app or game functionality and interaction that makes your game or app what it is. 00047 Actors are created inside a scene and belong to that scene. When the scene is destroyed its actors will also be destroyed. 00048 00049 A CzActor is a very generic object that provides quite a lot of functionality out of the box. The idea is for developers to create their own actor types 00050 from the base CzActor class then implement their own custom functionality within its Update() method. The basic functionality provided by CzActor includes: 00051 - Support for actor pooling to help reduce memory fragmentation 00052 - Unique names so they can be searched 00053 - Actor types 00054 - Size, Margin and Docking 00055 - Position, Depth, Origin, velocity and velocity damping 00056 - Angle, angular velocity and angular velocity damping 00057 - Scale and Colour 00058 - Draggable state 00059 - Layers 00060 - Active and visible states 00061 - A visual that represents it on screen 00062 - Animation timeline that can be attached to the visual 00063 - Collision size / rectangle 00064 - Wrapping at scenes extents 00065 - Instantiate itself from XOML 00066 - Other actor linkage (used to connect actors in a child / parent style system) 00067 - A Box2D physical body consisting of a material and shape 00068 - Box2D collision category, mask and group 00069 - Managing and clean up of actor local animation timelines 00070 - Managing and clean up of actor local animation timers 00071 - Managing and clean up of actor local events / actions 00072 - Data bindings 00073 00074 CzActor is derived from the IzXomlResource and IzAnimTarget interfaces which enables the actor to be declared in XOML and enables its properties to be 00075 targetted and modified by the animation system. The base CzActor has many base properties that define where, how and what the actor appears as in your 00076 app / game. For example, all actors have position, angle, scale, colour, events list etc.. 00077 00078 AppEasy comes with many pre-defined actor types that each have their own specific purpose. For example, we have Text Actors (CzActorText) that display text, 00079 Image Actors (CzActorImage) that display images, Icon actors (CzUIIcon) that act as buttons and many more. Usually actors have a visual attached which is 00080 an object that is derived from CzSprite. CzSprite gives the actor its visual appearance on screen. For example CzBitmapSprite enables you to display the actor 00081 as an image whilst CzTextSprite enables you to display the actor as text. 00082 00083 Actors can also be augmented to give them additional functionality. Actors can be augmented in a number of ways including adding modifiers (IzModifier) 00084 to them which modify their behaviour, they can respond to events (CzEvent) with actions (CzActions) which in turn can affect the scene and other actors 00085 and they can run XOML programs (CzProgram) or call functions in script (CzScript) languages to create more complex behaviours. Actors can also take 00086 full advantage of the built in physics (CzBox2dBody, CzBox2dJoints, CzBox2dWorld, CzBox2dMaterial, CzBox2dCollidable) and animation systems (CzAnim) to 00087 truly bring them to life. 00088 00089 AppEasy provides a large array of different types of actors out of the box, but all actors are derived from 2 basic types of actors: 00090 - ActorImage - This type of actor enables you to display images or more commonly portions of images within a scene 00091 - ActorText - This type of actor enables you to display text using a font within a scene 00092 00093 All other actors that can be created are derived from these two types of actors. Now lets take a brief look at all of the other types of actors that XOML can use: 00094 - ActorImage - Basic image actor that can display an image or brush 00095 - ActorText - Basic text actor that can display text using specific fonts 00096 - ActorParticles - An actor that can generate particles used for special / spot effects 00097 - Icon - An Image actor that can also be used as a button or check box 00098 - Label - An image actor that contains a text actor, can also be used as buttons 00099 - VideoOverlay - An image actor that can display video content 00100 - TextBox - A label actor that allows text entry via on screen keyboard 00101 - Slider - Image actor that can be used as a slider control 00102 - ListBox - A complex actor that displays a list of child actors that can be selected / toggled etc 00103 - Grid - A complex actor that displays a grid / data grid and allows selection of cells 00104 - Image View / Text View - Displays an image or text area that can be pinch zoomed and panned 00105 - Web View - Displays web content 00106 - Tab Bar - A complex actor that can be used to create navigation between different views 00107 - Canvas, StackPanel and WrapPanel - Image actors that act as containers that arrange content in specific ways 00108 00109 As you can see there is a large selection of actors that you can use as-is or as a starting point to create your own actors. 00110 00111 <h1>Basic Actor Properties</h1> 00112 00113 <b>General Properties:</b> 00114 - Name (string) - Name of the actor, used to refer to the actor from scripts and such. Note that no two actors in the same scene should share the same name. 00115 - Style (style) - Provides a style that this actor should use to style its properties 00116 - Type (number) - A numerical type that can be used to identify the type of this actor (default is 0) 00117 - Active (boolean) - Active state (default is true), actors that are not active will not be processed 00118 - Visible (boolean) - Visible state (default is true), actors that are not visible will not be shown on screen. 00119 - Tappable (boolean) - If true then this actor will receive touch events when touched (default is true). IsTappable in C++ 00120 - Draggable (boolean) - When set to true the user can drag the actor around the world with their finger (default is false). IsTappable in C++ 00121 - Timeline (timeline) - The time line that should be used to animate the actor 00122 - Bindings (bindings list) - Name of the bindings set that will be bound to this actors properties 00123 - Binding (binding) - A simple binding that is bound to a specific property of the actor 00124 - UserData (number) – A user data, can be used to store anything Visual Properties: 00125 - Position (x, y) - The actors position within the scene (default is 0, 0) 00126 - PositionX (number) - The actors position on the x-axis 00127 - PositionY (number) - The actors position on the y-axis 00128 - PositionOrg (x, y) - Allows setting of actors position based on the actors original position, the new position will be original_position + offset 00129 - PositionOrgX (number) - Allows setting of actors position on the x-axis based on the actors original position, the new position will be original_position + offset 00130 - PositionOrgY (number) - Allows setting of actors position on the y-axis based on the actors original position, the new position will be original_position + offset 00131 - PercPos (boolean) - When set to true positions are specificity as a percentage of the devices screen size (default is false) 00132 - Angle (degrees) - The angle of the actor (default is 0) 00133 - Origin (x, y) - Sets the offset around which the actor will rotate and scale (default is 0,0) 00134 - Depth (number) - Depth of the actor in 3D (larger values move the sprite further away, default is 1.0 for parent actors and 0.0 for child actors) 00135 - Scale (x, y) - The x and y axis scale of the actor (default is 1, 1, which represents no scaling) 00136 - ScaleX, ScaleY (number) - The separate x and y axis scale of the actor 00137 - Colour (r, g, b, a)- The colour of the actor, Each component red, green, blue and alpha should be between the value of 0 and 255 (0 is no colour, whilst 255 00138 is full colour, default) 00139 - Opacity (opacity) - The opacity of the actor (how see-through the actor appears). Opacity value ranges from 0 (invisible) to 255 (fully visible, default) 00140 - Layer (number) - The visible layer that the actor should appear on (maximum layer number is limited by the number of actor layers defined by the scene) 00141 - Docking (dock position) - When set will dock the actor to an edge of the screen or canvas, valid values are top, left, right, bottom, topleft, topright, 00142 bottomleft and bottomright 00143 - Margin (left, right, top, bottom) - The amount of space to leave around the actor when placed in a container or docked 00144 - UseParentOpacity (boolean) - When set to true this actor will scale its own opacity by its parents opacity (default is true) 00145 - IgnoreCamera (boolean) – If set to true then this actor will ignore the cameras transformation staying in place when when the camera moves, scales or rotates 00146 (default is false) 00147 - Orphan (boolean) – If set to true then this actor will ignore its usual parentchild hierarchy when sorting by layer. This enables child actors to be sorted by 00148 layer with parent actors (default is false) 00149 00150 <b>Physical Properties:</b> 00151 - Velocity (x, y) - Initial velocity of the actor 00152 - VelocityDamping (x, y) - The amount to dampen velocity each frame, values of less than 1.0 will slow the actor down over time, values of greater than 1.0 will 00153 speed the actor up over time. 00154 - AngularVelocity (number) - The rate at which the orientation of the actor changes in degrees per second 00155 - AngularVelocityDamping (number) - The amount of rotational velocity damping to apply each frame 00156 - WrapPosition (boolean) - If true then the actor will wrap at the edges of the canvas 00157 - Box2dMaterial (material) - Sets the physical material type used by the Box2D actor 00158 - Shape (shape) - Box2D fixture shape for that represents this actor during collisions 00159 - COM (x, y) - Centre of mass of Box2D body 00160 - Sensor (boolean) - Can be used to set the actor as a sensor (default is false) 00161 - CollisionFlags (category, mask, group) - Box2D collision flags 00162 00163 <b>Event Properties:</b> 00164 - OnBeginTouch (actions list) - When the user begins to touch this actor it fires this event and calls the supplied actions list. Actor also supports 00165 OnBeginTouch2 to OnBeginTouch5 representing the 2nd to 5th touches on multi-touch devices. 00166 - OnEndTouch (actions list) - When the user stops touching this actor it fires this event and calls the supplied actions list. Actor also supports OnEndTouch2 to 00167 OnEndTouch5 representing the 2nd to 5th end touches on multi-touch devices. 00168 - OnTapped (actions list) - When the user taps this actor it fires this event and calls the supplied actions list. Actor also supports OnTapped2 to OnTapped5 00169 representing the 2nd to 5th taps on multi-touch devices. 00170 - OnCreate (actions list) - When this actor is first created it fires this event and calls the supplied actions list 00171 - OnDestroy (actions list) - When the actor is about to be destroyed it fires this event and calls the supplied actions list 00172 - OnOrientationChange (actions list) - When the devices orientation changes it fires this event and calls the supplied actions list 00173 - OnSizeChange (actions list) - When the devices screen size changes it fires this event and calls the supplied actions list (only valid for devices that support dynamic display / window size changing) 00174 - OnCollisionStart (actions list) - When two actor that have Box2D physics enabled start to collide it fires this event and calls the supplied actions list (only 00175 if the actor has the iw_notifycollision modifier attached) 00176 - OnCollisionEnd (actions list) - When two actor that have Box2D physics enabled stop colliding it fires this event and calls the supplied actions list (only 00177 if the actor has the iw_notifycollision modifier attached) 00178 - OnTick (actions list) - Provides an actions group that is called every time the scene is updated (30 to 60 times per second) 00179 - Bubbling (boolean) - When set to true touch events can bubble up from child actors 00180 00181 <b>Miscellaneous Properties:</b> 00182 - GridPos (x, y) - Grid cell in which to place the actor in a grid 00183 - LinkedTo (actor) - Name of actor that this actor links to (advanced) 00184 00185 <h1>Creating Actors</h1> 00186 The usual way to create an actor is to choose which type of actor is most appropriate to the task. For example, if you want a simple game character then an CzActorImage 00187 will suffice, or maybe you want a button with a background and text, in which case a CzUILabel would be the better choice. Lets take a look at a few different ways to create 00188 a label: 00189 00190 @par XOML Example: 00191 @code 00192 <Label Font="serif" Background="Button1Brush" Text="Im a label" /> 00193 @endcode 00194 00195 @par Code Example: 00196 @code 00197 // Find the font and brush 00198 CzFont* font = (CzFont*)CZ_GLOBAL_RESOURCE_MANAGER->findResource("serif", CzHashes::Font_Hash); 00199 IzBrush* background_brush = (IzBrush*)CZ_GLOBAL_RESOURCE_MANAGER->findResource("Button1Brush", CzHashes::Brush_Hash); 00200 // Create the label 00201 CzUILabel* label = new CzUILabel(); 00202 label->setName("label1"); 00203 scene->addActor(label); 00204 label->Init(background, 200, 70); 00205 CzIRect rc = CzIRect(0, 0, -100, -100); 00206 label->InitTextActor(font, rc, "Im a label", false); 00207 @endcode 00208 00209 @par Code Example (using macros): 00210 @code 00211 // Find the font and brush 00212 CzFont* font = (CzFont*)CZ_GLOBAL_RESOURCE_MANAGER->findResource("serif", CzHashes::Font_Hash); 00213 IzBrush* background_brush = (IzBrush*)CZ_GLOBAL_RESOURCE_MANAGER->findResource("Button1Brush", CzHashes::Brush_Hash); 00214 // Create the label 00215 CzIVec2 size(200, 70); 00216 CZ_NEW_LABEL(scene, label, "label1", CzString("Im a label"), background_brush, font, size, false); 00217 @endcode 00218 00219 @par Lua Script Example: 00220 @code 00221 local font = resource.find("serif", "font"); 00222 local brush = resource.find("Button1Brush", "brush"); 00223 local label_actor = actor.create("label1", scene, font, "Im a label", brush, 200, 70); 00224 @endcode 00225 00226 As you can see from all of the above examples, object creation in XOML is by far the easiest, most well organised and quickest approach. Lua is the 2nd, code macros the third 00227 and pure code last. We focus mainly on the XOML approach throughout most of the AppEasy documentation as it is by far the most efficient. 00228 00229 <h1>Actor Hierarchies</h1> 00230 00231 In XOML actors can be declared inside others actors to form an hierarchy (called linking). In this hierarchy actors that are declared inside other actors are called 00232 child actors, whilst the container actor is called the parent actor. You will see hierarchical actors used extensively throughout XOML, especially in regards to the 00233 user interface system. This child / parent system enables the creation of complex multi-part actors that are built from many actors. In code to make an actor the child 00234 of another actor you call setLinedTo() passing in the parent. 00235 00236 When you place child actors inside a parent actor the child is modified in a number of ways: 00237 - Position, scale, rotation and depth become relative to the parent actor, so if the parent actor moves around then the child actors will follow. So for example if 00238 you set the child actors position to 0, 0 then it will be centered at the parent. If the parent rotates or scales then the child will also rotate and scale by the 00239 same rate as the parent 00240 - The opacity of child actors will be scaled by the parent actors opacity if UseParentOpacity="true" was specified in the child actors definition. For example, 00241 if you set the parents opacity to half then all child actors will also appear at half opacity 00242 - When a parent actor is hidden or made visible then all child actors will also be made hidden or visible 00243 - Child actors no longer obey layer ordering and are instead layered in the order in which they are declared inside. You can override this behaviour by adding 00244 Orphan=”true” property to the actor definition 00245 - Child actors will steal input events from the parent actor, if the parent actor is drawn before the child actors, unless the parent has Bubbling="true" set, in 00246 which case both the child actor and its parent will both receive the input event 00247 00248 <h1>Absolute / Percentage Positioning and Sizing</h1> 00249 00250 When you begin developing apps and games for mobile you will quickly discover that you need to deal with a large selection of different screen sizes, orientations 00251 and aspect ratios. The scenes virtual canvas can go a long towards helping to alleviate this problem. However (for apps in particular) its often more appropriate 00252 to render the user interface at the screens native resolution but use a series of clever layout panels to position and size content. 00253 00254 Actors can be positioned in a scene using two methods: 00255 - Absolute Positioned - The position you specify is in absolute or actual scene coordinates 00256 - Percentage Positioned - The position you specify is a percentage of the devices screen size 00257 00258 The default mode of actor positioning is absolute. To change an actors positioning mode to percentage based you need to add PercPos=”true” to the actors definition. 00259 00260 Lets take a look at an example: 00261 @par XOML Example 00262 @code 00263 <Label Font="serif" Text="Hello World" Position="10, 20" Size="210, 100" /> - Create a label at 10, 20 of size 200 x 100 00264 <Label Font="serif" Text="Hello World" Position="10, 20" PercPos=”true” Size="210, 100" /> - Create a label at 10%, 20% of size 200 x 100 00265 @endcode 00266 00267 As wall as absolute and percentage based positioning the size of an actor can be absolute or percentage based: 00268 - Absolute Size - The size that you specify is in absolute / actual width and height in scene coordinates 00269 - Percentage Size - The size that you specify is a percentage of the actors parents size or if the actor has no parent a percentage of the devices screen size 00270 00271 The default mode of actor sizing is absolute. By passing a negative width or height you switch the actors sizing mechanism to percentage based. Lets take a look at 00272 an example: 00273 00274 @par XOML Example 00275 @code 00276 <Label Font="serif" Text="Hello World" Position="0, 0" Size="-50, -50" /> - Create a label at 0, 0 of size 50% screen width and height 00277 @endcode 00278 00279 Using percentage based positioning and sizing with layout panels enables production of device screen size independent apps and games. 00280 00281 Its important to note that actors that are positioned / sized using percentages will change position / size when the devices screen orientation changes. 00282 00283 <h1>Docking and Margins</h1> 00284 00285 Its often very useful to place an actor somewhere on screen without worrying about the exact position where it needs to be placed. To solve this problem XOML 00286 introduces the concept of docking. Docking allows actors to be placed at the edge of the screen or the edge of a canvas. Lets take a look at a XOML example that 00287 shows actor docking: 00288 00289 @par XOML Example 00290 @code 00291 <-- Create a bunch of docked labels:>; 00292 <Label Font="serif" Background="Button1Brush" Size="100, 100" Text="Left" Docking="left" /> 00293 <Label Font="serif" Background="Button1Brush" Size="200, 200" Text="Right" Docking="right" /> 00294 <Label Font="serif" Background="Button1Brush" Size="150, 150" Text="Top" Docking="top" /> 00295 <Label Font="serif" Background="Button1Brush" Size="180, 180" Text="Docked" Docking="bottom" /> 00296 @endcode 00297 00298 You can see a working example of actor docking by taking a look at the ActorDocking example. 00299 00300 Note that when the devices screen orientation changes docked actors will re-dock themselves to dock to the new screen edges. When an actor is docked at a screen 00301 or canvas edge you do not always want the actor to be appear right up against the edge, sometimes it looks better to leave a little space. XOML provies the Margin 00302 property that allows you to specify some space to leave around the actor. You can set the space to leave around an actor by adding Margin=”left space, right space, 00303 top space, bottom space”, where left, right, top and bottom space is the amount of space to leave around the actor. Lets revisit our previous example and add a 00304 margin to the first actor: 00305 00306 @par XOML Example 00307 @code 00308 <Label Font="serif" Background="Button1Brush" Size="100, 100" Text="Left" Docking="left" Margin="20, 0, 0, 0" /> 00309 @endcode 00310 00311 Although this actor is docked to the left hand side of the screen it is no longer clinging to the edge, instead it is pushed our by 20 units, leaving a nice gap. 00312 Margins sizes can also be specified using percentage sizing, by making margin values negative you force them to be percentage based. For example: 00313 00314 @par XOML Example 00315 @code 00316 <Label Font="serif" Background="Button1Brush" Size="100, 100" Text="Left" Docking="left" Margin="-5, 0, 0, 0" /> 00317 @endcode 00318 00319 This label now has a gap down its left hand side that is 5% of the screens width 00320 00321 <h1>Layers</h1> 00322 00323 Its customary in game and app development to have some kind of visual order in which objects appear. For example, a button should appear over the background that 00324 it sits on or the foreground in a game world should appear above the background. To accomplish this XOML uses actor layering. Each scene has a number of layers that 00325 actors can be placed on (layers 0 to 15 by default, although this can be changed in the scene definition). Actors that are placed on higher number layers will appear 00326 above actors on lower number layers. To set an actors layer you add the Layer=”layer number” property to the actor definition. e.g: 00327 00328 @par XOML Example 00329 @code 00330 <Icon Name=”icon1” Background="Button1Brush" Size="250, 200" Text="Layer 7" Layer="7" /> 00331 <Icon Name=”icon2” Background="Button1Brush" Size="500, 200" Text="Layer 1" Layer="1" /> 00332 @endcode 00333 00334 In this example, icon1 will appear above icon2 because icon1 is on layer 7 whereas icon2 is on layer 1. 00335 00336 <h1>Actor Origin</h1> 00337 00338 Sometimes we want objects to move a little differently than the norm. All actors by default spin and scale around their centre when rotated or scaled. We can modify 00339 this behaviour by moving the origin of the actor. The origin of an actor is the point around which the actor will spin and scale and by moving this origin we can 00340 change the position around which it spins and scales. 00341 00342 The ActorChildren example shows an example of moving the origin to change how one actor spins around another. If you pay attention to the small green cube that is 00343 orbiting Child 4 you will notice that it orbits Child 4 much like a space craft would orbit a planet. Lets take a look at the XOML for this green cube actor: 00344 00345 <Icon Origin="0, 80" Background="Button1Brush" BackgroundColour="80, 255, 80, 255" Size="20, 20" AngularVelocity="7.5" /> 00346 00347 In this example, we add the Origin=”0, 80” to the icon definition which pushes its centre of rotation 80 units downwards, this in turn causes the actor to have an 00348 orbital distance of 80 units from the centre of the parent actor. 00349 00350 <h1>Animation</h1> 00351 00352 Because there is a lot of focus on actors in XOML, XOML provides a number of ways to animate them. Actors can be assigned an animation timeline which contains many 00353 animations that target its properties for example (animations and timelines are covered in the animation section). Actors can also be placed under control of the 00354 physics system (covered in a later section) Besides timelines and physics, actors can be animated using linear and angular velocity. If we take a look our basic 00355 actor properties again we notice two particularly interesting properties: 00356 - Velocity (x, y) - Initial velocity of the actor 00357 - AngularVelocity (number) - The rate at which the orientation of the actor changes in degrees per second 00358 00359 These two properties allow us to set an initial linear velocity (moves the actor in a direction) and angular velocity (spins the actor at a set speed). 00360 If you one again take a look at the ActorChildren example, you will notice that each actor has an AngularVelocity property defined: 00361 00362 @par XOML Example 00363 @code 00364 <Label Position="0, 0" Font="serif" Background="Button1Brush" BackgroundColour="80, 80, 255, 255" Size="100, 100" Text="Parent" AngularVelocity="1"> 00365 @endcode 00366 00367 By setting this property we can et the actor off spinning as soon as it comes into the game world. 00368 00369 <h1>Dragging Actors</h1> 00370 00371 XOML provides a neat little feature for all actors called dragging. Any actor can be marked as dragabble by adding Draggable=”true” to the actor definition. 00372 Marking the actor as draggable allows the user to drag the actor around the screen using their finger. 00373 00374 <h1>Physics</h1> 00375 00376 There's nothing like adding realistic physics to a game to bring it to life and increase its immersion factor. To that end XOML provides out of the box physics 00377 via Box2D. Any actor can be made to use physics by simply assigning a shape and a Box2D material to it in the actor definition. This includes all actors including 00378 user interface components! Lets have a quick recap of the available properties that affect the physics of our actor: 00379 - Velocity (x, y) - Initial velocity of the actor 00380 - VelocityDamping (x, y) - The amount to dampen velocity each frame, values of less than 1.0 will slow the actor down over time, values of greater than 1.0 will 00381 speed the actor up over time. 00382 - AngularVelocity (number) - The rate at which the orientation of the actor changes in degrees per second 00383 - AngularVelocityDamping (number) - The amount of rotational velocity damping to apply each frame 00384 - WrapPosition (boolean) - If true then the actor will wrap at the edges of the canvas 00385 - Box2dMaterial (material) - Sets the physical material type used by the Box2D actor 00386 - Shape (shape) - Box2D fixture shape for that represents this actor during collisions 00387 - COM (x, y) - Centre of mass of Box2D body 00388 - Sensor (boolean) - Can be used to set the actor as a sensor 00389 - CollisionFlags (category, mask, group) - Box2D collision flags 00390 00391 Now would be a good to open up the ActorPhysics example that has been provided. Lets take a quick look at some of the important parts of the XOML for this example: 00392 00393 @par XOML Example 00394 @code 00395 <Scene Name="Scene1" Current="true" Physics="true" WorldScale="1, 1" Gravity="0, 30" Camera="Camera1"> - Create a scene with physics enabled 00396 @endcode 00397 00398 Firstly we create a scene that can support physics by enabling physics, settings the worlds scale to 1, 1 (this means 1 scene unit is 1 physical unit) and then we 00399 set the gravity to act downwards. 00400 00401 @par XOML Example 00402 @code 00403 <-- Create Box2D materials -->; 00404 <Box2dMaterial Name="Bouncey" Type="dynamic" Density="1.0" Friction="0.3" Restitution="0.6" /> 00405 <Box2dMaterial Name="Heavy" Type="static" Density="2.0" Friction="0.8" Restitution="0.8" /> 00406 @endcode 00407 00408 Next we create two box2d materials. The first is quite boucey and will be used by our bouncey box. The second material is quite solid and will represent out floor. 00409 It is also marked as a static materuial because we do not expect the floor to move. The first material is marked as dynamic becuase we expect our boncey box to move. 00410 00411 @par XOML Example 00412 @code 00413 <-- Create Box2D shapes -- >; 00414 <Shape Name="Button" Type="box" Width="100" Height="100" /> 00415 <Shape Name="Floor" Type="box" Width="1000" Height="100" /> 00416 @endcode 00417 00418 Next we create two shapes (thes represent the physical shape of our objects). In this example we have a small box 100x100 units in size that represents our bouncey 00419 box and a much larger 1000x100 box shape that represents our solid floor. 00420 00421 @par XOML Example 00422 @code 00423 <Label Position="0, 200" Font="serif" Background="Button1Brush" BackgroundColour="255, 80, 80, 255" Size="1000, 100" Text="Floor" Shape="Floor" Box2dMaterial="Heavy" 00424 CollisionFlags="1, 1, 1" /> - Create the floor 00425 <Label Position="-50, -180" Font="serif" Background="Button1Brush" BackgroundColour="80, 255, 255, 255" Size="100, 100" Text="Bouncey" Shape="Button" Box2dMaterial="Bouncey" 00426 CollisionFlags="1, 1, 1" /> - Create an actor to drop onto the floor 00427 @endcode 00428 00429 Lastly we create a bunch of actors (we have only included the floor and one box here). The first actor (Floor) represents our floor and is assigned the Floor shape and 00430 the Heavy material. The second actor (Bouncey) is assigned the Button shape and Bouncey material. 00431 00432 You may by now have noticed an additional property called CollisionFlags. Collision flags are described as: 00433 - Category - The category bits describe what type of collision object the actor is 00434 - Mask - The mask bits describe what type of other collision objects this actor can collide with 00435 - Group - The group index flag can be used to override category and mask, but we generally do not need to use it and usually set it to 0 for all actors. 00436 00437 The ActorCollisionFlags example has been provided to show how collision flags work. 00438 00439 The centre of mass (COM) of an actor in simple terms is the point at which the mass of the object is balanced. If the centre of mass of an object is directly at its 00440 centre then when hit towards its centre of mass by another object will generally cause it to spin around its centre. We can move the centre of mass of an actor to give 00441 the impression that the mass is centred elsewhere. For example, we may want to move the centre of mass towards the bottom of a box to make it look like it is weighted 00442 at the bottom. We can move an actors centre of mass by setting the actors COM attribute to the position of the centre of mass. 00443 00444 Lastly, we can mark actors as being sensors instead of interactive physical objects. When an actor collides with a sensor the sensor does not affect the actor and the 00445 actor does not physically affect the sensor. In essense a sensor is there just to detect that something has collided with it. This type of actor is good for actors that 00446 represent switches and other types of none interactive actors. To mark an actor as a sensor set Sensor=”true” in the actor definition. 00447 00448 <h1>Modifiers</h1> 00449 00450 Modifiers can be thought of as small functional building blocks that can be stacked in an actor or scene to extend the functionality of that actor or scene. For example, 00451 a typical modifier for a scene could be one that tracks the players scores / hi-scores, change day / night settings or detects special gestures. An actor modifier 00452 example could be a modifier that allows the actor move around using heading and speed or even a modifier with functionality specific to your game such as make a baddy 00453 that walks left and right on a platform. Lets take a look at how we add a modifier to an actor: 00454 00455 @par XOML Example 00456 @code 00457 <ActorImage Name="Car" ........ > 00458 <Modifiers> 00459 <Modifier Name="iw_notifycollision" Active="false" Param1="0" /> 00460 </Modifiers> 00461 </ActorImage> 00462 @endcode 00463 00464 In this example we add the iw_notifycollision modifier which allows the actor to respond to collision events between actors. 00465 00466 A modifier accepts the following properties: 00467 - Name - Name of the modifier 00468 - Active - Active state of the modifier 00469 - Param1 to Param4 - Parameters that can be passed to the modifier when it is initialised 00470 00471 At the moment only a few different modifiers are available for actors but more will be added over time. Lets take a look at the modifiers that are currently 00472 available. 00473 - Collision Notification Modifier - The iw_ notifycollision modifier when attached to an actor allows it to generate and respond to collision events between actors 00474 using OnCollisionStart() and OnCollisionEnd() event handlers (See ActorModifier example for an example showing how to use this modifier). Ths modifier accepts a number 00475 of parameters which include: 00476 - Param1 - An optional mask that can be used to mask collision with actors by their Type. The value supplied will mask actors by type and only allow collision events 00477 to be called for those actors that pass the bit mask. For example actor 1 could have a mask of 3 and actor 2 a mask of 1. if the mask is set to 1 then both actors can 00478 collide, but if the mask was set to 3 then they could not. 00479 - Script Modifier - the iw_callscript modifier when attached to an actor will call a function in a script each time the actor is updated. This modifier is useful as 00480 an alternative to using OnTick event handlers. This modifier accepts the following parameters: 00481 - Param1 - Script function name 00482 - Param2 to Param3 - Parameters to be passed to the script function 00483 00484 Future out of the box functionality will be added to XOML using modifiers. 00485 00486 <h1>Scripts</h1> 00487 00488 Whilst XOML is very powerful it does have some limits when it comes to defining very complex application / app logic, for example path finding algorithms would be 00489 quite cumbersome to create using XOML. Actors support the calling of script functions via actions in response to various events occurring. Also, as shown in the previous 00490 section, a modifier can be added to an actor that automatically calls script functions every time the actor is updated via the OnTick event, for example: 00491 00492 @par XOML Example 00493 @code 00494 <Label Font="serif" Text="OnTick Example" OnTick="Update"> 00495 <Actions Name="Update"> 00496 <Action Method="CallScript" Param1="Actor_OnTick" /> 00497 </Actions> 00498 </Label> 00499 @endcode 00500 00501 <h1>Events</h1> 00502 00503 Actors can receive and react to a number of different types of events including: 00504 - OnBeginTouch to OnBeginTouch5 - The user has began to touch the actor (up to 5 simultaneous touches) 00505 - OnEndTouch to OnEndTouch5 - The user has stopped touching the actor (up to 5 simultaneous touches) 00506 - OnTapped to OnTapped5 - The user tapped the actor (up to 5 simultaneous touches) 00507 - OnCreate - The actor has been created 00508 - OnDestroy - The actor is about to be destroyed 00509 - OnOrientationChange - A screen orientation or size change has just taken place 00510 - OnCollisionStart - A collision with another actor has begun 00511 - OnCollisionEnd - A collision with another actor has ended 00512 - OnTick - The actor is being updated 00513 00514 All touch events can bubble up to parent actors if the parent actor has event bubbling enabled. Event bubbling is the process of passing the same event on up to actors further up 00515 the parent-child heirearchy. Lets take a quick look at an example actor that responds to a number of different events: 00516 00517 @par XOML Example 00518 @code 00519 <Label Font="serif" Text="Tap Me" Background="Button1Brush" OnTapped="Tapped" OnCreate="Created"> 00520 <Actions Name="Created"> 00521 <Action ....... /> 00522 <Action ....... /> 00523 </Actions> 00524 <Actions Name="Tapped"> 00525 <Action ....... /> 00526 <Action ....... /> 00527 </Actions> 00528 </Label> 00529 @endcode 00530 00531 <h1>Data Bindings</h1> 00532 AppEasy supports the binding of XOML variables to properties of actors. When the variable is changed the target property of the actor is automatically updated. Actors can use bindings 00533 lists or simple bindings. A bindings list is a collection of bindings that bind specific variables to specific properties of the actor. Lets take a look at a short XOML example: 00534 00535 @par XOML Example 00536 @code 00537 <!-- Create a variable that holds the labels position -->; 00538 <Variable Name="LabelPosition" Type="vec2" Value="0, 0" /> 00539 00540 <!-- Create a variable that holds the labels angle -->; 00541 <Variable Name="LabelAngle" Type="float" Value="0" /> 00542 00543 <!-- Create a data bindings list -->; 00544 <Bindings Name="LabelBindings"> 00545 <Binding Property="Position" Variable="LabelPosition" /> 00546 <Binding Property="Angle" Variable="LabelAngle" /> 00547 </Bindings> 00548 00549 <!-- Create a label with bound data -->; 00550 <Label Font="serif" Text="Tap Me" Background="Button1Brush" Bindings="LabelBindings" /> 00551 @endcode 00552 00553 In the above example we create two variables, a bindings list and a label. In the bindings list we bind LabelPosition to the Position property and LabelAngle to the Angle property. 00554 We then assign the bindings list to the label actor using Bindings="LabelBindings". Now any changes to LabelPosition / LabelAngle will automatically be applied to the actors Position 00555 and Angle properties. 00556 00557 Simple data bindings work in much the same way except a simple binding is the binding of a single variable to a single property. Lets take a look: 00558 00559 @par XOML Example 00560 @code 00561 <!-- Create a variable to track number of collisions -->; 00562 <Variable Name="num_collisions" Type="int" Value="0" /> 00563 00564 <!-- Create a label to display number of collisions -->; 00565 <Label Font="serif" Background="Button1Brush" Docking="topleft" Binding="[Text]num_collisions" /> 00566 @endcode 00567 00568 In this example we speciofy the property "Text" by including the prtoperty name in square brackets [Text], we then tag on the name of the bound variable. Only a single simple 00569 binding may be attached to an actor. Actors can have a bindings list and a simple binding at the same time. Note that a simple binding bound to the same property as a bindings list 00570 will take precedence over the property in the bindings list. Also note that some actor properties are two way bindings, so the actor can write values back to the variable. 00571 00572 <h1>Creating a Custom Actor</h1> 00573 Whilst CzScene can be instantiated and used as-is, CzActor is abstract and cannot. The actor system is designed this way to allow th developer to create their own custom actor 00574 types that provide bespoke functionality that is specific to their game or app. Whilst AppEasy Core provides a multitide of actor types as well as ways of extending actors with the 00575 likes of modifiers (see IzModifier), in some cases the required functionality could be better achieved by deriving a new type of actor from one of the base actor types. 00576 00577 You begin the creation of a custom actor by deriving your own actor class from one of the actor classes then overloading the following methods to provide implementation: 00578 - void Init() 00579 - bool Update(float dt) 00580 - bool UpdateVisual() 00581 00582 Here's a quick example: 00583 00584 @code 00585 class MyActor : public CzActor 00586 { 00587 public: 00588 MyActor() : CzActor() {} 00589 ~MyActor() {} 00590 00591 void Init() 00592 { 00593 CzActor::Init(); 00594 } 00595 00596 bool Update(float dt) 00597 { 00598 if (!CzActor::Update(dt)) 00599 return false; 00600 00601 // Here we put our actor specific implementation 00602 00603 return true; 00604 } 00605 00606 bool UpdateVisual() 00607 { 00608 if (!CzActor::UpdateVisual()) 00609 return false; 00610 00611 // Here we put our actor specific rendering code (if any is needed) 00612 00613 return true; 00614 } 00615 }; 00616 @endcode 00617 00618 We have provided a very basic implementation of Init(), Update() and UpdateVisual() which call the base CzActor class methods so we keep its functionality in-tact. 00619 00620 You can take the implementation one step further by implementing both the IzXomlResource and IzAnimTarget interfaces to allow instantiation of your custom actor class 00621 from XOML and to allow your class to be a target for animation time lines. 00622 00623 Firstly lets take a look at XOML enabling your custom actor class. To get AppEasy to recognise your actor class whilst parsing XOML files you need to do a few things: 00624 - Derive your class from IzXomlResource class and implement the LoadFromXoml method 00625 - Create a class creator that creates an instance of your class then add this to the XOML engine 00626 00627 Lets start by taking a look at step 1. 00628 00629 Because we have derived our class from CzActor (which is derived from IzXomlResource) we already have the support for step 1. However we would like to insert our own 00630 custom attribute tags so we need to make a few changes. 00631 00632 Lets take a look at our new class with thiose changes: 00633 00634 @code 00635 class MyActor : public CzActor 00636 { 00637 public: 00638 // Properties 00639 protected: 00640 int NumberOfEyes; 00641 public: 00642 void setNumberOfEyes(int num_eyes) { NumberOfEyes = num_eyes; } 00643 float getNumberOfEyes() const { return NumberOfEyes; } 00644 // Properties End 00645 public: 00646 MyActor() : CzActor() {} 00647 ~MyActor() {} 00648 00649 void Init() 00650 { 00651 CzActor::Init(); 00652 } 00653 00654 bool Update(float dt) 00655 { 00656 if (!CzActor::Update(dt)) 00657 return false; 00658 00659 // Here we put our actor specific implementation 00660 00661 return true; 00662 } 00663 00664 bool UpdateVisual() 00665 { 00666 if (!CzActor::UpdateVisual()) 00667 return false; 00668 00669 // Here we put our actor specific rendering code (if any is needed) 00670 00671 return true; 00672 } 00673 00674 // Implementation of IzXomlResource interface 00675 bool LoadFromXoml(IzXomlResource* parent, bool load_children, CzXmlNode* node) 00676 { 00677 if (!CzActor::LoadFromXoml(parent, load_children, node)) // Notice how we call the base implementation of LoadFromXoml to ensure that any base actor properties also get loaded 00678 return false; 00679 00680 // Add our own custom attribute parsing 00681 for (CzXmlNode::_AttribIterator it = node->attribs_begin(); it != node->attribs_end(); it++) 00682 { 00683 unsigned int name_hash = (*it)->getName().getHash(); 00684 00685 if (name_hash == CzString::CalculateHash("NumberOfEyes")) 00686 { 00687 setNumberOfEyes((*it)->getValueAsInt()); 00688 } 00689 } 00690 00691 return true; 00692 } 00693 }; 00694 @endcode 00695 00696 00697 Our new class now basically supports a new NumberOfEyes attribute that we will eventually be able to set in XOML using something like: 00698 00699 @code 00700 <MyActor Name="AlienCritter" Position="100, 100" Size="100, 100" NumberOfEyes="3" /> 00701 @endcode 00702 00703 However, before we can do that we need to let the XOML system know about our new type of class (MyActor), so it can be instantiated when the XOML parser comes across it. To do this 00704 we need to create a XOML class creator: 00705 00706 @code 00707 class MyActorCreator : public IzXomlClassCreator 00708 { 00709 public: 00710 MyActorCreator() 00711 { 00712 setClassName("MyActor"); 00713 } 00714 IzXomlResource* CreateInstance(IzXomlResource* parent) { return new MyActor(); } 00715 }; 00716 @endcode 00717 00718 The creator basically defines the tag name "MyActor" and returns an instance of the MyActor class when CreateInstance() is called. 00719 00720 To get the XOML system to recognise our new creator we need to add it to the XOML parsing system using: 00721 00722 @code 00723 // Add custom MyActor to XOML system 00724 CZ_XOML->addClass(new MyActorCreator()); 00725 @endcode 00726 00727 Now XOML integration is out of the way, lets take a quick look at enabling our class as an animation target. 00728 00729 To enable a class as an animation target we derive it from IzAnimTarget and implement the UpdateFromAnimation() method. Luckily we derived our MyActor class from the CzActor class which 00730 already provides this functionality. Lets take a quick look at how we extend the animation update method to account for animating our NumberOfEyes variable. 00731 00732 @code 00733 bool UpdateFromAnimation(CzAnimInstance *animation) 00734 { 00735 if (CzActor::UpdateFromAnimation(animation)) // Notice how we call the base implementation of UpdateFromAnimation to ensure that any base actor properties also get animated 00736 return true; 00737 00738 // Add our own custom animating property 00739 unsigned int property_name = animation->getTargetPropertyHash(); 00740 00741 if (property_name == CzString::CalculateHash("NumberOfEyes")) 00742 { 00743 CzAnimFrameFloat* frame = (CzAnimFrameFloat*)animation->getCurrentData(); 00744 setNumberOfEyes((int)frame->data); 00745 return true; 00746 } 00747 00748 return false; 00749 } 00750 @endcode 00751 00752 We added the above code to our MyActor class definition. We begin by calling the base UpdateFromAnimation() method so we can keep the existing animation properties of the actor. 00753 We then add our own custom check for the NumberOfEyes variable. If the animation property matches NumberOfEyes then we set the number of eyes to the provided interpolated value. 00754 00755 @todo 00756 - setProperty() needs to be replaced with CzXomlProperty instead of CzString as string conversion has to take place each time a property is set. 00757 - Refactor setProperty(), UpdateFromAnimation(). UpdateBinding() and LoadFromXoml() so they all use a centralised update property method. 00758 - Optimise setProperty(), getProperty(), UpdateFromAnimation(), UpdateBinding() and LoadFromXoml() to perform less comparisons (divide search by first character of property name. 00759 - Make property system more extensible by replacing current if-then-else system with a new class property system that stores a list of available properties along with which static methods 00760 should be called to modify them. This will enable users to more easily extend derived actors. 00761 00762 */ 00763 00764 class CzActor : public IzXomlResource, public IzAnimTarget 00765 { 00766 public: 00767 /** 00768 @enum eCzActorCategory 00769 00770 @brief Values that define the category of the actor 00771 */ 00772 enum eCzActorCategory 00773 { 00774 AC_Generic, ///< Actor is a generic type of actor (CzActorImage or CzActorText) 00775 AC_UI, ///< Actor is a UI actor such as CzUIIcon, CzUILabel etc.. 00776 }; 00777 00778 00779 protected: 00780 // Properties 00781 CzScene* Scene; ///< Scene that actor lives in 00782 eCzActorCategory Category; ///< Category of actor 00783 int Type; ///< User defined type of Actor (use to distinguish beteeen different actor types) 00784 CzIVec2 Size; ///< Visual size 00785 CzVec2 OriginalPosition; ///< Original position of actor in the scene (when actor was first spawned) 00786 CzVec2 Position; ///< Current position of actor in the scene 00787 CzScene::eDocking Docking; ///< Docking position 00788 CzIRect Margin; ///< Margin (spacing around the actor) 00789 float Depth; ///< Parallax depth 00790 CzVec2 Origin; ///< Origin of actor 00791 CzVec2 Velocity; ///< Current velocity of actor 00792 CzVec2 VelocityDamping; ///< Dampens the velocity (Values less than 1.0f will reduce velocity over time, whilst values larger than 1.0f will increase velocity over time) 00793 float OriginalAngle; ///< Original angle in scene (when first spawned) 00794 float Angle; ///< Orientation in scene (degrees) 00795 float AngularVelocity; ///< Angular velocity 00796 float AngularVelocityDamping; ///< Angular velocity damping 00797 CzVec2 OriginalScale; ///< Original scale of actor in the scene (when actor was first spawned) 00798 CzVec2 Scale; ///< Scale 00799 CzColour OriginalColour; ///< Original colour 00800 CzColour Colour; ///< Colour 00801 int Layer; ///< Depth layer 00802 bool Orphan; ///< Actors orphaned status 00803 bool Used; ///< Used is used when actors pooled to reduce memory fragmentation 00804 bool IsActive; ///< Active state of actor 00805 bool IsVisible; ///< Visible state of actor 00806 bool IsCollidable; ///< Collidable state of actor 00807 bool IsTappable; ///< Tappable state of actor 00808 bool IsDraggable; ///< Draggable state of actor 00809 bool IsDragging; ///< Dragging state of actor 00810 bool ReceiveEventFromChild; ///< If true then this actor will receieve events from its children 00811 bool WrapPosition; ///< If true then if position exits the extents of the scene actor will wrap back around to the opposite side of the scene 00812 bool Destroyed; ///< An actor is marked asd destroyed when it has been marked for deletion 00813 bool ScreenDocking; ///< if true then the actors docking value will be applied to the screen and not any parent containers that support edge docking 00814 bool HoldFocus; ///< When set to true this actor will not lose focus when the user moves out of its range 00815 bool UseParentOpacity; ///< If true then this actors visuals opacity will be scaled by its parent, if it has one 00816 bool PercentagePosition; ///< If true then position 00817 bool IgnoreCamera; ///< If true then actor will not move with scene camera 00818 eCzAspectLock AspectLock; ///< Determines which acis to use to lock aspect ratio of actors size 00819 CzSprite* Visual; ///< Visual element that represents the actor 00820 CzAnimTimeline* Timeline; ///< Timeline, controls animation of the actor 00821 CzXomlBindings* Bindings; ///< Manages any attached bindings 00822 CzXomlBinding* SimpleBinding; ///< A simple one property binding 00823 int CollisionSize; ///< Size of collision area 00824 CzIRect CollisionRect; ///< Spherical collision size 00825 float PreviousAngle; ///< Previous updates angle 00826 CzVec2 PreviousPosition; ///< Previous updates position 00827 CzActor* LinkedTo; ///< Actor that this actor links to. Linked actors will utilise their target links colour, visibility and transform etc.. 00828 CzActor* Target; ///< An actor target 00829 int TouchIndex; ///< Index of last touch on this actor 00830 CzBox2dBody* Box2dBody; ///< Box2D physics body 00831 CzUserPropertyList* UserPropertyList; ///< User properties list 00832 CzActionsManager* ActionsManager; ///< Manages actions 00833 CzAnimTimelinesManager* TimelinesManager; ///< Manages timelines 00834 CzTimersManager* TimersManager; ///< Manages attached timers 00835 CzEventManager* EventsManager; ///< List of events that the actor handles 00836 CzModifierManager* Modifiers; ///< Class modifiers manager 00837 unsigned int GridPos; ///< x, y position in grid 00838 void* UserData; ///< Extra custom data 00839 bool TickEnabled; ///< True if OnTick event specified 00840 public: 00841 void setCategory(eCzActorCategory cat) { Category = cat; } 00842 eCzActorCategory getCategory() const { return Category; } 00843 void setUsed(bool in_use) { Used = in_use; } 00844 bool isUsed() const { return Used; } 00845 void setScene(CzScene* scene) { Scene = scene; } 00846 CzScene* getScene() { return Scene; } 00847 void setType(int type) { Type = type; } 00848 int getType() const { return Type; } 00849 CzIVec2 getSize() const { return Size; } 00850 void setOriginalPosition(float x, float y) { OriginalPosition.x = x; OriginalPosition.y = y; } 00851 CzVec2 getOriginalPosition() { return OriginalPosition; } 00852 void setPosition(float x, float y); 00853 void setPosition(const CzVec2& pos) { setPosition(pos.x, pos.y); } 00854 void setPositionX(float x) { setPosition(x, Position.y); } 00855 void setPositionY(float y) { setPosition(Position.x, y); } 00856 void setDocking(CzScene::eDocking docking); 00857 void setDocking(CzScene::eDocking docking, int width, int height); 00858 CzScene::eDocking getDocking() { return Docking; } 00859 void setMargin(int left, int right, int top, int bottom) { Margin.x = left, Margin.y = right, Margin.w = top, Margin.h = bottom; } 00860 CzIRect getMargin() const { return Margin; } 00861 void setOriginalMargin(int left, int right, int top, int bottom) { OriginalMargin.x = left, OriginalMargin.y = right, OriginalMargin.w = top, OriginalMargin.h = bottom; } 00862 CzVec2 getPosition() { return Position; } 00863 void setDepth(float depth) { Depth = depth; } 00864 float getDepth() const { return Depth; } 00865 void setOrigin(float x, float y) { Origin.x = x; Origin.y = y; } 00866 CzVec2 getOrigin() { return Origin; } 00867 void setOriginalAngle(float angle) { OriginalAngle = angle; } 00868 float getOriginalAngle() { return OriginalAngle; } 00869 void setAngle(float angle); 00870 float getAngle() const { return Angle; } 00871 void setVelocity(float x, float y); 00872 CzVec2 getVelocity() const { return Velocity; } 00873 void setVelocityDamping(float x, float y); // When using Box2d, the y value is ignored 00874 CzVec2 getVelocityDamping() const { return VelocityDamping; } 00875 void setVelocityDamping(float damping); 00876 void setAngularVelocity(float velocity); 00877 float getAngularVelocity() const { return AngularVelocity; } 00878 void setAngularVelocityDamping(float damping); 00879 float getAngularVelocityDamping() const { return AngularVelocityDamping; } 00880 void setOriginalScale(float x, float y) { OriginalScale.x = x; OriginalScale.y = y; } 00881 CzVec2 getOriginalScale() { return OriginalScale; } 00882 void setScale(const CzVec2& scale) { Scale = scale; } 00883 void setScale(float x, float y) { Scale.x = x; Scale.y = y; } 00884 void setScale(float scale) { Scale.x = Scale.y = scale; } 00885 CzVec2 getScale() const { return Scale; } 00886 void setColour(uint8 r, uint8 g, uint8 b, uint8 a) { Colour.r = r; Colour.g = g; Colour.b = b; Colour.a = a; } 00887 void setColour(const CzColour& colour) { Colour = colour; } 00888 CzColour getColour() const { return Colour; } 00889 CzColour getOriginalColour() const { return OriginalColour; } 00890 void setOpacity(uint8 opacity) { Colour.a = opacity; } 00891 int getOpacity() const { return Colour.a; } 00892 void setLayer(int layer) { Layer = layer; } 00893 int getLayer() const { return Layer; } 00894 void setActive(bool active); 00895 bool isActive() const { return IsActive; } 00896 virtual void setVisible(bool visible, bool force_set = false); 00897 bool isVisible() const { return IsVisible; } 00898 void setCollidable(bool collidable); 00899 bool isCollidable() const { return IsCollidable; } 00900 void setTappable(bool tappable) { IsTappable = tappable; } 00901 bool isTappable() const { return IsTappable; } 00902 void setDraggable(bool draggable) { IsDraggable = draggable; } 00903 bool isDraggable() const { return IsDraggable; } 00904 bool isDragging() const { return IsDragging; } 00905 void setReceiveEventFromChild(bool enable) { ReceiveEventFromChild = enable; } 00906 bool canReceiveEventFromChild() const { return ReceiveEventFromChild; } 00907 void setVisual(CzSprite* visual) { Visual = visual; } 00908 CzSprite* getVisual() { return Visual; } 00909 void removeVisual(); 00910 void setTimeline(CzAnimTimeline* timeline); 00911 CzAnimTimeline* getTimeline() { return Timeline; } 00912 void setBindings(CzXomlBindings* bindings); 00913 CzXomlBindings* getBindings() { return Bindings; } 00914 void setSimpleBinding(CzXomlBinding* binding); 00915 CzXomlBinding* getSimpleBinding() { return SimpleBinding; } 00916 void setCollisionRect(const CzIRect& rect); 00917 void setCollisionSize(int size); 00918 CzIRect getCollisionRect() const { return CollisionRect; } 00919 int getCollisionSize() const { return CollisionSize; } 00920 void setPreviousPosition(float x, float y) { PreviousPosition.x = x; PreviousPosition.y = y; } 00921 CzVec2 getPreviousPosition() const { return PreviousPosition; } 00922 void setPreviousAngle(float angle) { PreviousAngle = angle; } 00923 float getPreviousAngle() const { return PreviousAngle; } 00924 void setWrapPosition(bool enable) { WrapPosition = enable; } 00925 bool getWrapPosition() const { return WrapPosition; } 00926 void setLinkedTo(CzActor* actor); 00927 CzActor* getLinkedTo() { return LinkedTo; } 00928 void setTarget(CzActor* target) { Target = target; } 00929 CzActor* getTarget() { return Target; } 00930 void setDestroyed(bool destroyed) { Destroyed = destroyed; if (Destroyed) NotifyDestroy(); } 00931 bool isDestroyed() const { return Destroyed; } 00932 void setBox2dBody(CzBox2dBody* body) { Box2dBody = body; Box2dBody->setUserData(this); } 00933 CzBox2dBody* getBox2dBody() { return Box2dBody; } 00934 CzActionsManager* getActionsManager() { return ActionsManager; } 00935 CzAnimTimelinesManager* getTimelinesManager() { return TimelinesManager; } 00936 CzTimersManager* getTimersManager() { return TimersManager; } 00937 CzEventManager* getEventsManager() { return EventsManager; } 00938 void setUserPropertyList(CzUserPropertyList* props) { SAFE_DELETE(UserPropertyList) UserPropertyList = props; } 00939 CzUserPropertyList* getUserPropertyList() { return UserPropertyList; } 00940 void setModifiers(CzModifierManager* mods) { Modifiers = mods; } 00941 CzModifierManager* getModifiers() { return Modifiers; } 00942 virtual bool setProperty(unsigned int property_name, const CzXomlProperty& data, bool delta); 00943 bool setProperty(const char* property_name, const CzString& data, bool delta); 00944 virtual bool setProperty(unsigned int property_name, const CzString& data, bool delta); 00945 bool getProperty(const char* property_name, CzXomlProperty& prop); 00946 virtual bool getProperty(unsigned int property_name, CzXomlProperty& prop); 00947 void setGridPos(int x, int y); 00948 unsigned int getGridPos() const { return GridPos; } 00949 void setScreenDocking(bool enabled) { ScreenDocking = enabled; } 00950 bool getScreenDocking() const { return ScreenDocking; } 00951 void setHoldFocus(bool hold) { HoldFocus = hold; } 00952 bool getHoldFocus() const { return HoldFocus; } 00953 void setTouchindex(int index) { TouchIndex = index; } 00954 int getTouchIndex() const { return TouchIndex; } 00955 void setUseParentOpacity(bool enable) { UseParentOpacity = enable; } 00956 bool getUseParentOpacity() const { return UseParentOpacity; } 00957 void setAspectLock(eCzAspectLock lock) { AspectLock = lock; } 00958 eCzAspectLock getAspectLock() const { return AspectLock; } 00959 void setPercPos(bool enable) { PercentagePosition = enable; } 00960 bool getPercPos() const { return PercentagePosition; } 00961 void* getUserData() { return UserData; } 00962 void setUserData(void *data) { UserData = data; } 00963 bool getOrphan() const { return Orphan; } 00964 void setOrphan(bool enable) { Orphan = enable; if (Visual != NULL) Visual->setOrphan(Orphan); } 00965 bool getIgnoreCamera() const { return IgnoreCamera; } 00966 virtual void setIgnoreCamera(bool enable) { IgnoreCamera = enable; } 00967 void setTickEnabled(bool enabled) { TickEnabled = enabled; } 00968 bool isTickEnabled() const { return TickEnabled; } 00969 void setOriginalSize(int w, int h) { OriginalSize.x = w; OriginalSize.y = h; } 00970 // Properties end 00971 protected: 00972 CzIVec2 OriginalSize; ///< Original visual size 00973 CzIRect OriginalMargin; ///< Original margin 00974 CzIVec2 DragAnchor; 00975 virtual bool UpdateBinding(unsigned int property_name, CzXomlVariable* var); 00976 virtual void UpdateBindings(bool force_modified = false); ///< Update data bindings 00977 virtual void LinkChanged(CzActor* child, bool remove) {} ///< Called from an actor when an actor that links to this actor unlinks itself 00978 CzActor* FindEventDependentParent(); ///< Events can be set up to bubble down to parents, this method finds parents that is enabled to receive touch events 00979 CzActor* FindClipper(); ///< Tracks back through actor parents to find any that change the clipping rect 00980 void UpdateMargins(); ///< Updates margin szie from original margin (used when orientation changes take place) 00981 00982 public: 00983 CzActor() : IzXomlResource(), Used(false), Scene(NULL), Visual(NULL), Timeline(NULL), EventsManager(NULL), Modifiers(NULL), LinkedTo(NULL), Bindings(NULL), SimpleBinding(NULL), ActionsManager(NULL), TimelinesManager(NULL), 00984 PercentagePosition(false), UserData(NULL), Orphan(false), IgnoreCamera(false), UserPropertyList(NULL) , Box2dBody(NULL), TimersManager(NULL) 00985 { 00986 setClassType("actor"); 00987 Reset(); 00988 ActionsManager = new CzActionsManager(); 00989 ActionsManager->setParent(this); 00990 TimelinesManager = new CzAnimTimelinesManager(); 00991 TimelinesManager->setParent(this); 00992 TimersManager = new CzTimersManager(); 00993 TimersManager->setParent(this); 00994 EventsManager = new CzEventManager(); 00995 #if defined(CZ_ENABLE_METRICS) 00996 CzMetrics::TotalActorsCreated++; 00997 #endif 00998 } 00999 virtual ~CzActor(); 01000 01001 // Initialise the actor 01002 virtual void Init(); 01003 virtual void SetFromBrush(IzBrush* brush); 01004 01005 // Reset the actor (used by memory pooling systems to save actor re-allocation, usually called after re-allocation to reset the object to a default state) 01006 virtual void Reset(); 01007 01008 // Update the actor 01009 virtual bool Update(float dt); 01010 01011 // Update the visual that represents this actor on screen 01012 virtual bool UpdateVisual(); 01013 01014 // Actors are responsible for carrying out there own collision checks. Called after all actor updates to check and resolve any collisions 01015 virtual void ResolveCollisions(); 01016 01017 // NotifyCollision is called by another actor when it collides with this actor 01018 virtual void NotifyCollision(CzActor* other); 01019 01020 // Hit test 01021 virtual CzActor* HitTest(float x, float y); 01022 01023 virtual bool isOutsideFocusRange(float x, float y, float scale = 1.0f); 01024 01025 // Checks to see if another actor is colliding with this actor 01026 bool TestOverlap(CzActor* other); 01027 bool TestOverlapRect(CzActor* other); 01028 01029 // Event handlers 01030 virtual void ProcessEventActions(unsigned int event_name); 01031 virtual void NotifyTapped(int index, int x, int y, bool allow_bubble); 01032 virtual void NotifyBeginTouch(int index, int x, int y, bool allow_bubble); 01033 virtual void NotifyEndTouch(int index, int x, int y, bool allow_bubble); 01034 virtual void NotifyCreate(); 01035 virtual void NotifyDestroy(); 01036 virtual void NotifyOrientationChange(CzScene::eOrientation old_orientation, CzScene::eOrientation new_orientation); 01037 virtual void NotifySizeChange(); 01038 01039 // Implementation of IzXomlResource interface 01040 int LoadFromXoml(IzXomlResource* parent, bool load_children, CzXmlNode* node); 01041 bool PostLoadFromXoml(IzXomlResource* parent, CzXmlNode* node); 01042 01043 // Implementation of IzAnimTarget interface 01044 bool UpdateFromAnimation(CzAnimInstance *animation); 01045 01046 // Utility 01047 void RemoveBody(); 01048 CzVec2 PercPosToPos(float x, float y); 01049 float getDistanceBetween(CzActor* actor); 01050 float getAngleBetween(CzActor* actor); 01051 int FindChildren(CzVector<CzActor*>& children); 01052 void RemoveChildren(); 01053 void BringActorToFront(); 01054 void CalculateSizes(int& width, int& height); ///< Calculate size of actor if parent or screen if size not specified 01055 void CalculateMargins(CzIRect& margin); ///< Calculate size of margin from parent or screen if size not specified 01056 01057 // Coordinate tranoform 01058 CzVec2 TransformPoint(float x, float y); // Transform point by actors local angle / scale transform 01059 CzVec2 TransformPointToScreen(float x, float y); // Transform point by actors local angle / scale transform to screen coordinates 01060 01061 // Internal (used by XOML system to setup and cleanup the XOML class properties system 01062 protected: 01063 static CzXomlClassDef* ActorClassDef; // XOML class definition 01064 public: 01065 static void InitClass(); 01066 static void ReleaseClass(); 01067 static bool _setName(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01068 static CzXomlProperty _getName(IzXomlResource* target); 01069 static bool _setType(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01070 static CzXomlProperty _getType(IzXomlResource* target); 01071 static bool _setTag(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01072 // static CzXomlProperty _getTag(IzXomlResource* target); 01073 static bool _setUserData(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01074 static CzXomlProperty _getUserData(IzXomlResource* target); 01075 static CzXomlProperty _getUserProperties(IzXomlResource* target); 01076 static bool _setPosition(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01077 static CzXomlProperty _getPosition(IzXomlResource* target); 01078 static bool _setPositionX(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01079 static CzXomlProperty _getPositionX(IzXomlResource* target); 01080 static bool _setPositionY(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01081 static CzXomlProperty _getPositionY(IzXomlResource* target); 01082 static bool _setPositionOrg(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01083 static bool _setPositionOrgX(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01084 static bool _setPositionOrgY(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01085 static bool _setDocking(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01086 static CzXomlProperty _getDocking(IzXomlResource* target); 01087 static bool _setMargin(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01088 static CzXomlProperty _getMargin(IzXomlResource* target); 01089 static bool _setDepth(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01090 static CzXomlProperty _getDepth(IzXomlResource* target); 01091 static bool _setOrigin(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01092 static CzXomlProperty _getOrigin(IzXomlResource* target); 01093 static bool _setVelocity(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01094 static CzXomlProperty _getVelocity(IzXomlResource* target); 01095 static bool _setVelocityDamping(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01096 static CzXomlProperty _getVelocityDamping(IzXomlResource* target); 01097 static bool _setAngle(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01098 static CzXomlProperty _getAngle(IzXomlResource* target); 01099 static bool _setAngularVelocity(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01100 static CzXomlProperty _getAngularVelocity(IzXomlResource* target); 01101 static bool _setAngularVelocityDamping(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01102 static CzXomlProperty _getAngularVelocityDamping(IzXomlResource* target); 01103 static bool _setScale(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01104 static CzXomlProperty _getScale(IzXomlResource* target); 01105 static bool _setScaleX(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01106 static CzXomlProperty _getScaleX(IzXomlResource* target); 01107 static bool _setScaleY(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01108 static CzXomlProperty _getScaleY(IzXomlResource* target); 01109 static bool _setColour(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01110 static CzXomlProperty _getColour(IzXomlResource* target); 01111 static bool _setOpacity(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01112 static CzXomlProperty _getOpacity(IzXomlResource* target); 01113 static bool _setLayer(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01114 static CzXomlProperty _getLayer(IzXomlResource* target); 01115 static bool _setOrphan(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01116 static CzXomlProperty _getOrphan(IzXomlResource* target); 01117 static bool _setActive(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01118 static CzXomlProperty _getActive(IzXomlResource* target); 01119 static bool _setVisible(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01120 static CzXomlProperty _getVisible(IzXomlResource* target); 01121 static CzXomlProperty _getScene(IzXomlResource* target); 01122 static bool _setCollidable(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01123 static CzXomlProperty _getCollidable(IzXomlResource* target); 01124 static bool _setTappable(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01125 static CzXomlProperty _getTappable(IzXomlResource* target); 01126 static bool _setDraggable(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01127 static CzXomlProperty _getDraggable(IzXomlResource* target); 01128 static bool _setBubbling(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01129 static CzXomlProperty _getBubbling(IzXomlResource* target); 01130 static CzXomlProperty _getDestroyed(IzXomlResource* target); 01131 static bool _setWrapPosition(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01132 static CzXomlProperty _getWrapPosition(IzXomlResource* target); 01133 static bool _setScreenDocking(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01134 static CzXomlProperty _getScreenDocking(IzXomlResource* target); 01135 static bool _setHoldFocus(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01136 static CzXomlProperty _getHoldFocus(IzXomlResource* target); 01137 static bool _setUseParentOpacity(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01138 static CzXomlProperty _getUseParentOpacity(IzXomlResource* target); 01139 static bool _setPercPos(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01140 static CzXomlProperty _getPercPos(IzXomlResource* target); 01141 static bool _setIgnoreCamera(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01142 static CzXomlProperty _getIgnoreCamera(IzXomlResource* target); 01143 static bool _setTimeline(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01144 static CzXomlProperty _getTimeline(IzXomlResource* target); 01145 static bool _setTimeScale(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01146 static CzXomlProperty _getTimeScale(IzXomlResource* target); 01147 static bool _setBindings(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01148 static CzXomlProperty _getBindings(IzXomlResource* target); 01149 static bool _setBinding(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01150 static CzXomlProperty _getBinding(IzXomlResource* target); 01151 static bool _setLinkedTo(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01152 static CzXomlProperty _getLinkedTo(IzXomlResource* target); 01153 static bool _setTarget(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01154 static CzXomlProperty _getTarget(IzXomlResource* target); 01155 static bool _setGridPos(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01156 static CzXomlProperty _getGridPos(IzXomlResource* target); 01157 static bool _setLinearImpulse(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01158 static bool _setAngularImpulse(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01159 static bool _setForce(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01160 static bool _setTorque(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01161 static bool _setBox2dMaterial(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01162 static CzXomlProperty _getBox2dMaterial(IzXomlResource* target); 01163 static bool _setShape(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01164 static bool _setSensor(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01165 static CzXomlProperty _getSensor(IzXomlResource* target); 01166 static bool _setCollisionFlags(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01167 static CzXomlProperty _getCollisionFlags(IzXomlResource* target); 01168 static bool _setOnTapped(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01169 static bool _setOnTapped2(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01170 static bool _setOnTapped3(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01171 static bool _setOnTapped4(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01172 static bool _setOnTapped5(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01173 static bool _setOnBeginTouch(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01174 static bool _setOnBeginTouch2(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01175 static bool _setOnBeginTouch3(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01176 static bool _setOnBeginTouch4(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01177 static bool _setOnBeginTouch5(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01178 static bool _setOnEndTouch(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01179 static bool _setOnEndTouch2(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01180 static bool _setOnEndTouch3(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01181 static bool _setOnEndTouch4(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01182 static bool _setOnEndTouch5(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01183 static bool _setOnCreate(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01184 static bool _setOnDestroy(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01185 static bool _setOnOrientationChange(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01186 static bool _setOnCollisionStart(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01187 static bool _setOnCollisionEnd(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01188 static bool _setOnTick(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01189 static bool _setBodyAwake(IzXomlResource* target, const CzXomlProperty& prop, bool add); 01190 static CzXomlProperty _getBodyAwake(IzXomlResource* target); 01191 }; 01192 01193 /// @} 01194 01195 01196 01197 01198 #endif // _CZ_ACTOR_H_