Studs mot objekt
Hej, i programmeringskursen jag går i ska vi göra ett breakout spel med brickor. Jag har stött på lite problem med kollision mellan bollen och alla brickor. Kollisionerna fungerar korrekt uppifrån och nerifrån men inte från sidan och kanter mellan bricka och boll. Det är det jag har fastnat på hur jag ska formulera mina if satser. Jag har räknat lite matte för att få ut positionen på varje bricka men är inte helt säker om jag har gjort rätt på det. Tänker att det är utifrån det man ska formulera if satserna, men typ x och y koordinater?
Här är bilder: I min square colletion class har jag gjort två loopar en för y kordinaterna på brickor och en för x:
Till sist en bild på game classen och hur spelet ser ut hittils:
Den första isColliding är mellan slagträ och boll. Det är i game som jag tänker att alla dessa if satser ska ligga, men det är då att när bollen studsar i från sidan och hörn som det inte fungerar. Har inte kommit så långt än att brickorna försvinner när bollen kolliderar med en viss bricka.
Tack på förhand!
Hej, har det löst sig?
Ser ingen kod för själva kollisionsdetekteringen dock.
Det ser ut som att brickorna placeras i en List, squares. Antar att du tänker loopa igenom den och kolla om rutan överlappar med bollen. Om man ser allt som rektanglar, alltså bollen, paddeln och brickorna, är jämförelsen likadan för alla fallen. Du kan eventuellt ha en basklass som alla dessa ärver från för att ha koden på ett ställe.
Skapa två rektanglar, en liten och en stor, och placera dem på olika sätt och testa att isCollining() ger rätt resultat. T ex ifrån varandra, överlappande på olika sidor etc. Det är mycket enklare att se till att metoden gör rätt när man skapar exempel där man vet önskat resultat. När det funkar kan man återgå till själva spelet.
Hej, det går sådär, har gjort framsteg men det studsar åt fel hål ibland eller hur man ska säga. ibland fungerar det helt korrekt. men vissa gånger kommer bollen tillbaka åt samma håll den studsade ifrån.
Har gjort en funktion isColliding2 i squarecollection klass som använder intersect mellan boll och rektangel som returnerar vilken bricka som träffades om det skedde en kollison:
Sen har jag gjort fyra funktioner till i squarecollection, isAbove, isBelow, isRight och isLeft som används i game klassen som där de olika if satserna är:
Här ligger då if-satserna som kollar vartifrån bollen träffar och med vilken riktning bollen har i game klassen:
Vet inte om det går att lägga in videos om hur bollen rör sig men ibland blir det att om exempelvis bollen träffar underifrån och kommer från höger att den åker tillbaka åt samma håll tillbaka när det studsar, eller ibland från sidan så kommer den underifrån och träffar sidan av en rektangel och åker tillbaka neråt när det egentligen borde åka uppåt. Det är det jag har fastnat på och inte vet hur jag ska lösa.
Här kan du se hur spelet fungerar när jag kör det. Studsar åt fel håll ibland men andra gånger fungerar det helt korrekt med kollisonerna :
Vet inte exakt vad du använder isAbove/Below/Left/Right till men de verkar inte ta hänsyn till objektens storlek, endast övre vänstra hörnet.
isLeft och isRight använder storek på square, men inte boll, men om de ska funka som above/below borde de inte ta . isLeft använder getHeight vilket verkar fel.
Om du menar att jämföra övre vänstra hörnet ska inte width/height vara med.
Om du menar att jämföra om hela objektet är bredvid ska både bollens och rutans storlek vara med (men inte alltid, t ex är bollen till höger om dess x är större eller lika med rutans x plus rutans bredd).
Testa funktionerna för sig genom att placera ut boll och ruta i alla kombinationer och kontrollera att du får förväntat resultat. Alldeles för mycket inblandat att sitta och ändra och testa i hela spelet på en gång.
Logiken: Som jag fattar det vill du ändra riktning beroende på vilken sida av rutan som bollen träffar. Träffar du ovan- eller undersidan borde både x- och y-riktning ändras. Träffar du vänster- eller högersidan ändras endast x-riktning.
Nu testar du vilken sida bollen är på när de kolliderar, då låter det som att du måste ta hänsyn till både bollens och rutans storlek.
Hej igen, har suttit några dagar nu och jobbat med detta och har försökt ändra lite med matten till de olika funktionerna och har fått det att fungera bättre nu. Hursomhelst, spelet ska ha fler bollar och tidigare hade jag bara kollision med en boll. Så jag gjorde en ballcollection på samma sätt som squarecollection. Dock har jag nu fått problem med kollisonen mellan väggarna och själva boxarna och det fungerar inte rätt. Alla 3 bollar åker snett uppåt vänster som jag satt dom att göra men när de ska studsa mot väggen så åker de istället bara uppåt till vänstra hörnet av rutan där de stannar.
Såhär har jag gjort i ballcollection men det är något som blir fel. När jag hade en boll så använda jag ballXdir = -ballXdir som jag kommenterade ut där
Har även detta i ballcollection som blir fel, det blir typ när en studsar mot paddle i game klassen så blir det som att alla bollar studsar mot den. Är det för att jag inte har en loop som går igenom alla bollar och kollar vilken som träffar? Och i den tredje bilden är själva funktionen som kollar efter kollision mellan boll och paddle i ballcollection klassen
Svårt veta i detalj men i första skärmdumpen verkar du sätta x till ballXdir som ser ut att vara det delta du adderar till bollen i varje steg. Att byta tecken på den som i den bortkommenterade koden verkar rätt.
Eftersom ballXdir och ballYdir är delta för bollens rörelse måste de vara en uppsättning per boll, dvs du lägger dem i klassen WhiteBall.
Blir det då att jag lägger dessa funktioner i WhiteBall klassen?
Och sedan gör något sånt här i ball collection klassen?
Får samma problem då typ att om en studsar mot en vägg så studsar alla bollar. Antar att det är för att jag ändrar riktningen på varje boll men är inte säker på hur jag ska göra för att få att just den bollen som studsa mot en vägg byter riktning?
Ser ut som du blandar ihop bollens variabler men de "lösa" som inte ska finnas längre, jobba med en boll i taget.
Lite förkortat:
for (....) {
WhiteBall ball = balls.get(i);
if (ball.getX() <= 0)
ball.setBallXDir(-ball.getBallXDir());
Lite snyggare om metoden heter get/setXDir(), när den ligger inuti WhiteBall blir det upprepning med "ball" i metodnamnet.
Du bör också sätt bollen x till 0 när den vänder vid vänsterkanten, inte snyggt att den kan vara t ex -2.
Okej tack, jag testar! Det blir inget krångel med detta då min Whiteball klass ärver från ColoredBall klass som i sin tur ärver från Sprite klassen?
Kan inte svara med 100% säkerhet eftersom jag bara sett och satt mig in i några delar av koden men det låter inte som något problem. Jag vet inte vilka variabler som hör till vilken klass i hierarkin men om arvet är "naturligt" verkar allt ok.
(Om ColoredBall och WhiteBall endast skiljer i att färgen är vald låter det inte som att det förtjänar en egen klass men det är bara en detalj).
Testade och försökte debuga vad som kan ha blivit fel men nu gick det åt skogen, bollarna studsade inte alls mot väggen utan gick igenom. Kan det vara för att jag har skrivit något fel i for-loopen?
Blev tvungen att type casta vid WhiteBall ball = balls.get(i), kan det bero på det?
Såg att jag glömde lägga till ball.getXdir() men fungerade inte ändå
BallColllection ska inte ha position och riktning för bollarna, de ligger ju i ColoredBall-klassen. Ser ut som kvarlämnat "skräp" som används, ta bort.
Frågan om cast: Din lista är ColoredBall, du bör använda ColoredBall i loopen (inte WhiteBall).
Deklarare balls så här:
List<ColoredBall> balls;
Sen skapar du med "diamond", alltså utan typ eftersom kompilatorn redan känner till den:balls = new ArrayList<>();
Alternativt:List<ColoredBall> balls = new ArrayList<>();
Blir detta rätt? Sätter balls = new Arraylist<>(); i konstruktorn. Det är någonting som inte blir korrekt med studsen, kan det vara rad 21 och 22 som spökar med balls.get(i).setX()? De är de som sätter "startriktingen" på bollen. Med List, menar du ArrayList?
Eller har jag gjort något fel med getBallxDir och de funktionerna i Colored Ball?
Bollens position och riktning ska vara i bollens klass. xDir och yDir i BallCollection kan inte fungera, de är ju olika för varje boll.
Om du är osäker på vad som händer, använd 1 boll och skriv ut x, y, xdir, ydir efter varje update.
Det är det enda sätter jag får bollarna att röra på sig när jag skriver sådär i BallCollection klassen, Om jeg exempelvis försöker med setX(getX()-5) och setX(getX()-6) i antligen ColoredBall eller WhiteBall, i public void Update så står bara bollarna stilla.
Fundera igenom vilka variables som hör til vilket objekt.
ColoredBall har position och riktning. Tänk på att bollen måste ha en hastighet (riktning) då den skapas, annars adderar du 0 och bollen står still.
BallCollection har INTE postion eller riktning, den har en lista med bollar.
Felsök genom att använda en (1) boll. Skriv ut variablerna i varje steg så du ser vad som händer, jämför med vad din kod förväntas göra.