pong collision from nerdy nights

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

User avatar
Kasumi
Posts: 1291
Joined: Wed Apr 02, 2008 2:09 pm

Post by Kasumi » Tue Nov 22, 2011 10:39 pm

I'm looking your code now. Do you mind if I make a pastebin of it and link it here? Others may be able to provide help if I can't. BTW, I had to do a little editing to get it working. (Adding tabs and stuff.) It's not a big deal in this case, but it may be worth finding a way to get the exact files off the computer in the future.

Code: Select all

 ;;if ball x < paddle1x
  ;;  if ball y > paddle y top
  ;;    if ball y < paddle y bottom
  ;;      bounce, ball now moving left
Is indeed what's included in the nerdy nights tutorial. Which does seem wrong. It should either be ball x > paddle1x, or it should say ball bounces RIGHT. But I want to get this working before I declare that.

There are a few things here you should change. Maybe this fill in the blank type of thing isn't a great way to learn. I can see what bunnyboy was trying to do, but sometimes there are better ways to do things that are just as easy to explain.

First off, this:

Code: Select all

	MovePaddle1ytop:
	LDA buttons1
	AND #%00001000
	BEQ MovePaddle1ytopDone

	;truncated
	MovePaddle1ytopDone:


	DownPaddle1ytop:
	LDA buttons1
	AND #%00000100
	BEQ DownPaddle1ytopDone

	;truncated
	DownPaddle1ytopDone:




	MovePaddle12:
	LDA buttons1
	AND #%00001000
	BEQ MovePaddle12Done

	;truncated
	MovePaddle12Done:



	DownPaddle12:
	LDA buttons1
	AND #%00000100
	BEQ DownPaddle12Done

	;truncated
	DownPaddle12Done:


	MovePaddle13:
	LDA buttons1
	AND #%00001000
	BEQ MovePaddle13Done

	;truncated
	MovePaddle13Done:



	DownPaddle13:
	LDA buttons1
	AND #%00000100
	BEQ DownPaddle13Done

	;truncated
	DownPaddle13Done:



	MovePaddle14:
	LDA buttons1
	AND #%00001000
	BEQ MovePaddle14Done

	;truncated
	MovePaddle14Done:



	DownPaddle14:
	LDA buttons1
	AND #%00000100
	BEQ DownPaddle14Done

	;truncated
	DownPaddle14Done:
You're doing these same two checks again and again and again:
Check 1:

Code: Select all

	LDA buttons1
	AND #%00001000;Check if up is pressed
	BEQ MovePaddle1ytopDone

	;Do stuff
	MovePaddle1ytopDone:
Check 2:

Code: Select all

	LDA buttons1
	AND #%00000100
	BEQ DownPaddle1ytopDone

	;Do stuff
	DownPaddle1ytopDone:
So how about putting ALL the code that needs those checks in between ONE branch and label?

Like so:

Code: Select all

	MovePaddle1ytop:
	LDA buttons1
	AND #%00001000
	BEQ MovePaddle1ytopDone

	LDA paddle1ytop
	SEC
	SBC #$01
	STA paddle1ytop
	
	LDA paddle12
	SEC
	SBC #$01
	STA paddle12
	
	LDA paddle13
	SEC
	SBC #$01
	STA paddle13
	
	LDA paddle14
	SEC
	SBC #$01
	STA paddle14
	
	MovePaddle1ytopDone:



	DownPaddle1ytop:
	LDA buttons1
	AND #%00000100
	BEQ DownPaddle1ytopDone

	LDA paddle1ytop
	CLC
	ADC #$01
	STA paddle1ytop
	
	LDA paddle12
	CLC
	ADC #$01
	STA paddle12
	
	LDA paddle13
	CLC
	ADC #$01
	STA paddle13
	
	LDA paddle14
	CLC
	ADC #$01
	STA paddle14
	
	DownPaddle1ytopDone:
This saves space, and takes less time to execute since you never have to check something again that you already know the result of. Make sense?

You can even simplify this further, but that will have to wait.

