It is currently Sun Dec 17, 2017 6:31 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 108 posts ]  Go to page 1, 2, 3, 4, 5 ... 8  Next
Author Message
 Post subject: Object collision
PostPosted: Sun Jun 12, 2005 5:16 pm 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2143
Location: Minneapolis, Minnesota, United States
I know how to move sprites and do backgrounds and all that, but how do you make an object collide with another one? I couldn't really find any info on it, so can someone help me? thanks. :)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 12, 2005 7:27 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3076
Location: Brazil
Well, if you know how to move sprites, you know their position, correct? I'm unsure about what do you plan but... anyway, keep track of sprite #0 - if it's a game character (or whatever) and you wanna collision, there are 2 points:

A. Sprite x Sprite collision = you could keep track of their X,Y positions in RAM 200-2FF as example. Once X1 = X2 and Y1 = Y2 (in a latency of S pixels, where S is the size of your desired sprite), you got a strike and triggers the event.

B. Sprite x Background collision = even if you use sprite #0 hits to detect solid background pixel, it's useless most of times. This way, you must read the nametable (a tile in X,Y position) and compares with the sprite - it would had attributes (as solid, air, spikes...). Another RAM region would get the things working good.

I'm sorry, try ASM code by yourself. Get the idea and test it.

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 12, 2005 7:38 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19354
Location: NE Indiana, USA (NTSC)
First, given two rectangles specified by left, right, top, and bottom, determine whether they overlap. Can you do that?

