Jump to content
  • entries
    106
  • comments
    796
  • views
    139,607

GTD: Number Three

Sign in to follow this  
Guest

690 views

I KEEP TINKERING and tinkering with this two-sprite flicker engine.

 

I'm not real enamored with it, but I'm having fun playing with it. I haven't drastically changed the kernel; despite my bold words, I haven't been able to make it work. :lol:

 

But I was able to figure out a quick sorting method that does work with the flicker engine. It isn't perfect, but objects don't disappear and it is slightly better than a 1-sprite flicker engine. The sort returns results like this:

 

For 3 objects:

123132123

 

For 4 objects:

1234134214231234etc.

 

In all cases, the first two objects are shown, only. So the highest object is shown on all frames and the following objects are rotated, once per frame.

 

It's a little more complicated than that, but that's the basic effect. And the sort is fairly fast, almost as fast as the flicker sort.The sorting algorithm is as follows:

1. Does this sprite have the same Y-value as the next sprite (in the list)? If so, swap them and move to the next sprite in the list, returning to 1.

2. Does the previous sprite overlap the the next sprite? If so, swap this sprite and the next sprite, move to the next sprite and return to 1.

 

As Manuel noted, and I was expecting, processing all these sprites (flicker-sorting, moving, etc.) takes a *lot* of time. Too much time, actually. So I split things over two frames. The current 2FP (2-frame program :lol:) goes a li'l something like this:

Move Sprites

Display

Flickersort

Display

repeat.

 

The next big step (BIG!) will be adding collision detection. A complete, brute force collision detection routine would take too long; impossibly long. To test each sprite (my engine supports 22 currently) against every other sprite to see if they overlap and have collided - ! Yeesh! What is that, 22! comparisons? Ouchie.

I wasn't sure exactly how I was going to solve that problem, then it came to me: if I assume that the flickersort will have the sprites in rough order (if not now then perhaps soon, anyway!), then I can just test each sprite against the sprites that are near it in the list. And since I only need to test collisions between the player's ship and enemies and the player's bullets and enemies (but not bullet-to-bullet and not enemy-to-enemy), that will cut things down to a (hopefully) manageable level. So the final 2FP will look like this:

Move Sprites

Display

Flickersort

Check Collisions

Display

 

With other assorted game logic fit into the cracks. At least that's the hope.Anyway, here's the demo without collisions working: ss.bin (See below!)Hit SELECT to change weapons.

Screenshot:

blog-6060-1138815694_thumb.jpg

EDIT: Got collisions working! Screen jumps rarely, I think. Flicker also becomes a bit intolerable, but that can probably be cleaned up somewhat by tweaking what happens when objects collide. ss.bin

Sign in to follow this  


5 Comments


Recommended Comments

I wasn't sure exactly what I was going to solve that problem, then it came to me: if I assume that the flickersort will have the sprites in rough order (if not this frame then perhaps soon, anyway!), then I can just test each sprite against the sprites that are near it in the list. And since I only need to test collisions between the player's ship and enemies and the player's bullets and enemies (but not bullet-to-bullet and not enemy-to-enemy

 

You're also going to need to test the collision between the enemy's bullets and the player's ship. The amount of comparisons might be reduced drastically if you restrict the number of bullets that each ship is allowed to fire. For example, if you only allow each enemy ship to have one bullet on the screen at one time instead of two (for instance), that will reduce the amount of collisions possible by half (at the most). A more lame solution would be to restrict the number of bullets the player can fire, say, to three (Mega Man style), instead of unlimited.

 

Also, as I can't watch the new demo at the moment, if the enemy ships only move vertically, you would only need to check alignment between the player's ship/bullets and the enemy's ships/bullets. If they're not vertically aligned, then there is no reason to test for collision. However, if the enemy's ships can move horizontally, then that will make things more complicated. Edit: Hmmm, never mind. I just realized that you can move wherever you want, so horizontal collisions are indeed possible. Never mind.

 

And, of course, my usual disclaimer that I don't really know what I'm talking about, so this might have made no sense whatsoever.

Share this comment


Link to comment

I think eventually I will have to restrict the number of bullets on the screen.

 

It is restricted now, to some extent, just by the bullets' speed.

 

Right now the max number of enemies on screen at once is 10, and the player's ship uses 2 sprites, so that leaves 10 sprites for player bullets. At the speed the bullets travel now, and with the rate of fire I'm allowing now, I don't think you can max out the sprites.

...

Just looked with the Stella debugger and it looks like it is maxing out at 21 sprites onscreen. Might be hitting 22 occasionally.

Share this comment


Link to comment

I think I figured out a good flicker algorithm; it seems to run reasonably in some simulation tests, though I'll have to bash it a bit more. Each object has two flag bits: show_now, and show_recent. Flicker generation requires two loops.

 

Key variables (other than loop indices) are pos1 and pos2 (bottom positions of the two sprites, pos2 always being the lower) and who1 and who2 (indices for who owns the two sprites at the current part of the scan, if the sprites are eligible for "repossession").