I promise I'll write a little more later, and try as hard as I can to get the heart of the problem. But, I'm actually keeping people up with my typing right now. :oops:

User avatar
log in
Posts: 72
Joined: Tue Jun 24, 2008 1:06 pm
Location: neverland

Post by log in » Wed Nov 23, 2011 4:03 am

No i don't mind, pasta bin all you want.

This helps other newbies in the future.
And if the collision is wrong from the rom,this might be a returning question.

Ill read everything later tonight,thanks so far.
im a newbie,lets see how far i can get

User avatar
Kasumi
Posts: 1291
Joined: Wed Apr 02, 2008 2:09 pm

Post by Kasumi » Wed Nov 23, 2011 7:32 am

First off, here's a pastebin of the original code for everyone: http://pastebin.com/dFekmaEh

The formatting is a little strange, since I only did the easy way to get it to assemble easily.

Anyway, I've found the issue.

I said earlier that the collision code we've been working with will only work for a paddle on the right bouncing the ball left.

Your paddle1 is on the left. And you're using it to bounce the ball left. It is a paddle that could only score on itself. :o

So what you need to do is change the branches and collision code so it will bounce the ball right, since that's easier than swapping the paddle locations with the code you currently have.

Here's another thing.

This:

Code: Select all

lda #$00
is different than this:

Code: Select all

lda $00
The first loads the actual number 0 to the acculator. The second loads the value stored at RAM LOCATION 0. I'm pretty sure you know that. But it also applies when you have a label.
So this:

Code: Select all

PADDLE1X = $08
lda PADDLE1X
Loads the number stored at RAM location $08 (which is probably always 0 with your current code) instead of the actual number 08. (Ram Location 8 looks like ballspeedy in your code. So lda PADDLE1X is like lda ballspeedy)

Whenever you have a constant, you usually put them in caps so you know which labels to put # before.

So for this:

Code: Select all

	LDA ballx
	CMP PADDLE1X
should be

Code: Select all

	LDA ballx
	CMP #PADDLE1X
The same goes for all your other constants that don't have # before them.

As well, change this, PADDLE1X = $08 to this PADDLE1X = $10. That'll make the bouncing easier for you to see when you get it working. Will say more late, but once again gotta go.

edit: I feel I should be more clear, just in case. bunnyboy DID put all your actual constants in caps. That means all your non constant variables (the lowercase ones) should NOT have # before them.

And one other small change is this:

Code: Select all

	LDA bally
	CMP paddle12
to this:

Code: Select all

	LDA bally
	CMP paddle14
paddle12 isn't the bottom sprite of the paddle.

User avatar
log in
Posts: 72
Joined: Tue Jun 24, 2008 1:06 pm
Location: neverland

Post by log in » Wed Nov 23, 2011 2:45 pm

Thank you very much,ill have a lot of work to do now.
Ill ad my progres later on.
Think i will get a lot further now.

User avatar
log in
Posts: 72
Joined: Tue Jun 24, 2008 1:06 pm
Location: neverland

Post by log in » Thu Nov 24, 2011 5:42 pm

I worked on my code some more today.
I changed the controls to the new improved style and changed the paddle positions of the paddle's vertical to 10 and e8.so bouncing can be seen better.
With the #PADDLE1x instead of PADDLE1X the code seems better but it still has 1 problem:

top screen and bottom screen is bouncing OK.
But when the paddles and the ball are on 1 line it bounces in mid air and to early.

Is this because the equal check is missing? i mean what does the game when its not less or more but equal? Or is it because im only checking the top pixel as mentiond before or is the x check still not functioning?
im a newbie,lets see how far i can get

User avatar
Kasumi
Posts: 1291
Joined: Wed Apr 02, 2008 2:09 pm

Post by Kasumi » Fri Nov 25, 2011 7:45 am

log in wrote: But when the paddles and the ball are on 1 line it bounces in mid air and to early.

Is this because the equal check is missing?
An equal check makes only a single pixel of difference on only one of the paddles, so it is probably not that. I'm not entirely sure what you're describing.

When everything is on the same horizontal line like below, it bounces too early? (In which direction?)

