Jump to content
  • entries
    106
  • comments
    796
  • views
    140,766

Step Two! There's so much we can do...


Guest

662 views

ARKANOID 2600?

I think I'll go through my already-started projects one by one and evaluate the pros and cons of each game as well as looking at the problems I encountered in each one.
Next up, my flier for an Arkanoid port to the 2600.Let's see...July 18 2005 looks like the latest source I have.Here's the latest, buggy, binary: It also has a thread in the homebrew forum.Here's a screenshot:Judging from the date on the latest source I have, I last worked on it January 21st of this year.Here's a screenshot:Status of this project:Preliminary, working kernel written, with 15x16 brick playfield, two larger balls, two (flickering) enemies, and a paddle-controlled, uh, paddle. :)Current version supports two kinds of bricks: breakable and unbreakable.I think I have a reasonable way to implement three kinds (unbreakable, breakable with two hits, and breakable with one hit), but it would require rewriting the kernel. And I'm not entirely sure it would work.Collision detection is buggy as hell.Second (and third) ball not moving.Ball-to-brick collision detection, besides not working, takes a LOOOOONG time. Implementing for three balls may not work because it takes so damn long.Needs a TON of work before it even has one playable level, let alone being an actual game. As an example, the (non-working) collision detection is hard-coded for only one level.Reason I stopped working on this:I needed to stop dinking around and focus on getting M-4 completed for the mid-August show.I didn't, and still don't, have a solution for the collision problem (specifically, how to do it faster).Pretty much everybody who commented on the project wanted:1. bigger balls :ponder:2. three balls :ponder: :ponder: :ponder:3. bricks that took multiple hits to breakI got 1 and 2 mostly implemented, but not 3, though I have since figured out a way to do it that I think would work (involving a 256-byte table).Pros of this project:Judging by the response to the trial balloon I floated in the homebrew forum, lots of people would be very enthusiastic about it.I'm pretty sure I could get a kernel that had three large, breakout-style balls, three types of bricks, two enemies, the floating pills, and a paddle-controlled paddle.I like breakout-style games.Having a screen-designing contest would be very cool.Cons of this project:Having a bunch of people looking over my shoulder and comparing my work to the million other versions of the game might not be the most fun in the world. :)I like Arkanoid, but it isn't my favorite game in the world. And, I really *don't* like the enemies in it - a bunch of twirling geometric shapes? Boring!I like this project, but I just can't seem to muster up a lot of enthusiasm for it right now. Of all my tentative projects, it is and would be by far the most popular. So I dunno.

9 Comments


Recommended Comments

Hi there!

 

Not sure what's the problem with the collisions. Basically you'd use hardware collisions to detect *that* a collision happened and then only need code to determine *which* block was hit, or?

 

For that you'd divide the ball position by 4 with two LSR, determine then the right PF column and then clear it with a mask table.

 

Or am I overlooking something?

 

Greetings,

Manuel

Link to comment
Hi there!

 

Not sure what's the problem with the collisions. Basically you'd use hardware collisions to detect *that* a collision happened and then only need code to determine *which* block was hit, or?

 

For that you'd divide the ball position by 4 with two LSR, determine then the right PF column and then clear it with a mask table.

Well, kinda. To determine which way to make the ball bounce (i.e., which axis of velocity to reverse) you have to know whether the ball hit the brick on a side or the top or bottom. Plus the corners are special cases.

 

Which isn't too hard when the ball is a single pixel. You just check that one position against the PF table (basically just like you outlined), if it hit a brick, then you find where on the brick (instead of two LSRs, you AND #3), then send the ball in the appropriate direction based on that.

 

It was working mostly fine with the wee balls.

 

But, with the larger balls, I then had four positions to check: each corner of the ball needed checking (well, I suppose a maximum of three corners needed checking) to see if it is touching a brick.

 

The hardware collision doesn't help much one way or another because if CXxxxx shows a collision, I still have to check all the corners to determine which brick(s) the ball hit and which way to send the ball bouncing in response.

 

Plus, with three balls on screen, not only would I have to check the corners of all three balls every frame, but two of the balls would be flickering at 30 Hz, thereby rendering the hardware collision detection useless in that case anyway.

 

Not that it's impossible to solve this problem; I just haven't figured out how - yet. :)

 

Here's the subroutine I was using to check for a ball-to-brick collision - I called this for each corner of the ball:

BallToBrickPointCheckSubroutine
 ;--first, change X,Y coords into row and column
  lda Temp+2          ;Y value
  sec
  sbc #26
  lsr
  lsr
  lsr                 ;divide by 8
  sta Temp+2          ;save row

 ;---now, find column
  lda Temp+1          ;X Value
  sec
  sbc #17
  lsr
  lsr
  lsr                 ;divide by 8
  sta Temp+1          ;save column

 ;--have column and row.  Now, does that brick exist on screen (in RAM)?
  lda Temp+1          ;load column
  lsr
  lsr                 ;divide by four == colgroup
  tay
  lda BrickMaskTableLo,Y
  sta PtrTemp
  lda BrickMaskTableHi,Y
  sta PtrTemp+1

  lda Temp+1          ;get column
  and #%00000011      ;get offset into colgroup
  tay
  lda (PtrTemp),Y     ;get exact mask
  sta Temp+3          ;save it

  lda Temp+1
  lsr
  lsr                         ;Y == colgroup
  tay
  lda BrickRAMTableLo,Y
  sta PtrTemp
  lda #0                      ;zero page
  sta PtrTemp+1
  ldy Temp+2                  ;load row
  lda (PtrTemp),Y             ;get brick RAM group
  and Temp+3                  ;use mask to isolate brick at row,col
  beq NoBrickExists

 ;--brick exists - so, destroy if possible and initiate pill, else just return
  lda Level0L,Y               ;Y==row
  sta Temp+4
  lda Level0LC,Y
  sta Temp+5
  lda Level0RC,Y
  sta Temp+6
  lda Level0R,Y
  sta Temp+7
  lda Temp+1                  ;load column
  lsr
  lsr
  tay                         ;Y == colgroup
  lda Temp+4,Y                ;get brick group
  and Temp+3                  ;isolate brick with mask in Temp+3

 ;--now see if it is indestructible or not
  sta Temp+4                  ;save isolated brick
  lda #%01010101
  and Temp+3                  ;and with mask
  cmp Temp+4  
  beq IndestructibleBrick
 ;--else, brick exists and can be destroyed
  lda Temp+3          ;get mask and invert it
  eor #$FF
  sta Temp+3          ;save inverted mask
  ldy Temp+2          ;load row
  lda (PtrTemp),Y     ;get brick RAM variable
  and Temp+3          ;clear brick
  sta (PtrTemp),Y  
 ;--brick cleared; drop pill if appropriate
;   jsr InitiatePillSubroutine

IndestructibleBrick
  sec
  rts
NoBrickExists
  clc
  rts

Any and all improvements/suggestions are welcome!

Link to comment
But, with the larger balls, I then had four positions to check: each corner of the ball needed checking (well, I suppose a maximum of three corners needed checking) to see if it is touching a brick.

 

I'm not sure if this helps, but there seems to be a neat deflection routine on this page. It appears to work by checking which edge of the brick is closest to the center of the ball and then deflecting accordingly. I'm not sure how this would work on the Atari, but it seems to be simpler than your approach.

 

Chris

Link to comment
But, with the larger balls, I then had four positions to check: each corner of the ball needed checking (well, I suppose a maximum of three corners needed checking) to see if it is touching a brick.

 

I'm not sure if this helps, but there seems to be a neat deflection routine on this page. It appears to work by checking which edge of the brick is closest to the center of the ball and then deflecting accordingly. I'm not sure how this would work on the Atari, but it seems to be simpler than your approach.

 

Chris

Thanks for the link. I'm not sure that will help directly, but it always helps to look at things from a different perspective. :)

Link to comment

Hi there!

 

Any and all improvements/suggestions are welcome!

 

Just to make that clear, is the code already working, but just too slow? I mean are you asking for a speedup or a solution? :)

 

Greetings,

Manuel

Link to comment
Any and all improvements/suggestions are welcome!

 

Just to make that clear, is the code already working, but just too slow? I mean are you asking for a speedup or a solution? :)

Well...;)

 

If you run the demo binary I attached, you'll see that collision detection is completely screwy. Sometimes it doesn't register a collision that it should register, the ball often bounces the wrong direction, etc.

 

I'm not sure exactly what is wrong with the detection...it might be the code I posted or it might be something else entirely! ;)

 

I *think* this code should work correctly, just reading through it yesterday I didn't see any problems, and I went through it very carefully in July and couldn't find the problem(s) in this routine then, either.

 

So, mostly, a speedup ;) Though if you see anything that looks goofy, let me know!

Link to comment

Hi there!

 

Ok, so I'll start with looking through this. Let's star with this part:

 

BallToBrickPointCheckSubroutine
 ;--first, change X,Y coords into row and column
  lda Temp+2          ;Y value
  sec
  sbc #26
  lsr
  lsr
  lsr                ;divide by 8
  sta Temp+2          ;save row

 ;---now, find column
  lda Temp+1          ;X Value
  sec
  sbc #17
  lsr
  lsr
  lsr                ;divide by 8
  sta Temp+1          ;save column

 

So, I understand that you call this 4 times, with Temp+1 and Temp+2 varying by one, a random example being:

 

50 / 60

50 / 61

51 / 60

51 / 61

 

Yes?

 

And, if I get that as well, your blocks are 8 scanlines tall and 2PF pixels wide?

 

And the two magic numbers are just two offsets until your block area starts?

 

Well, my first suggestion would be making the ball joystick controled and highlight hit situations with different colors, just to make sure that the magic numbers match precisely as intended :)

 

A next assumtion I have to make, is that it is impossible for the ball to move straight vertical or horizontal? I'm thinking along the lines, that you probably only need to run your checking code twice:

 

If this is the ball:

 

12

34

 

For 0-30° you check 24

For 30-60° you check 14

For 60-90° you check 12

 

Next idea. There's some redundancy in this:

 

50 / 60

50 / 61

51 / 60

51 / 61

 

as you run the dividing code 8 times instead of 4.

 

Final idea for today: Have a look at Lee Fastenaus Reflex code ;)

 

Greetings,

Manuel

Link to comment
I like this project, but I just can't seem to muster up a lot of enthusiasm for it right now. Of all my tentative projects, it is and would be by far the most popular. So I dunno.

 

As previously noted, this is a project that I would really like to see completed as I have fond memories of playing it on the ST. Perhaps you are wanting to produce something more original, or it doesn't seem like enough of a challege?

 

Chris

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