Jump to content

Photo

Making platformers in XB


9 replies to this topic

#1 Retrospect OFFLINE  

Retrospect

    Dragonstomper

  • 866 posts
  • Location:Wakefield, England

Posted Fri Apr 21, 2017 8:56 AM

Hi everyone.  I'm wanting to make a third game in the "Eric" series, there's Castle Conquer, Eric in Monsterland (soon) and after that, "Eric goes to Egypt" ... now, I want Eric to be able to jump up to another platform instead of him being always fastened to the floor except when he jumps.

 

Let's assume, Eric's pixel position is set to 135 .. so Variable MX = 135 

 

There's a platform for him to jump onto - it's set at say position 112 (character position 14 for the tiles) ... how would I work it so that it checks whether there's anything for him to jump onto, during the jump routine?

 

My jump routines are fairly simple, they are literally

 

MA= eric's character

LEV = whatever screen he's on

 

 

10 LEV=1 

 

IF player jumps then goto 4100 

 

2110 CALL SPRITE(#1,MA,16,MX,MY,#2 whatever monsters are here ) :: RETURN

2120 stuff for screen 2

2130 stuff for screen 3

 

4100 MA=64::FOR L=1 TO 3 :: MX=MX-4 :: MY=MY+3 :: GOSUB 8000 :: NEXT L 

4110 FOR L=1 TO 2 :: MX=MX-3 :: MY=MY+3 :: GOSUB 8000 :: NEXT L

4120 FOR L=1 TO 2 :: MX=MX-2 :: MY=MY+1 :: GOSUB 8000 :: NEXT L::MA=68

4130 FOR L=1 TO 2 :: MX=MX+2 :: MY=MY+1 :: GOSUB 8000 :: NEXT L

4140 FOR L=1 TO 2 :: MX=MX+3:: MY=MY+3 :: GOSUB 8000 :: NEXT L

4150 FOR L=1 TO 3 :: MX=MX+4 :: MY=MY+3 :: GOSUB 8000 :: NEXT L::MA=60

 

8000 CALL COINC(ALL,C) :: IF C=-1 THEN 9000

8010 GOSUB 8100 :: CALL LINK("DELAY",80) :: RETURN

 

8100 ON LEV GOSUB 2110,2120,2130 and so on

8110 CALL LINK("SCPXLF",184,4,1)::CALL LINK("SCPXLF",200,4,1) (this does the water scroll, it's always active whether water is there or not in order to maintain a steady speed and not go up n down all over the place )

 

 

.... what would I do to check if there's a platform anywhere?  This sort of code would have to be entirely re-written? Any help would be great if I can understand it. :)

 



#2 Willsy OFFLINE  

Willsy

    River Patroller

  • 2,972 posts
  • Location:Uzbekistan (no, really!)

Posted Fri Apr 21, 2017 9:44 AM

I prefer the title "Eric Drops Acid in a Hamburg Brothel"

Might lose the U rating though...!

#3 Retrospect OFFLINE  

Retrospect

    Dragonstomper

  • Topic Starter
  • 866 posts
  • Location:Wakefield, England

Posted Fri Apr 21, 2017 10:11 AM

I prefer the title "Eric Drops Acid in a Hamburg Brothel"

Might lose the U rating though...!

lol or "Eric and the Meth Factory" ... yeah gone beyond even PG there.



#4 Asmusr OFFLINE  

Asmusr

    River Patroller

  • 2,308 posts
  • Location:Denmark

Posted Fri Apr 21, 2017 11:20 AM

I used to code jumps using a fixed table of y offsets, so that every time the sprite moves one pixel in x it gets the movement in y from the next entry of the table. The jump finishes when the last entry is reached. This is the table from Jet Set Willy:

 

JMPTBL BYTE -4,-4,-3,-3,-2,-2,-1,-1,0,0,1,1,2,2,3,3,4,4

 

Recently I have started coding jumps using velocities and accelerations instead. Say you have two variables for the Y direction: VY (velocity) and AY (acceleration). For the X direction you only need the velocity VX since you usually don't accelerate during a jump. Now a jump can simply be coded something like this:

VX=1               (or -1, depending on the direction of movement)
AY=0.05            (a small downwards acceleration)
VY=-4.0            (a relatively high upwards velocity)
FOR I=1 to 100     (adjust duration to fit)
  MX=MX+VX
  VY=VY+AY
  MY=MY+VY
  display sprite at (MX,MY)
  check collision with platforms
NEXT I

The central movement code is not limited to jumps, but can also be used for both straight movement and falling. You probably only need these lines once in your central loop. When you move the joystick left or right you set VX. When you jump you set AY and VY. When you detect you're in open space you set AY. If you move into something horizontally you reset VX. If you jump into something with your head you reset VY. And so on... 

 

To check collision with platforms, you need a routine to get the character at pixel position (X,Y). I rarely used XB, but I think you need to divide X and Y by 8 and use GCHAR?

 

When you move upwards (jump) you need to check the character above the head. and possibly the one next to it as well. When you move left or right you need to check one or two character to the left or right. When you fall or stand you need to check characters beneath the feet.  

 

During falling (when VY > 0), if you detect a character beneath the feet you will probably want round off the sprite Y position to the integer multiple of 8 above it, to prevent sinking into the platform. If afraid I don't remember how to do that in XB, but it something like MY = MY - (MY MOD 8 ) where MOD is the remainder after a division.



#5 Retrospect OFFLINE  

Retrospect

    Dragonstomper

  • Topic Starter
  • 866 posts
  • Location:Wakefield, England

Posted Fri Apr 21, 2017 11:33 AM

Thanks Rasmus that helps quite a bit, I'll have a bash at this over the weekend.  :thumbsup:



#6 PeteE OFFLINE  

PeteE

    Space Invader

  • 35 posts
  • Location:Beaverton, OR

Posted Fri Apr 21, 2017 11:58 AM

If you lay out your screen characters carefully, you can use CALL GCHAR to detect if the ground is solid or not.  For example, put all the solid characters above 95, and all open space or background characters at 95 or below.  In Magellan, you can use shift-click to swap two character tiles, so rearranging them above or below a certain number is pretty easy.  Then to detect solid ground you would use:

CALL GCHAR(INT((MY+16)/8)+1, INT((MX+4)/8)+1, C)
IF C > 95 THEN  (solid ground detected below)

The INT((MY+16)/8)+1 converts the sprite Y coordinate 16 pixels down to the screen row, and INT((MX+4)/8)+1 converts the sprite X coordinate 4 pixels to the right (centered under the sprite) to the screen column.  You would need to do the test during the downward path of the jump, and also check for space after moving left or right so the player will fall after walking off the edge of the platform.

 

I haven't tested this, and it's been a while since I've done any basic programming, but I use the same concept for an assembly game I'm working on.



#7 Retrospect OFFLINE  

Retrospect

    Dragonstomper

  • Topic Starter
  • 866 posts
  • Location:Wakefield, England

Posted Fri Apr 21, 2017 12:19 PM

Thanks Pete, that's also helpful.  Work on the new game will begin soon!



#8 Tursi OFFLINE  

Tursi

    River Patroller

  • 4,622 posts
  • Location:BUR

Posted Fri Apr 21, 2017 12:22 PM

Regarding acceleration on the jumps - it's also perfectly okay to use integer values, which I believe will work better on the compiler. I usually use a gravity (acceleration Y) of '1' and then tweak the initial upwards velocity to get the desired arc. It does result in a very natural looking jump.

 

Catching the ground on the downward arc can be fiddly - make sure you check before you draw the sprite to avoid him popping into the ground then back out. Also you will want to cap the maximum positive acceleration - otherwise a long fall will result in velocities that are large enough to make detecting a platform or the ground difficult. (Just think of it as terminal velocity ;) ). Again, I don't have hard and fast rules for those, I just tweak values till I like what I see.

 

When you detect ground, you can then snap to the calculated row by multiplying by 8 and adding 1 (for the sprite offset).

 

I don't think XB has a MOD function, but it's faster to round with INT anyway. SCREENY = INT(SPRITEY/8) - be aware that SPRITEY of 0 is actually the second row on the screen, so this could be off by 1. Usually that's not a problem and in XB the speed is worth it, but since you're compiling you could adjust for it. A quick and dirty program to show how it lines up (and so you can adjust the code to get the exact match you want):

 

 
100 PI2=PI*2
110 CALL CLEAR
120 CALL MAGNIFY(2)
130 REM MANUALLY MOVE A SPRITE IN A CIRCLE
140 CALL SPRITE(#1,ASC("Y"),2,193,1)
150 FOR AN=0 TO PI2 STEP PI2/360
160 SPX=COS(AN)*64+128
170 SPY=SIN(AN)*64+96
180 CALL LOCATE(#1,SPY,SPX)
190 REM GET THE SPRITE POSITION AND PUT A CHARACTER UNDER IT
200 IF SCR=0 THEN 220
210 CALL HCHAR(SCR,SCC,32,3)
220 CALL POSITION(#1,INR,INC)
230 SCR=INT((INR+23)/8)
240 SCC=INT(INC/8)
250 REM SPRITE IS 2 CHARS WIDE, MEANS IT WILL OFTEN STRADDLE 3 CHARS
260 CALL HCHAR(SCR,SCC,ASC("#"),3)
270 NEXT AN
280 GOTO 150


#9 Retrospect OFFLINE  

Retrospect

    Dragonstomper

  • Topic Starter
  • 866 posts
  • Location:Wakefield, England

Posted Fri Apr 21, 2017 12:40 PM

Nice , I like that - the chars follow the sprite.  As you say, ensure the sprite isn't going to show up in the wrong place before I update all sprites.  I've seen that done before popping up and down, :)

 

Cheers Tursi.



#10 Retrospect OFFLINE  

Retrospect

    Dragonstomper

  • Topic Starter
  • 866 posts
  • Location:Wakefield, England

Posted Sun Apr 23, 2017 10:41 AM

My idea is to make another game after "monsterland" with the same sprite, "Eric" and have it set in Egypt - this gives me an opportunity to attempt graphics of the Nile, the Sphinx, and the pyramids .... the 9918's colours are just the job ...  






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users