Omnimaga: The Coders Of Tomorrow
Welcome, Guest. Please login or register.
 
Omnimaga: The Coders Of Tomorrow
23 May, 2013, 06:34:51 *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   home   news downloads projects tutorials misc forums rules new posts irc about Login Register  
+-OmnomIRC

You must Register, be logged in and have at least 40 posts to use this shout-box! If it still doesn't show up afterward, it might be that OmnomIRC is disabled for your group or under maintenance.

Note: You can also use an IRC client like mIRC, X-Chat or Mibbit to connect to an EFnet server and #omnimaga.

Pages: [1] 2 3 ... 5   Go Down
  Print  
Author Topic: [tutorial] Program Flow - Platformer -  (Read 4735 times) Bookmark and Share
0 Members and 1 Guest are viewing this topic.
Eeems
THE GAME
Administrator
LV13 Extreme Addict (Next: 9001)
*
Offline Offline

Gender: Male
Last Login: Today at 04:48:40
Date Registered: 14 March, 2009, 03:32:57
Location: Edmonton, Alberta
Posts: 5075


Topic starter
Total Post Ratings: +230

View Profile WWW
« on: 20 March, 2010, 08:29:56 »
+8

Code is outdated, but the ideas behind it is not
Index
Preface
Program flow can sometimes be one of the toughest challenges when programming. In Axe it can still be a problem, especially with the buffers.
This is a short guide on how to setup your program so that it is easy to handle and relativly quick.
*Note - this is for AXE programs only, but you can take some of what you learn and apply it to xLib/Celtic III programs.
Structure
the basic structure I find  Is sometimes the hardest to come up with, but a good one for platformer games is as follows:
Initialize sprites and variables
store 'map' or screen to back buffer
repeat getkey(15) and (other checks
all drawing things here, like animations
draw sprites that are constant
dispGraph
recallpic
X axis collision check
X axis movement code
Y axis collision check
Jump check
gravity/jump action
End
return
routines
I will go more in depth tomorrow on each section.
Initialize sprites and variables
Sprites and variables are a no brainer. Everybody will have to initialize them at some time, so why not do it right at the start? The easiest way to do it is to store all the character sprites to one location, and all the enemy sprites to another, and then all the other sprites to yet, another.
[sprite data->Pic1
[sprite data->Pic2
[sprite data->Pic3
This is the usual setup for sprites, and it works quite well. Pic1 will store all the standard sprite data for the character and can be called by:
A*8+Pic1
where A is the sprite you want to call starting at 0.
You can also just change the sprite calling to exact numbers, so:
Pic1         sprite 0
Pic1+8       sprite 1
Pic1+16      sprite 2
Pic1+24      sprite 3
    ...etc...

You will then want to initialize the other variables. So there are "real" variables and then pointers. "Real" variables will be easy you just store the value to it.
0->X
0->Y
10->Z
Storing to pointers is kind of hard compared to that. You can store it in a few different ways. You can just do the standard:
10->{L1
Then there is the harder to use:
[data->GDB1
conj(GDB1,L1,size)
This is a lot harder to use due to how it is stored.
Store 'map' or screen to back buffer
This can be kind of hard, you can either draw it manually or you can just use a map type engine to draw using sprites.

Map data format:

The data uses run length encoding for compression.  Lets say we had a simple map:
11111000001111
00000222220000
Pretty simple, each number representing a different tile.  With normal storage this would take a single byte per tile.  Or we could represent the data in a different way:
150514052504
Seems much smaller, but what does it mean?  lets insert some imaginary commas and dashes to make it easier:
1-5,0-5,1-4,0-5,2-5,0-4
Now you may or may not be able to see how the data is represented.  The first segment is 1-5, or 5 '1's in a row, followed by 0-5, or five '0's in a row, and so on.  This is how the data in run length encoding is represented.  And to further the compression (or confusion), each #-# segment is packed into a single byte. Instead of two hex digits to represent a number from 0-255, we will have 2 hex digits, each from 0-15, representing the two numbers of each #-# element.
The first Hex digit 0 to 15 is the tile number.  The second hex digit is the number of tiles to add to the tilemap.  The digit goes from 0-15, but 0 doesnt make much sense, since that would mean this element doesnt do anything , so we will add one to this after we decompress it so that it has a range of 1 to 16.  
There is a small disadvantage that if you have empty spaces of 17 or more in a row, it will take more than 1 byte to represent in the code.

Decompressing the Map:

[Data]->GDB1 //map data to GDB1
[tileData]->Pic1 //tile data for tilemap

0->N //element index for map data
0->I //map index for storing tile data

While I>=96 //until we have stored all tiles
{GBD+N}->A //Take the first element of the map data
N+1->N //Increment the map index
A^16->B //spit the map element into it
A/16->A two separate elements

For(F,0,B //fill the map from current position I to I+B
A->{L1+I} //could be optimized with Fill but i couldn't get it 
I+1->I //working :/
End

End //End while
After this code is run, the tile data will be decompressed into L1, as follows
0  1  2  3  4  5  6  7  8  9  10 11 12 13...
ect, it will be in a straigt line, but you will have to access it using your own routine.  Something like this
{Y*W+X+L1}
where W is the width in tiles of your map.  X and Y would be the tile coordinates starting at the top left at 0,0.

Displaying the map:

here is a rudimentary program that should be run right after the previous decompressing program:
For(X,0,11 //loop through the entire screen coordinates with tiles of 8x8
For(Y,0,7
{Y*12+X+L1}->A //retrieve the correct tile from the data in L1
Pt-On(X*8,Y*8,A*8+Pic1 //draw the sprite to the screen
End
End
Also attached is a PEDIT program to create and compress maps into a Hex String into Str1, as well as an Axe program to decompress and display them.  Just put the string data into GDB1
Repeat getkey(15) and (other checks
This is the core of the program, the <body> tag if you will. All your checks to see if the game has ended go here in this format:
getkey(15) and (check 0 and (check 1 and (check 2
The easiest way is to make a variable your game end flag, I usually use F, and do all your checks in the loop.
Animations/Sprites
All animation code should be put before the screen is updated as well as all the sprite code. The most basic one would be to just display the enemy and the character.
pt-change(X,Y,Pic1
pt-change({L1},{L1+1},Pic2
Updating the Screen
Next You want to update the screen and then prepare if for collision detection.
DispGraph
RecallPic
If you store the map to the back-buffer then you will want to recall it so that you can use pixel-based collision detection.
Collision Check
The easiest way to do collision check in a pixel-based way is to check one pixel off of the side:
0->Z
0->V
0->S
0->T
For(A,0,7
Z+pxl-test(X-1+A,Y)->Z
V+pxl-test(X+8+A,Y)->V
S+pxl-test(X,Y-1+A)->S
T+pxl-test(X,Y+8+A)->T
End
Z will return the amount of pixels on on the left of the character, V returns on the right, S above, and T below. the way to return  where the pixels are would be:
0->Z
0->V
0->S
0->T
For(A,0,7
Z+(8-A*(pxl-test(X-1+A,Y)))->Z
V+(8-A*(pxl-test(X+8+A,Y)))->V
S+(8-A*(pxl-test(X,Y-1+A)))->S
T+(8-A*(pxl-test(X,Y+8+A)))->T
End
This will return 1 if the first pixel tested is on, 2 if the second, 3 if the third, etc. This can be good for detecting slopes.
Gravity and Jumping
Now there are many different way's to do gravity, but the easiest way is to apply a constant force in one direction.
Y+(!collision)->Y
your character will fall until you a collision is detected, creating the effect of gravity. Jumping is harder, you have to have a jump variable which changes as your jump progresses.
!If J
10*(getkey(4) and (collision))-J
Else
J-1->J
End
Y+(2*(!collision and (J)))->Y
If the ground beneath you is solid, and J is 0 and you are pressing the up key then 10 will be stored to J. If  J !=0 then it will decrement. If J !=0 then your character will move up two pixels.  two pixels compensates for the gravity so in reality you move down one pixel and up two, which balaces out to 1 pixel up.
End/Return and Routines
The last part of your code will include and End statement to end the loop and then whatever closing code you want. then you will place all your routines due to the fact that it is the logical place to place them :)
Conclusion
In this tutorial I have taught you how to set up your program flow easily for platformer games in AXE. So remember anything involving animation or sprites should go before the dispGraph command and everything involving movement should be after it.


* codebox.png (29.24 KB, 640x400 - viewed 965 times.)
« Last Edit: 21 November, 2012, 22:11:08 by Eeems » Logged

DJ Omnimaga
Retired Omnimaga founder (Site issues must be PM'ed to Netham45, Eeems, Shmibs, Deep Thought and AngelFish, not me.)
Editor
LV15 Omnimagician (Next: --)
*
Online Online

Gender: Male
Last Login: Today at 06:13:26
Date Registered: 25 August, 2008, 07:00:21
Location: Québec (Canada)
Posts: 50226


Total Post Ratings: +2615

View Profile WWW
« Reply #1 on: 20 March, 2010, 08:34:49 »
0

mhmm that might be useful, because sometimes I have no clue about the best order for my code x.x

Btw can we post here?

And 6000th post for me on the new forums Tongue
« Last Edit: 20 March, 2010, 09:04:31 by DJ Omnimaga » Logged

Retired 83+ coder, Omnimaga/TIMGUL founder. Now doing power metal music (formerly did electronica)

Follow me on Bandcamp|Facebook|Reverbnation|Youtube|Twitter|Myspace
trevmeister66
LV9 Veteran (Next: 1337)
*********
Offline Offline

Last Login: 12 January, 2011, 01:00:06
Date Registered: 30 October, 2008, 08:31:38
Posts: 1067

Total Post Ratings: +9

View Profile
« Reply #2 on: 20 March, 2010, 09:00:53 »
0

Very nice start and layout. I'm looking forward to reading more.
Logged

Projects:    nameless RPG: 1.0%  |  Reverse Snake v1.5: 100%  |  Secret Project: 5%  |  DUNGEON: 70%

My MW2 Blog <-- Please visit Smiley
Eeems
THE GAME
Administrator
LV13 Extreme Addict (Next: 9001)
*
Offline Offline

Gender: Male
Last Login: Today at 04:48:40
Date Registered: 14 March, 2009, 03:32:57
Location: Edmonton, Alberta
Posts: 5075


Topic starter
Total Post Ratings: +230

View Profile WWW
« Reply #3 on: 20 March, 2010, 09:07:07 »
0

Thanks! Don't worry, any new additions I'll add to the first post.
Logged

ztrumpet
The Rarely Active One
LV13 Extreme Addict (Next: 9001)
*************
Offline Offline

Gender: Male
Last Login: Yesterday at 03:10:30
Date Registered: 08 November, 2009, 21:10:12
Location: Michigan
Posts: 5687


Total Post Ratings: +360

View Profile
« Reply #4 on: 20 March, 2010, 20:39:22 »
0

That looks great Eeems!  That's the general layout I use too. Grin

Congratz DJ! Afro
Logged

Eeems
THE GAME
Administrator
LV13 Extreme Addict (Next: 9001)
*
Offline Offline

Gender: Male
Last Login: Today at 04:48:40
Date Registered: 14 March, 2009, 03:32:57
Location: Edmonton, Alberta
Posts: 5075


Topic starter
Total Post Ratings: +230

View Profile WWW
« Reply #5 on: 20 March, 2010, 21:46:35 »
0

updated the look I'll post more later today.
also thanks ztrumpet Smiley
EDIT: added new section
« Last Edit: 20 March, 2010, 22:22:21 by Eeems » Logged

Will_W
LV3 Member (Next: 100)
***
Offline Offline

Gender: Male
Last Login: 06 April, 2011, 19:14:41
Date Registered: 18 March, 2010, 05:42:28
Location: Not sure, I was hoping you knew.
Posts: 54


Total Post Ratings: 0

View Profile
« Reply #6 on: 20 March, 2010, 22:37:46 »
0

It's often helpful to make a flowchart.  I use Dia for that.

The core of my BASIC parser by the way.
Logged

ex de,hl
ld (hl),e
inc hl
ld (hl),d
ld a,(hl)
Eeems
THE GAME
Administrator
LV13 Extreme Addict (Next: 9001)
*
Offline Offline

Gender: Male
Last Login: Today at 04:48:40
Date Registered: 14 March, 2009, 03:32:57
Location: Edmonton, Alberta
Posts: 5075


Topic starter
Total Post Ratings: +230

View Profile WWW
« Reply #7 on: 20 March, 2010, 22:39:16 »
0

True, but this is a good way for people to get started. Also, I have added another section.
Logged

Quigibo
The Executioner
LV11 Super Veteran (Next: 3000)
***********
Offline Offline

Gender: Male
Last Login: 21 May, 2013, 02:03:21
Date Registered: 22 January, 2010, 05:02:37
Location: Los Angeles
Posts: 2022


Total Post Ratings: +1019

View Profile
« Reply #8 on: 20 March, 2010, 22:50:40 »
+1

You should get used to having the number come before the sprite.

Instead of doing:
Pic1+(A*8

Do this:
A*8+Pic1

It saves 2 bytes in the compiled code since you don't need the parenthesis.  Same thing with lists.  You can even extend it to 3 dimensions.  Say you need to reference an 8x8x8 grid:

Instead of doing this:
L1+(X*64)+(Y*8 )+Z

You can do this:
X*8+Y*8+Z+L1

Notice the multiplication distributes which even further reduces the code since powers of 2 are more optimized when they're smaller.


EDIT:  By the way, the routine for copying memory from one place to another is conj(source,destination,bytes to copy)  So your example would be conj(GDB1,L1,#)
« Last Edit: 20 March, 2010, 22:55:01 by Quigibo » Logged

___Axe_Parser___
Today the calculator, tomorrow the world!
Eeems
THE GAME
Administrator
LV13 Extreme Addict (Next: 9001)
*
Offline Offline

Gender: Male
Last Login: Today at 04:48:40
Date Registered: 14 March, 2009, 03:32:57
Location: Edmonton, Alberta
Posts: 5075


Topic starter
Total Post Ratings: +230

View Profile WWW
« Reply #9 on: 20 March, 2010, 22:51:56 »
0

Thanks I'll fix that Smiley
Logged

jsj795
LV9 Veteran (Next: 1337)
*********
Offline Offline

Gender: Male
Last Login: 26 April, 2013, 03:43:03
Date Registered: 28 July, 2009, 22:10:35
Location: __̴ı̴̴̡̡̡ ̡͌l̡̡̡ ̡͌l̡*̡̡ ̴̡ı̴̴̡ ̡̡͡|̲̲̲͡͡͡ ̲▫̲͡ ̲̲̲͡͡π̲̲͡͡ ̲̲͡▫̲̲͡͡ ̲|̡̡̡ ̡ ̴̡ı̴̡̡ ̡͌l̡̡̡̡.___
Posts: 1087


Total Post Ratings: +81

View Profile
« Reply #10 on: 20 March, 2010, 22:54:18 »
0

-post deleted due to quigobo's edit-
« Last Edit: 20 March, 2010, 23:04:20 by jsj795 » Logged



Spoiler for funny life mathematics:
1. ROMANCE MATHEMATICS
Smart man + smart woman = romance
Smart man + dumb woman = affair
Dumb man + smart woman = marriage
Dumb man + dumb woman = pregnancy
2. OFFICE ARITHMETIC
Smart boss + smart employee = profit
Smart boss + dumb employee = production
Dumb boss + smart employee = promotion
Dumb boss + dumb employee = overtime
3. SHOPPING MATH
A man will pay $2 for a $1 item he needs.
A woman will pay $1 for a $2 item that she doesn't need.
4. GENERAL EQUATIONS & STATISTICS
A woman worries about the future until she gets a husband.
A man never worries about the future until he gets a wife.
A successful man is one who makes more money than his wife can spend.
A successful woman is one who can find such a man.
5. HAPPINESS
To be happy with a man, you must understand him a lot and love him a little.
To be happy with a woman, you must love her a lot and not try to understand her at all.
6. LONGEVITY
Married men live longer than single men do, but married men are a lot more willing to die.
7. PROPENSITY TO CHANGE
A woman marries a man expecting he will change, but he doesn't.
A man marries a woman expecting that she won't change, and she does.
8. DISCUSSION TECHNIQUE
A woman has the last word in any argument.
Anything a man says after that is the beginning of a new argument.

Girls = Time * Money (Girls are a combination of time and money)
Time = Money (Time is money)
Girls = Money squared (So, girls are money squared)
Money = sqrt(Evil) (Money is also the root of all evil)
Girls = sqrt(Evil) squared (So, girls are the root of all evil squared)
Girls = Evil (Thus, girls are evil)
*Girls=Evil credit goes to Compynerd255*
Eeems
THE GAME
Administrator
LV13 Extreme Addict (Next: 9001)
*
Offline Offline

Gender: Male
Last Login: Today at 04:48:40
Date Registered: 14 March, 2009, 03:32:57
Location: Edmonton, Alberta
Posts: 5075


Topic starter
Total Post Ratings: +230

View Profile WWW
« Reply #11 on: 21 March, 2010, 00:02:33 »
0

oh right Smiley thanks Quigobo.
also, adding a few more sections
Logged

Gale
LV4 Regular (Next: 200)
****
Offline Offline

Gender: Male
Last Login: 03 December, 2010, 15:17:04
Date Registered: 13 March, 2010, 17:52:12
Location: USA
Posts: 117


Total Post Ratings: +1

View Profile
« Reply #12 on: 21 March, 2010, 00:45:14 »
0

that was great!!! exactly what i needed to know for making a platformer under axe!!! i gave you a +1 thumbs up P:, but i wish i could give more!
Logged

remember me as a time of day...
Eeems
THE GAME
Administrator
LV13 Extreme Addict (Next: 9001)
*
Offline Offline

Gender: Male
Last Login: Today at 04:48:40
Date Registered: 14 March, 2009, 03:32:57
Location: Edmonton, Alberta
Posts: 5075


Topic starter
Total Post Ratings: +230

View Profile WWW
« Reply #13 on: 21 March, 2010, 00:51:00 »
0

Thanks Smiley I still have two more sections to add, but they are inconsequential Smiley hope it helps a lot Smiley I actually am using this on a project I'm working one, which is what gave me idea to write it.

EDIT: added some cooler styling Tongue
« Last Edit: 21 March, 2010, 01:03:34 by Eeems » Logged

Gale
LV4 Regular (Next: 200)
****
Offline Offline

Gender: Male
Last Login: 03 December, 2010, 15:17:04
Date Registered: 13 March, 2010, 17:52:12
Location: USA
Posts: 117


Total Post Ratings: +1

View Profile
« Reply #14 on: 21 March, 2010, 01:05:23 »
0

i have a question. for the gravity and jumping section, what would you put in (collision)? sorry, i'm kinda new to platformers
Logged

remember me as a time of day...
Pages: [1] 2 3 ... 5   Go Up
  Print  
 
Jump to:  

Powered by EzPortal
Powered by MySQL Powered by SMF 1.1.18 | SMF © 2013, Simple Machines Powered by PHP
Page created in 0.236 seconds with 30 queries.
Skin by DJ Omnimaga edited from SMF default theme with the help of tr1p1ea.
All programs, games and songs avaliable on this website are property of their respective owners.
Best viewed in Opera, Firefox, Chrome and Safari with a resolution of 1024x768 or above.