Jump to content
IGNORED

Collision detection question...


PacManPlus

Recommended Posts

Hello all:

 

Does anyone have a good algorithm (that applies to the 7800) to check collision between a 'ball' sprite and a background character (tile)? I'm trying to come up with one, as the major problem is I also need to know *where* the ball hit the tile (i.e. the left side, right side, top, or bottom). Sometimes the ball moves pretty fast so by the time I get to check there may be a false reading of the ball having a 'top' and 'left' collision (for example) when in all actuality it's the same tile and not two different ones. (The ball is so deep in the tile from moving fast that the top of it *and* the side are in the same tile).

 

Any advice?

 

Thanks in advance,

Bob

Link to comment
Share on other sites

Hello all:

 

Does anyone have a good algorithm (that applies to the 7800) to check collision between a 'ball' sprite and a background character (tile)? I'm trying to come up with one, as the major problem is I also need to know *where* the ball hit the tile (i.e. the left side, right side, top, or bottom). Sometimes the ball moves pretty fast so by the time I get to check there may be a false reading of the ball having a 'top' and 'left' collision (for example) when in all actuality it's the same tile and not two different ones. (The ball is so deep in the tile from moving fast that the top of it *and* the side are in the same tile).

 

Any advice?

 

Thanks in advance,

Bob

Is knowing if it is closer to the top or closer to the left good enough? If not, maybe the position of the ball last checked or the vertical and horizontal speed could be used?

Link to comment
Share on other sites

Hello all:

 

Does anyone have a good algorithm (that applies to the 7800) to check collision between a 'ball' sprite and a background character (tile)? I'm trying to come up with one, as the major problem is I also need to know *where* the ball hit the tile (i.e. the left side, right side, top, or bottom). Sometimes the ball moves pretty fast so by the time I get to check there may be a false reading of the ball having a 'top' and 'left' collision (for example) when in all actuality it's the same tile and not two different ones. (The ball is so deep in the tile from moving fast that the top of it *and* the side are in the same tile).

 

Any advice?

 

Thanks in advance,

Bob

Is knowing if it is closer to the top or closer to the left good enough? If not, maybe the position of the ball last checked or the vertical and horizontal speed could be used?

 

When you get a collision, see which direction the ball is heading to help determine where it hit first. You may need to back it up a fraction as well.

Link to comment
Share on other sites

If the ball is moving more than 1 pixel per frame, but less than one tile per frame, then you first do a simple bounding box to see if the ball is inside the tile. Then you do a line intersection between the line the ball is moving along and each of the tile's sides.

Link to comment
Share on other sites

Thanks Guys:

 

Your advice reaffirmed me to go back to what I started with. It originally didn't work, but this time it's much better. I know there are still a few places to fix, but the majority of the ball/playfield collisions are ok. :)

 

(See attachment)

 

Unfortunately, this speed is the fastest the ball can go without beginning to move through walls, etc. So there is some more to figure out. As it is, I've still seen it go through a wall once or twice :(

 

This is going to be a pinball/breakout hybrid. As you can see from the attachment, I started with the BombBee playfield - but that's just to test with. This playfield will not be in the final product. It's going to be along the same lines of BombBee/GeeBee/CutieQ, but with some functional differences. Also, I plan on holding a playfield design contest because I want 32 different screens to advance to.

 

The paddles do work (on the real thing), but there is no paddle/ball detection yet.

 

I figure I should get the 'paddle' games out of my system. ;)

Link to comment
Share on other sites

I think I got it, although the ball cannot move faster that 2 pixels horizontally - due to the 'top' of the ball being in the same character. Problem is (for example) if the ball is moving at a velocity of 3 pixels horizontally to the right and 2 pixels horizontally up, the ball *could* (and has) been 3 pixels deep in a vertical wall - making the 'top' of the ball inside the same wall. Now, being that the ball is moving 'right' and 'up' they are both valid positions, so it acts on both directions, sending the ball back in the direction it came instead of just negating the 'x' velocity.

 

Also,

 

Attached is the fastest speed currently the ball can travel. Let me know if you see any 'abnormal' behaviour.

 

Thanks,

Bob

Link to comment
Share on other sites

Oh, btw, I saw the same thing in Arkanoid. :)

Eventually, yes, you end up with a speed limitation.

If you demo Arkanoid, and just let it go faster and faster, eventually, it gets into weird states where it can't do collision detection well, and the ball may either miss tiles or do some weird things.

 

