Jump to content

Photo

Entry 2018: A Sparrow Goes Flapping


13 replies to this topic

#1 Kiwi OFFLINE  

Kiwi

    Stargunner

  • 1,564 posts

Posted Wed Jul 4, 2018 7:32 PM

This is my entry.  Today is the 2 year anniversary that I released an "improvement" version of A Sparrow Goes Flapping. So, I'm porting that game to the Intellivision.  It is called A Sparrow Goes Flapping.  You can get the Colecovision ROM version here: http://atariage.com/forums/topic/254474-kiwis-game-a-sparrow-goes-flapping-available-to-play/?hl=%2Bsparrow+%2Bflapping#entry3547284 Eventually I'll add more improvements to that version like adding the volcano level to it.  Maybe a snow level...

It is early in development.  No sound effect or music yet, so you don't disturb your next door neighbor or any other family member who may be sleeping at this time. It's pretty much my very least favorite part of making a game.  It only contain 1 level, but defeating the boss will make the game more difficult and difficult.

 

Here's the Intellivision ROM: Attached File  Asparrow.rom   15.06KB   10 downloads

And here's the gif.

 

Asparrow.gif
Dang it, 1 point away...

 

Instructions: Go through trees to the end of the forest, where you face a badly rendered owl, pretty hard to make a good looking one in 8x16 card.  You can break sticks(and stones[which will be in level 2]) with your birddash attack ability, which can be press with the top button. While birddashing, you are invincible(becomes blue) during this time. Solid object like trees will halt the birddash.  After birddashing, it takes the sparrow some time to recover. He flashes pink when he's recovering.  Also use this birddash ability to attack the boss of the level. 

 

Keypad 0 is the pause key.  it overrides the 5 objects on screen to display the word "PAUSE". Use this to do whatever you need to do in the real world.  Any of the side button or key 0 will remove the pause feature and the game will resume.  Pressing the top button from unpausing the game will make the bird, birddash, so I recommend pressing the bottom buttons to unpause. 

Breaking sticks will cause the power up to appear later in the stage.  Eating apple will spawn a star.

Items:

Star:Makes you invincible for about 9 seconds

Heart:Restore your health to the maximum
Cape:Reduce your rest time after birddashing

Shield:Increase your after hit invincibility

I haven't tried the ROM on the Intellivision.  It should work. 

Bug: Sometime apple may hurt you, I'm not sure why yet.  I'm using hardware collision. 



#2 Steve Jones OFFLINE  

Steve Jones

    Dragonstomper

  • 789 posts
  • Location:Toronto Canada

Posted Wed Jul 4, 2018 8:46 PM

awesome, thanks



#3 Utopia OFFLINE  

Utopia

    Dragonstomper

  • 775 posts
  • Location:Brisbane Australia

Posted Wed Jul 4, 2018 9:28 PM

Very nice, playing it now!



#4 emerson OFFLINE  

emerson

    Star Raider

  • 95 posts
  • Location:Northeast Ohio

Posted Thu Jul 5, 2018 8:51 AM

I just played a few rounds, and this is pretty good! Decent graphics overall, plus it has a quick learning curve. My only suggestion is to add some code that waits for the "unpause button" to be released before returning to gameplay.



#5 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 10,865 posts
  • Triple-Stripe Mo' Bro
  • Location:NC, USA

Posted Fri Jul 6, 2018 3:07 AM

It looks great! I'll take it for a spin this week-end. :thumbsup:

 

 

Go through trees to the end of the forest, where you face a badly rendered owl, pretty hard to make a good looking one in 8x16 card.

 

Looks like a flying squirrel to me! :lol:

 

 


Bug: Sometime apple may hurt you, I'm not sure why yet.  I'm using hardware collision. 

 

That's probably because some apples are rotten and have worms. :grin:

 

   -dZ.



#6 carlsson OFFLINE  

carlsson

    Metagalactic Mule

  • 7,084 posts
  • Location:Västerås, Sweden

Posted Fri Jul 6, 2018 3:42 AM

Over at FB, some of us are trying to convince Kiwi to turn the sparrow into a swallow and add killer rabbits, coconuts and a shrubbery... :)



#7 Kiwi OFFLINE  

Kiwi

    Stargunner

  • Topic Starter
  • 1,564 posts

Posted Fri Jul 6, 2018 3:07 PM

New v0.15 ROM: Attached File  Asparrow015.rom   17.56KB   9 downloads

 

Solved the collision issue.  The stic.txt said that collision is sticky. So I update the sprite table after removing the sprite. poke 0 to the collision register to clear it since the txt said the CPU suppose to clear it(I don't know when it to get around doing it, and obviously it can't do it when the screen is being drawn.).  So the apple now won't hurt or give you the star invincibility. The star spawn immediately upon getting over 5 apples, and the stick spawning might occur exact time you ate the apple. So the collision register wasn't being cleared and activate whatever it has just loaded into that object slot. Hopefully that makes sense.  So the code is now...

if objID(i)=3 then ID=i:gosub RemoveObject:poke $0018,0:gosub UpdateSprite:#score=#score+2:birdHP=birdHP+1:apple=apple+1:gosub DrawHP:wait:poke $0018,0:if apple>5 then objecttype=1:d=0:gosub CreateObject:apple=0

And I added 2 more items, the green magic mushroom and the purple jewel.  The green magic mushroom will revive you on the spot if you take a fatal hit, and then disappears.  The purple jewel just add 50 points to your score.  I redrew the "Owl".  The pause screen now shows the item you have in your possession.  I made the items higher resolution since I'm not using 14 cards that reserved for the background tileset.

shot0020.gif


Edited by Kiwi, Fri Jul 6, 2018 3:10 PM.


#8 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 10,865 posts
  • Triple-Stripe Mo' Bro
  • Location:NC, USA

Posted Sat Jul 7, 2018 4:42 AM

Solved the collision issue.  The stic.txt said that collision is sticky. So I update the sprite table after removing the sprite. poke 0 to the collision register to clear it since the txt said the CPU suppose to clear it(I don't know when it to get around doing it, and obviously it can't do it when the screen is being drawn.).  

 

It means that they will remain until the programmer clears them manually, i.e., when the CPU is instructed to write zero into the collision registers.

 

nanochess:  Since these are cached by IntyBASIC, should the kernel have the responsibility of clearing them on every frame?

 

By the way, I know you are one of the old-school users of IntyBASIC from when it was growing up, but it now supports "IF/END IF" blocks, so you don't have to put all that into a single line. ;)

 

Now, about the game, I finally took some time to play it, so here's my feedback:

  • Works great! I like it.  I beat the flying squirrel mean owl! :)
  • It "feels" as if it could use some acceleration when moving.
  • I don't understand what the floating yellow horizontal things are...
  • Apples and other debris fall at a too much constant rate, it seems artificial.  Perhaps you could add acceleration due to gravity to make it feel a bit more natural.
  • I understand that the sparrow flickers with some colour when recovering from its "dash," but it is too subtle.  When I am fighting with the flying squirrel owl, for example, I am paying attention to many items on the screen and can't really focus on the sparrow.  Maybe you can make it flicker in a more obvious way so that it can still be noticed in my peripheral vision.  As it stands right now, I have to stare at it directly and focus in order to notice (and I get hit by some flying thing).
  • When fighting the flying squirrel owl, he shoots some blue "force field" (it reminds me of the satellite force fields in Gyruss).  These seem randomly positioned but 99% of the time they are aligned vertically covering the entire stretch of the screen, and I cannot avoid it.  Very, very, very seldomly do they leave a tiny gap between them through which I can manœuvre.  I do not know if this is intentional, but if it is, it feels unfair -- as if every time the force field shows, I am going to get hit no matter what.
  • Could you make the game start by pressing the disc also?  It's sort of common...
  • The scrolling is not completely smooth: there is a glitch/stutter after every few columns.  You may need to review your game loop to make sure the screen block-copy on every 8th shift is occurring correctly.
  • I can't wait to hear some sound effects and perhaps some background music.

 

It's looking very good! :thumbsup:  Keep it up!

 

   -dZ. 



#9 Kiwi OFFLINE  

Kiwi

    Stargunner

  • Topic Starter
  • 1,564 posts