Code: Select all

* = ball
| = paddle1
# = paddle2

|       #
|    *  #
|       #
|       #

If not, could you diagram or say more about the problem?

User avatar
log in
Posts: 72
Joined: Tue Jun 24, 2008 1:06 pm
Location: neverland

Post by log in » Tue Nov 29, 2011 2:06 pm

This is copy and pasta of my actual code

LDA ballx
CMP #PADDLE2X
BCC Skip


LDA bally
CMP paddle2ytop
BCC Skip

LDA bally
CMP paddle24
BCS Skip

LDA #$00
STA ballright
LDA #$01
STA ballleft

Skip:

LDA ballx
CMP #PADDLE1X
BCC Skin


LDA bally
CMP paddle1ytop
BCC Skin

LDA bally
CMP paddle14
BCS Skin

LDA #$01
STA ballright
LDA #$00
STA ballleft
Skin:

I waited a couple of days reading more about collisions,trying to solve the problem on my own.

BTW: how bad is it to only use this in pong?How many times will the ball go threw in actual gameplay?
im a newbie,lets see how far i can get

User avatar
Kasumi
Posts: 1291
Joined: Wed Apr 02, 2008 2:09 pm

Post by Kasumi » Tue Nov 29, 2011 5:22 pm

One of these two things has to be wrong.

Code: Select all


  LDA ballx
  CMP #PADDLE2X
  BCC Skip

Skip:

Code: Select all

  LDA ballx
  CMP #PADDLE1X
  BCC Skin

Skin:
You can't check if the ball is to the right of one position and the left of another using the same branch condition.

BTW: how bad is it to only use this in pong?How many times will the ball go threw in actual gameplay?
Probably somewhat often when the ball in near the bottom of the paddle or vice versa. At the moment you're not doing enough for perfect box collision detection.

paddle24 is (if I remember correctly) the top of the bottom sprite of the paddle, so as long as the ball is one pixel below that, no collision can occur even though the paddle should be collision enabled for 7 pixels below that sprite's top.

It is the same when the paddle is one pixel below the ball's top. No collision can occur even though the objects are visually colliding.

This is how you do it if you want it to work in all cases, since the current method relies on something being on the right, and something being on the left.

Code: Select all

//If all the following conditions are true
if( 
ballx+ballwidth >= paddlex
&&
ballx<= paddlex+paddlewidth
&&
bally+ballheight >= paddley
&&
bally<= paddley+paddleheight
)
{
//we collided
}else{
//no collision occurred.
}
Are you familiar with subroutines? Whenever you want to do the same thing multiple times, it's best to use them.

Right now you want to check if the ball is colliding with the left paddle. Then you want to check if the ball is colliding with the right paddle.

So if you wrote a subroutine that checked if one object was colliding with another, you could use it for both cases. It is good practice to write a small piece of code and verify it works. Then write a slightly larger piece of code and verify that works.

For instance to write a pong game you might first:

Get the ball displayed.
Then, make a debug function that allows you to move the ball with the d-pad.
Then, create another simple 8x8 object that never moves and display that.
Then, write a subroutine that checks if the ball is colliding with that object.
Then, make that other object the size of the paddle and make sure the detection still works.
Then, make the ball move on its own and bounce off the walls of the playfield.
Then, make it bounce off just one still paddle.
Then, make it bounce off one moveable paddle.
Then, add another paddle.
Then, add scoring/

etc. etc.

Would you mind starting over in a way? I could write a framework like bunnyboy's that does much less for you, and we could work through the above steps. It might make everything easier to understand, rather than relying on a lot of things that you are not quite sure about how they work.

User avatar
log in
Posts: 72
Joined: Tue Jun 24, 2008 1:06 pm
Location: neverland

Post by log in » Sat Dec 03, 2011 4:32 pm

My progress

I could not get the x check right.i had them both bcc and no mather what i tried i could not get them to work. :oops:

So .. i read a lot more on the web on collisions and i must say this seems the hardest part of programming games.

But i have to come up with some kind of box and it simple.
ON PAPER THAT IS. I draw a lot of pictures and its simple.

