Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
I need input on a possible bug in v3.5.0
#41
Wow, loving this discussion! So many ideas.
Reply
#42
Thumbs Up 
(01-21-2023, 08:37 PM)SMcNeill Wrote: And here's a completely different way to check for pixel perfect collision with our two stars:

Code: (Select All)
TYPE PointType
    AS INTEGER x, y
END TYPE

SCREEN _NEWIMAGE(1280, 720, 32)
DIM AS _UNSIGNED LONG target
DIM SHARED Backdrop AS LONG: Backdrop = _COPYIMAGE(0)
REDIM CA(0) AS PointType
blueStar = _LOADIMAGE("Z:\starBlue.png", 32)
redStar = _LOADIMAGE("z:\starRed.png", 32)

CleanImage blueStar
CleanImage redStar
MakeCollisionArray redStar, CA()

t# = TIMER + 1
DO
    CLS , 0
    IF TIMER > t# THEN
        out$ = STR$(count)
        count = 0
        t# = TIMER + 1
    END IF
    count = count + 1
    LOCATE 2, 1: PRINT out$; "FPS"
    IF _KEYDOWN(18432) THEN yPos = yPos - 1
    IF _KEYDOWN(20480) THEN yPos = yPos + 1
    IF _KEYDOWN(19200) THEN xPos = xPos - 1
    IF _KEYDOWN(19712) THEN xPos = xPos + 1
    IF _KEYDOWN(32) THEN xPos = 0: yPos = 0 'reset
    IF _KEYDOWN(27) THEN SYSTEM

    _PUTIMAGE (xPos, yPos), redStar
    _PUTIMAGE (100, 100), blueStar
    CheckCollision xPos, yPos, CA()
    _DISPLAY
LOOP


SUB CheckCollision (xOffset AS INTEGER, yOffset AS INTEGER, CA() AS PointType)
    FOR i = 1 TO UBOUND(CA)
        x% = xOffset + CA(i).x
        y% = yOffset + CA(i).y
        IF POINT(x%, y%) <> &HFFFF0000&& THEN
            LOCATE 1, 1: PRINT "Collision at:"; x%, y%
            EXIT SUB
        END IF
    NEXT
END SUB

SUB MakeCollisionArray (image AS LONG, CA() AS PointType) 'CA = Collision Array
    REDIM CA(_WIDTH(image) * _HEIGHT(image)) AS PointType
    DIM AS LONG D, S: D = _DEST: S = _SOURCE
    DIM AS LONG count: count = -1
    _SOURCE image
    FOR y = 0 TO _HEIGHT - 1
        FOR x = 0 TO _WIDTH - 1
            IF POINT(x, y) = &HFFFF0000&& THEN
                IF y > 0 THEN
                    IF POINT(x, y - 1) = 0 THEN
                        count = count + 1
                        CA(count).x = x
                        CA(count).y = y
                        _CONTINUE
                    END IF
                END IF
                IF y < _HEIGHT - 1 THEN
                    IF POINT(x, y + 1) = 0 THEN
                        count = count + 1
                        CA(count).x = x
                        CA(count).y = y
                        _CONTINUE
                    END IF
                END IF
                IF x > 0 THEN
                    IF POINT(x - 1, y) = 0 THEN
                        count = count + 1
                        CA(count).x = x
                        CA(count).y = y
                        _CONTINUE
                    END IF
                END IF
                IF x < _WIDTH - 1 THEN
                    IF POINT(x + 1, y) = 0 THEN
                        count = count + 1
                        CA(count).x = x
                        CA(count).y = y
                        _CONTINUE
                    END IF
                END IF
            END IF
        NEXT
    NEXT
    REDIM _PRESERVE CA(count) AS PointType
    _DEST D: _SOURCE S
END SUB