I tried getting around it by keeping track of the ball direction, and hit 2 routines based on that.

So, for example, if going up and left, I would do the left collision check, followed by the up collision check.

When going up and left, I would check the up-left pixel and see if it hit on my grid.

I'd check all of the positions along the top, and all along the side.

If memory serves, it's a 3x5 ball, so I checked 7 places. If there was a hit, it would stop checking, and rotate velocity accordingly.

 

I can dive in and share some source code if you're interested.

Note that it wasn't perfect-- there was a bug somewhere in there, but I didn't figure it out before putting that project on hiatus.

 

-John

Link to comment
Share on other sites

Oh, btw, I saw the same thing in Arkanoid. :)

Eventually, yes, you end up with a speed limitation.

If you demo Arkanoid, and just let it go faster and faster, eventually, it gets into weird states where it can't do collision detection well, and the ball may either miss tiles or do some weird things.

 

 

Would trying to include a "phantom ball" slightly ahead of the real ball help with collision detection when going really fast? The phantom not actually being displayed, just it's coordinates being used to calculate a potential collision to react on (Since if you waited until the next frame, the real ball would be past the current phantom's position and probably too far into the block to accurately detect a proper collision.

 

No idea if it'd work or not as I haven't tried it before. Just a random thought.

Link to comment
Share on other sites

Hi Guys:

 

John - here is the paddle code *ONLY WORKS IN DLIs* I tried moving it, got a blank screen :(

 

BIG Thanks to DEBRO for giving me this code...

 

DLITOP
         LDA     #$00
         STA     DLITEMP                 ;THIS IS THE LINE COUNTER THAT'S USED TO FIGURE OUT WHAT ZONE WE ARE IN
         LDA     #$01
         STA     DLIFLG                  ;THIS JUST TELLS THE NEXT DLI THAT WE ARE AT THE BOTTOM
DLIPADDLES
         LDA     #$00
         STA     INPTCTRL                ;THIS NEEDS TO BE DONE TO START THE PADDLE DISCHARGE

         LDY     #73                     ;THE NUMBER OF RASTERS I NEED FOR FULL RANGE OF PADDLE MOVEMENT (YOUR MILEAGE MAY VARY)
DLIPLOOP
         STA     WSYNC                   ;ENSURE THE BEGINNING OF A LINE
         LDA     INPT2                   ;CHECK PADDLE 3 (FIRST PADDLE IN SECOND PORT)
         BMI     DLISKIP0                ;PADDLE NOT BEING USED - SKIP
         STY     OUTP0                   ;SAVE CURRENT RESISTANCE
DLISKIP0
         LDA     INPT3                   ;CHECK PADDLE 4 (SECOND PADDLE IN SECOND PORT)
         BMI     DLISKIP1                ;PADDLE NOT BEING USED - SKIP
         STY     OUTP1                   ;SAVE CURRENT RESISTANCE
DLISKIP1
         LDA     DLITEMP                 ;GET CURRENT RASTER
         LSR                             ;DIVIDE BY 4 TO GET CURRENT ZONE (I THINK THE ABOVE PADDLE ROUTINE TAKES 4 LINES)
         LSR
         TAX
         LDA     ZONCOLOR,X              ;GET THE COLOR FOR THIS ZONE
         STA     Z0C3                    ;UPDATE IT
         INC     DLITEMP                 ;INCREMENT THE RASTER COUNT
         DEY                             ;DECREMENT THE PADDLE DISCHARGE COUNT
         BNE     DLIPLOOP                ;DO IT ALL AGAIN.

My DLL is set up with one interrupt at the top (for the above code) and one at the bottom (to do VBlank stuff).

 

I think at this point the collision detection is where I want it.

 

Thanks guys for the compliments and the advice.

 

@Walter - I may add joystick support later on. :)

 

Here's the .a78 and bin, now with paddle collision detection (only the top paddle though, as I still have the ball rebounding from the bottom of the screen).

 

Still not sure what I'm going to do about the 'Kangaroo' issue though... :ponder:

 

Bob

Link to comment
Share on other sites

Thanks Drac / potatohead

 

Pretty soon I will move this to the appropriate place in the 7800 forum, but I want to do the following first:

- Animation of the bumpers and spinners

- points for spinners

- ball seems to get 'stuck' a lot

- hitting all 'bonus' lights incrementing a multiplier

 

Here are a few more screenshots for now:

post-1787-129461732373_thumb.png

post-1787-12946174463_thumb.png

post-1787-129461732772_thumb.png

 

Thanks again... I know I'm not doing the great work that GroovyBee is doing, but I'm doing what I'm capable of.

Bob

  • Like 4
Link to comment
Share on other sites

Better than I can do! And it really does look good. Don't beat yourself up on that stuff.

 

I'm kind of fixated on the more square pixel look, and your game, fonts, etc... has it! I gotta get a good 7800 to play on again. Doing paddle games is really great! They are my favorites.

 

Are you gonna leave the paddles white?

Edited by potatohead
Link to comment
Share on other sites

Thanks again... I know I'm not doing the great work that GroovyBee is doing, but I'm doing what I'm capable of.

Bob

 

Good Gravy!

 

Don't denigrate yourself! You've released some great stuff and your contributing more to the 7800 homebrew scene than almost everyone else short of a couple people. Believe you me, you're up there int the pantheon of 7800 gods.

 

 

I have to say that this pinball/breakout hibred thing really looks to be a neat idea. I'm really looking forward to seeing what the end product is like.

Edited by Lendorien
Link to comment
Share on other sites

Thank guys :)

 

I've made quite a bit of progress on this, but the only area I'm having an issue with is ball movement. It was getting stuck *quite a bit* and I'm trying to find good angles and speed increases. If I can get past this, I only need to create the playfields. Like I stated before, I plan on having 32 playfields. Not sure yet if they will be random or played straight through.

 

Wish I could find a good table of x and y ball movements (including rebounds and the like). It seems silly to 'reinvent the wheel' as I'm sure this was already done somewhere.

 

Thanks,

Bob

Link to comment
Share on other sites

I've made quite a bit of progress on this, but the only area I'm having an issue with is ball movement. It was getting stuck *quite a bit* and I'm trying to find good angles and speed increases.

 

Can you explain the algorithm/logic you've come up with for movement/hit detection so far?

Link to comment
Share on other sites

Sure!

 

I'll break this up into two parts: collision and ball properties

 

For collision, I have a table of each tile, and what to do if the ball hits the top, left, right and bottom of each tile. Please note that there are only 128 tiles (not 256) because I'm using 320B mode with two-byte character mode which only leaves me with half the normal number of characters:

 

;  THESE ARE THE TABLES FOR WHAT TO DO WHEN THE BALL HITS A CERTAIN CHARACTER FROM EACH SIDE (UP,RIGHT,LEFT,DOWN)
;  THE OPTIONS ARE AS FOLLOWS:
;  MAKE Y NEGATIVE (PAIED WITH BIT 1 BELOW)
;  |MAKE X NEGATIVE (PAIRED WITH BIT 0 BELOW)
;  ||ANIMATE CHARACTER (I.E. BUMPER) (NEED CHARACTER)
;  |||CLEAR CHARACTER BALL HIT (NEED CHARACTER)
;  ||||ADD POINTS (NEED CHARACTER)
;  |||||SWAP X AND Y VALUES (BOUNCE ON A 45 DEGREE ANGLE)
;  ||||||MAKE Y POSITIVE
;  |||||||MAKE X POSITIVE
;  ||||||||
;  XXXXXXXX 

ACTBALLL

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000

 

.byte %11101100,%10101000,%10101001,%01101000,%00101000,%00101001,%01101110,%00101010,%00101011

.byte %01101000,%00101000,%00101001,%01101000,%00101000,%00101001

.byte %00001000,%01011000,%01011000,%01011000,%00001000,%00001000

.byte %01000000,%01000000,%11000100,%01000000,%01000110,%00000000,%01000000,%01000000

.byte %01000000,%01000000,%01000110,%11000100,%01000000,%01000000,%01000000,%01000000

 

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000

.byte %00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000

.byte %00011000,%00011000,%00011000,%00011000,%00101000,%00101000

ACTBALLR

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000

 

.byte %11101100,%10101000,%10101001,%01101000,%00101000,%00101001,%01101110,%00101010,%00101011

.byte %01101000,%00101000,%00101001,%01101000,%00101000,%00101001

.byte %00001000,%00011001,%00011001,%00011001,%00001000,%00001000

.byte %00000001,%10000101,%00000001,%00000111,%00000001,%00000000,%00000001,%00000001

.byte %00000001,%00000001,%00000111,%00000001,%00000001,%00000001,%00000001,%00000001

 

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000

.byte %00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000

.byte %00011000,%00011000,%00011000,%00011000,%00101000,%00101000

ACTBALLT

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000

 

.byte %11101100,%10101000,%10101001,%01101000,%00101000,%00101001,%01101110,%00101010,%00101011

.byte %01101000,%00101000,%00101001,%01101000,%00101000,%00101001

.byte %00001000,%10011000,%10011000,%10011000,%00001000,%00001000

.byte %10000000,%10000101,%11000100,%10000000,%10000000,%00000000,%10000000,%10000000

.byte %01000110,%11000100,%10000000,%10000000,%10000000,%10000000,%10000000,%10000000

 

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000

.byte %00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000

.byte %00011000,%00011000,%00011000,%00011000,%00101000,%00101000

ACTBALLB

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00000000,%00000000,%00000000

 

.byte %11101100,%10101000,%10101001,%01101000,%00101000,%00101001,%01101110,%00101010,%00101011

.byte %01101000,%00101000,%00101001,%01101000,%00101000,%00101001

.byte %00001000,%00011010,%00011010,%00011010,%00001000,%00001000

.byte %00000010,%00000010,%00000010,%00000111,%01000110,%00000000,%00000010,%00000010

.byte %00000111,%01000110,%00000010,%00000010,%00000010,%00000010,%00000010,%00000010

 

.byte %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000

.byte %00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000

.byte %00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000,%00011000

.byte %00011000,%00011000,%00011000,%00011000,%00101000,%00101000

 

Here is the Character map that goes with the above table:

post-1787-129502918871_thumb.png

 

Now, regarding ball movement, what I *did* have until today was a routine to take each bit from the table above and act on it:

CHGBSWAP
         LDA     TEMP6                   ;THE VALUE FROM THE TABLE ABOVE
         AND     #$04                    ;ARE WE SWAPPING VALUES?
         BEQ     CHGBNEGX                ;NOPE, SKIP
         LDA     BALLYDIR,X              ;YES
         PHA
         LDA     BALLXDIR,X
         STA     BALLYDIR,X
         PLA
         STA     BALLXDIR,X
CHGBNEGX
         LDA     TEMP6
         AND     #$40                    ;MAKE X NEGATIVE?
         BEQ     CHGBNEGY                ;NOPE, SKIP
         LDA     BALLXDIR,X
         BMI     CHGBNEGY                ;X IS ALREADY NEGATIVE
         EOR     #$FF
         CLC
         ADC     #$01
         STA     BALLXDIR,X
CHGBNEGY
         LDA     TEMP6
         AND     #$80                    ;MAKE Y NEGATIVE?
         BEQ     CHGBPOSX                ;NOPE, SKIP
         LDA     BALLYDIR,X
         BMI     CHGBPOSX                ;Y IS ALREADY NEGATIVE
         EOR     #$FF
         CLC
         ADC     #$01
         STA     BALLYDIR,X
CHGBPOSX
         LDA     TEMP6
         AND     #$01                    ;MAKE X POSITIVE?
         BEQ     CHGBPOSY                ;NOPE, SKIP
         LDA     BALLXDIR,X
         BPL     CHGBPOSY                ;X IS ALREADY POSITIVE
         EOR     #$FF
         CLC
         ADC     #$01
         STA     BALLXDIR,X
CHGBPOSY
         LDA     TEMP6
         AND     #$02                    ;MAKE Y POSITIVE?
         BEQ     CHGBPOINT               ;NOPE, SKIP
         LDA     BALLYDIR,X
         BPL     CHGBPOINT               ;Y IS ALREADY POSITIVE
         EOR     #$FF
         CLC
         ADC     #$01
         STA     BALLYDIR,X

 

I had three variables to work with as far as these went: X Direction, Y Direction, and FrameSkip (the number of frames to skip before moving the ball).

 

What I am doing today and I am in the middle of, is trying to create a table of ball movements, and just read from that table. I have split the 'FrameSkip' into separate X and Y values. Being that the 'X' value can't really go past 2 pixels per movement (in either direction) before causing problems - (because the X direction already moves in 2-pixel increments in 320 mode), I have to play with the $FE,$FF,$01,$02 values, along with the FrameSkipX value to get different ball movements. In the Y direction, I can use up to 3 pixels per movement before causing issues. This leaves $FD,$FE,$FF,$01,$02,$03 and the FrameSkipY values to get different ball movements. And I have to swap / negate all of these directions as well.

 

Just trying to find the correct algorithm. :)

 

Thanks,

Bob

 

EDIT - crap - the 'code' tag removed the percent signs...

Edited by PacManPlus
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...