FAQ: ImagesCollide & Memory Access Violation ?!
Übersicht BlitzBasic FAQ und Tutorials
BIG BUGBetreff: FAQ: ImagesCollide & Memory Access Violation ?! |
Do, Jan 31, 2008 22:23 Antworten mit Zitat |
|
---|---|---|
ImagesCollide und ImageRectCollide kann trotz korrektem Aufruf zu einer MAV (MemoryAccessViolation) führen. Dieses Problem liegt an Inkompatibilitäten zu manchen Grafiktreiberversionen.
Es ist schwierig den Fehler nachzustellen, er tritt nicht bei jedem, und dann auch nur sporadisch auf. Bei animierten Bildern scheint es jedoch häufiger zur MAV zu kommen. Dem Anwender in diesem Fall einfach zu sagen, er solle sich den neuesten Treiber herunterladen wie es gerne vorgeschlagen wird, ist lächerlich, da sich die Grafikhersteller kaum mehr mit DX7 rumschlagen und das Problem in der Vergangenheit immer wieder aufgetreten ist. Auch wenn es schade ist, die Empfehlung lautet hier: Verzichte komplett auf ImagesCollide und ImageRectCollide! Im ersten Gedanken mag das vielleicht schmerzen, aber ImagesCollide ist vielleicht die einfachste Lösung, nicht unbedingt aber die beste. Gehen wir mal die verschiedenen Anwendungsfälle durch: -Mauscourser gegen Button (bei Anfängern) Brrrr grausam.... da sag ich mal nix zu -Spieler <> Gegner-Kollision Hier ist selten Pixelgenauigkeit gefragt. Es empfehlen sich eigene Kollisionsboxen, die wohlgemerkt kleiner als die Original-Grafiken sind, da sich die Kollisionen dann fairer anfühlen. Die Kollisionsboxen können ja dann einfach mit RectsOverlap geprüft werden. Beispiel -Spieler <> Map-Kollision Bei Tilemaps sind die Kollisionen normalerweise ja recht einfach durch ein bisschen Mathematik durchzuführen. Muß es dennoch pixelgenau sein(wie z.B. bei einer zerstörbaren Worms-Landschaft) reicht normalerweise ein ImageRectCollide Landschaftsgrafik <> SpielerKollisionsbox. Doch Vorsicht! ImageRectCollide ist ebenfalls von den MAVs betroffen! Daher habe ich hier mal zwei Routinen gebastelt, die statt ImageRectCollide benutzt werden können: Code: [AUSKLAPPEN] ;Ersetzt ImageRectCollide, ist aber leider recht langsam Function ImgRectCollide(image,xpos1, ypos1, xpos2, ypos2, width2, height2, mask=0) Local startx, starty, endx, endy, ix, iy Local width1 = ImageWidth(image) Local height1 = ImageHeight(image) xpos1 = xpos1 - ImageXHandle(image) ypos1 = ypos1 - ImageYHandle(image) startx = xpos2 - xpos1 starty = ypos2 - ypos1 endx = startx + width2 endy = starty + height2 If startx < 0 Then startx = 0 If starty < 0 Then starty = 0 If endx > width1 Then endx = width1 If endy > height1 Then endy = height1 endx = endx - 1 endy = endy - 1 If startx > endx Or starty > endy Then Return 0 LockBuffer ImageBuffer(image) For ix = startx To endx For iy = starty To endy If mask <> (ReadPixelFast(ix, iy, ImageBuffer(image)) And $00FFFFFF) Then UnlockBuffer ImageBuffer(image) Return 1 EndIf Next Next UnlockBuffer ImageBuffer(image) End Function ;Schneller als ImgRectCollide, es werden jedoch nur Eck- und Mittelpunkte geprüft Function ImgRectCollideFast(image,xpos1, ypos1, xpos2, ypos2, width2, height2, mask=0) Local startx, starty, endx, endy, ix, iy, x[3], y[3] Local width1 = ImageWidth(image) Local height1 = ImageHeight(image) xpos1 = xpos1 - ImageXHandle(image) ypos1 = ypos1 - ImageYHandle(image) startx = xpos2 - xpos1 starty = ypos2 - ypos1 endx = startx + width2 endy = starty + height2 If startx < 0 Then startx = 0 If starty < 0 Then starty = 0 If endx > width1 Then endx = width1 If endy > height1 Then endy = height1 endx = endx - 1 endy = endy - 1 If startx > endx Or starty > endy Then Return 0 x[0] = startx y[0] = starty x[1] = (startx + endx) Shr 1 y[1] = (starty + endy) Shr 1 x[2] = endx y[2] = endy LockBuffer ImageBuffer(image) For ix = 0 To 2 For iy = 0 To 2 If mask <> (ReadPixelFast(x[ix], y[iy], ImageBuffer(image)) And $00FFFFFF) Then UnlockBuffer ImageBuffer(image) Return 1 EndIf Next Next UnlockBuffer ImageBuffer(image) End Function Es gibt sicherlich noch andere Fälle, aber generell kann man gerade dadurch, dass man nur ausgewählte Punkte mit ReadPixel einliest, trotzdem eine hohe Geschwindigkeit erreichen. |
||
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final) |
da_poller |
So, Sep 14, 2008 22:17 Antworten mit Zitat |
|
---|---|---|
hier vielleicht eine kleine funktion meinerseits die ich mir nach lesen dieses beitrags geschrieben habe (vielleicht kann es ja jemand brauchen):
Code: [AUSKLAPPEN] Function rectposcollide(posx,posy,rectx,recty,width,height)
If posx>rectx And posy>recty And posx<(rectx+width) And posy<(recty+height) Return 1 EndIf Return 0 End Function ist vielleciht nicht die idealste lösung aber funktioniert(gibt es für den fall eine einfachere lösung die ich evtl übersehen habe? fals ja BITTE per pn bescheid sagen ... edit: dank meines nachposters zeilen gespaart und return0 eingefügt viel spaß damit |
||
- Zuletzt bearbeitet von da_poller am Mo, Sep 15, 2008 15:27, insgesamt einmal bearbeitet
Goodjee |
So, Sep 14, 2008 22:29 Antworten mit Zitat |
|
---|---|---|
warum nich alles in eine zeile und eventuell ein return 0 ans ende, aber ansonsten kann man es nich anders machen | ||
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/ |
mabox |
So, Sep 14, 2008 22:29 Antworten mit Zitat |
|
---|---|---|
kommt es bei ImagesOverlap nicht zu solchen problemen? | ||
Fujitsu-Siemens Laptop, 2Ghz Intel Core2Duo Prozessor, 2GB Ram, 120GB Festplatte, ATI Mobility Radeon X1400, Windows Vista Ultimate
www.mausoft.de.tl Dönerfresser Homepage |
BIG BUG |
Mo, Sep 15, 2008 0:58 Antworten mit Zitat |
|
---|---|---|
Nein, ImagesOverlap funktioniert, da hier nur ein Koordinatenvergleich stattfindet. | ||
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final) |
BIG BUG |
Fr, März 27, 2009 17:17 Antworten mit Zitat |
|
---|---|---|
Habe mal zwischenzeitlich auch echtes ImagesCollide benötigt. Daher hier auch noch eine Funktion um ImagesCollide direkt zu ersetzen. Wenn sich große Teile der Bilder überlappen wird diese aber langsam. Mit Banken könnte man das zumindest für statische Bilder noch wesentlich beschleunigen.
Code: [AUSKLAPPEN] ;replaces ImagesCollide because of MAV bug Function ImgCollide(image1,xpos1, ypos1, frame1, image2, xpos2, ypos2, frame2=0, mask=0) Local startx, starty, endx, endy, ix, iy Local width1 = ImageWidth(image1) Local height1 = ImageHeight(image1) Local width2 = ImageWidth(image2) Local height2 = ImageHeight(image2) xpos1 = xpos1 - ImageXHandle(image1) ypos1 = ypos1 - ImageYHandle(image1) xpos2 = xpos2 - ImageXHandle(image2) ypos2 = ypos2 - ImageYHandle(image2) startx = xpos2 - xpos1 starty = ypos2 - ypos1 start2x = startx start2y = starty endx = startx + width2 endy = starty + height2 If startx < 0 Then startx = 0 If starty < 0 Then starty = 0 If endx > width1 Then endx = width1 If endy > height1 Then endy = height1 endx = endx - 1 endy = endy - 1 If startx > endx Or starty > endy Then Return 0 LockBuffer ImageBuffer(image1, frame1) LockBuffer ImageBuffer(image2, frame2) For ix = startx To endx For iy = starty To endy If mask <> (ReadPixelFast(ix, iy, ImageBuffer(image1, frame1)) And $00FFFFFF) Then If mask <> (ReadPixelFast(ix-start2x, iy-start2y, ImageBuffer(image2, frame2)) And $00FFFFFF) Then UnlockBuffer ImageBuffer(image1, frame1) UnlockBuffer ImageBuffer(image2, frame2) Return 1 EndIf EndIf Next Next UnlockBuffer ImageBuffer(image1, frame1) UnlockBuffer ImageBuffer(image2, frame2) End Function |
||
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final) |
Silver_Knee |
Sa, März 28, 2009 20:02 Antworten mit Zitat |
|
---|---|---|
Hey du kannst die Funktion ruhig guten gewissens imagesCollide nenne. damit überschreibst du dann die blitz-interne funktion. Das funktioniert halt nur solange du in deiner ImagesCollide-Funktion nicht imageCollides verwendest. Das tust du nicht. Also mach es den coder einfacher: Die fügen die Function am ende des codes ein und brauchen sonst keine Zeile zu ändern | ||
M0rgenstern |
Mo, Apr 06, 2009 13:37 Antworten mit Zitat |
|
---|---|---|
Also ich hatte das Problem mit ImagesCollide auch.
Ich habe jetzt mal BigBugs Lösung probiert und diese funktioniert perfekt. Eine Frage nur: Darf man die in eigenen Programmen benutzen? LG, M0rgenstern |
||
FWeinbehemals "ich" |
Mo, Apr 06, 2009 13:48 Antworten mit Zitat |
|
---|---|---|
Ein Tutorial ist zur Erklärung da der Autor Versucht damit Typische "noob" Fehler zu erklären und daher denke ich das du den Code so verwenden darfst.
mfg ich |
||
"Wenn die Menschen nur über das sprächen, was sie begreifen, dann würde es sehr still auf der Welt sein." Albert Einstein (1879-1955)
"If you live each day as if it was your last, someday you'll most certainly be right." Steve Jobs |
Übersicht BlitzBasic FAQ und Tutorials
Powered by phpBB © 2001 - 2006, phpBB Group