Posted Sat Jul 7, 2018 5:46 AM


It means that they will remain until the programmer clears them manually, i.e., when the CPU is instructed to write zero into the collision registers.
 
nanochess:  Since these are cached by IntyBASIC, should the kernel have the responsibility of clearing them on every frame?

It does as I look at the asm .lst.  I think when I added gosub updatesprite, which update all 6 sprites perimeter, The sprite removed no longer overlaps.  But this insures that Col0 is zero.
 
By the way, I know you are one of the old-school users of IntyBASIC from when it was growing up, but it now supports "IF/END IF" blocks, so you don't have to put all that into a single line. ;)
To keep it in one line. There's many if/end if blocks in the code. ;)
Now, about the game, I finally took some time to play it, so here's my feedback:

  • Works great! I like it.  I beat the flying squirrel mean owl! :)
    Cool :)
  • It "feels" as if it could use some acceleration when moving.
  • I don't understand what the floating yellow horizontal things are...
    The star.  Collecting this will make you invincible. Cape and other items I listed will show up if you defeat enough enemies.  
  • Apples and other debris fall at a too much constant rate, it seems artificial.  Perhaps you could add acceleration due to gravity to make it feel a bit more natural.
  • I understand that the sparrow flickers with some colour when recovering from its "dash," but it is too subtle.  When I am fighting with the flying squirrel owl, for example, I am paying attention to many items on the screen and can't really focus on the sparrow.  Maybe you can make it flicker in a more obvious way so that it can still be noticed in my peripheral vision.  As it stands right now, I have to stare at it directly and focus in order to notice (and I get hit by some flying thing).
    There will be audio cue when you're ready to dash again.
  • When fighting the flying squirrel owl, he shoots some blue "force field" (it reminds me of the satellite force fields in Gyruss).  These seem randomly positioned but 99% of the time they are aligned vertically covering the entire stretch of the screen, and I cannot avoid it.  Very, very, very seldomly do they leave a tiny gap between them through which I can manœuvre.  I do not know if this is intentional, but if it is, it feels unfair -- as if every time the force field shows, I am going to get hit no matter what.
    They are towering tornadoes.  Air dashing when it is at the very left edge of the screen will let you pass through to avoid being hit.
  • Could you make the game start by pressing the disc also?  It's sort of common...
  • The scrolling is not completely smooth: there is a glitch/stutter after every few columns.  You may need to review your game loop to make sure the screen block-copy on every 8th shift is occurring correctly.
    This is something I have to test on the real Intellivision.  With the emulator on this machine, JZintv, drops 1%-2% of frames. And block copy is probably the most cycle intensive part of the frame. And I'm unsure how much cpu cycle is left before wait on that frame, and prefer the game to run at 60fps if possible.  I did some technique that let me guess where the beam is at by writing to the border color before wait and after wait. After a wait, I used border 0, then before the wait I used border 4.  If the border doesn't flash, it means that the intellivision is still drawing the screen and deny the write to the register.   
  • I can't wait to hear some sound effects and perhaps some background music.

It's looking very good! :thumbsup:  Keep it up!
 Thank you for your comments and playing my game. 
   -dZ.


Edited by Kiwi, Sat Jul 7, 2018 5:47 AM.


#10 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 10,865 posts
  • Triple-Stripe Mo' Bro
  • Location:NC, USA

Posted Sat Jul 7, 2018 6:07 AM

