Gå til innhold

Anbefalte innlegg

Har så smått startet på et plattformspill som jeg skriver for å lære. Spillet er ikke mindre enkelt enn at du skal hoppe fra plattform til plattform mens de sakte men sikkert kommer fra høyre til venstre uten å dette ned for lengst mulig tid.

 

Jeg lurte på hva som var vanlig å gjøre når det kommer til "tyngdekraft" ? Den koden jeg bruker nå er sikkert helt jalla da det går ut på å bevege spriten av personen du spiller nedover hele tiden og sjekke etter om han kolliderer med plattformer, når man trykker space så blir dette reversert for å hoppe. Men er vel garantert en enklere metode?

 

Beklager om det var formulert litt noobete men :(

Lenke til kommentar
Videoannonse
Annonse

Regner ikke med at det er meningen at det skal være realistisk. Særlig siden realistisk gjerne == kjedelig i sånne type spill :)

 

Hvis det du har nå "funker" for spillet, dvs. at det føles spillbart, så ville jeg beholdt det.

 

Hvis ikke kan du gjøre noe som dette:

 

 

HoppFart = 30; // for å kunne hoppe litt over 3 meter

 

OnHopp:

Player.SpeedY = HoppFart;

 

OnTick:

if( Player.IsOnPlatform )

Player.SpeedY = 0;

Player.LocationY += Player.SpeedY * AntSecSidenForrigeTick;

Player.SpeedY -= 9.8 * AntSecSidenForrigeTick; (Gravitasjonskraften)

 

 

Btw: syntes å huske at Mario spillene økte HoppFart'en avhengig av hvor lenge man holdt inne hoppknappen....

Endret av jorn79
Lenke til kommentar

Lurset er å bruke noe som kalles vektorer, sett at en sprite har en bevegelses vektor, som man alltid adderer til posisjonen. Tyngdekraft legges til ved å legge til tyngdekraft konstant etterpå.

Man må alltid sjekke om neste posisjon vil krysse en linje, så lenge det er snakk om firkanter, er dette ganske simpelt å få til.

 

en vektor kan defineres på denne måten:

 

public struct Vector
{
 float m_x;
 float m_y;
 float m_mag;
 public float X { get { return m_x; } set { m_x = value; } }
 public float Y { get { return m_y; } set { m_y = value; } }
 public float Magnitude { get { return m_mag; } set { m_mag = value } }

 public Vector(float x, float y, float mag)
 {
   m_x = x; m_y = y; m_mag = mag;
 }
}

 

Her sier man at Magnitude er lengden av vektoren (hastigheten) og x og y er retningen (posisjon relativt i forhold til objektet, så en som beveger seg 1 pixel mot høyere ville gitt { 1, 0, 1 })

 

Ofte kan magnitude regnes utifra bare X og Y, men vi tar den med her for enkelhetsskyld.

 

Nå har sikkert j0rn funnet en mye bedre løsning mens jeg har skrevet :(

 

edit: la til constructor

 

edit2: vil legge til at den beste måten å finne antall ticks siden forrige frame på, er å bruke noe i Windows som heter High resolution timer, framfor noen av .NET funksjonene.

Forskjellen, er at high reolution timer, henter antall instruksjoner, noe som gjør at den aldri vil bli null.

Ved bruk av .NET sine funksjoner, kan man komme i skade for å få 0 sekunder, noe som fører til at spillet står stille.

Endret av GeirGrusom
Lenke til kommentar
Skjønner hva dere mener, må se til å teste dette så fort jeg kommer meg hjem =)

Tusen takk. Tror jeg skal teste jorn79 sin først da jeg synes denne var enklere å forstå.

9085371[/snapback]

 

Det er ikke noe problem å kombinere dem. Bare bytte ut Speed, Location, og "HoppFart" med vectorer. Med ordentlige vectorer er det også enklere å legge på flere faktorer som vind, "bomber" som smeller og dytter figuren, etc...

Lenke til kommentar

public struct Vector
{
float m_x;
float m_y;
float m_mag;
public float X { get { return m_x; } set { m_x = value; } }
public float Y { get { return m_y; } set { m_y = value; } }
public float Magnitude { get { return m_mag; } set { m_mag = value } }

public Vector(float x, float y, float mag)
{
  m_x = x; m_y = y; m_mag = mag;
}
 public static Vector operator + (Vector a, Vector b)
 {
   return new Vector(a.X * a.Magnitude + b.X * b.Magnitude, a.Y * a.Magnitude + b.Y * b.Magnitude, 1);
 }
 public static Vector operator - (Vector a, Vector b)
 {
   return new Vector(a.X * a.Magnitude - b.X * b.Magnitude, a.Y * a.Magnitude - b.Y * b.Magnitude, 1);
 }

