.[ ČeskéHry.cz ].
C# problém s gravitací
Jdi na stránku 1, 2  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> .NET
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
egrishot



Založen: 05. 01. 2011
Příspěvky: 23

PříspěvekZaslal: 13. únor 2012, 22:13:31    Předmět: C# problém s gravitací Odpovědět s citátem

Dobrej den chtěl bych jsem se zeptat na gravitaci.Totiž takhle dělám něco ve stylu super mario takovou skákačku a potřeboval bych poradit nějaký postup
jak na skákání mám zatím ve hře pár objektů typů texture2d panáček ,a desky po kterých by měl skákat .ty desky jsou vedle sebe a je mezi nimy mezera. Chtěl bych vědět jak na to aby když stiskne hráč šipku nahoru mu vyskočil plynule a zase dopadl hlavně by mě zajímala gravitace nebo alespoň nějaký nápad na její realizaci a taktéž aby do padla na čtverec a nepropadl se.Ovšem jak jistě tušíte pokud by měl skákát tak také do kopce či z kopce prostě skákání.Nevíte někdo co stím.
Jinatk pohyb v pravo a vlevo už mám vyřešený.
programujiv visual studio 2010 (c#) a používám tam platformu xna .
Děkuji pokud někdo odepíše
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
satik



Založen: 06. 05. 2010
Příspěvky: 161
Bydliště: Krkonose

PříspěvekZaslal: 13. únor 2012, 22:55:22    Předmět: Odpovědět s citátem

Gravitaci muzes vyresit treba tak, ze u panacka budes udrzovat float s jeho rychlosti na ose Y a v kazdym framu zjistis, jestli je pod panackem pevna zeme a pokud ne, tak k nemu prictes gravitacni konstantu, jinak ho vynulujes.

Pokud hrac vyskoci, tak pokud je pod nim pevna zem, tak mu taktez nastavis tenhle vektor na nejakou hodnotu, ktera ho bude posouvat nahoru a vyse popsana gravitace uz se postara, aby za chvili zase zacal klesat.

Samozrejme musis v kazdem framu tenhle float pricitat k jeho Y pozici, jen pri tom je dobry jeste nejak zajistit, aby se nedostal treba skrz slabou desku, kdyz ma rychlost vetsi nez +-1.

A co se detekce prekazek tyce, tak ti asi bude stacit detekovat kolize ctvercu, to uz si nekde vygooglis.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
egrishot



Založen: 05. 01. 2011
Příspěvky: 23

PříspěvekZaslal: 14. únor 2012, 06:00:12    Předmět: odpověď Odpovědět s citátem

Aha takže počkej ten float tím doufám myslíš datový typ, který budu přičítat k té ose y, když stisknu šipku nahoru.Nebo si naopak myslel nějakou funkci pro obtékání?
Jinak celkově jestli jsem to pochopil.Já si vlastně zajistím kolize na těch destičkách potom vyskočím postupně bych zvyšoval tu hodnotu y a když by uplinulo nějakých prá vteřin nebo milisekund tak bych odčítal hodnotu y a jelikož by byla detekována kolize tak by se odčítání přerušilo tak to myslíš?
Protože ta gravitační konstanta mi takhle nic neříká jakože ve fyzice ano ale takhle jak to popisuješ nějak moc ne.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
manutara



Založen: 02. 01. 2012
Příspěvky: 81
Bydliště: Kosice SVK

PříspěvekZaslal: 14. únor 2012, 07:07:17    Předmět: gravitace Odpovědět s citátem

zdravim,
podobne som riesil pri ``landerovi'' tam je inicializacia pohybu zlozitejsie
riesena, pretoze posun v smere Y zavisi od dlzky doby stlacenia tlacice.
u teba treba jedine vyriesit tu inicializaciu smerom hore, kedze je jedno
ci tlacicu drzis, alebo ju stlacis len raz, stale je to len jeden skok a teda konci
az pri dotknuti sa zeme, pokial sa panak po skoku nedotkne zeme je skok
blokovany.

po vyrieseni inicializacie, to potom moze vyzerat aj takto:

position_Y+=INICIALIZACIA - G * time * time,

takto to je u mna. pre vysvetlenie, modul sa vlastne v kazdom frejme
pohybuje aj hore (INICIALIZACIA) aj dole (G*time*time). ide o to, ze
pokial je ``time'' male potom ``time*time'' je este mensie a teda
prevlada pohyb hore, akonahle zacne byt ``time'' dostatocne velke zacne
sa modul pohybovat viac dole ako hore a teda pada. vyhoda takeho
riesenia je plynuly prechod medzi pohybom hore a pohybom dole, tzn,
pohyb pri skoku bude parabola ako v skutocnom svete, pretoze rovnomerne
zrychleny pohyb sa pocita ako ``1/2 * ZRYCHLENIE * CAS * CAS''
1/2*zrychlenie samozrejme das do parametra G napr. jeho hodnotu zistis
pri ladeni, ked to vyzera dobre je to dobre Wink


tak hadam som velmi nedristal takto po ranu.

PS: je to myslene pre modul, ale panak je skoro to iste, hlavny rozdiel je
v ``INICIALIZACII''. ja pouzivam dva ``timery'' jeden pre pohyb hore
jeden pre pohyb dole, tak nejak sa mi to osvedcilo.
_________________
hadam to OpenGL este par rokov prezije
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
satik



Založen: 06. 05. 2010
Příspěvky: 161
Bydliště: Krkonose

PříspěvekZaslal: 14. únor 2012, 10:00:08    Předmět: Re: odpověď Odpovědět s citátem

egrishot napsal:
Aha takže počkej ten float tím doufám myslíš datový typ, který budu přičítat k té ose y, když stisknu šipku nahoru.Nebo si naopak myslel nějakou funkci pro obtékání?
Jinak celkově jestli jsem to pochopil.Já si vlastně zajistím kolize na těch destičkách potom vyskočím postupně bych zvyšoval tu hodnotu y a když by uplinulo nějakých prá vteřin nebo milisekund tak bych odčítal hodnotu y a jelikož by byla detekována kolize tak by se odčítání přerušilo tak to myslíš?
Protože ta gravitační konstanta mi takhle nic neříká jakože ve fyzice ano ale takhle jak to popisuješ nějak moc ne.


Jj, datovy typ.

Ne, myslel jsem to tak, ze budes mit vektor pohybu v ose Y, ktery budes v kazdym framu pricitat k pozici panacka (a jeste pri tom hlidat kolize, abys ho treba nepresunul do cihly).

K tomu Y vektoru v kazdym framu prictes nejaky cislo, ktery bude simulovat gravitaci, cim vetsi, tim rychleji se bude zvysovat ten vektor a tim rychleji pak bude padat, ale pokud pod nim bude podlaha, tak ten vektor pohybu v Y vynulujes.

Ten vektor vlastne jen urcuje aktualni rychlost padani dolu / skoku nahoru.

A kdyz hrac chce skok, tak ten vektor nastavis na nejakou zapornou hodnotu (abys mu nastavil pohyb smerem vzhuru a ne dolu) a to ze zacne padat uz pak zaridi to pricitani gravitace k vektoru v kazdym framu.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
uiii



Založen: 12. 08. 2007
Příspěvky: 251

PříspěvekZaslal: 14. únor 2012, 10:14:15    Předmět: Odpovědět s citátem

Nečetl jsem předchozí diskuzi, ale tady je zajímavý článek (několik dílů) o základní lineární lagebře ve hrách. http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/ Hned v prvním díle zrovna o skákání mluví.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
egrishot



Založen: 05. 01. 2011
Příspěvky: 23

PříspěvekZaslal: 14. únor 2012, 18:10:24    Předmět: Asi už tomám Odpovědět s citátem

Asi jsem ve vlaku přišel na algoritmus.
Btw .S vektorama v programování nemám zkušenosti ani bych si nedokázal představit jak to tam udělat.
Ale zpět k algoritmu chtěl bych znát váš názor.
jsou dvě textury a panáček mezi dvěmi texurami je díra, kterou má samozřejmě panáček přeskočit.
Tady zhruba jeten algoritmus(je to jenom takový symbolický zápis aby jste věděli nejsou tam žádné opravdové funkce
):

kód:
   
   
   // pozice_akt pozice aktuální v jaké se zrovna nachází myslým y pozici
   //pozice_start pozice ve které se nacházel před skokem tedy ze které skočil zase y pozice+jmpmax kdy jmpmax je maximální výška výskoku tedy základní pozice plus těch třeba 80 px.



if(stiskuná klávesa down==true)
{
   while(pozice_akt != pozicestart+jmpmax)      
   {
   y=y-5;//zvedá se hodnota y zdá se tedy že skáče    
   
   }

   if(pozice_akt == pozicestart+jmpmax)
   {
      while(kolize!=true)
      {
      y=y+5;
      }
   }

}

if(pozicestart!=pozice_akt)//skok byl proveden
{
   
   while(kolize!=true)//bude klesat dokud nedojde ke kolizi
   {
   y=y+5;// panáček klesá dokud nedojde ke kolizi
   }


}
//a když k ní dojde tak konec





jednoduše řečeno na ty (čtverce) textury aplikuji čtverce snímané na kolizi.
Fungovalo by to tak že když hráč stiskne klávesu tak se dostává výš avíš a větví se to když se teda nedostane na max a
upustí klávesu tak jelikož jeho aktuální pozice y není shodná s předešlou tedy tou od které skákal tak se dostává dolů dokud nedojde
ke kolizi čímž je konec.Nebo druhá možnost hráč se dostane na jmpmax tedy maximální dosažitelnou hodnotu skoku a padá dokud nedojde ke kolizi.


Naposledy upravil egrishot dne 14. únor 2012, 18:30:45, celkově upraveno 1 krát
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Houp



Založen: 28. 07. 2007
Příspěvky: 672

PříspěvekZaslal: 14. únor 2012, 18:26:11    Předmět: Re: Asi už tomám Odpovědět s citátem

kód:
použij code, takhle se to nedá číst

_________________
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
manutara



Založen: 02. 01. 2012
Příspěvky: 81
Bydliště: Kosice SVK

PříspěvekZaslal: 14. únor 2012, 18:40:14    Předmět: gravitace Odpovědět s citátem

zdravim,

skok=FALSE;
down=FALSE;
//hlavny cyklus
while(1){

___if(skok==FALSE && klavesa_down==TRUE){

______skok=TRUE;
______down=FALSE;

___}else{

______if(kolize==TRUE){

_________skok=FALSE;
_________down=FALSE;

______}else if(down==TRUE){
_________pozice_akt += 5; //DOLE
______}else if(down==FALSE){
_________pozice_akt -= 5; //HORE
______}

______if(pozice_akt>=pozice_start+jmp_max){
_________down=TRUE;
______}

___}

}

takto v hlave mi to funguje, len ci by to fungovalo aj v hre Wink
_________________
hadam to OpenGL este par rokov prezije
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
egrishot



Založen: 05. 01. 2011
Příspěvky: 23

PříspěvekZaslal: 14. únor 2012, 19:01:35    Předmět: Hmm Odpovědět s citátem

No hezký ale to moje mi přijde reálnější protože zatímco ty máš ty tkzv. proměnné skok nebo down tak já to mám ošetřené i když bude na maximu nebo ne. Tak bude padat.Kdežto ty máš jestli jsem to dobře pochopil nějaké události ještě asi bool nebo co Very Happy nevím ale je pravda že asi skusím udělat něco s těmi vektory ale to až o víkendu ten můj algoritmus má taky svoje chyby.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
satik



Založen: 06. 05. 2010
Příspěvky: 161
Bydliště: Krkonose

PříspěvekZaslal: 14. únor 2012, 22:34:59    Předmět: Odpovědět s citátem

Toho vektoru se neboj, to je jen cislo, ktery ti rika, jak rychle pandulak pada/stoupa.

kód:

// tohle bude ve funkci, kdyz zmackl skok:
if (panak ma pod sebou neco, s cim muze kolidovat = od ceho by se mohl odrazit) Yvector = -rychlostVyskoku;


// tohle se bude provadet porad do kola po nebo pred vykreslenim (proste nekde v game loopu):

if (panak ma pod sebou volno)
  panakY = panakY + Yvector;
else
  Yvector = 0;

Yvector = Yvector + gravitace;



EDIT:

Takhle to pak vypada:
www.satik.eu/temp/jumper.zip (potrebuje to xna 3.1 redist http://www.microsoft.com/download/en/details.aspx?id=15163 )
ovladani sipky, tlacitka mysi a kolecko Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
egrishot



Založen: 05. 01. 2011
Příspěvky: 23

PříspěvekZaslal: 15. únor 2012, 05:46:40    Předmět: Odpovědět s citátem

OK dík.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Al



Založen: 23. 10. 2007
Příspěvky: 196

PříspěvekZaslal: 17. únor 2012, 23:47:12    Předmět: Odpovědět s citátem

Toto patří do jiné kategorie (.NET).
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
egrishot



Založen: 05. 01. 2011
Příspěvky: 23

PříspěvekZaslal: 10. březen 2012, 19:16:36    Předmět: Zase nic Odpovědět s citátem

Už fakticky nevím napsal jsem to takhle ale nefnuguje to
kód:

namespace Jumpermen
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GameObject jumper = new GameObject(20,422);
        plosina plos = new plosina(0, 0);
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D Jumperman;
        Texture2D ploska_tlusta;
        Texture2D mrak;
   
       

       
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            if (new Rectangle(jumper.PosX, jumper.PosY, jumper.jmp_width, jumper.jmp_height).Intersects(new Rectangle(plos.pos_x, plos.pos_y, plos.width, plos.height)) == false)
            {
                jumper.Yvector -= jumper.speed;
            }
            else
            {
                jumper.Yvector = 0;
                jumper.Yvector += 10;
            }

       
            base.Initialize();
           
           
            }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Jumperman = Content.Load<Texture2D>("jumperman_1");
            ploska_tlusta = Content.Load<Texture2D>("ploska_tlusta_1");
           
            mrak = Content.Load<Texture2D>("mracek");
           
           
            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
        KeyboardState keyState = Keyboard.GetState();
        if (keyState.IsKeyDown(Keys.Right) && (jumper.PosX < GraphicsDevice.Viewport.Width - 1))

            jumper.PosX = jumper.PosX + 2;

        if (keyState.IsKeyDown(Keys.Left) && jumper.PosX > 0)

            jumper.PosX = jumper.PosX - 2;

        if (keyState.IsKeyDown(Keys.Space) && (new Rectangle(jumper.PosX, jumper.PosY,jumper.jmp_width,jumper.jmp_height).Intersects(new Rectangle(plos.pos_x,plos.pos_y,plos.width,plos.height)))==true)
        {
            jumper.PosY =jumper.PosY - 3;


            jumper.Yvector = jumper.Yvector - jumper.speed;
            }

       


            // TODO: Add your update logic here

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
           
            // TODO: Add your drawing code here
            spriteBatch.Begin();
           
           
            //plosky: vyska 50, sirka 120
         
            spriteBatch.Draw(ploska_tlusta, new Vector2(plos.pos_x,plos.pos_y+450), Color.White);
            spriteBatch.Draw(ploska_tlusta, new Vector2(plos.pos_x + 150, plos.pos_y + 450), Color.White);
            spriteBatch.Draw(ploska_tlusta, new Vector2(plos.pos_x + 300, plos.pos_y + 450), Color.White);
            spriteBatch.Draw(ploska_tlusta, new Vector2(plos.pos_x + 450, plos.pos_y + 450), Color.White);
            spriteBatch.Draw(ploska_tlusta, new Vector2(plos.pos_x + 600, plos.pos_y + 450), Color.White);
                //mracky: vyska 50, sirka 120
           
            spriteBatch.Draw(mrak, new Vector2(0,0), Color.White);
            spriteBatch.Draw(mrak, new Vector2(150, 0), Color.White);
            spriteBatch.Draw(mrak, new Vector2(300, 0), Color.White);
            spriteBatch.Draw(mrak, new Vector2(450, 0), Color.White);
            spriteBatch.Draw(mrak, new Vector2(600, 0), Color.White);
            //konec prvni rady
            spriteBatch.Draw(mrak, new Vector2(50, 100), Color.White);
            spriteBatch.Draw(mrak, new Vector2(200, 100), Color.White);
            spriteBatch.Draw(mrak, new Vector2(350, 100), Color.White);
            spriteBatch.Draw(mrak, new Vector2(500, 100), Color.White);
            spriteBatch.Draw(mrak, new Vector2(650, 100), Color.White);
            //konec druhe rady
            //32*32
            spriteBatch.Draw(Jumperman, new Vector2(jumper.PosX, jumper.PosY), Color.White);
           
   
    spriteBatch.End();                      //20, 420

    base.Draw(gameTime);
        }
       
    }
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
egrishot



Založen: 05. 01. 2011
Příspěvky: 23

PříspěvekZaslal: 10. březen 2012, 19:19:15    Předmět: Zde připojuji ještě třídy pro game object a plošku Odpovědět s citátem

Ploška
kód:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Jumpermen
{
    class plosina
    {
        public int pos_x { get; set; }
        public int pos_y {get; set;}
        public int width=120;
        public int height=50;
        public plosina(int pos_x, int pos_y)
        {
            this.pos_x = pos_x;
            this.pos_y= pos_y;
        }


    }
}





game objekt
kód:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace Jumpermen
{
    class GameObject
    {

        public int PosX { get; set; }

        public int PosY { get; set; }
        public int speed=250;
        public int jmp_width=32;
        public int jmp_height=32;
        public int Yvector = 5;   
       

        public GameObject(int posX, int posY)
        {

            this.PosX = posX;

            this.PosY = posY;

        }
       

    }



}

Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> .NET Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2  Další
Strana 1 z 2

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna