Angrenzende Tiles ermitteln

Previous topic - Next topic

Dakker

Hi, hab ein kleines Problem mit mienem Spiel. Ich hab ein Spielfeld, das aus 10x13 Blöcken besteht, die verschiedene Farben haben. Das ganze ist in einem 2 dimensionalem Array gespeichert. Ich möchte nun, wenn ich mit dem Mauzeiger über einen Block fahre, ermitteln welche Blöcke an disen Block angrenzen, und welche Blöcke wiederum an diese Blöcke angrenzen(horizontal und vertikal), so dass dann eine Blockgruppe entsteht, die wiederum in einem eigenen Array gspeichert wird.

hier mal ein Bild:





Wie man sieht, werden nicht alle Blöcke erkannt, die zu der Gruppe gehören. Hat jemand eine Idee, wie ich das lösen könnte?

Kitty Hello

Hehe. Du musst von dem Punkt den Du angeklickt hast aus alle mit der gleichen Farbe "füllen".

Pseudocode:

Code (glbasic) Select
function Fill: feld[], x,y, color
local n=0
   if feld[x][y] = color
      feld[x][y] = 1000 // merken, dass dieses Feld schon benützt wurde
      n= 1 + Fill(feld[],x-1,y,color) + fill(feld[],x+1,y,color) + fill(feld[],x,y+1,color)+fill(feld[],x,y-1,color)
   endif
endfunction

function Prüfen: feld[], x,y
local n
static fcopy[]
   fcopy[] = feld[] // eine kopie anlegen - das originalfeld nicht anfassen
   n = fill(fcopy[], x,y, fcopy[x][y])

   // Feld jetzt anzeigen
   DisplayFeld(fcopy[])

   if n>4
      RemoveBubble(fcopy[], 100) // alle 100er rausmachen und runterfallen usw...
      feld[] = fcopy[]
   endif

endfunction
EDIT:
Aufpassen, dass Du nicht direkt an den Rand kommst, sonst frägst Du das feld[-1][y] ab -> Grrr
Oder oben eine IF Abfrage mit einbauen. Klar, oder?

Schranz0r

Hatte ich auch mal gemacht, du musst jedes Tile durchgehn das angrenzt.
Sprich grenzt ein Tile an, an deiner aktiven Farbe musst du dieses auch auf oben unten links und rechts prüfen ob da noch was da ist...
Ist garnet mal so einfach....

Lass mich lügen, ich glaub ich hatte das mit Types gemacht.
I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

Kitty Hello

Ich hatte dazu so ein PuyoPuyo Dingens. Aber ich find's nimmer :(
Mein Ordner ist mittlerweile so überladen mit Zeug.. .ich muss mal ausmisten.

Dakker

Quote from: Schranz0rHatte ich auch mal gemacht, du musst jedes Tile durchgehn das angrenzt.
Sprich grenzt ein Tile an, an deiner aktiven Farbe musst du dieses auch auf oben unten links und rechts prüfen ob da noch was da ist...
Ist garnet mal so einfach....

Lass mich lügen, ich glaub ich hatte das mit Types gemacht.
In die Richtung hab ichs auch schon probiert, aber irgendwie klappt das nicht. Ich habs bestimmt schon zehn mal neu programmiert und immer was neues probiert. Der fehler ist dass er ab der 2 bzw 3 wechsel von Horizontal auf Vertikl bzw umgekehrt, einfach aufhört. Ich prüf das ganze übers Array.

Die steine sind als Tileset mit 6 verschiedenen Tiles gespeichert und werden als Anim geladen.
Das Feld erzeuge ich mit folgender Schleife:

Code (glbasic) Select
FOR x = 0 TO 9
FOR y = 0 TO 12
Feld[x][y] = RND(2)   //Feld generieren RND(anzahl der Farben - 1)
NEXT
NEXT
Später wird es dann mit drawanim gezeichnet. Zum überprüfen der angrenzenden Blöcke habe ich die funktinon chkumg():

Code (glbasic) Select
FUNCTION chckumg:
// Diese Variablen sind als LOCAL definiert:
// numwor$
FOR dlx = 0 TO 9
IF Group[dlx][y] = 1
FOR dly = y TO 12
IF Feld[dlx][dly] = Feld[x][y]
Group[dlx][dly] = 1
ELSE
BREAK
ENDIF
NEXT
ENDIF
NEXT

FOR dlx = 0 TO 9
IF Group[dlx][y] = 1
FOR dly = y TO 0 STEP -1
IF Feld[dlx][dly] = Feld[x][y]
Group[dlx][dly] = 1
ELSE
BREAK
ENDIF
NEXT
ENDIF
NEXT