SUB CleanImage (image AS LONG) 'make backdrop image
    DIM m AS _MEM: m = _MEMIMAGE(image)
    DIM AS _OFFSET o, l
    DIM AS _UNSIGNED LONG p
    o = m.OFFSET: l = m.OFFSET + m.SIZE
    $CHECKING:OFF
    DO UNTIL o >= l
        _MEMGET m, o, p
        SELECT CASE p
            CASE &HFFFF0000, &HFF0000FF
            CASE ELSE: _MEMPUT m, o, &H00000000 AS _UNSIGNED LONG
        END SELECT
        o = o + 4
    LOOP
    $CHECKING:ON
END SUB


This basically forms an array of the coordinates which are needed to create the outline for our red star, and then it compares to see if they're still red or not.  Simple enough, right?

And, would you guys believe that this little red star has 383 points in its outline?!  Even so, without trying to do anything fancy to optimize things (this is all software images and POINT calculations, with no hardware or mem at use at all), this still runs at over 500 FPS on my PC and has no issues with the collision detection at all, that I can find.

Now this one looks super handy for editing images (MakeCollisionArray) as well as collision code. Very Interesting another +1 to Steve Smile
I think this is what I set out to do Friday before all new stuff Sat.

I am going to play around with this one today, maybe compare to Terry's. Do we have two completely different methods?
b = b + ...
Reply
#43
@bplus The process of what it does is really rather simple:

1) It takes a look at your image, and assumes that the background is transparent color 0 (&H00000000).
2) Then it checks each pixel from top to bottom, left to right, and checks to see if it borders a transparent pixel.  (For example, point (100,100) is red, and point(100,101) is transparent.)  If a point has a transparent parner beside it, it stores that point into our array -- that's how it forms an outline of the image.
3) It then checks later to see if our point has changed from the default color of our image.  (In this case, I was only using the redStar, or redScribble, so I hardcoded to check to see if our array still pointed to all red pixels on the screen where our outline was produced.)  Other ways to do this check would be to make certain the pixel in question was still clear transparent 0 *before* placing the redStar onto the screen over it, or to store the redStar's pixel colors with the x/y point information to compare against in case we had multiple colors in our raindowStar...

But the overall process is rather simple in concept -- make an outline of the image and store that outline in an array.  Then just check those array points to see if they match what we expect our outline to be.  If not, the *something* has been drawn on top of our image, and *THAT* qualifies as a collision.  Wink
Reply
#44
Aye, do you think if we saved the color with the x,y it would slow it down much?

Then for collision check, we can just see that point is the color it was.
b = b + ...
Reply
#45
(01-22-2023, 08:59 PM)bplus Wrote: Aye, do you think if we saved the color with the x,y it would slow it down much?

Then for collision check, we can just see that point is the color it was.

I wouldn't think so.  Hpw much slower is an IF x <> y THEN....  than an IF x <> &HFFFF0000 THEN?  Looking up a variable's value shouldn't have that much overhead attached to it, I wouldn't think.
Reply
#46
Thinking on the concept of a CollisionArray a little more, I think I'd do my data structure a wee bit different.

TYPE CA_Type
   AS INTEGER y, x1, x2
   AS _UNSIGNED LONG kolor
END TYPE

Now, why would I define my data in such an odd way?  Let's say we have some image like the below:

...................
.
.
.
...................

(And pretend our text is actually pictures creating a C shaped square with the right side opened.)

Now, all our colors are black, so I can store by CA(value).kolor as Black.
And the first line, I can store as :   CA(value).Y = 1:  CA(value).X1 = 0: CA(value).X2 = 20

Then when it comes time to check for collisions, I know to check:  (X1,Y) to (X2,Y) for black

HOW I check that range of X values for that color, is up to me to decide, based upon how complex I want my code and how important speed is for the routine.  Am I doing something simple which can render 600FPS, while I have a limit 30 in play?  PFFFTT!  In that case, I can code whatever the heck I want.  A FOR...NEXT loop and check each value POINT by point would be fine.  Do I need something speedier though, as I've got 80 enemy ships shooting a dozen bullets across the screen to track as well??  I might want to read in that whole strip of video information into a string with _MEM, and then just do a quick INSTR check for the string equivalent of a 4-byte Black pixel.  If I've got an enemy bullet that I know is going to be at point (x,y), then I can just check my array for y matches first, and then see if the bulletX is >= array.X1 and <= array.X2....