 public static Vector operator / (Vector a, Vector b)
 {
   return new Vector(a.X * a.Magnitude / b.X * b.Magnitude, a.Y * a.Magnitude / b.Y * b.Magnitude, 1);
 }

 public static Vector operator * (Vector a, Vector b)
 {
   return new Vector(a.X * a.Magnitude * b.X * b.Magnitude, a.Y * a.Magnitude * b.Y * b.Magnitude, 1);
 }
}

public class Player
{
 protected Vector m_pos;
 protected Vector m_acc;

 public Vector Position { get { return m_pos; } set { m_pos = value; } }
 public Vector Momentum { get { return m_acc; } set { m_acc = value; } }

 public void PerformMove()
 {
   m_pos = m_pos + m_acc;
 }
}

public static void Main()
{
 Vector Force_Gravity;

 Force_Gravity = new Vector(0, -1, 0.98f);

 Player m_player;

 while(true)
 {

   // Sett spilleren sin momentum(fart) her
   m_player.Momentum = m_player.Momentum + m_player.Momentum * Force_Gravity;
   Vector target_pos = m_player.Position + m_player.Momentum;
   // Sjekk kollisjoner evt. her
   m_player.Position = target_pos;
   // Tegn spilleren her
 }
}

 

Vet ikke om dette kan brukes....

edit: yikes! ble mye lenger en jeg trodde.....

edit2: kritisk bug :p

Endret av GeirGrusom
Lenke til kommentar

Er det vanlig å bruke "Magnitude" på denne måten? Virket tungvindt syntes jeg, og man må jo gange med den veldig ofte. Eneste poenget er at du slipper å normalisere så ofte, men det kan man jo unngå lett ved å "cache" den normaliserte vectoren... Dessuten må han jo fortsatt normalisere hver eneste gang etter at man har gjordt en operasjon på vectoren.... :thumbdown:

 

Edit: lest litt mer av koden nå og ser at du setter Magnitude til 1 hver gang du gjør en operasjon. Så i prinsippet ender du (ofte) opp med en haug med unormliserte vectorer hvor Magnitude ikke er i bruk (=1) -- uten å få noen fordeler igjen for det....?

Endret av jorn79
Lenke til kommentar
Er det vanlig å bruke "Magnitude" på denne måten?  Virket tungvindt syntes jeg, og man må jo gange med den veldig ofte. Eneste poenget er at du slipper å normalisere så ofte,  men det kan man jo unngå lett ved å "cache" den normaliserte vectoren...  Dessuten må han jo fortsatt normalisere hver eneste gang etter at man har gjordt en operasjon på vectoren....  :thumbdown:

9085797[/snapback]

 

Du har rett, jeg unnlot normalisering pga. at det ble mindre matte, men i etterkant ser jeg at det hadde gjort koden mindre :(

 

Edit: Jeg resetter magnitude etter at den har vært i bruk, for at mengden ikke skal multiplisere seg oppover av seg selv. :)

Endret av GeirGrusom
Lenke til kommentar
Nei, der bruker jeg alltid normalisering, og henter magnitude fra vectorene uten å lagre det seperat sqrt((x + x) * (y + y) * (z + z))

Brukes blant annet til å generere normaler til polygoner.

9085926[/snapback]

 

Jeg også.. Førstegangen jeg har sett den måten du gjorde det på i eksempelet over, så jeg ble litt forvirret ;)

Lenke til kommentar
Nei, der bruker jeg alltid normalisering, og henter magnitude fra vectorene uten å lagre det seperat sqrt((x + x) * (y + y) * (z + z))

Brukes blant annet til å generere normaler til polygoner.

9085926[/snapback]

 

Jeg også.. Førstegangen jeg har sett den måten du gjorde det på i eksempelet over, så jeg ble litt forvirret ;)

9085936[/snapback]

 

Skjønner, du har ingenting å frykte, i knowses whats i am doing!

Lenke til kommentar
  • 2 uker senere...

Nå har jeg null peiling på High Resolution Timer, men vil ikke antall ticks som utføres i løpet av en gitt tid variere med hvor rask prosessor du har, eller misforstår jeg nå? (Tenker på ticks som klokkesykler)

 

Husker problemet med en del gamle spill (deriblandt CS) var at folk som fikk lynraske prosessorerer nærmest fløy avgårde, fordi spillene var basert på sykler, og etterhvert som disse gikk raskere å utføre, gikk spillene også raskere.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...