FOR dly = 0 TO 12
IF Group[x][dly] = 1
FOR dlx = x TO 9
IF Feld[dlx][dly] = Feld[x][y]
Group[dlx][dly] = 1
ELSE
BREAK
ENDIF
NEXT
ENDIF
NEXT

FOR dly = 0 TO 12
IF Group[x][dly] = 1
FOR dlx = x TO 0 STEP -1
IF Feld[dlx][dly] = Feld[x][y]
Group[dlx][dly] = 1
ELSE
BREAK
ENDIF
NEXT
ENDIF
NEXT



ENDFUNCTION // CHCKUMG
Wie genau hast du es mit den Types gelöst?


//EDIT:
Ok, hat sich erledigt. Hab etz nach 2 Wochen endlich die Lösung. Bin da viel zu kompliziert rangegangen, is eigentlich ganz einfach! ^^ Danke für die Hilfe!

D2O

Kleines beispiel ohne sicherheitsabfragen.
Geh mit maus auf 22 dann leuchtets auch bei der 12.


Code (glbasic) Select
DRAWRECT 0,0,32,32,RGB(0xff, 0x00, 0x00)
GRABSPRITE 0,0,0,32,32

BLACKSCREEN

SYSTEMPOINTER TRUE

DIM a[10][10]


FOR iy = 0 TO 9
FOR ix = 0 TO 9

a[ix][iy] = b
INC b,1

NEXT
NEXT




WHILE TRUE
MOUSESTATE mx,my,b1,b2
FOR iy = 0 TO 9
FOR ix = 0 TO 9
PRINT a[ix][iy] ,ix*32,iy*32
IF mx > ix*32 AND mx < (ix*32)+32 AND my > iy*32 AND my < (iy*32)+32
ALPHAMODE -0.5
DRAWSPRITE 0,ix*32,iy*32
ALPHAMODE 0

IF a[ix][iy-1] = 12
ALPHAMODE -0.5
DRAWSPRITE 0,ix*32,(iy-1)*32
ALPHAMODE 0
ENDIF
ENDIF
NEXT
NEXT


SHOWSCREEN
WEND
END
Edit:
Nun mit einer sicherheitsabfrage und die Wertrückgabe der Tiles/Arrays von oben/unten/links und rechts.
Code (glbasic) Select
DRAWRECT 0,0,32,32,RGB(0xff, 0x00, 0x00)
GRABSPRITE 0,0,0,32,32

BLACKSCREEN

DRAWRECT 0,0,32,32,RGB(0xff, 0xff, 0x00)
GRABSPRITE 1,0,0,32,32

BLACKSCREEN

SYSTEMPOINTER TRUE

DIM a[10][10]
DIM wert[5]

 b = 1
 
FOR iy = 0 TO 9
FOR ix = 0 TO 9

a[ix][iy] = b
INC b,1

NEXT
NEXT

GLOBAL posx = 32
GLOBAL posy = 32


WHILE TRUE
MOUSESTATE mx,my,b1,b2
FOR iy = 0 TO 9
FOR ix = 0 TO 9
PRINT a[ix][iy] ,posx+ix*32,posy+iy*32
IF mx > posx+ix*32 AND mx < posx+((ix*32)+32) AND my > posy+iy*32 AND my < posy+((iy*32)+32)
wert[0] = a[ix][iy]
ALPHAMODE -0.5
DRAWSPRITE 1,posx+ix*32,posy+iy*32

IF iy > 0

DRAWSPRITE 0,posx+ix*32,posy+(iy-1)*32
wert[1] = a[ix][iy-1]
ENDIF

IF iy < 9

DRAWSPRITE 0,posx+ix*32,posy+(iy+1)*32
wert[2] = a[ix][iy+1]
ENDIF

IF ix > 0

DRAWSPRITE 0,posx+(ix-1)*32,posy+iy*32
wert[3] = a[ix-1][iy]
ENDIF


IF ix < 9

DRAWSPRITE 0,posx+(ix+1)*32,posy+iy*32
wert[4] = a[ix+1][iy]
ENDIF

ALPHAMODE 0


ENDIF
NEXT
NEXT


PRINT "Feld mitte  = "+wert[0],100,350
PRINT "Feld oben   = "+wert[1],100,360
PRINT "Feld unten  = "+wert[2],100,370
PRINT "Feld links  = "+wert[3],100,380
PRINT "Feld rechts = "+wert[4],100,390


FOR p = 0 TO 4
wert[p] = 0
NEXT

SHOWSCREEN
WEND
END
I7 2600K; 8 GB RAM ; Win10 Pro x64 | NVidia GTX 750 TI 2048MB ; Realtec OnBoard Sound;
Lenovo ThinkPad T400: XP Pro
GLB Premium-immer Aktuell