Thanks for the response.  A few more things:

  • Looking back at your comments, the "yellow horizontal things" are sticks.  Perhaps painting them brown would help clarify this (I don't know).
  • I get the tornadoes, those seem fine.  But there are some vertical bars that show up, two of them at a time, and when they align vertically (which they do 99% of the time), they block the entire screen.  A few points on that:
    • Forcing to use the dash mechanic to avoid them seems unfair, since the dash mechanic is used to attack the owl as well and requires a long cool-down period.
    • Also, sometimes you get the force field and the tornadoes at the same time, but you only have one dash at a time.  It seems unfair to force the player to lose health by one or the other.
    • They look too much like energy force-fields, which does not seem to belong in this kind of game.
    • I just played a round where by pure luck most of those force-fields had a gap between them.  This suggests that it is not really intentional for them to block completely the screen.  I recommend adding a check to always leave a little sparrow-sized gap.  This allows the player to use his manœuvering skills to escape, giving him a chance to survive even when his dash is not available.  It is still quite challenging to manœuvre between them.

Here's a screenshot of what I mean:

shot0003.gif

 

Note that since they blue thingies are multiplexed, they don't show up in the screenshot.  In practice, those two blue thingies, replicate vertically blocking the entire screen path.

 

Cool, nonetheless.  :thumbsup:

 

   -dZ.



#11 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 10,865 posts
  • Triple-Stripe Mo' Bro
  • Location:NC, USA

Posted Sat Jul 7, 2018 6:46 AM

  • This is something I have to test on the real Intellivision.  With the emulator on this machine, JZintv, drops 1%-2% of frames. And block copy is probably the most cycle intensive part of the frame. And I'm unsure how much cpu cycle is left before wait on that frame, and prefer the game to run at 60fps if possible.  I did some technique that let me guess where the beam is at by writing to the border color before wait and after wait. After a wait, I used border 0, then before the wait I used border 4.  If the border doesn't flash, it means that the intellivision is still drawing the screen and deny the write to the register. 

 

It doesn't necessarily have to be the scrolling skipping (I just checked in the debugger, and STIC writes are not dropped except when moving many sprites on screen -- and that was clearing the collision register of MOB #0, so that's not it).  It is most likely screen "tearing" which occurs when the copy block does not stay ahead of the STIC pre-fetch to draw the frame.

 

As you know (but for the benefit of others) the scrolling mechanic works like this:

  1. Every frame you shift then screen by one pixel via the "horizontal/vertical delay" register of the STIC.
  2. When you have shifted 8 pixels, an entire column/row has been moved, so...
    • you draw a new column/row on the appropriate edge,
    • and shift the entire screen one card in the direction of scrolling.
  3. You then reset the horizontal/vertical delay register to zero and start again with step #1.

Concurrently, the STIC drawing of the screen works like this:

  1. On every Vertical Blank (VBLANK) period of the TV raster, it interrupts the CPU giving it a chance to update the STIC and graphics memory.  This "VBLANK Period" is divided into two:
    • VBLANK 1 - in which the CPU gets access to the graphics bus and the STIC registers.  We normally update MOB, Scroll, and other STIC registers here.
    • VBLANK 2 - in which the CPU still has access to the graphics bus, but not to the STIC itself.  We normally update GRAM here.
  2. Right after VBLANK 2 completes, the CPU starts "pre-fetching" card data from the BACKTAB and populating its FIFO which ultimately will be used to guide the raster.
  3. This pre-fetching is done periodically through active display, and is done from top-to-bottom, left-to-right, i.e., in BACKTAB address order.

The trick to smooth scrolling is to get your horizontal/vertical delay updates (step #1 in scrolling algorithm above) during VBLANK 1, and to keep your screen shifts (step #2 in scrolling algorithm above) ahead of the pre-fetching requests of the STIC.  If you let the STIC overrun you, the updated BACKTAB will not make it to the next frame, and will instead have to wait an entire other frame.

 

In practice, there should be plenty of time, since copy loops are much faster than the interval of BUSRQ pre-fetching interrupts.  The critical thing is to start as early as possible so that you can stay ahead.  Once you have that lead, you're probably safe, but if you miss it -- even if you catch up -- you would have missed the updating of some BACKTAB cards.

 

Note that we're not talking about the BACKTAB not getting updated.  The updates happen as you do them (unlike GRAM when you miss the VBLANK window).  We're merely talking about those updates making it to the next frame sent to the TV raster.  Missing the pre-fetch means that the old data would be used for those cards when drawing the next frame.

 

As you may imagine, this results in the screen either "jumping" between frames, or in "tearing" when some parts belong to the new frame and others to the old frame.

 

This is why IntyBASIC reserves 20 cards for scrolling, even if you are scrolling horizontally:  in order to draw the top row as quickly as possible and stay ahead of the BUSRQ pre-fetch requests.

 

...

 

All that said, I also recommend you test your game on the Intellivision just to rule out any jzIntv quirks or PC-induced latency.  This is usually a hard problem to troubleshoot.  In my experience, the best way to handle this is to have as much stuff pre-calculated on a previous frame, and make sure to optimize the top of your game loop (i.e., after calling WAIT) to do all it needs to do.  Critical stuff are, in order:

  1. MOB registers
  2. Scroll registers
  3. GRAM updates
  4. Scroll screen shifts

The first two must be done at the tipity-top, there's no way around it; you need VBLANK 1 for that.  The last two need to be coordinated so that your graphics and background can be updated adequately with minimal impact.  Who has priority depends on your preference, but if there are not enough cycles to do both, you'll have to be aware that one will be affected.

 

     -dZ.

 

 

P.S.  To intvnut and other experts:  I wrote the above from memory with the best of intentions to simplify the very technical aspects of the issue and help programmers deal with smooth scrolling.  If I got something wrong or inaccurate, please let me know so that I can correct it.  :)


