Jump to content
IGNORED

Stickman! (INTY Basic)


Recommended Posts

This is Stickman!, well what I have so far of Stickman! anyway. He's in stick-figure land. The mean, evil, and downright rotten Stickvillain has stolen Stickwoman and held her captive. It's up to Stickman to get Stickwoman back. And if problems weren't enough, Stickvillain has hypnotized the erasers to erase you when they see you!

So what I have so far of Stickman! is Stickman moving back and forth like Mario. Since this is a platform game. I plan to add holes, and erasers that could rub you out.

I worked for a few hours, since I had to relearn everything I had forgotten programming GoSub. So, with the Red Krayola playing on my computer (that's a band), I started.

I am also wondering what I should use to jump. Should I use the fire buttons or the keypad?

platform.bin

  • Like 5
Link to comment
Share on other sites

OK. I made it so any of the four fire buttons make Stickman jump.

 

Intv has 3 action buttons as top left and right are the same.

 

You're both right. :D All four buttons make you jump, and two of the buttons are indistinguishable from each other. :D

Link to comment
Share on other sites

I'm not sure I like the jump mechanic myself. It feels too... linear. A proper jump follows a parabolic arc.

 

To get that, you need three variables in addition to your Y position.

  • Your current velocity
  • Your current "jump acceleration"
  • A flag saying "player is still holding 'jump'"

The basic idea is this: On every frame, you add your current acceleration to your velocity, and your current velocity to your position. Acceleration comes from two components: Jump acceleration and gravity acceleration. Jump acceleration applies when you're holding the jump button, and gravity acceleration applies when you're not touching the ground.

 

You want logic something like this on each frame:

  • If player is touching the ground:
    • If jump isn't pressed: Set vertical velocity to 0. Set jump acceleration to 0. Set player Y position to lock player to the ground.
    • If jump is pressed: Set vertical velocity to initial jump velocity. Set jump acceleration to initial jump acceleration. Update player Y position by lifting a pixel. Set flag saying "player is holding 'jump'."
  • Else, player is not touching the ground:
    • Add gravity acceleration to player's vertical velocity
    • Add jump acceleration to player's vertical velocity
    • Decrease jump acceleration by fixed amount (clamping at 0)
    • If jump isn't pressed OR "player is holding 'jump'" flag is clear: Clear "player is holding 'jump'" flag and zero out jump acceleration

That will allow the player to control the magnitude of the jump by how long they hold the jump button, but as soon as they let go, they can't jump again until they land on a surface. If they hold jump, they'll "pogo" along, though, jumping again as soon as they land. If you don't want the pogo effect, then you need a slight tweak to the logic:

  • If player is touching the ground:
    • Set vertical velocity to 0. Set jump acceleration to 0. Set player Y position to lock player to the ground.
    • If "player is holding 'jump' is clear AND jump is pressed: Set vertical velocity to initial jump velocity. Set jump acceleration to initial jump acceleration. Update player Y position by lifting a pixel. Set flag saying "player is holding 'jump'."
    • If jump isn't pressed, clear "player is holding 'jump' flag.
  • Else, player is not touching the ground:
    • Add gravity acceleration to player's vertical velocity
    • Add jump acceleration to player's vertical velocity
    • Decrease jump acceleration by fixed amount (clamping at 0)
    • If jump isn't pressed OR "player is holding 'jump'" flag is clear: Clear "player is holding 'jump'" flag and zero out jump acceleration

That forces the player to press 'jump' again on landing.

 

The net effect of separating acceleration from velocity is to give nice parabolic arcs. The jump acceleration value should decay quickly, over a few frames. The only reason for having an initial value and letting it decay is to allow the player to make different sized jumps based on how long they hold the button. You might also modulate the jump acceleration value based on their current horizontal velocity, allowing higher jumps when running than when standing still.

 

I believe that's how games like Mario work the jumping motion.

 

One possible variant: Instead of decreasing the jump acceleration, just set a short "jump timer" that counts down toward 0 each frame, and as long as it's non-zero, add the jump acceleration to the velocity. Either way, the total time that the jump acceleration is non-zero should be no more than 10-15 frames, I'd reckon.

 

Space Patrol used something like this, although much, much simpler, because how long you held 'jump' doesn't matter in that game. Each time you press 'jump', the tank jumps a fixed height. Pressing 'jump' when the tank was on the ground and 'jump' wasn't already pressed would set the vertical velocity to a fixed value, and as long as the tank wasn't on the ground, I'd apply a fixed gravity acceleration downward. How far you jumped ended up solely being a function of forward velocity only because the screen scrolled below you at different rates. The vertical arc doesn't change.

 

But for a platformer, typically how long you hold 'jump' determines how big of a jump you want, so that needs some additional logic. Also, IIRC, the faster you run in Mario, the higher you can jump.

 

To make this scheme work, you will likely need to keep your Y position in a 16-bit variable (with the upper 8 bits holding the actual Y coordinate, and lower 8 bits holding a fraction.) Your Y velocity and Y acceleration may be able to live in 8 bit variables, although it might be easier to keep them in 16-bit variables while you work the logic out.

Link to comment
Share on other sites

Yes, but as it's set right now, you can make different sized jumps. If you lightly tap a fire button you'll make a little jump, whereas if you hold it, you'll get the maximum jump height. Besides, I don't think I can work something that complex into my program, I think I would need the space for platform layout logic. I have used 5.5k so far on this alone! Right now I've added two holes. If you don't jump over them, you'll fall into them. After the two holes, the game goes on forever, so if you don't want to keep walking forever, reset. This was the result of about 90 minutes' worth of toying around. I've added the code so far, so if you want to, feel free to add that stuff you talked about in the game.

platform.bin

platform.bas

  • Like 1
Link to comment
Share on other sites

Yes, but as it's set right now, you can make different sized jumps. If you lightly tap a fire button you'll make a little jump, whereas if you hold it, you'll get the maximum jump height. Besides, I don't think I can work something that complex into my program, I think I would need the space for platform layout logic. I have used 5.5k so far on this alone! Right now I've added two holes. If you don't jump over them, you'll fall into them. After the two holes, the game goes on forever, so if you don't want to keep walking forever, reset. This was the result of about 90 minutes' worth of toying around. I've added the code so far, so if you want to, feel free to add that stuff you talked about in the game.

 

I agree with intvnut that it would be nice to have more parabolic arc jumps. This shouldn't be too complex to implement. Even if you don't go for an accurate physics simulation, you should just be able to "fake" it with some data tables or simple maths.

 

If you point me to the part in your code that handles the jump right now, I could try to see how to adapt it. Just add some comments to your code. ;)

 