First loop:
 Set pos1 and pos2 to 0
 For each item i
   If ypos(i) > pos1 (no conflicts from above)
     show_now(i) = 1
     pos1 = pos2
     who1=who2
     pos2 = ypos(i)+sprite_height
     if show_recent(i)
       who2 = i
     else
       who2 = 255
     endif
     show_recent(i)=1
   else if who2<>255 and show_recent(i)==0  ' Repossess lower sprite
     show_now(who2)=0
     show_now(i)=1
     pos2 = ypos(i)+sprite_height
     who2 = 255
     show_recent(i)=1
   else if who1 <> 255 and show_recent(i)==0  ' Repossess upper sprite
     show_now(who1)=0
     show_now(i)=1
     pos1 = pos2
     who1 = who2
     pos2 = ypos(i)+sprite_height
     who2 = 255
     show_recent(i)=1
   else
     show_now(i)=0
 End loop

Second loop:
 Set cf to 0
 For each item
   If show_now(i) then
     set cf to show_recent(i)
   else if cf then
     show_recent(i)=0
 End loop

 

Simulation suggests that this algorithm should work pretty well. Here's a clip from a typical run (sprite height=8, with one dot required between sprites)

---
...AAAAAAAA.FFFFFFFF...KKKKKKKK...NNNNNNNN....QQQQQQQQ..
....BBBBBBBB..GGGGGGGG....LLLLLLLL....OOOOOOOO..........
---
.....CCCCCCCC...HHHHHHHH..LLLLLLLL....OOOOOOOO..........
......DDDDDDDD....IIIIIIII....MMMMMMMM....PPPPPPPP......
---
...AAAAAAAA.FFFFFFFF...KKKKKKKK...NNNNNNNN....QQQQQQQQ..
..........EEEEEEEE..JJJJJJJJ..MMMMMMMM....PPPPPPPP......
---
....BBBBBBBB..GGGGGGGG.KKKKKKKK...NNNNNNNN....QQQQQQQQ..
.....CCCCCCCC...HHHHHHHH..LLLLLLLL....OOOOOOOO..........
---
......DDDDDDDD....IIIIIIII....MMMMMMMM....PPPPPPPP......
..........EEEEEEEE..JJJJJJJJ......NNNNNNNN....QQQQQQQQ..
---
...AAAAAAAA.FFFFFFFF...KKKKKKKK...NNNNNNNN....QQQQQQQQ..
....BBBBBBBB..GGGGGGGG....LLLLLLLL....OOOOOOOO..........
---
.....CCCCCCCC...HHHHHHHH..LLLLLLLL....OOOOOOOO..........
......DDDDDDDD....IIIIIIII....MMMMMMMM....PPPPPPPP......

Each character is one scan line; the two rows for each frame show what's done with the two sprites. With that particular batch of sprites, the pattern repeats every five scan lines. Sprites that can be shown more often (like "Q", which only has a conflict in one out of every five scan lines) are.

Share this comment


Link to comment

The engine looks very good - just add vertical scrolling and you will have the makings of an Xenon port ;) It is very interesting to see that flickering both sprites (instead of one) doesn't make that much difference to the visual quality - this is something that I was also thinking about for Juno First.

 

Chris

Share this comment


Link to comment
I think I figured out a good flicker algorithm; it seems to run reasonably in some simulation tests, though I'll have to bash it a bit more.  Each object has two flag bits: show_now, and show_recent.  Flicker generation requires two loops.

Before I go to the trouble of trying to decipher your pseudo C code (;)), I thought I'd ask: is this flickersort designed to work with my kernel as-is? If it hasn't been clear from the past few blog posts how my kernel works, I'll be happy to explain. ;)

 

And thanks for taking the time to work this out.

 

And Chris

It is very interesting to see that flickering both sprites (instead of one) doesn't make that much difference to the visual quality - this is something that I was also thinking about for Juno First.

I wouldn't give up on the two-sprite flicker just yet. My engine certainly isn't an optimal one, and probably the flickersort I'm using could be dramatically improved, but even still, in some situations the display looks much, much better than a single-sprite engine would.

 

I think the difference between my engine and a single-sprite engine is smallest, perhaps counterintuitively, when there are many many sprites on the screen. But when there are fewer, there are many situations where 30 Hz flicker (with a 1-sprite engine) can be turned into no flicker (with my engine). ;)

 

It isn't perfect or even perhaps very good, but it is a little bit better. ;)

 

EDIT: John, does your flickersort require that the sprites be looped through from top to bottom or bottom to top? Or does it matter?

 

EDIT II: Okay, after a little more study I see that it probably doesn't matter. But now I have another question: I assume that the kernel should only display sprites with the show_now flag set, yes? Not sure I can fit that additional check into the kernel; I'll see.

Share this comment


Link to comment
Guest
Add a comment...

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