Instead of storing every pixel individually, it'd be a case of storing which row they're on (Y value) and then their start and stop points (X1 and X2).   (And color may not even matter, if you draw you draw your hero/ship/character onto the screen last.  Just check to see if any pixel from X1, Y to x2, Y is non-transparent (or non-background, whatever the background color is).  

Seems a slightly better data structure, to me, than using a type which just holds one pixel and its color.
Reply
#47
@Terry  a feedback on alpha channel
on studing a my idea  I have painted some picture sprites with Paintbrush and saved as PNG files.
The first demo of Terry worked weel, while with the new demo I find this issue showed in the image posted.

On the left the original demo 5 in which the alpha 0 has been set on _rgb32(255,0,255)
on the right the demo 5 in which the alpha 0 has been set on _rgb32(0)  (because in my pictures the background to be transparent is black).

[Image: immagine-2023-01-24-160559321.png]




So with original demo something is lost also if in the code the alpha 0 has been set for each image..
In the demo modded the alpha 0 channel has been set to black as the background of image loaded.
Here the images used 


[Image: Try1.png]



[Image: Try2.png]

I hope it can be useful for future development.

@Bplus
I'm sorry, while I was typing the demo, very simple, in my mind grew up a dubt that need more test to do for getting an universal well working function of collision detection...
So,please gimme more Tempo to use for coding! I have no time in the week, I hope to have good time for weekend.
Reply
#48
Quote:@Bplus
I'm sorry, while I was typing the demo, very simple, in my mind grew up a dubt that need more test to do for getting an universal well working function of collision detection...
So,please gimme more Tempo to use for coding! I have no time in the week, I hope to have good time for weekend.


I tested Terry's Collision detection here with Spiders: https://qb64phoenix.com/forum/showthread...6#pid12986

Very similar to your images! (except mine wiggle and are freshly drawn every loop!) ;-)) Great minds...

I isolated spots needed to setup for Terry's collision code with '++++++++++ comment lines
in that code.

Steve's Collision Routine is next on my ToDo list, one routine looks handy for editing images or other things.
b = b + ...
Reply
#49
(01-24-2023, 03:10 PM)TempodiBasic Wrote: @Terry  a feedback on alpha channel

on the right the demo 5 in which the alpha 0 has been set on _rgb32(0)  (because in my pictures the background to be transparent is black).

_RGB32(0) is not valid. Remember, _RGBA32(0,0,0,0) and _RGB32(0) are not the same. _RGB32(0) returns the value of 4278190080 because _RGB32(0) is actually 255,0,0,0 (11111111000000000000000000000000) 11111111 = Alpha, 00000000=Red, 00000000=Green, 00000000=Blue.
Reply
#50
(01-25-2023, 09:59 PM)TerryRitchie Wrote:
(01-24-2023, 03:10 PM)TempodiBasic Wrote: @Terry  a feedback on alpha channel

on the right the demo 5 in which the alpha 0 has been set on _rgb32(0)  (because in my pictures the background to be transparent is black).

_RGB32(0) is not valid. Remember, _RGBA32(0,0,0,0) and _RGB32(0) are not the same. _RGB32(0) returns the value of 4278190080 because _RGB32(0) is actually 255,0,0,0 (11111111000000000000000000000000) 11111111 = Alpha, 00000000=Red, 00000000=Green, 00000000=Blue.

I agree _RGB32(0) and _RGBA32(0,0,0,0) are not the same and they give back different results.

What I am trying to say you is that using a sprite (PNG files) with no already set transparent color (see my sprites made by WPaint) I got the overlapping of sprite and bad collision detect. 
BUT we set the transparent color (alpha) on the background color I get a good working of the code with NO mistakes in collision detection.
SO (imho) this minor aspect of the already or not set the transparent color is relevant for a good working of your demo.
Reply




Users browsing this thread: 5 Guest(s)