If my ball is above the padlle's top or below the bottom or left or right its a miss.
The problem is the programming,how do i explain the computer what i want.Well i understand that bcc is less and bcs is more etc. etc.

So after some more recearch i put this code together.

LDA ball left
CMP paddle right
BCS NoHit

+ the other way around

LDA ball top
CMP paddle bottum
BCS NoHit

+ the otherway around for bottum

followed by

LDA #$01
STA ballright
LDA #$00
STA ballleft

NoHit:

I have not tested this code yet but on paper and in my head it works.

BUT ...here comes my QUESTION: if this is correct?
And how do you handle left right top bottum of 1 sprite?

For the top and bottum of Y its simple 4 sprites so top and bottum paddle sprite or better said top and bottum variables can be handled.
im a newbie,lets see how far i can get

User avatar
log in
Posts: 72
Joined: Tue Jun 24, 2008 1:06 pm
Location: neverland

Post by log in » Sat Dec 03, 2011 4:43 pm

sorry saw your post again and forgot the comment of starting all over.
That might be a good idea .
I got the feeling im almost there but im not.
learning a subrouting for sprite collisions would be awsome thats my biggest problem right now.

I really got to understand collisions better because its getting silly now.
I got pong with score and moving paddles and a space shooter with scrolling background but no collisions :oops:
im a newbie,lets see how far i can get

User avatar
Kasumi
Posts: 1291
Joined: Wed Apr 02, 2008 2:09 pm

Post by Kasumi » Sat Dec 03, 2011 7:48 pm

Get ready for a long post :oops:
log in wrote:My progress

I could not get the x check right.i had them both bcc and no mather what i tried i could not get them to work. :oops:
I said before they can't both be bcc. One has to be bcs, and the other must be bcc.

Here is a line with two points:

Code: Select all

     |
1    |    2
     |
lda point1x
cmp linex
Would clear the carry.

lda point2x
cmp linex
would set the carry.

If you want to check if a point is to the left of another point, you have to do something different than checking if its to the right.
I have not tested this code yet but on paper and in my head it works.

BUT ...here comes my QUESTION: if this is correct?
It is correct so far, but it will depend on if you fill in the "+ the other way around " parts with.
And how do you handle left right top bottum of 1 sprite?
I wrote it up in my last post.

Code: Select all

//If all the following conditions are true

ballx+ballwidth >= paddlex

ballx<= paddlex+paddlewidth

bally+ballheight >= paddley

bally<= paddley+paddleheight

There was a collision.
If any of them were false, the collision failed.
Figure out how to implement a check for each of those individually and you are done.

In any case if you do want to try it, here's a new starter document: http://pastebin.com/50Q1K5U6

I cut out basically everything from it, and also did things slightly different than bunnyboy. Here is a list of differences:

1. I didn't use the .rs command. I don't personally like it, but if you do you can use it.
2. Took out the background loading and replaced it with code that just writes tile 0 to every tile in the background.
3. Removed all the constants and code that was not filled in.

And the most important change: I made it so that the main game loop is not in the NMI.

Apologies if I explain anything you already know, but I am assuming nothing.

Code: Select all

.org $FFFA ;first of the three vectors starts here
	.dw NMI ;when an NMI happens (once per frame if enabled) the
	;processor will jump to the label NMI:
	.dw RESET ;when the processor first turns on or is reset, it will jump
	;to the label RESET:
That code above sets your vectors. Each .dw here refers to an address that the CPU will go to when a specific thing happens.

The first is your NMI. If enabled, the label specified here (NMI in this case) will be jumped to every 60th of a second. Bunnyboy had it so that all of your game logic was here, but I believe this is bad form. What if the game takes longer than a 60th of a second to run?

In any case, the new code you write in my starter doc should be after the controller is read from, and before "JMP main".

Again, apologies if I am covering easy stuff.

Your first task is getting a sprite on screen. This code is underneath your NMI label:

Code: Select all

 
	LDA #$00
	STA $2003 ; set the low byte (00) of the RAM address
	LDA #$02
	STA $4014 ; set the high byte (02) of the RAM address, start the transfer
You may recall that everything in your NMI routine is run every 60th of a second. What the code above does is copy all of the RAM in page 2 ($0200-$02FF) to the PPU's internal object memory.

What does this mean for you? That writing values to RAM anywhere from $0200-$02FF will update the sprites in the next 60th of second.

There are 64 sprites which each use four bytes to fill page 02 evenly.

Byte 0 is the sprite's y position. So writing #$10 to $0200 would set one of the 64 sprite's y position to #$10. Writing #$20 to $0204 would set the next sprite's y position to #$20. Etc.

Byte 1 is the sprite's tile. Whatever byte you write here is the tile graphic the sprite will use. $0201 refers to one sprite. $0205 refers to the next. etc.

Byte 2 ($0202, $0206 etc) is broken down like this:

Code: Select all

Byte 2

Attributes

76543210
||||||||
||||||++- Palette (4 to 7) of sprite
|||+++--- Unimplemented
||+------ Priority (0: in front of background; 1: behind background)
|+------- Flip sprite horizontally
+-------- Flip sprite vertically
But you can just write #$00 there for now.

Byte 3 ($0203, $0207) is the sprite's X position.

So to display one sprite, all you have to do is write the tile you want to $0201, #$00 to $0202, and the X and Y position you to want to $0203, and $0200.

To add another sprite, you'd set the values you want to $0204-$0207. Just keep moving up four bytes to add more sprites.

If that's easy for you, the next step is to make your sprite move with d-pad presses. Start with just one direction.

Use one of the buttons variables (buttons1 or buttons2) to check if a button is pressed.

Each one contains the state of all 8 buttons, so you have to isolate the bit that you want.

Here is how they are laid out:

Code: Select all

bit:   	7	6	5	   4	   3	 2	   1	    0
button:	A	B	slct	strt	up	down	left	right
So to do something if A was pressed...

Code: Select all

lda buttons1
and #%10000000;This makes bits 6-0 equal to 0. 
;So there are only two possibilities left. Either #%10000000 (if A was pressed) or
;#%00000000(if A was not pressed)
beq skip;If the button was not pressed, we do not want to do the action.
;Code dependent on A being pressed would go here
skip:
So to make the sprite move, you would make a check for all the dpad buttons. Then you would update the sprite's position ($0200 and $0203) when a button is pressed.

The next step is to add another sprite.

Then make that one controlled with the other controller.

The next step is collision detection.

Start with something simple. For instance, make it so that a new sprite appears near the top of the screen when just one of the collision checks is true. For instance, if this is true (sprite1x<= sprite2x+sprite2width ) the sprite will appear. If the sprite appears as you expect, add the next check. It should then appear only when both checks are true.

If you work by adding new code slowly like this, you will know what part of your code is wrong immediately.

Keep going until you have added all four checks.

If you have any questions on any part of this, let me know.

User avatar
log in
Posts: 72
Joined: Tue Jun 24, 2008 1:06 pm
Location: neverland

Post by log in » Wed Dec 14, 2011 4:05 pm