Then for each game object, construct its bounding box. (Normally, games will leave a few pixels outside the bounding box to compensate for the fact that sprite cels aren't rectangular.)

For each pair of game objects, compare their bounding boxes to see if they overlap.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 12, 2005 9:55 pm 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2143
Location: Minneapolis, Minnesota, United States
I didn't really understand what you were saying there Fx3, though it's probably completely logical, and I'm just bad at interperting things into my own head. I have an idea to tell it when the object moving is in tile #99, it will disable the RIGHTKEYdown function. But I don't know how to define a variable in RAM for a tile #, because you can only say something like this:

Something = $80

you couldn't say this:

Something = #80

You can only define variables with hex crap, you can't do it with decimal, and that sucks! I think I'm using a crappy assembler, though, I'm using Nesasm, and I heard that sucks. I'm probably not making sense, so I'm gonna stop babling now.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 12, 2005 10:54 pm 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2143
Location: Minneapolis, Minnesota, United States
Sorry, ignore that thing above. This is my code:

Code:
Collide:
   lda Y_Pos
   cmp #100
   beq NOTHINGdown
   lda X_Pos
   cmp #99
   beq NOTHINGdown


I know that that isn't correct by the way. I don't know how to get it to stop when it's at location 99,100 if 100 is Y and 99 is X. It of course stops at in the column where X= 99, and in the column where Y= 100. Ya know what I mean? I can't think of a better way to explain it. How do you get it so it only stops when X= 99 and Y=100?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 13, 2005 5:43 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3076
Location: Brazil
Please, you must clarify what you want to do. Go read again what I and tepples wrote about it. :|

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 13, 2005 12:46 pm 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2143
Location: Minneapolis, Minnesota, United States
Sorry I'm not clear enough about what i want. I am trying to make a collision with my moving sprite, and a still sprite. It has the effect of a background collision, where when you hit the sprite, you stop moving. The still sprite basicly acts as a block like on mario. Sorry if I'm annoying everyone with my dumb questions... :(


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 13, 2005 1:33 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3488
Location: Indianapolis
These questions aren't dumb, just kinda hard. :)

I'd say that collision detection is one of the trickier things to code. At least for for sprite-to-bg. Sprite-to-sprite is easier and a good place to start, since the sprites are on the same coordinate system to begin with.

What you need to do to use bounding boxes like tepples said, is to do some range checking. This probably isn't an ideal example, but here's how I do this in Munchie Attack.

notes:
player's "mouth" sprite starts at $204
food objects start at $240
the @itsblank label is where it goes for 'no hit'.
the BCC/BCS branch after CMP is used to do greater/less than checking. For example, food objects are coming from the right, so the food's coordinate has to be less than the player's right edge, and greater than the player's left edge to count as a hit.
The values added and subtraced change the size of the box.

Code:
hit_detection:
        ldx #0
@hitloop:
        lda $241,x
        sta tiletype
        bne :+
        jmp @itsblank
:
        lda $243,x
        sec
        sbc #8
        cmp $207
        bcc :+
        jmp @itsblank
:
        clc
        adc #24
        cmp $207
        bcs :+
        jmp @itsblank
:

        lda $240,x
        sec
        sbc #15
        cmp $204
        bcc :+
        jmp @itsblank
:
        clc
        adc #30
        cmp $204
        bcs :+
        jmp @itsblank
:

        lda #0            ; if it makes it all the way here, it was hit
        sta $241,x
        sta $245,x
        sta $249,x
        sta $24D,x


Also see here for some info about sprite-to-bg collisions:
http://www.greggman.com/mckids/programming_mc_kids.htm


Top
 Profile  
 
 Post subject: collision sample logic
PostPosted: Mon Jun 13, 2005 1:36 pm 
my guess is that you are doing something like this:

byte check_for_collision(
byte sprite_1_x, int sprite_1_y,
byte sprite_2_x, int sprite_2_y,
byte x_distance, /*max X distance needed for collision*/
byte y_distance /*max Y distance needed for collision*/
)
{
byte x_diff = sprite_1_x - sprite_2_x;

if (x_diff < 0)
x_diff = -x_diff;

if (x_diff > x_distance)
return(0); /*no collision*/

byte y_diff = sprite_1_y - sprite_2_y;

if (y_diff < 0)
y_diff = -y_diff;

if (y_diff > y_distance)
return(0); /*no collision*/

return(1); /*collision happened*/
}

Translating to assembly language should not be that difficult.


Top
  
 
 Post subject:
PostPosted: Mon Jun 13, 2005 2:20 pm 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2143
Location: Minneapolis, Minnesota, United States
I wouldn't have trouble with this if there were some way to say this:

lda Y_Pos
cmp #100
and
lda X_Pos
cmp #93
bne NOTHINGdown

When I say and, I don't mean the actuall command. Is there some way to say only go to NOTHINGdown, if Y_Pos = 100 and X_Pos = 93?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 13, 2005 2:28 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3488
Location: Indianapolis
Celius wrote:
When I say and, I don't mean the actuall command. Is there some way to say only go to NOTHINGdown, if Y_Pos = 100 and X_Pos = 93?


Yeah. You need to change the branch condition and/or destination of the first check. What comes to mind for me is this:
Code:
 lda y_pos
 cmp #100
 bne skip
 lda x_pos
 cmp #93
 beq NOTHINGdown
skip:


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 13, 2005 2:50 pm 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2143
Location: Minneapolis, Minnesota, United States
Thank you! But is there a simpler way to do this? because if you're making a platformer with about as many platforms as say Metroid, You probably wouldn't want to do all that for every little pixel, if you know what I mean. Is there a way to write to the object, instead of the pixel? :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 13, 2005 6:24 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Oh man, you should have seen the code for a PC sidescroller I tried to write when I was first learning C. I used fractional values for the player position and I think my "move until hit obstacle" tried every single sub-pixel position. A later version found the intercept of the movement vector. Still all major overkill; this wasn't a physics simulation that required absolute accuracy.

Draw a picture and think about the minimum work necessary to find if movement is possible, and how far. Then find simplifications that don't add much more work than the minimum. Be sure to abstract the problem to only the essential details.

Also, find a way to enjoy experimenting with 6502 programming techniques. It really helps to write simple debugging output routines to print a byte (or find an emulator with a good debugger), so you can write short test code and see the results.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 13, 2005 10:30 pm 
Offline
User avatar

Joined: Thu Oct 21, 2004 4:02 pm
Posts: 210
Location: San Diego
Combining the responses already given in another way, here's my $0.02: You obviously don't want to write custom code to detect collision between every object on every map of every level of your game. As blargg suggests, you should try to abstract this problem so that it is more general. This abstracted version (often called a "engine") should allow you design levels using the concept of objects, as opposed to pixels. The key is to get the level of abstraction right. The more abstract it is the more general your engine is, but it also becomes more difficult to implement it. You want it abstract enough that it simplifies your design, but not so abstract that it does more than you need.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 14, 2005 2:43 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19354
Location: NE Indiana, USA (NTSC)
Try prototyping on a PC first. Get collision detection working in pure C code, then reduce the algorithm to what a 6502 can handle.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 108 posts ]  Go to page 1, 2, 3, 4, 5 ... 8  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 11 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group