Bevægende bold

Tags:    visual-basic

Hej der.
Hvordan får jeg en Picture-kontrol til at bevæge sig af sig selv i et område begrænset af en anden Picture-kontrol?
Den skal så også reagere på stød med 'væggen'
(i VB 6.0)

Søvn er den eneste lykke, som man først nyder rigtig, når den er forbi.
Alfred Polgar



6 svar postet i denne tråd vises herunder
1 indlæg har modtaget i alt 4 karma
Sorter efter stemmer Sorter efter dato
Her er så hele source koden, læg mærke til at jeg ikke blot har tilføjet en masse nyt, men også har ændret noget af det gamle. Det var nemlig ikke helt ligegyldigt hvilken en af metoderne man brugte til at dele den tilfældige trekant op i en retvinklet som jeg snakkede om.

Fold kodeboks ind/udKode 


Grunden til at jeg har brugt GoTo istedet for en do-loop er fordi at det er så forfærdeligt sjældent at man får brug for at loope dette her stykke kode! Derfor valgte jeg GoTo da det gik lidt hurtigere. VB er jo i forvejen ikke god til at lave grafik så man kan lige så godt gøre arbejdet for timeren så let så muligt så man kunne få en lidt mere flydende bevægelse.

Som du kan se er der nogle kommandoer i parentes. Dette er fordi at det er lidt overflødigt i et simpelt spil, men hvis du skal lave noget realistisk skal de tages med! Man kan jo ikke flytte en picturebox 1,4 pixel, og man vil herved glemme de 0,4 pixel og bare flytte den en. Ved at tilføje koderne husker den de 0,4 pixel til næste gang den skal flyttes.

Du må foresten undskylde at jeg ikke lige gider at forklare koden, for den er faktisk ret inviklet!! Desuden så fandt jeg ud af senere at man slet ikke behøver at bruge sin(), cos() og tan() til udregning af kollition med væg. Derfor kan det godt være jeg lige uploader et styks kode mere hvor denne hurtigere metode er taget i brug...

// Great programs often follow great brains!



Ahh, se det var et spørgsmål der var spændende synes jeg!

Du skal først tænke på hvordan en bold reagere når den rammer en væg. Her kan du tænke på billiard hvor reglen siger at "indgangsvinkel = udgangsvinkel" hvis der ikke er noget skru i bolden hvilket jeg ikke regner med...
Derfor forslår jeg at du har en variabel der indeholder vinklen som bolden bevæger sig i. Vi ved jo at der er 360 grader i en cirkel. (Hvis det skal være 3d, og at bolden ikke altid ruller, skal der på være en variabel der indeholder vinklen på den ene led og en der indeholder vinklen på den anden led.)

Du skal også have en variabel der indeholder hvor hurtigt bolden bevæger sig i denne retning (igen hvis det er 3d skal du have 2 variabler - en til hver retning).

Så skal du have en timer. Hvis enheden på hvor hurtigt bolden bevægede sig i en retning er fx pixel/sek skal du naturligvis indstille din form og pictureboxes til at måle i pixels. Men du skal også huske at hvis du har sat timeren til at udfører udregningerne hvert 0,5 sek skal du dividere antal pixel den skulle bevæge sig med 2 således at tidsintervallet passer med enheden...

Det svære er at flytte den hvilket dit spørgsmål faktisk også bygger på (forklaring til en 2d bevægelse). Lad os holde os til at se på bolden som en firkant der omklamrer den (pictureboxen). Vi siger også at 0 grader betyder lodret op og at graderne stiger med uret som det plejer.
Oki, her tegner vi så denne her streg op i luften fra en af firkantens hjørner (det er lettest senere hvis du vælger oppe i venstre hjørne). Fra den streg tegner så en anden streg fra hjørnet der bevæger sig med en vinkel (fx 20 grader) i forhold til den lodrette streg. Den streg du lige har tegnet skal være lige så lang som den længde bolden skal bevæge sig!
Hvis du har valgt en vinkel på under 90 grader har du tegnet dig en retvinklet trekant som du har vinklen på og hypotenusen. Herved kan du benytte dig af sinus til at finde vinklens modstående katete (som jo er den længde som figuren skal bevæge sig til venstre) og cosinus til at finde vinkles hosliggende katete (som er den højde som figuren skal bevæge sig opad).
Hvis vinklen dog er større end 90 grader skal du til at tegne en retvinklet trekant udfor den tilfældige trekant. Der gælder for den retvinklede trekant at dens hypotenuse er lig med den tilfældige trekants hypotenuse. Men vi har også brug for den retvinklede trekants vinkel før vi kan beregne på den. Dette gøres ved at se på sammenhængen mellem vinklen og den vinkel som den retvinklede trekant skal have, hvilket er:

Over 0 grader og under 90 grader:
V1 = V
eller
V1 = 90 - V
Over 90 grader og under 180 grader
V1 = 180 - V
Over 180 grader og under 270 grader
V1 = V - 180
Over 270 grader og under 360 grader
V1 = V - 270

Læg mærke til at der er 2 muligheder ved den første... Dette er fordi at den hosliggende katete og den modstående katete bare bliver byttet om, så hvor cosinus relationen før gav højden ville den ved ombytning give længden!
De andre bliver bare udregnet som retvinklede trekanter som den første!

Kode indtil videre

Her er koden for alt det jeg har forklaret om indtil videre:
Fold kodeboks ind/udKode 


Nu ved du da hvordan man får bolden til at bevæge sig... Men det er ved at blive så sent nu så jeg skriver måske hvordan man får den til at bounce på væggen i morgen!

// Great programs often follow great brains!



Lige en indskydelse:

Den kode du så fint har skrevet - eller modificeret - kan den også bruges under DirectX 8, med en uendelig Do...Loop i stedet for en timer?



Her er den i hvert fald med do-loop'et:

Fold kodeboks ind/udKode 


Jeg har faktisk også repareret en forholdsvis stor fejl i koden! Nemlig at, da jeg skulle beregne om denne bevægelse var valid, havde glemt at sammenligne om vinklen overhovedet parrede ind mod væggen mere!!

Desuden har jeg også optimeret måden at udregne kordinaterne for kassen, når den kollidere med en væg. Denne optimering har også gjort at jeg har været nød til at ændre på nogle enkelte tal, men det ligger du sikkert ikke mærke til :P

// Great programs often follow great brains!



Hvor kommer Timer og starttimer fra?



Sådan et do-loop bliver jo kørt lige så hurtigt som computeren kan. Derfor vil farten på bolden afhænge meget af hvor hurtig computeren er.
Ved at undersøge hvor lang tid computeren var om at loope vil en kraft på 60pixel/sek være ens på alle computere og den vil blot hakke lidt mere på svage computere end på stærke!

Forskellen er altså at den med timeren vil flytte bolden 60pixel i sekundet, mens den unden timeren vil flytte bolden 60 pixel så hurtigt så muligt!

// Great programs often follow great brains!



t