How do i do AABB collision on this program?
Root / Programming Questions / [.]
furcutieCreated:
There are several ways to do collision in SB. You can make your own custom collision with just regular code (like Separating Axis) or you can use some of the builtin SmileBASIC functions like SPHIT / SPHITRC
I'm going to make a full collision detection tutorial using the builtin commands later today if you want to wait.
Edit: oh sorry I just noticed you wanted axis-aligned bounding box. You can use math to do it manually if you want, but SPHIT and SPHITRC use AABB (I'm pretty sure) to detect collisions between sprites.
I would really appreciate it if you could do that for me. And don't worry it's alright maybe i should have been more clearer in my post. Also wouldn't you mind doing the tutorial and after you finish it, could you post here a example on how to make a aabb collision?<3Do you want specifically AABB done manually or are you just trying to get a sprite to collide with tiles from a map? The tutorial will cover map collision (hopefully in a way that's easy to understand). Doing any collision detection manually is going to be much slower; SB isn't very fast, so you want to use the built-in functions as much as possible.
I just want to make sprites collide manually at the moment, with the aabb collision method. specifically 2 moving sprites, even tho i am open to new methods of doing things in this program. <3Oh two sprites? That's not bad:
'Setup two sprites SPSET 0,856 SPSET 1,900 'Give them both a collision box. It's ID,Start,End,Width,Height,ScaleWithSprite,Mask. 'Collision is only detected if at least one bit is set in the same place in both masks. SPCOL 0,0,0,16,16,TRUE,&HFFFFFFFF SPCOL 1,0,0,16,16,TRUE,&HFFFFFFFF 'And this is all you need to check if those two are colliding IF SPHITSP(0,1) THEN PRINT "HITTING"; 'You can also check against a range VAR HITTER=SPHITSP(0,1,100) 'Anything from 1 to 100 hitting 0? IF HITTER>=0 THEN PRINT "HITTING ";HITTER
Thankyou! It actually works! But, not to be unappreciative of you taking your precious time here, but can you explain me how can i make a collision doing something that is similar to this kind of code for sprite collision?That IS what this is doing though. Like I said before, it's much slower to do it manually (and it's a waste of time) because SmileBASIC has this check built in. I'm sorry, I really suggest against doing this manually. This collision check is exactly what that is. If you need collision with an arbitrary rectangle rather than two sprites, SB provides that too:IF X2<X+W AND X2+W2>X AND Y2<Y+H AND Y2+H2>Y THEN BEEP
IF SPHITRC(0,X,Y,W,H) THEN 'hitting rectangle at X,Y with width W,HThis is precisely what your kind of code collision is doing; you just don't have to do the check yourself. If you're absolutely dead-set on doing it manually, the code is long and slow:
SPOFS 0 OUT X,Y 'Get sprite X and Y SPOFS 1 OUT X2,Y2 'The other sprite's position SPCHR 0 OUT U,V,W,H 'Get sprite width and height (U,V is mandatory) SPOFS 1 OUT U,V,W2,H2 'Other sprite's width/height XM=X+W YM=Y+H X2M=X2+W2 Y2M=Y2+H2 IF XM>X2 && YM>Y2 && X<X2M && Y<Y2M THEN PRINT "HITTING"
Doing SPHOME messes up the collision box. Also, i've been having a problem. The program doesn't read the hight and width of the sprites.( /,\) it still collides tho..
Here is the code:
ACLS SPSET 0, 702 SPSET 1, 34 SPHOME 1, -100, -100 WHILE 1 H=500 W=500 W2=100 H2=100 SPOFS 0, X, Y SPOFS 1, X2,Y2 SPOFS 0 OUT X,Y SPOFS 1 OUT X2,Y2 SPCHR 0 OUT U,V,W,H SPCHR 1 OUT U,V,W2,H2 BTN=BUTTON( ) IF BTN AND #RIGHT THEN X=X+1 IF BTN AND #LEFT THEN X=X-1 IF BTN AND #UP THEN Y=Y-1 IF BTN AND #DOWN THEN Y=Y+1 IF BTN AND #A THEN X2=X2+2 IF BTN AND #Y THEN X2=X2-2 IF BTN AND #X THEN Y2=Y2-2 IF BTN AND #B THEN Y2=Y2+2 IF X+W>X2 AND Y+H>Y2 AND X<X2+W2 AND Y<Y2+H2 THEN HIT=HIT+1 LOCATE 10, 10: PRINT HIT VSYNC WEND
Idk i though it was necessary. ( / b\) i found something weird that happend using SPHOME tho. The collision box of the second sprite, ( SPSET 1, 34) stayed at the corner of the screen but that's only when SPHOME is set, unless I've done a mistake. Also, this might sound dumb, but what's the difference between the out option? I understand it stands for output but doesn't SPOFS does the same thing without the out being written there? Also, I have another problem, what's wrong with my variables? when i change the variables that stand for the width and the height of the sprite, the collision box doesn't get bigger. When it's supposed to get bigger..sorry if i ask to much questions. <3
SPHOME sets the origin of the sprite's internal coordinate system, NOT its home position relative to the screen.
By default, the origin is the top left corner of the sprite:
This has implications for rotation and (maybe?) collision: if we rotate the sprite, it rotates around that corner point.
Usually if we redefine the home, it's to the center
or maybe in a platformer it can be useful to set it to the "feet" of a sprite.
If you want to normalize everything to a screen coordinate, you'll have to account for it in SPOFS (perhaps with a CENTERX/Y constant)
A summary, as source code, of the suggestions in this thread
VAR W=16,H=16, W2=16,H2=16 SPSET 0,304,176,W,H SPSET 1,32,16,W2,H2 SPCOL 0,0,0,W,H,TRUE,&HFFFFFFFF SPCOL 1,0,0,W2,H2,TRUE,&HFFFFFFFF VAR X,Y, X2,Y2 VAR HIT = 0 WHILE 1 SPOFS 0 OUT X,Y SPOFS 1 OUT X2,Y2 SPCHR 0 OUT ,,W,H SPCHR 1 OUT ,,W2,H2 BTN=BUTTON( ) IF BTN AND #RIGHT THEN SPOFS 0,X+1,Y IF BTN AND #LEFT THEN SPOFS 0,X-1,Y IF BTN AND #UP THEN SPOFS 0,X,Y-1 IF BTN AND #DOWN THEN SPOFS 0,X,Y+1 IF BTN AND #A THEN SPOFS 1,X2+1,Y2 IF BTN AND #Y THEN SPOFS 1,X2-1,Y2 IF BTN AND #X THEN SPOFS 1,X2,Y2-1 IF BTN AND #B THEN SPOFS 1,X2,Y2+1 'ignoring custom AABB for now IF SPHITSP(0,1) THEN INC HIT LOCATE 10,10:PRINT HIT VSYNC WENDSPHITSP should still work even if you change the SPHOME; I think not accounting for the origin offset may have broken your attempt.
SmileBASIC has an in-game manual that tells what each command does and how to use it. For instance, type SPOFS and click the little ? button above the right side of the keyboard and it'll tell you how to use it. Use the circle pad to scroll through the text and see new ways of using it.
SPOFS moves a sprite to a location on the screen, as I'm sure you've seen. It can also give the position: this is the OUT version. For instance:
SPOFS 0,50,75 'Put sprite 0 at 50,75 SPOFS 0 OUT X,Y 'Get sprite 0 position and put in X,Y PRINT X,Y 'Prints 50 75This is true of most of the other sprite commands. For instance, as Lumage said, SPHOME sets the origin of the sprite. 12me21 was suggesting that we retrieve the origin as part of the collision check. You can set SPHOME just like SPOFS, and you can also get the values.
SPHOME 0,8,8 'Set the origin to the middle of a 16x16 sprite SPHOME 0 OUT X,Y 'Get the origin of the sprite and put it in X,Y PRINT X,Y 'Prints 8 8I'm not sure what to say about the variables though.