Edited by DZ-Jay, Sat Jul 7, 2018 6:59 AM.


#12 Kiwi OFFLINE  

Kiwi

    Stargunner

  • Topic Starter
  • 1,564 posts

Posted Sat Jul 7, 2018 7:32 PM


  •  

    • VBLANK 2 - in which the CPU still has access to the graphics bus, but not to the STIC itself.  We normally update GRAM here.

 

This is interesting.   I guess my poke to the border register won't work here.  I shouldn't worry too much about the scrolling lag now and the game still run ok enough.   I gotta build the 2nd level, the cave. 

The scroll code is right after the wait. 
 

	WAIT
'	poke $2C,0
if scrolloffset=7 AND scrolltime=0 then gosub DrawStrip:treespawn=treespawn-1:#leveltime=#leveltime-1
if scrolltime=0 then scrolltime=scrollspeed:scrolloffset=scrolloffset-1: if scrolloffset=255 then move=2 :scrolloffset=7
if scrollon=1 then scrolltime=scrolltime-1
SCROLL scrolloffset,0,move
move=0	

 

 

  1. MOB registers
  2. Scroll registers
  3. GRAM updates
  4. Scroll screen shifts

Looking at the .list, intybasic handles that upon wait. 



#13 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 10,865 posts
  • Triple-Stripe Mo' Bro
  • Location:NC, USA

Posted Sun Jul 8, 2018 4:19 AM

Hmm... I think you got it reversed.  I'll wait for nanochess to confirm, but my understanding is that (see UPDATE below) The SCROLL statement will buffer the scroll update until the next frame.  I see that the "scroll.bas" example suggests this as well by performing the WAIT after the scroll statement:

REM >>>> Scroll to right
FOR time=1 to 240
	IF offset_x=0 THEN offset_d=2:offset_x=7 ELSE offset_x=offset_x-1
	SPRITE 0, 64 + VISIBLE + ZOOMX2 - offset_x, 48 + ZOOMY2 - offset_y, SPR02 + SPR_YELLOW
	SCROLL offset_x,offset_y,offset_d
	WAIT
	offset_d=0
	IF offset_x=7 THEN COL=19:GOSUB clear_column:PRINT AT RAND%BACKGROUND_ROWS*BACKGROUND_COLUMNS+19,"\257"
NEXT time

The idea is that, by the time WAIT is called (i.e., when the next VBLANK interrupt occurs), all the scrolling information is ready to go.

 

This is similar to all MOB information:  remember, you are composing the next frame.

 

About the only thing that you need to check right after WAIT is collision and user input, which came from the previous interrupt, and are needed to update the game state for the next frame.

 

    -dZ.

 

 

UPDATE:  The IntyBASIC manual confirms that the SCROLL statement is buffered until the next frame.


Edited by DZ-Jay, Sun Jul 8, 2018 4:54 AM.


#14 PuzZLeR OFFLINE  

PuzZLeR

    Chopper Commander

  • 121 posts
  • WiLd CaRd
  • Location:Toronto Canada

Posted Tue Jul 10, 2018 1:48 PM

Tough to beat.






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users