Jump to content

Recommended Posts

Hello everyone, this is my first post on this forum. I'm a game designer/programmer for my day job, working on mobile games. Lately I've been getting into 2600 programming, with the initial idea of porting a prototype I made for mobile over to the 2600.

 

It's been a lot of fun getting back into assembly coding, I haven't really touched it since high school, when I learned some Z85 asm to make games for my graphing calculator :grin:

 

 

The game is a simple one-button game: a ninja is sliding down a wall, tap the button to jump away and slide down the other wall. There is an opening on the right, make it through and you are in the next room (the opening closes behind you).

 

It has roughly analog input, e.g. the longer you hold the button, the higher you will jump. As you progress the position of the door changes, and the size of the door opening gradually decreases. Spikes also appear that you have to avoid as well.

 

I've been working on the 2600 version for about a week or so now, and I'm really pleased with the progress so far. :)

 

here is a screenshot:

post-40857-0-40567000-1416985314_thumb.png

 

And a short video I posted on Vine:

https://vine.co/v/O1PTebm37er

 

I'm currently working on getting a basic footer that will display what "room" you are in (this is essentially your score). After that I need to get collision detection between the player and spikes (this triggers a game over), and then work on fixing bugs and adjusting the feel of the timing, maybe adding some more animation frames for the player, adding some sound effects, etc.

 

Any feedback is welcome!

 

  • Like 12
Link to comment
https://forums.atariage.com/topic/232200-ninja-wall-jump-game-wip/
Share on other sites

Thanks for the encouraging notes everyone! I've now got a rudimentary 2-digit score display working on the bottom of the screen: my first attempt at an asymetrical playfield, and also figuring out how to turn a score into two digits lined up in PF1 (because that's the easy non-mirrored byte).

 

I'm sure there are much fancier and more efficient methods of doing everything I'm doing, but I'm having a blast getting the game running! It's fun to sit down for an hour or two and make visible progress in the game, and also learn something new at the same time.

 

obligatory screenshot:

post-40857-0-19914500-1417064431_thumb.png

 

I still have some game logic to clean up, and then I think I'll detour into sounds a bit. :D

  • Like 2

Thanks to everyone's help, I've got the 48-bit sprite kernel working, in order to add a title screen to the game. I really wish I could change the colors for each scanline, but I haven't found a way to squeeze the cycles needed into the kernel. Almost, but not quite: I can find enough time to change COLUP0 or COLUP1, but not both :)

 

I have some free cycles because the logo is static so the LDX are only 4 cycles each instead of 5, and I'm happy that I was able to figure out how to compensate my kernel for this... my fallback will be to have "wall jump" be 1 color, and then in the blank line between that i can change the colors, and have "NINJA" be in another color.

 

Here's the title screen, I've decided to call the game "Wall Jump Ninja" :-D

post-40857-0-09742700-1417204261_thumb.png

 

Also I think I'll try to use the playfield and background colors to make the title screen a little more exciting. but for now, back to game logic, and then onto sounds.

 

 

Hi,

 

great project you have going on there!

 

I really wish I could change the colors for each scanline, but I haven't found a way to squeeze the cycles needed into the kernel. Almost, but not quite: I can find enough time to change COLUP0 or COLUP1, but not both :)

 

There are two ways to do that.

 

1) Invert your graphics, and set COLUP0 and COLUP1 to black. Set the playfield to mirrored (register CTRLPF), and put playfield graphics behind the sprites (that works because your logo is centered on the screen). That way, the playfield graphics will "shine through" where your logo is, and you only need to set one color (COLUPF) per scanline.

 

2) Here's a 48 pixel kernel that sets both COLUP0 and COLUP1 (caution: written off the top of my head, and thus untested):

.loop:
	ldy lineCount		; 3
	lda colors,y		; 4
	sta COLUP0		; 3
	sta COLUP1		; 3	
	lda data_1,y		; 4
	sta GRP0		; 3
	lda data_2,y		; 4
	sta GRP1		; 3
	lda data_3,y		; 4
	sta GRP0		; 3
	lda data_6,y		; 4
	sta tmp			; 3
	lax data_5,y		; 4
	lda data_4,y		; 4
	ldy tmp			; 3
	sta GRP1		; 3
	stx GRP0		; 3
	sty GRP1		; 3
	sta GRP0		; 3
	nop			; 2
	nop			; 2
	dec lineCount		; 5
	bpl .loop		; 2/3

If I haven't miscounted, the kernel should be exactly 76 cycles. Since it lacks a sta WSYNC, you need to enter it exactly at the correct cycle so the sta/stx/sty sequence matches the player placement. And if you don't like undocumented opcodes (lax loads the value in A and X simultaneously, so you save a tax), you can change it into a lda/tax and remove one nop instead.

 

Hi,

 

great project you have going on there!

 

 

There are two ways to do that.

 

1) Invert your graphics, and set COLUP0 and COLUP1 to black. Set the playfield to mirrored (register CTRLPF), and put playfield graphics behind the sprites (that works because your logo is centered on the screen). That way, the playfield graphics will "shine through" where your logo is, and you only need to set one color (COLUPF) per scanline.

That's my preferred method. I update COLUBK each line though. I think that's what you meant too.

 

 

However you can also do writes to COLUPF and use it for the ball. The Playfield will be colored black from taking the players color, but the ball still takes it's color from COLUPF. Add in a HMOVE on each line and you create a nice shine effect.

 

 

If you start running short on cycles then storing one of the digits in ram saves a lot. This:

    lda    (digitSix),Y          ;5  @5
    sta    temp                  ;3  @8
    lda    (digitFour),Y         ;5  @13
    tax                          ;2  @15
    lda    (digitFive),Y         ;5  @20
    ldy    temp                  ;3  @23

Reduces to this, saving 7 cycles:

    lax    (digitFour),Y         ;5  @5
    lda    (digitSix),Y          ;5  @10
    tay                          ;2  @12
    pla                          ;4  @16  digit 5 stored in ram

You can also use the timer to save cycles over dec tempRegister, and of course by loading absolute Y or X.

Thanks for the feedback everyone! Today I've added in logic to detect when you collide with a spike, and have the player fall off the screen, resulting in a simple 'game over' state. Press the hardware reset button and the game will restart.

 

Here is an initial build of the game, please give it a try and let me know what you think!

wall_jump_ninja_20141129.bin

 

:arrow: Use player 1 FIRE button to start the game from the title screen, and the same button to jump (hold to jump higher).

 

I haven't tested it on hardware yet, so play at your own risk. It seems to be a pretty solid 262 scanlines on Stella though (except for transitioning between the title screen and gameplay for a frame).

 

Next I think I'll try to make the title screen more interesting, and then focus on tuning the gameplay a little more (I think the walls are too far apart right now). I also think adding more player frames would look nice, since the movement is pretty fluid, it would be cool if the player sprite animated more fluidly to match.

  • Like 2

This looks good, but I'm not crazy about the horizontal play. I think this could work well as a vertical game. You start at the bottom and need to make your way up to the top. The spikes could serve as obstacles, but you could also have other items thrown in to get in the way, similar to NinJump: https://itunes.apple.com/us/app/ninjump/id379471852?mt=8

Yeah Ninjump is fun, and I think a fun 2600 port could be made. I still have a few elements to add to the game that will hopefully make it feel even more fun than it is right now, keeping the horizontal design.

 

I'm working on cleaning up the code now, I got some tweaks in today to the width of the rooms and the collision detection and spike placement.

post-40857-0-75046200-1417391935_thumb.png

continued progress, I've cleaned up the kernel a bunch, and found cycles to implement the final main feature I wanted... the relentless death beam!! (the green thing). it chases you and if it hits you, you DIE. :mad:

 

post-40857-0-26128700-1417591766_thumb.png

 

I've also tried a new look for the "sunset" backdrop, and made a variety of other cleanup. Here's the latest gameplay video:

 

:arrow: https://vine.co/v/OvihJxg5PzX

 

 

  • Like 1

Progress! I found cycles in the kernel to support "double spikes" as the game gets more difficult. I also created moving spikes that oscillate up and down in the middle of a room, forcing you to time your jumps carefully in order to get past. Title screen got an additional credit line as well :)

 

I also added support for one of the difficulty switches, the different settings control how quickly the difficulty ramps up. I have an idea for the other difficulty switch too that should be fun.

 

I'm getting close to completion on this. On my list right now is:

- additional difficulty switch mode change

- finalize title screen

- add a few more frames of player animation

- fix a few bugs

 

post-40857-0-11989800-1417714804_thumb.png post-40857-0-29710600-1417714815_thumb.png post-40857-0-16866700-1417714821_thumb.png

  • Like 2

Very nice! I do think think that adding vertical action would be great, but not sure in my ignorance how easy that would be. A power up like in Ninjump to provide temporary invincibility or a "hit point" would be fun as well, or perhaps a change in gravity. Hoping there will be a great fall to your death or splat sound effect when you fail. Thanks for sharing!

Edited by Chuck D. Head

I thought since this is a programming forum after all, I'd post an explanation of how the game has been implemented. I'd live any feedback or comments.

 

post-40857-0-01329600-1417842069_thumb.png

 

The background color is changed frequently to make the "sunset" background. Color for P0 and P1 are both set to black, so that the 2 walls can be made from both missiles (mostly just left on for the entire frame to make a vertical line). The opening in the wall is just turning off one missile for a few scanlines.

 

Player 0 is the actual ninja character.

 

Player 1 stands in as the spikes (which sometimes appear double, but never overlap horizontally, simplifying the logic).

 

The playfield is set to be in front of sprites, and is used to make the black bars on either end of the screen, which help mask the scrolling effect, when objects leave/enter the screen from the edges.

 

The "death beam" is implemented with the BALL, which means that I have to change the playfield color mid-scanline in order to change from black (for the edge) to green (for the beam), and then back to black before the other edge, all while cramming in the other sprite routines.

 

bottom of the screen you can see another playfield effect for the "lava" (that's new, it's an option you can choose, without it the player is allowed to wrap vertically around the screen).

 

playfield is also used to draw the "ROOM: XX" display as well.

  • Like 3

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...