V2 8-Way Movement by Omni 2.0.1
Displaying 1-2 of 2 total.
1
Please enter a numerical value for the importance of this sticky.
Enter 0 to unsticky.
Omni

Supports caterpillar following, entity autoface, chance, and adjacent activation, and supports chance, delays, and adjacent activation for zones. Party following has a rare error where the fourth person will wander from the rest of the group. If anyone can pinpoint what causes this (and looking at the code, it's not easy), let me know.

This system can load configurations for the movement system, and load framelists for entities. You can check SaveMoveSystem() to get an idea of what to put in mcfg.cfg, and by checking LoadFrames() you can get an idea of what to put in pframes.cfg, but basically, for all eight directions, the frames are

standing frames
starting frames
wait delay in ticks between frames
number of frames in each cycle.

I am working on a compressed version that does not depend on all my splitered code libraries, where you just include one file in your own code and that's it. I am also working on a standard party following system, for those who want party following but don't want to have a custom movement engine to do it.

Get it here at http://www.vergesource.com/files/seek/tilmv201.zip



It is not wrong to not understand, for we are all ignorant, but neither is understanding pointless.

Posted on 2002-04-14 08:02:44

Omni

8-way Tile Movement System by Omni


Contents


Introduction
The Demo
Breakdown
Bugs
The Movement System
Breakdown
Integrating with your game
Functions
Variables
Bugs
The Following System
Breakdown
Functions
Bugs
Closing Comments


------
Introduction
------


I originally built this for two reasons. One, because I wanted a new movement system for the game I was making. Verge's built in system is fine, but I wanted more. So I first tried Hatchet's pixel movement system. Good pixel movement, but it didn't know how I wanted to manage my own events, zones, and entity frames. All of it was hardcoded; you had to adapt your maps to the pixel movement code. I didn't want that. I wanted pixel movement code that could adapt to my maps.
So, I started work on my own pixel movement system. I got pretty far, having custom animations and the actual movement part itself working perfectly, but I had a huge problem with obstructions and entity obstructions: they were tile based, not pixel-based, and I never got obstructions to work. I still don't see how Hatchet did, either.
At this point, I kinda despaired. Verge used tile-based maps, entities, and obstructions, so my creating my own pixel movement code was pretty much out of the question. Then, I saw Vecna commenting on V3's new movement system on the boards at Vergesource.com. He said that although pixel movement is cool, tile movement is much easier to code and much cleaner. Eventually, we learned V3 would use pixel movement, but not before I had my grand idea:
Build a tile-based movement system and entity following code for V2. I wasn't exactly waiting for V3 anymore; I was waiting for a chance to get work done on my game. And that meant a movement system. So, several releases later ("You update too much," :)) I came out with version 2.0.1.


------
The Demo
------


------Breakdown


The demo part was easy to make. There are two zones, and one entity. Talking to the entity will display a brief (though ugly) textbox, and add one follower to your chain. If your chain is maxed out at four followers, then no more will be added by talking to them. This demo does not demonstrate RemoveFollower(), so you will be stuck with those four followers throughout it; though that's not such a bad thing.
The zones, one layed on the upper edge of the map which says "Ha Ha! You can't leave!" (a joke among my friends, after seeing the first version of Winv2 where you could just walk off the map), and the second one along the water, which says "Looks deep." (Splish-splash, it's a tree. (More in-jokes))


-------Bugs


None at this time. Maybe a few more events if I'm feeling active, but uh...no more updates here.


------
The Movement System
------


------Breakdown


Well, you see, this is the part that moves you. No, really. It is made up of a few simple parts. (Press "S" on the keyboard to enter setup mode.) The code is a while loop that has the following commands chained together.

(HookTimered version)
updatecontrols()------------checks to see if you pressed a key.
runadjzones()---------------if you are adjacent to a zone with adjacent activation, runs it.
runzones()------------------runs the zone you are currently standing on.
runadjevents()--------------runs events next to you with adjacent activation.
runevents()-----------------runs an event when you press the event key (Enter).
showentities()--------------shows the players and chain followers' current frames.
refreshscreen()-------------Renders map, Processes Entities, Shows page.

(Looped version)
updatecontrols()------------checks to see if you pressed a key.(is HookTimered in HookTimered version)
checkbuttons()--------------checks to see if you pressed a function key, such as run or setup.
moveplayer()----------------changes the direction of and moves the player and followers by checking what key you pressed.(is HookTimered in HookTimered version)
showentities()--------------shows the players and chain followers' current frames.
refreshscreen()-------------Renders map, Processes Entities, Shows page.
runadjzones()---------------if you are adjacent to a zone with adjacent activation, runs it.
runzones()------------------runs the zone you are currently standing on.
runadjevents()--------------runs events next to you with adjacent activation.
runevents()-----------------runs an event when you press the event key (Enter).
stop()----------------------halts the system for a number of ticks, to slow down the loop if it is moving too fast.

There are two versions, a hooked one and a looped one. They are both called with FreeMoveSystem(2,3,"chrono.chr"), whose arguments are the same as entityspawn(). FreeMoveSystem() checks two variables, FMPison and HFMPison, to see which system to run. If HFMPison=1, then the hooked version is on. If FMPison=1, then the looped version is run. I don't know what happens if they are both on. Also, by disabling FMPison or HFMPison, you stop the movement version you are running, so remember that if you have to get out of it.
In the Hooked version, Checkbuttons() and MovePlayer() are Hooked. Also, the Counter and Framecounter of ShowEntities is hooked. Counter and FrameCounter control how many ticks until the next frame, and which frame to display next, respectively, and are made more consistent by Hooktimering them in the Hooked version.


------Integrating with your game


To do this, include the files move.vc, define.vc, saveload.vc, config.vc, and hook.vc in your program. Set the setting you want in config.vc, whether FMPison or HFMPison, then #include them in your system.vc (with saveload.vc included first.) Also, to have Setup work, you must have a global variable MyCustomFont set to the default verge font that comes with the utilities packet of Verge 2(included with this tutorial as custom.fnt).
Once this is done, replace any SetPlayer calls with FreeMoveSystem(int x, int y, string chrfile), and you're done. Also, make sure you fix the HookRetrace and HookTimered lists in Hook.vc, then call them on the autoexec event of a map with RunHook. You can add a limitless amount of functions to be Timered and Retraced to the functions tober() and tobert(), which are then HookTimered and HookRetraced. Just make sure to hook them.


------Functions


--void MoveEntities()--

Sets the directions for the player depending on which key you passed, then passes directions down the chain of followers, and moves them all according to them.

--void Checkbuttons()--

Checks to see if you are pressing buttons known to the engine. In particular, the setup toggle button (Default: S) and the run button (default: B3).

--void FreeMoveSystem(int x, int y, string chr)--

Sets a free movement system up with the string CHR at tile location X,Y.

--void FreeMovePerpetual()--

Runs the looped free movement system. Is called by FreeMoveSystem, though you could just entityspawn and set its value to entityID[1] and then run FreeMovePerpetual().

--void FreeMoveHook()--

Runs the HookTimered movement system. Uses same conditions to run as FreeMovePerpetual() (read above).

--void takecontrol()--

Takes control from the movement engine and gives it to the VC interpreter during the execution of an event.

--void Givecontrol()--

Gives control back to the movement engine.

--void controlmovecall()--

Takes control from the interpreter for events, gives control back to the movement system, and runs events (not in that order.)

--void checkanim()--

The initialization functions for FreeMoveHook and Perpetual(), it loads the configuration and entity animation files and sets starting directions.

--void setfollowerdirections()--

Sends directions down the chain of followers based on the direction last taken by the previous follower.

--void standstill()--

Stops moving followers. Used when main player is obstructed.

--void movefollowers()--

Called by MovePlayer(). Moves all chained followers (if active) in the path specified by their direction.

--void CallStandingFrames(int ID)--

Calls the standing frame of the follower ID passed, whether the constant entityone, entitytwo, entitythree, or entityfour.

--void RefreshScreen()--

Processes entities, renders the map, shows the page. If setup toggle is on, draws the setup window.

--void Showplayer(), Showplayer2(), Showplayer3(), ShowPlayer4()--

Calls the code that displays the current animation for the chain follower.

--void showentities()--

Updates all follower animations at once by called all the ShowPlayer() functions.

--void runzones()--

Checks to see if the player is standing on a zone, and if so, runs the zone event.

--void runadjzones()--

Checks to see if the player is facing adjacent to a zone, and if so, runs it.

--void checkzone()--

Checks the entities facing direction and returns a value based on whether or not he is facing adjacent to a zone.

--void runevents()--

Runs the specified event if the event key (default: Enter) is pressed.

--void runadjevents()--

Runs the specified event if player is facing it and the entity's adjacent activation tag is on.

--void standingframe()--

Used in event code to make an entity face the player when called if so desired, based on the player's current facing direction.

--void checkentity()--

Used to check if an entity is on and returns a value based on whether or not the player is facing it.

--void checkentityob()--

Based on the direction of travel by the player, returns a value determining whether or not the player is obstructed by an entity.

--void LoadFrames(int ID, string filename)--

Loads the animation data for the follower ID from the file filename.

--void SaveMoveSystem(string filename)--

Saves Movement System configuration data in the passed filename.

--void LoadMoveSystem(string filename)--

Loads Movement System configuration data from the passed filename.

--void ClearFrameStats(int ID)--

Clears all frame information of the passed follower. Use when removing a follower.


------Variables


Defines----------------------

DUP 1
DDOWN 2
DLEFT 3
DRIGHT 4
DUR 5
DDL 6
DLU 7
DRD 8
----Defines used to keep track of the directions in an easy to remember format.

startframe 1
standframe 2
waitframe 3
framenum 4
----Defines to keep track of what frame animation is being loaded to arrays, instead of using the number.

entityone 1
entitytwo 2
entitythree 3
entityfour 4
----Defines to keep track of the followers' IDs. The player is always entityID 1+number of entities on map, and entityone always equals 1, although it does not need to be changed, since it points to the entity's ID instead of specifying it, and the followers are always added to the last player/follower spawned. You could expand the number of followers by adding an "Entityfive 5" and then his appropriate animation file and direction branch sequence.

runkey b3
----The default key to toggle running (ESC)

eventkey b1
----The default key to toggle events (Enter)

setupkey KEY_S
----The default key to toggle setup (Scancode 31, provided by the define.vc file)

MAXENTITIES 100
----The default number of maximum entities to check for on each map. Set as you want.

Variables------------------------------

entity1.standframe[9]
entity1.waitframe[9]
entity1.framenum[9]
entity1.startframe[9]

Controls the player standing frame, starting animation frame, delay in ticks between frames, and number of frames in each cycle, according to the direction (ex. DUP) passed. Index 0 is not used. Followers 2-4 also have their own branch of these.

personactive[5]

Sets whether or not a follower is active based on the entity passed, ex. entityone. Index 0 is not used.

entityID[5]

Used to store the ID of the current follower entityspawned.

entitydirection[5]

Keeps track of directions, in defined code ex. DUP, for the entity passed.

entityfacing

Keeps track of the facing direction of the main player, separate from his walking direction.

pastdirection[5]

The last direction moved by the passed entity; passed down the branch as the next follower's current direction.

entitymoving[5]

Is the entity moving?

wasmoving[5]

Checks the last value of entitymoving passed to it. Good determining if the character has started moving in the map yet.

entitycounter

Used by the entity-checking commands to check all entities onscreen.

numpartyentities

Number of entities current forming the follower chain, including the player.

zonedelaycounter

Ticks off the number of milliseconds before a zone is activated.

counter[5], framecounter[5], animation[5]

Checks to see, respectively, the number of milliseconds before each next frame for the entity, the next frame to be displayed in the cycle by the entity, and if the entity animation has just begun or already started.

walkingspeed, runningspeed, movingspeed

Depending on which button you press (run or not), the value of the variables walkingspeed and runningspeed (in pixels) are passed to movingspeed for MovePlayer();

zonechance[128]

Sets the chance for the zone to occur, just pass the zone number to the array (zone 128 and zone 0 are not used).

zoneadj[128]

Sets whether or not the zone can be activated by adjacently facing it.

zonedelay[128]

The number of milliseconds(will change to steps soon) walking into a zone before it is activated.

entityadj[MAXENTITIES]

Sets if the given entity(passed to the array by entity ID) can be activated.

entitychance[MAXENTITIES]

Chance if the entity can be activated, from 0 (always) to whatever.

pixelcounter

Specifies number of pixels to move before waiting for the next move command. Stops at 16, the tile size for map tiles.

moveloop

Specifies whether or not the player is still moving to the next tile.

zone

Keeps track of the zone ID player is currently standing on.

pastzone

Keeps track of the last zone ID player stood on.

adjzone

Used to keep track of the zone ID adjacent to the player.

timerticker

Used by the Looped FreeMovePerpetual to delay the loop for a number of ticks.

setuptoggle

Sets whether or not setup is called.

AnimationSpeed

Sets delay between frames, along with entityX.waitframe[X].

HTAnimationSpeed

Same, but for HookTimered loop. Is lower than AnimationSpeed because HookTimer increases in ticks every centisecond instead of every loop called.

busy, called;

Sets, respectively, if the VC interpreter has control, and if an adjacent entity has been called.

string movefilename

Can be used to store the name of the configuration filename for Load and SaveMoveSystem.


------Bugs

None as far as I know.

------
Following System
------

------Breakdown

This sucker checks to see if an entity is on, then if so, checks what direction it has based on the last direction moved by the follower before it, then moves the entity and shows its animations.


------Functions

--int SetFollower(int ID, string chr, string filename)--

Sets the specified follower as the entity chr, loading animation data from FileName. Returns 1 if successful.

--int AddNewFollower(string chr, string filename)--

Checks the next available follower ID and assigns it the character chr and animation data from filename. If there is no more open slot, returns 0.

--int RemoveFollower(int ID)--

Removes the specified follower, ex. entitytwo, from the chain, and moves all followers up one index. Returns 1 if successful.

--void RemoveAllFollowers()--

Just what it says.

--int MakeEntityFollower(string character, string filename)--

Removes the entity that called an event last, and gives him to you with the chr file Character and the animation data filename. Returns 1 if successful.

--int ReturnEmptySpace()--

Returns the next empty ID in the follower chain. Returns 0 if none.


------Bugs

1. As of this readme, MakeEntityFollower() does not load animation data, you must do that yourself.

2. As of this readme, I believe there is a bug in SetFollower that causes past entities to be displayed. Maybe not.

3. There is a bug where sometimes, when creating the four entity, it will be placed one tile away from the rest of the chain, and travel separately from it. I should be able to fix this, but I'm not sure what causes it. If the entity appears correctly though, there's no way he'll walk away from the party or anything.


------
Closing Comments
------

I am working on two more things. One is a simple version of this system that is independent from all my branching code libraries, so you can just #include one file and have the Movement system available.
The second thing is a following system that uses Verge's hardcoded entity movement, rather than my hackish substitute, so if you don't like hackish running, and diagonal movement, then this would work for you.

No updates for a while though, as I've got a bit of schoolwork to catch up on...


Last Updated by Omni 6:40 PM 4/14/2002



It is not wrong to not understand, for we are all ignorant, but neither is understanding pointless.

Posted on 2002-04-14 17:36:33


Displaying 1-2 of 2 total.
1
 
Newest messages

Ben McGraw's lovingly crafted this website from scratch for years.
It's a lot prettier this go around because of Jon Wofford.
Verge-rpg.com is a member of the lunarnet irc network, and would like to take this opportunity to remind you that regardless how babies taste, it is wrong to eat them.