This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
en:orx:tutorials:community:grey:firstscene [2010/04/22 13:33 (16 years ago)] – grey | en:orx:tutorials:community:grey:firstscene [2011/01/16 15:30 (15 years ago)] (current) – removed grey | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Static Scene ===== | ||
- | Just to let you guys know, I've shamelessly ripped apart Iarwain' | ||
- | Right, let's to it! | ||
- | |||
- | We'll need a few files, I've copied these out of Iarwain' | ||
- | Drop the ' | ||
- | |||
- | Next we're going to create a new file, and call it ' | ||
- | |||
- | I'm going to describe each chunk of information as I go, and try to give a reason for it so that it (hopefully) makes a little more sense. | ||
- | |||
- | Firstly, we're going to create a ' | ||
- | |||
- | ==== StaticScene.ini ==== | ||
- | <code ini> | ||
- | [Scene] ; | ||
- | ChildList | ||
- | </ | ||
- | |||
- | And here it is... our [Scene] object. When we create new things to put in the scene, we simply add them to this object' | ||
- | Now, as you can see we're going to create a soldier. Lets do that now: | ||
- | |||
- | <code ini> | ||
- | [Soldier] ; | ||
- | ChildList | ||
- | </ | ||
- | |||
- | This is another container object, essentially the same as our [Scene] above, however this one is specifically for our Soldier, we've already added two items to its childlist, which we'll create in a moment, and a position. We want to be able to move the " | ||
- | |||
- | <code ini> | ||
- | [SoldierPivot] ; | ||
- | Pivot = (16.0, 16.0, 0.0) ; Move to centre of image on X axis, bottom of image on Y axis (Soldier' | ||
- | |||
- | [SoldierGraphics@SoldierPivot] ; | ||
- | Graphic | ||
- | |||
- | [StoppedFrame] ; | ||
- | Texture | ||
- | </ | ||
- | |||
- | This is the graphics for our soldier (or at least, the beginnings of them), this defines the default image that we'll see when the soldier is un-animated. | ||
- | The Pivot is also defined so we have a logical point to move our guy around with. In this case, approximately the base of his feet. | ||
- | We use @SomethingElse in the name of our object, to ' | ||
- | |||
- | Thus [SoldierGraphics@SoldierPivot] is the same as saying 'Make [SoldierGraphics] with everything we've added AND everything from [SoldierPivot]. | ||
- | |||
- | <code ini> | ||
- | [SoldierNameTag] ; | ||
- | Graphic | ||
- | Position | ||
- | |||
- | [SoldierName] ; | ||
- | Text = SoldierNameString | ||
- | Color = (255, 255, 255) | ||
- | Pivot = center | ||
- | |||
- | [SoldierNameString] ; | ||
- | String | ||
- | </ | ||
- | |||
- | And this is our name-tag for the soldier. | ||
- | |||
- | Right. Let's add some new code to our project. | ||
- | |||
- | We need to make only one minor change: | ||
- | |||
- | ==== StandAlone.cpp ==== | ||
- | <code c> | ||
- | orxSTATUS orxFASTCALL StandAlone:: | ||
- | { | ||
- | orxViewport_CreateFromConfig( " | ||
- | |||
- | // Our new static scene is loaded from this file: | ||
- | orxConfig_Load( " | ||
- | // And we create the ' | ||
- | orxObject_CreateFromConfig( " | ||
- | |||
- | return orxSTATUS_SUCCESS; | ||
- | } | ||
- | </ | ||
- | |||
- | Simple aye? Let's compile this and see what happens! | ||
- | |||
- | {{http:// | ||
- | |||
- | Not very interesting so far... fine, lets get something happening! | ||
- | |||
- | First, we're going to do the large job of adding our animation frames to our StaticScene.ini file: | ||
- | |||
- | ==== StaticScene.ini ==== | ||
- | <code ini> | ||
- | [SoldierGraphics@SoldierPivot] ; | ||
- | Graphic | ||
- | AnimationSet | ||
- | </ | ||
- | |||
- | First we modify our SoldierGraphics object, giving it access to our animation set. | ||
- | |||
- | <code ini> | ||
- | [AnimSet] ; | ||
- | AnimationList | ||
- | LinkList | ||
- | </ | ||
- | |||
- | This horrifying looking thing is actually very simple. The first item " | ||
- | The second item, is the list of all the ' | ||
- | |||
- | <code ini> | ||
- | [IdleRightLoop] ; | ||
- | Source | ||
- | Destination | ||
- | [IdleRight2Left] ; | ||
- | Source | ||
- | Destination | ||
- | Property | ||
- | [IdleRight2WalkRight] ; | ||
- | Source | ||
- | Destination | ||
- | Property | ||
- | </ | ||
- | |||
- | This is our first set of animation ' | ||
- | |||
- | <code ini> | ||
- | [WalkRightLoop] ; | ||
- | Source | ||
- | Destination | ||
- | [WalkRight2IdleRight] ; | ||
- | Source | ||
- | Destination | ||
- | Property | ||
- | Priority | ||
- | </ | ||
- | |||
- | This is our list of links for our WalkingRight animation. Again, we're allowed to loop (walk forever), or, we're allowed to drop back to the ' | ||
- | |||
- | <code ini> | ||
- | [IdleLeftLoop] ; | ||
- | Source | ||
- | Destination | ||
- | [IdleLeft2Right] ; | ||
- | Source | ||
- | Destination | ||
- | Property | ||
- | [IdleLeft2WalkLeft] ; | ||
- | Source | ||
- | Destination | ||
- | Property | ||
- | |||
- | [WalkLeftLoop] ; | ||
- | Source | ||
- | Destination | ||
- | [WalkLeft2IdleLeft] ; | ||
- | Source | ||
- | Destination | ||
- | Property | ||
- | Priority | ||
- | </ | ||
- | |||
- | Here are the left-facing versions of those same links. While I'm at it, the Priority value; The default value for this is 8. This is used to make the engine automatically step into this link when nothing else is asked for. In this case, what that means is that unless we -specifically- ask the animation to continue playing WalkLeft, it will finish its current playthrough, | ||
- | |||
- | |||
- | The engine now knows what it can and cannot link together, but it doesn' | ||
- | |||
- | <code ini> | ||
- | [IdleRight] ; | ||
- | KeyData1 | ||
- | KeyDuration1 | ||
- | </ | ||
- | |||
- | One whole frame here, delicious. We could put a few here and have the soldier ' | ||
- | |||
- | <code ini> | ||
- | [IdleLeft] ; | ||
- | KeyData1 | ||
- | KeyDuration1 | ||
- | </ | ||
- | |||
- | Left version, bet you didn't guess that! :) | ||
- | |||
- | <code ini> | ||
- | [WalkRight] ; | ||
- | DefaultKeyDuration | ||
- | KeyData1 | ||
- | KeyData2 | ||
- | KeyData3 | ||
- | KeyData4 | ||
- | KeyData5 | ||
- | KeyData6 | ||
- | |||
- | [WalkLeft] ; | ||
- | DefaultKeyDuration | ||
- | KeyData1 | ||
- | KeyData2 | ||
- | KeyData3 | ||
- | KeyData4 | ||
- | KeyData5 | ||
- | KeyData6 | ||
- | </ | ||
- | |||
- | Here's a longer example, with 6 frames ie: our walk-left and walk-right animations! | ||
- | Each ' | ||
- | |||
- | <code ini> | ||
- | [FullGraphic@SoldierPivot] ; | ||
- | Texture | ||
- | TextureSize | ||
- | </ | ||
- | |||
- | This is how we define where we are getting our image data from. We can either use a single image per frame | ||
- | (in which case we'll have lots of these ) or as in our case, one image with lots of frames inside it. | ||
- | |||
- | <code ini> | ||
- | [AnimRight1@FullGraphic] ; | ||
- | TextureCorner | ||
- | |||
- | [AnimRight2@FullGraphic] ; | ||
- | TextureCorner | ||
- | |||
- | [AnimRight3@FullGraphic] ; | ||
- | TextureCorner | ||
- | |||
- | [AnimRight4@FullGraphic] ; | ||
- | TextureCorner | ||
- | |||
- | [AnimRight5@FullGraphic] ; | ||
- | TextureCorner | ||
- | |||
- | [AnimRight6@FullGraphic] ; | ||
- | TextureCorner | ||
- | </ | ||
- | |||
- | Because we're using a single image with lots of frames, we need to define where in that image we get each frame from. TextureCorner is the corner of each frame, combined with our earlier " | ||
- | |||
- | <code ini> | ||
- | [AnimLeft1@AnimRight1] ; | ||
- | Flip = x | ||
- | |||
- | [AnimLeft2@AnimRight2] | ||
- | Flip = x | ||
- | |||
- | [AnimLeft3@AnimRight3] | ||
- | Flip = x | ||
- | |||
- | [AnimLeft4@AnimRight4] | ||
- | Flip = x | ||
- | |||
- | [AnimLeft5@AnimRight5] | ||
- | Flip = x | ||
- | |||
- | [AnimLeft6@AnimRight6] | ||
- | Flip = x | ||
- | </ | ||
- | |||
- | See this... we've just made all our " | ||
- | |||
- | aaaanyway... all that work, now means that we've got lots of walking animations... what next? Oh, yes... we should actually make the code -use- them, so that we don't just get a repeat of our last test run aye? :) | ||
- | |||
- | < | ||
- | Following is -very- work in progress, don't expect it to work yet. Just my thoughts being ' | ||
- | </ | ||
- | |||
- | ==== StaticScene.h ==== | ||
- | <code c> | ||
- | #include " | ||
- | #include < | ||
- | |||
- | class StandAlone | ||
- | { | ||
- | public: | ||
- | static StandAlone* Instance(); | ||
- | |||
- | static orxSTATUS orxFASTCALL Init(); | ||
- | static orxSTATUS orxFASTCALL Run(); | ||
- | static void orxFASTCALL Exit(); | ||
- | |||
- | static orxOBJECT* GetObjectByName( std::string objectName ); | ||
- | static void orxFASTCALL Update( const orxCLOCK_INFO* clockInfo, void* Context ); | ||
- | static orxSTATUS orxFASTCALL EventHandler( const orxEVENT* currentEvent ); | ||
- | </ | ||
- | |||
- | Here we add the definitions of three new functions, GetObjectByName is a helper function so that we can search through the list of objects we have created earlier, and grab specific ones. (This is the function that will be using the string library.) | ||
- | |||
- | The second is function that will be called whenever a orxCLOCK updates. We'll be putting our animation logic in here. | ||
- | |||
- | The third is used to make something happen whenever an event goes off (Animations have 4 events, Start, Stop, Loop and Cut - Cut being a ' | ||
- | |||
- | ==== StaticScene.cpp ==== | ||
- | We're going to add three new functions to our StaticScene class now. | ||
- | |||
- | <code c> | ||
- | orxOBJECT* StandAlone:: | ||
- | { | ||
- | std:: | ||
- | orxOBJECT* TempObject; | ||
- | |||
- | for( TempObject = orxOBJECT( orxStructure_GetFirst( orxSTRUCTURE_ID_OBJECT ) ); | ||
- | TempObject != orxNULL; | ||
- | TempObject = orxOBJECT( orxStructure_GetNext( TempObject ) ) ) | ||
- | { | ||
- | TempName = orxObject_GetName( TempObject ); | ||
- | if( TempName.compare( objectName ) == 0 ) | ||
- | return TempObject; | ||
- | } | ||
- | |||
- | return orxNULL; | ||
- | } | ||
- | </ | ||
- | |||
- | GetObjectByName, | ||
- | |||
- | <code c> | ||
- | void orxFASTCALL StandAlone:: | ||
- | { | ||
- | orxOBJECT* Object = orxOBJECT( context ); | ||
- | if( Object != NULL ) | ||
- | { | ||
- | std:: | ||
- | |||
- | if( ObjectName.compare( " | ||
- | orxObject_SetTargetAnim( Object, " | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | Update is the function that will be called whenever our clock " | ||
- | |||
- | <code c> | ||
- | orxSTATUS orxFASTCALL StandAlone:: | ||
- | { | ||
- | // We could just use a direct cast, but in case we expand this handler later to deal with different event types, | ||
- | // | ||
- | switch( currentEvent-> | ||
- | { | ||
- | case orxEVENT_TYPE_ANIM: | ||
- | { | ||
- | orxANIM_EVENT_PAYLOAD* EventPayload = (orxANIM_EVENT_PAYLOAD*)currentEvent-> | ||
- | |||
- | const orxCHAR* AnimationName = EventPayload-> | ||
- | const orxCHAR* ObjectName = orxObject_GetName( orxOBJECT( currentEvent-> | ||
- | const orxCHAR* EventName; | ||
- | |||
- | switch(currentEvent-> | ||
- | { | ||
- | case orxANIM_EVENT_START: | ||
- | case orxANIM_EVENT_STOP: | ||
- | case orxANIM_EVENT_CUT: | ||
- | case orxANIM_EVENT_LOOP: | ||
- | } | ||
- | |||
- | orxLOG(" | ||
- | break; | ||
- | } | ||
- | } | ||
- | |||
- | return orxSTATUS_SUCCESS; | ||
- | } | ||
- | </ | ||
- | |||
- | This is essentially a rewritten version of Iarwain' | ||
- | |||
- | Next we modify StandAlone:: | ||
- | <code c> | ||
- | orxSTATUS orxFASTCALL StandAlone:: | ||
- | { | ||
- | orxViewport_CreateFromConfig( " | ||
- | |||
- | // Our new static scene is loaded from this file: | ||
- | orxConfig_Load( " | ||
- | // And we create the ' | ||
- | orxObject_CreateFromConfig( " | ||
- | |||
- | // We're creating a clock here, this will be used later to update our animations. | ||
- | orxCLOCK* AnimationClock = orxClock_Create( 0.2f, orxCLOCK_TYPE_USER ); | ||
- | |||
- | // Next we find the ' | ||
- | orxOBJECT* Soldier = GetObjectByName( " | ||
- | |||
- | // if we're sure we found him, we register the clock to the soldier (using the Update function!) | ||
- | // and then set his default animation. | ||
- | if( Soldier != NULL ) | ||
- | { | ||
- | orxClock_Register( AnimationClock, | ||
- | orxObject_SetTargetAnim( Soldier, " | ||
- | } | ||
- | |||
- | return orxSTATUS_SUCCESS; | ||
- | } | ||
- | </ | ||
- | |||
- | Okay, time to compile and test again. I won't screenshot this again this time, but by now your little soldier should be running like a madman. |