Never mind, I got it. It took me a few seconds to realize that "sticky" means "stick y". :lol:

Edited by DZ-Jay
Link to comment
Share on other sites

OK, here's a stupidly simple implementation:

prets:
    ' ...

    basesticky  = 84  ' Floor baseline, max Y
    baseaccstep = 2   ' Number of cycles to skip per acceleration adjustment
    #baseaccy   = -6  ' Base acceleration due to gravity, pixels to adjust Y

    gosub resetjump

    ' ...
dojump: procedure
        if (accstep > 0) then accstep = accstep - 1 : return ' jump every step-th cycle

        sticky = sticky + #accy
        #accy = #accy + 1

        if (sticky > basesticky) then gosub resetjump

        accstep = baseaccstep
        return
        end

resetjump: procedure
        sticky = basesticky
        jump = 0
        accstep = baseaccstep
        #accy = #baseaccy

        return
        end

It just gives you a nice parabolic jump. You can control the height with the "baseaccy" variable, which represents the simulated acceleration due to gravity; and you can control the speed of the jump with the "baseaccstep" variable, which represents the number of cycles to skip between acceleration changes.

 

To me, with only that change, it already feels like a platformer game. :)

 

Attached find the updated and tested code.

 

Enjoy!

-dZ.

 

platform.bas platform.rom

Edited by DZ-Jay
  • Like 1
Link to comment
Share on other sites

OK, here's an updated version with the different size jumps:

 

Initialization:

prets:
    ' ...

    basesticky  = 84    ' Floor baseline, max Y
    baseaccstep = 2     ' Number of cycles to skip per acceleration adjustment
    #baseaccy   = -4    ' Base acceleration due to gravity, pixels to adjust Y
    #maxaccy    = -8    ' Maximum acceleration due to gravity

    ' ...

Jump trigger:


    ' jump: 1=jump higher; 2=start fall; 0=no jump
    if (cont1.button) and (jump=0) then jump=1 
    if (cont1.button=0) and (jump=1) then jump=2



         WAIT

     holexplus=holex+6 
     holexminus=holex-6

     ' If we're jumping, go do it...
     if (jump > 0) then gosub dojump

Jump routines:

dojump: procedure
        if (accstep > 0) then accstep = accstep - 1 : return ' jump every step-th cycle

        ' jump=1: While jumping, increase acceleration until max.
        ' jump=2: Otherwise, just fall by decreasing acceleration.
        if (jump = 1) then #accy = #accy - 1 : if (#accy = #maxaccy) then jump = 2
        if (jump = 2) then #accy = #accy + 1

        ; Adjust vertical position based on adjusted acceleration
        sticky = sticky + #accy

        ' Stop falling when we reach the floor
        if (sticky > basesticky) then gosub resetjump

        accstep = baseaccstep
        return
        end

resetjump: procedure
        jump = 0                ' No more jumping
        sticky = basesticky     ' Reset position to floor (just in case)
        accstep = baseaccstep   ' Reset jump step
        #accy = #baseaccy       ' Reset acceleration to base

        return
        end

By the way, it works on the same general principle explained by intvnut:

  1. When the button is pressed, we subtract the acceleration amount from the vertical position, which essentially accelerates upwards.
  2. While the button is pressed, the acceleration increases upwards (negative), making the jump not only higher, but faster.
  3. When the button is released, or the maximum acceleration is reached, we decrease the acceleration, essentially decelerating until we reach the apex.
  4. When acceleration finally reaches zero, we start to fall by accelerating downwards (positive).
  5. The vertical position is adjusted until it reaches the floor again.

 

I like this version better, but I think the control detection is a bit sluggish. I haven't touched the rest of the program, only the jump action section.

 

I think the engine could use a bit of tweaking for performance and maybe quantize the control detection a bit better.

 

Enjoy

-dZ.

 

platform.bas platform.rom

Edited by DZ-Jay
Link to comment
Share on other sites

OK, so I discovered that when I'm using sprite 1,200+$700,96+$300,(256+53)*16+9 instead of sprite 1,200+$700,96+$300,(256+53)*8+9 I am actually accessing the letters and stuff instead of my sprites I have made. It appears as though I just accidentally was using 53 and that just happened to be a character that made the hole, not my sprite. I tried this with an enemy and the first time instead of my sprite I had designed, it was the letter W! So I changed the whole thing. I think the eraser I had made is a stretched out period that just happens to look like an eraser. So I guess if I want to access colors 9-15, they have to be characters? I'm so confused now. I put the jumping code, and man, he goes high. I toned that down a little in this version.

platform.bas

platform.bin

Link to comment
Share on other sites

Yes, but as it's set right now, you can make different sized jumps. If you lightly tap a fire button you'll make a little jump, whereas if you hold it, you'll get the maximum jump height. Besides, I don't think I can work something that complex into my program, I think I would need the space for platform layout logic. I have used 5.5k so far on this alone! Right now I've added two holes. If you don't jump over them, you'll fall into them. After the two holes, the game goes on forever, so if you don't want to keep walking forever, reset. This was the result of about 90 minutes' worth of toying around. I've added the code so far, so if you want to, feel free to add that stuff you talked about in the game.

 

Just 'cause my explanation is long winded, I'm not expecting it to be a lot of code. Maybe 10-15 lines, not War and Peace. I haven't looked at your .BAS file yet, but here's a quick sketch I whipped up in ~10 minutes. Yeah, it uses GOTO, because IntyBASIC lacks multi-line IF statements. This version allows for pixel rates up to 4 pixels/frame; you can change that by changing the *4 in the first line. The upper 8 bits of #y_pos give your actual Y position. Use y_pos / 256 to get the actual Y position.

.

    #y_pos = #y_pos + (y_vel - 128) * 4       ' bias y_vel by 128 so 128 means "none"
    IF on_ground = 0 THEN GOTO in_air
    ' On the ground:
        y_vel = 128 : jump_cnt = 0
        IF jump_flag = 0 AND cont.button <> 0 THEN jump_flag = 1 : jump_cnt = 15
        IF cont.button = 0 THEN jump_flag = 0 
    GOTO jump_done
in_air:
    IF jump_cnt > 0 THEN jump_cnt = jump_cnt - 1 : IF y_vel < 200 THEN y_vel = y_vel + 40
    IF y_vel > 16 THEN y_vel = y_vel - 16 ELSE y_vel = 0    ' accelerate due to gravity
    IF cont.button = 0 OR jump_flag = 0 THEN jump_cnt = 0
jump_done:

Edited by intvnut
Link to comment
Share on other sites

I'm so confused now. I put the jumping code, and man, he goes high. I toned that down a little in this version.