very Very low on time these days but worked some on it again.
I got myself a powerpak now and that helps a lot with testing.
Seeing my own pong on tv and "" playing''' it rules.

How far i got ... :oops: well working this new method is confusing at first.
Because of the constants that are missing for exsample.

googled and looked at a lot in books and im ashamed to say im still kind of in the dark

i know that ill have to make 4 checks for each paddle .
left right under and above
And if im correct im not only compairing the ball and the paddle but also the other paddle,thats a part i was missing if i am correct.

Im still in doubt if ill leave the ball the nerdy nights way or a bitt more old skool bouncing up and down.

sorry to say i tested your file but it did not work for me because it didn't accepted the variables input?
ill wor on it later

BTW is pong really the easiest game to program :wink: because i find it still a lot of programming.
most likeley because i still suck :D

User avatar
Kasumi
Posts: 1291
Joined: Wed Apr 02, 2008 2:09 pm

Post by Kasumi » Wed Dec 14, 2011 4:46 pm

log in wrote: Because of the constants that are missing for exsample.
If they're missing, all you would have to do is add them. I didn't give you the file so you could make pong right away. I gave it to you so you could do easier stuff, that eventually helps you understand how to make pong.
sorry to say i tested your file but it did not work for me because it didn't accepted the variables input?
What do you mean? The program compiles and runs exactly as intended. It does absolutely nothing except update the joypad variables. You can even see that happen if you look at $00FF and $00FE with your debugger and press buttons.
i know that ill have to make 4 checks for each paddle .
left right under and above
And if im correct im not only compairing the ball and the paddle but also the other paddle,thats a part i was missing if i am correct.
No. Don't do any of that. Just get a sprite displayed. We're starting over completely.
BTW is pong really the easiest game to program.
It's almost certainly the easiest game to make. Other than a text adventure which is hard to make for a different reason, any game you'll want to make will need collision detection. If that is the problem you're having, you will run into it with any game.

A basic Pong pretty much deals ONLY with object object collision detection and controller reading.

But we can start with simpler programs that are not games.

So please just try getting a sprite displayed. I laid out most of how to do it in the last post, and I'll quote it here.

I'm not going to help you do hard stuff anymore until you show me you can do simple stuff.

The new code you write in my starter doc should be after the controller is read from (jsr ReadController1 and jsr ReadController2), and before "JMP main".

Your first task is getting a sprite on screen. This code is underneath your NMI label:

Code: Select all

 
   LDA #$00
   STA $2003 ; set the low byte (00) of the RAM address
   LDA #$02
   STA $4014 ; set the high byte (02) of the RAM address, start the transfer
You may recall that everything in your NMI routine is run every 60th of a second. What the code above does is copy all of the RAM in page 2 ($0200-$02FF) to the PPU's internal object memory.

What does this mean for you? That writing values to RAM anywhere from $0200-$02FF will update the sprites in the next 60th of a second.

There are 64 sprites which each use four bytes to fill page 02 evenly.

Byte 0 is the sprite's y position. So writing #$10 to $0200 would set one of the 64 sprite's y position to #$10. Writing #$20 to $0204 would set the next sprite's y position to #$20. Etc.

Byte 1 is the sprite's tile. Whatever byte you write here is the tile graphic the sprite will use. $0201 refers to one sprite. $0205 refers to the next. etc.

Byte 2 ($0202, $0206 etc) is broken down like this:
Code:

Code: Select all

Byte 2

Attributes

76543210
||||||||
||||||++- Palette (4 to 7) of sprite
|||+++--- Unimplemented
||+------ Priority (0: in front of background; 1: behind background)
|+------- Flip sprite horizontally
+-------- Flip sprite vertically
But you can just write #$00 there for now.

Byte 3 ($0203, $0207) is the sprite's X position.

So to display one sprite, all you have to do is write the tile you want to $0201, #$00 to $0202, and the X and Y position you to want to $0203, and $0200.

To add another sprite, you'd set the values you want to $0204-$0207. Just keep moving up four bytes to add more sprites.
You can ask me questions about adding sprites if you don't understand that, or post about how you got a sprite displayed and I'll move onto the next thing. You can even jump ahead, since my last post gives you all the actual info you need to make pong. It just doesn't do it for you.

User avatar
log in
Posts: 72
Joined: Tue Jun 24, 2008 1:06 pm
Location: neverland

Post by log in » Sun Dec 18, 2011 12:10 pm

http://youtu.be/x88dH81QugE

This is a video reaction showing 4 things.

1.source code with .rs code and old nmi technik.This gets transformed to nes rom that shows that i can get 2 sprites on screen (balls) and that i can make them move any way i want (up,down,left,right).


2. Source code with your 'new' nmi technik that i use in combination with.rs code but the vblank does not get accepted in .rs code?


3. my nes rom on a tv with the powerpak.(the reason i made this video)For some reason it works fine on the emulator ,but on the powerpak there is background garbage.

4.a old pong rom from me with paddles made and black bakground.

I hope this is enough proof that i can make sprites on screen and make them move anyway i want.
The biggest problem i got is collisions ..collisions and collisions.

So to learn this ill have to test xand y 1 at a time like you said.
But i have no clue how to make a sprite apair if the collision is true.
How do you come up with all these code btw,own creations or from exsamples?
im a newbie,lets see how far i can get

User avatar
Kasumi
Posts: 1291
Joined: Wed Apr 02, 2008 2:09 pm

Post by Kasumi » Sun Dec 18, 2011 2:48 pm

Reading code off youtube doesn't make things to easy for me. I have to put that stuff in 1080p and look real closely. :o

The easiest thing to do for me (and probably you) is:

"I added this after line 302 to add a sprite to your code."

Code: Select all

;Code here
Or, "NESASM gives this exact error"

Code: Select all

vblank  .rs1
Unknown instruction!
If you're not using a text editor that easily shows line numbers (looks like you're using notepad?), try this program: http://notepad-plus-plus.org/download/v5.9.6.2.html

If you use that program for nothing else, at least you will get a bunch more undo steps than notepad has.

Now, here's what I think is the problem based on what I can see:

You forgot a space.

You have

Code: Select all

vblank .rs1
It needs to be

Code: Select all

vblank .rs 1
(If it's already like the second one, then it's something else which I'll help with)

Here's a tip: If nesasm is only complaining about one line from a bunch of similar statements, try to figure out why that one is not like all the others. Then make that one like all the others. If any of the others were missing spaces, it would have complained about them too in this case.

One other problem: In between LeftBall2XDone and ReadController1, you seem to be missing an RTS.

What this means is that when you jsr to updateSprites, you code will actually continue down and update the joypad variables again.

Whenever I added a new subroutine, I put an RTS immediately after the label, and then add my code in between the label and the RTS so it's never possible to forget the RTS.

This is good, though. You can do this stuff. I'll put a reminder, that when you do add the jsr UpdateSprites to my base file, you put it after the jsr readcontroller lines, but before jmp main.

We will not put stuff in the NMI until later.
3. my nes rom on a tv with the powerpak.(the reason i made this video)For some reason it works fine on the emulator ,but on the powerpak there is background garbage.
The reason for this is that NES does not clear out anything for you when the program starts. You'll notice the background garbage is in the same place as the PowerPak label was on the loading screen. This is because the NES is now displaying the nametable from what the Powerpak wrote to the PPU, but using the tiles included in your program.

The pastebin code I uploaded has code underneath a label called "clearnametables" that should fix this problem.

How do you come up with all these code btw,own creations or from exsamples?
For what I sent you, it's just a modified version of bunnyboy's asm file. You can even see the differences in coding style. Bunnyboy capitalizes his mnemonics (LDA, STA), and I keep mine in lowercase (lda, sta).

But if I wanted to, I could have made it without any reference. I've actually taught some friends some of this stuff with examples and everything I wrote myself.

You have to learn to solve problems on your own, or you will always be stuck waiting for a tutorial when you want to do new, exciting things.

The next thing I want you to do:

Display a third sprite when A button is pressed, but make it disappear when A button is not pressed.

You can do this by setting up its X position and Tile first.

Then depending on if A is pressed, set its Y position to say... #$80 if A is pressed, and #$FE (which is off screen) when A is not pressed.

We will use this sprite that appears based on a condition to help you verify the first parts of your collision detection code a little later.

If you want to jump ahead to that without me, here's what you'll do.

Make the sprite appear when ONE condition of your collision detection code is true. So, if object1X + object1width > object2x, the sprite will appear.

When you have verified this single part works as expected, add another condition. You want it so that the sprite appears only when BOTH the conditions are true. So if object1X < object2x+object2width AND object1X + object1width > object2x the sprite will appear. Otherwise it will disappear.

These two checks will make it so the sprite disappears whenever the sprites are colliding on the X axis. If that works perfectly, all you need to do is add similar checks for the y axis.

Remember: Add the checks one at a time. Run the ROM. If you see the sprite appearing in a case that doesn't seem to make sense for the check you added, look at the most recent check you have added and fix it.

Post Reply