Are you confused by the jumping code I provided? Take a look at the files I attached before; they contain your original with my changes.

 

I left it jumping high to show a large range, but you could tone it down by adjusting the constants. It is not very granular, but it should do the trick for a quick-and-dirty and simple jump physics mechanics.

Link to comment
Share on other sites

Is thare any chance you can number your builds. It would make it easier for me as i have archived every rom ever released on the web including all 73 versions of GoSub!. If not, biggie, i will just have to try to keep track. :)

Also, try to refrain from archiving all MY roms, like you said, you'll end up with 72 uncomplete versions of the same game.

Link to comment
Share on other sites

OK, so I discovered that when I'm using sprite 1,200+$700,96+$300,(256+53)*16+9 instead of sprite 1,200+$700,96+$300,(256+53)*8+9 I am actually accessing the letters and stuff instead of my sprites I have made. It appears as though I just accidentally was using 53 and that just happened to be a character that made the hole, not my sprite. I tried this with an enemy and the first time instead of my sprite I had designed, it was the letter W! So I changed the whole thing. I think the eraser I had made is a stretched out period that just happens to look like an eraser. So I guess if I want to access colors 9-15, they have to be characters?

 

Long story short, no, you can use all 16 colors in a GRAM-defined MOB. Take a look at the register description. Your value of (256+53)*8+9 gets placed into the A register for a MOB. Let's look at it in detail:

 

256 is simply a trick to specify the GRAM bit (bit 11, we'll get to how it does this in a second). 53 is the GRAM card number. When you add those 2 together, and then multiply by 8, this shifts all of those bits over by 3 - in other words, to their correct positions (bit 11 for GRAM flag, and bits 10-3 for the card #). +9 sets the FG color for the mob - except there's a problem. The FG color bits are spread out, with bit 3 of the color being at bit 12, and bits 2-0 being where you'd expect them to be given that +color syntax.

 

Now, the consequences of this are as follows:

 

1. *16 will shift everything over one bit too many. So not only are you no longer selecting from GRAM - which means you're getting a GROM card - AND the card number is twice what you specified. Basically it's a crapshoot as to what happens - especially if you overflow into other bits. Don't do this :)

 

2. +9 to set a color will not work. To use the first 8 colors (black through white), you can just add the color. +1, +2, etc all the way to +7. HOWEVER - if you want to use the higher colors, you need to account for bit 12. Which means "ugly" values. If you're trying to use color "9" (cyan), you want to +$1001. This makes sure all 4 color bits are set properly.

 

Tarzilla has a nice layout of CONSTs that he uses specifically because of this issue. No more magic numbers in the code. I'm gonna shamelessly copy them here and he can yell at me for copyright infringement later :) You'll notice that the first 8 colors are just 0, 1, 2 etc. He put then in hex for consistency but there's no actual need to. 0-9 are the same in decimal or hex.

	CONST X_BLK  = $0              ' Black
	CONST X_BLU  = $1              ' Blue
	CONST X_RED  = $2              ' Red
	CONST X_TAN  = $3              ' Tan
	CONST X_DGR  = $4              ' Dark Green
	CONST X_GRN  = $5              ' Green
	CONST X_YEL  = $6              ' Yellow
	CONST X_WHT  = $7              ' White
	CONST X_GRY  = $1000           ' Grey
	CONST X_CYN  = $1001           ' Cyan
	CONST X_ORG  = $1002           ' Orange
	CONST X_BRN  = $1003           ' Brown
	CONST X_PNK  = $1004           ' Pink
	CONST X_LBL  = $1005           ' Light Blue
	CONST X_YGR  = $1006           ' Yellow-Green
	CONST X_PUR  = $1007           ' Purple

At least, that's my guess from what you've described. I haven't looked at your code at all.

  • Like 1
Link to comment
Share on other sites

Also, try to refrain from archiving all MY roms, like you said, you'll end up with 72 uncomplete versions of the same game.

i am ok with that. I believe in the preservation of video games and having every rom version incomplete or not. One day i can look back and see the progress made through a game and see what is was to what it is now. Plus i like testing every rom version so i can help test and provide input.
Link to comment
Share on other sites

OK, I understand now. I changed everything to work good and added a title screen. It is clear I am going to need more than just 16k for this one. Looking at the INTV Basic manual, it says I can add "ASM ORG $D000" for more room. Would I put this at the beginning of my code? And would that make my game 32k?

platform3.bin

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...