Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Ajastin

Sivun loppuun

mika132 [07.11.2009 21:04:16]

#

Kyllä tiedän, että kielsitte käyttämästä SDL:ää, mutta nyt tuli eräs asia katsoessani yhden pelin ilähdekoodia ja kirjatessani bugeja ylös. Sain kaksi korjattua ja kolmas vaatii ajastimen ja sen jälkeen peli toimii tismalleen niinkuin haluan. Eli miten SDL:llä tehdään ajastin? SDL_Timer()? :)

Macro [07.11.2009 21:07:14]

#

Voit laittaa SDL_Wait(aika), jonka jälkeen suoritus jatkuu jos sitä tarkoitit.

mika132 [07.11.2009 21:54:22]

#

Tarkoitan sellaista, että peli pyörii silti. Eli koodin suorittaminen ei pysää niinkuin SDL_Delay():ssä.

Onko tuo sellainen ja jos on voiko tarkistaa, että onko aika kulunut näin:

int aika=2000;
SDL_Wait(aika);
if (aika>=2000)
{
//tehdään haluttu jutut
}

Sami [07.11.2009 23:00:43]

#

Esimerkiksi vähän tähän malliin, eli otat tarvittaessa ylös mitä kello on nyt ja joka kierroksella tarkistat onko haluttu aika jo kulunut.

bool ajastin_käynnissä = false;
int ajastin = 0;
while (pääsilmukan_toistoehto()) {
  if (ajastin_käynnissä && ajastin + 2000 <= aika_nyt()) {
    // Ajastin on käynnistetty vähintään 2000 aikayksikköä sitten (luultavasti käytät millisekunteja), joten tee halutut jutut
    ajastin_käynnissä = false;
  }

  // tee pääsilmukan muut toimenpiteet

  if (haluat_asettaa_ajastimen()) {
    ajastin = aika_nyt();
    ajastin_käynnissä = true;
  }
}

mika132 [07.11.2009 23:15:51]

#

Ongelmana on vain se, etten tiedä enkä googlella löytänyt miten C++ tarkistetaan kellon aika.

Metabolix [07.11.2009 23:17:54]

#

SDL_GetTicks-funktio palauttaa millisekuntien määrän SDL:n alustuksesta (ohjelman alun SDL_Init-kutsusta).

mika132 [08.11.2009 00:05:23]

#

Eli:

void aika_nyt(time) {


}
				while (SDL_PollEvent(&event))
				{
					hiiri=SDL_GetMouseState(&hiiren_x,&hiiren_y);
					if(event.type == SDL_MOUSEBUTTONDOWN)
					{
						if(event.button.button == SDL_BUTTON_LEFT)
						{
							if(hiiren_mukana==1)
							{
								SDL_Init();
								napattu = true;
							}
						}
					}
					else
					if(event.type == SDL_MOUSEBUTTONUP)
					{
						if(event.button.button == SDL_BUTTON_LEFT)
						{

if (ajastin_käynnissä && ajastin + 2000 <= aika_nyt()) {
							kuvanX = hiiren_x;
							kuvanY = hiiren_y;
							napattu = false;
}
						}
					}
				}

Tähän kohtaan aivot ovat menneet lukkoon.

Teuro [08.11.2009 06:27:35]

#

Ei ihme että aivot ovat lukossa eihän tuossa koodissa ole päätä eikä häntää. SDL_Init() pitää olla koodin alussa vain kerran. Ei suinkaan montaa kertaa keskellä pelin pääsilmukkaa. Mistä tulee hiiren_mukana muuttujalle true arvo?

mika132 [08.11.2009 12:25:38]

#

napattu = true;

Tuo? Se tulee kun painetaan esinettä ja sitä lähdetään kuskaamaan. Ongelma on siinä, että kun esinettä painetaan siinä niin hiiren pitää liikku samalla katsos kun ei ole ns. Ote aikaa.

mika132 [13.11.2009 19:20:20]

#

Eli palataanpa takaisin tähän.

Se ajastin jonka sain on melko ongelmallinen. Eli kellon tarkastus, enkä sitä saa toimimaan. Eikö ole mitään muuta konstia tehdä ajastin ilman, että koodi pysää kuin seinään?

Macro [13.11.2009 19:48:52]

#

Koitappas ottaa "ajastimen" alkukohdassa kellonaika unix timestamppina ja vertaat sitä toiseen aikaan.

unix_aika = aika_nyt();
odotettava_aika = 300; // 300 / 60 = 5 minuuttia

while(true) {
	//Asetaan nykyinen aika muuttujaan
	aika = aika_nyt()

	//Jos unix_aika + odotettava_aika on aika, tehdään mitä halutaan
	if(unix_aika + odotettava_aika =< aika) {
		//Tee mitä lystäät
	}
}

mika132 [13.11.2009 21:26:04]

#

Mitä sisällän aika_nyt funktioon?

vehkis91 [13.11.2009 22:05:24]

#

Sen ajan joka tällähetkellä on... -.-

Metabolix [13.11.2009 22:22:08]

#

Luetko koskaan näitä vastauksia? Luitko esimerkiksi minun edellisen vastaukseni?

Grez [13.11.2009 22:38:13]

#

Eikös se ADHD oo nykyajan muotitauti (ei millään pahalla ADHD:ta oikeasti sairastavia kohtaan)

vehkis91 [13.11.2009 22:57:15]

#

Ja tämä liittyi aiheeseen miten????

ankzilla [13.11.2009 23:22:39]

#

Niinpä, vehkis91.. Grezillä tais mennä viesti väärään topikkiin tms?

Mutta ittiä jäi mietityttään että mikä on SDL_Waitin ja SDL_Delayn ero? :o

Grez [13.11.2009 23:24:03]

#

No ei se kyllä mennyt väärään topikkiin. Kommentoin vaan Metabolixin kommenttia ja sitä kautta mika132:n kommenttia. Eihän tämä ketju mitenkään pahimmasta päästä ole, että sikäli voisi olla jossain muuallakin.

Okei, ehkä se ei ollut asiallisimmasta päästä mutta joskus vaan tekee mieli sanoa mitä ajattelee. PC-filtterini on huollossa.

mika132 [13.11.2009 23:52:33]

#

En ole koskaan sisältänyt funktiion muuttujaa. Eli miten saan funktioon muuttujan?


ja miten antamani aika siihen tapahtuu joka sekuntti jotta se suurenee?

Päärynämies [14.11.2009 01:40:46]

#

mika132 kirjoitti:

En ole koskaan sisältänyt funktiion muuttujaa. Eli miten saan funktioon muuttujan?

https://www.ohjelmointiputka.net/opas.php?tunnus­=cpp_ohj_01
Sieltä lukemaan.

mika132 [15.11.2009 18:19:49]

#

Noniiiiiin. Nyt olen lukenut koko oppaan läpi jo toiseen kertaan, mutta yksi ongelma:

#include <time.h>

float aika_nyt(const float a) {
    return (a);
}

int unix_aika = aika_nyt(0);
odotettava_aika = 5;


void Lyo(void){
	PiirraKuva(kentta_1, naytto, 0, 0);
	PiirraKuva(koko_hahmo_1_lyonti, naytto, vasX, vasY);
	PiirraKuva(koko_hahmo_1, naytto, hahmo_x_sijainti, hahmo_y_sijainti);
	SDL_Flip(naytto);
}

void VastustajanTekoaly(void) {
int erotus_x = hahmo_x_sijainti - vasX;
int erotus_y = hahmo_y_sijainti - vasY;

if (erotus_x <= -60)
{
	vasX=vasX-1;
}
else
if (erotus_x >= 60)
{
	vasX=vasX+1;
}
if (erotus_x >= -61 && erotus_x <= 59)
{
if (tap == 1)
{
hahmo_x_sijainti=hahmo_x_sijainti+100;
Lyo();
tap=0;
}
}
}

while (aika_paalla==true)
{

    aika = aika_nyt(unix_aika);
    if(unix_aika + odotettava_aika =< aika)
    {
        unix_aika = aika_nyt();
        tap=1;
    }
}

siinä on tekoäly koodini eikä se edelleenkään odota tuota haluttua aikaa vaan lyö ilmoille kasan erroreita. Osa erroreista menee jo eri tiedostoihinkin. Ymmärsin kaikki errorit, että puuttuu merkkejä ; ja on liikaa } mutta en minä löytänyt liikaa enkä puuttuvia? :O

1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\hahmo_valinta.gfr(2) : error C2144: syntax error : 'void' should be preceded by ';'
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\data\tekoaly.ggy(7) : warning C4244: 'initializing' : conversion from 'float' to 'int', possible loss of data
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\data\tekoaly.ggy(8) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\data\tekoaly.ggy(33) : error C2065: 'tap' : undeclared identifier
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\data\tekoaly.ggy(37) : error C2065: 'tap' : undeclared identifier
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\data\tekoaly.ggy(42) : error C2059: syntax error : 'while'
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\data\tekoaly.ggy(43) : error C2143: syntax error : missing ';' before '{'
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\data\tekoaly.ggy(43) : error C2447: '{' : missing function header (old-style formal list?)

ankzilla [15.11.2009 20:24:05]

#

Ite määrittelen funktioita, joihin ei tule parametreja tyyliin void funktio() enkä void funktio(void)...
En kyllä tiedä onko tällä merkitystä, mutta en löytänyt muutakaan koodistasi.

Mutta ehkä virheen paikannus olisi helpompaa, jos laittaisit niitä välejä ja sisennyksiä oikein. :)
hahmo_x_sijainti=hahmo_x_sijainti+100; => hahmo_x_sijainti = hahmo_x_sijainti + 100;
ja

if(ehto) {
	if(!ehto) {
		std::cout << "Hello world!" << std::endl;
	}
}

mika132 [15.11.2009 20:27:17]

#

float aika_nyt(const float a)
{
    return (a);
}

float unix_aika = aika_nyt(0);
int odotettava_aika = 5;


void Lyo(SDL_Surface *kentta_1, SDL_Surface *koko_hahmo_1_lyonti, SDL_Surface *koko_hahmo_1)
{
	PiirraKuva(kentta_1, naytto, 0, 0);
	PiirraKuva(koko_hahmo_1_lyonti, naytto, vasX, vasY);
	PiirraKuva(koko_hahmo_1, naytto, hahmo_x_sijainti, hahmo_y_sijainti);
	SDL_Flip(naytto);
}

void VastustajanTekoaly(int hahmo_x_sijainti, int hahmo_y_sijainti, int vasX, int vasY, SDL_Surface *kentta_1, SDL_Surface *koko_hahmo_1_lyonti, SDL_Surface *koko_hahmo_1)
{
	int erotus_x = hahmo_x_sijainti - vasX;
	int erotus_y = hahmo_y_sijainti - vasY;

	if (erotus_x <= -60)
	{
		vasX=vasX-1;
	}
	else
	if (erotus_x >= 60)
	{
		vasX=vasX+1;
	}
	if (erotus_x >= -61 && erotus_x <= 59)
	{
		if (tap == 1)
		{
		hahmo_x_sijainti=hahmo_x_sijainti+100;
		Lyo(kentta_1, koko_hahmo_1_lyonti, koko_hahmo_1);
		tap=0;
	}
}

while (aika_paalla == true)
{
    aika = aika_nyt(unix_aika);
    if(unix_aika + odotettava_aika <= aika)
    {
        unix_aika = aika;
        tap=1;
    }
}

Siinä uusi koodi.

Ja sain erroreitakin hieman pois, mutta enää en keksi, että miksi se valittaa main.cpp main funktiota ja miksi se väittää, että rivillä 19 on jotain häikkää merkissä {.

1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\fight in street.cpp(21) : error C2601: 'SDL_main' : local function definitions are illegal
1> c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\data\tekoaly.ggy(19): this line contains a '{' which has not yet been matched
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\fight in street.cpp(90) : fatal error C1075: end of file found before the left brace '{' at 'c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\data\tekoaly.ggy(19)' was matched

ankzilla [15.11.2009 20:32:18]

#

if (erotus_x <= -60)
{
    vasX=vasX-1;
}
else
if (erotus_x >= 60)
{
    vasX=vasX+1;
}

Pitäisikö tuossa olla else if vai mitä?

Sit katoppa tuon VastustajanTekoAly funktion viimeistä iffiä. Miten ne aaltosulut siellä menee?

vehkis91 [15.11.2009 20:35:51]

#

Mikähän seuraavan funktion tarkoitus on?

float aika_nyt(const float a)
{
    return (a);
}

ankzilla [15.11.2009 20:37:27]

#

vehkis91 kirjoitti:

Mikähän seuraavan funktion tarkoitus on?

float aika_nyt(const float a)
{
    return (a);
}

Hehe, se palauttaa parametrina annetun aan. :DD
Tämä lienee hyödyllisin funktio mitä C++:n historian aikana lienee koodattu?

Grez [15.11.2009 20:43:47]

#

Tuohan on erittäin hyödyllinen jos on esim. kotitehtävä "tee funktio, joka ottaa parametrin ja palauttaa arvon"

mika132 [15.11.2009 21:22:53]

#

Oho sulkeet oli vääri ja ne muokattuani erroria tuli.
Miksi ihmeessä while ei muka toimi?

while (aika_paalla == true)//errori 1
{ // errori 2 ja 3
    aika = aika_nyt(unix_aika);
    if(unix_aika + odotettava_aika <= aika)
    {
        unix_aika = aika;
        tap=1;
    }
}

1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\data\tekoaly.ggy(43) : error C2059: syntax error : 'while'
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\data\tekoaly.ggy(44) : error C2143: syntax error : missing ';' before '{'
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\fight in street\fight in street\data\tekoaly.ggy(44) : error C2447: '{' : missing function header (old-style formal list?)

Grez [15.11.2009 21:50:33]

#

Mitä lie mahtaa lukea ennen while

jlaire [15.11.2009 21:53:38]

#

Veikkaan, että while-silmukka ei ole minkään funktion sisällä. Ei tässä ole mitään järkeä, lukisit sitä opasta.

mika132 [15.11.2009 22:01:03]

#

Juu vika olikin siinä.


Mutta en tiedä miten saan sen "ajastimen" nyt toimimaa. Eli hahmot eivät liiku mihinkään, koska ajastin ei ilmeisesti toimi. Odotin 20sek mutta ei tapahtunut mitään. :O

float aika_nyt(const float a)
{
    return (a);
}

float unix_aika = aika_nyt(0);
int odotettava_aika = 5;


void Lyo(SDL_Surface *kentta_1, SDL_Surface *koko_hahmo_1_lyonti, SDL_Surface *koko_hahmo_1)
{
	PiirraKuva(kentta_1, naytto, 0, 0);
	PiirraKuva(koko_hahmo_1_lyonti, naytto, vasX, vasY);
	PiirraKuva(koko_hahmo_1, naytto, hahmo_x_sijainti, hahmo_y_sijainti);
	SDL_Flip(naytto);
}

void VastustajanTekoaly(int hahmo_x_sijainti, int hahmo_y_sijainti, int vasX, int vasY, SDL_Surface *kentta_1, SDL_Surface *koko_hahmo_1_lyonti, SDL_Surface *koko_hahmo_1)
{
	int erotus_x = hahmo_x_sijainti - vasX;
	int erotus_y = hahmo_y_sijainti - vasY;

	if (erotus_x <= -60)
	{
		vasX=vasX-1;
	}
	else
	if (erotus_x >= 60)
	{
		vasX=vasX+1;
	}
	if (erotus_x >= -61 && erotus_x <= 59)
	{
		if (tap == 1)
		{
		hahmo_x_sijainti=hahmo_x_sijainti+100;
		Lyo(kentta_1, koko_hahmo_1_lyonti, koko_hahmo_1);
		tap=0;
		}
	}
	while (aika_paalla == true)
	{
		aika = aika_nyt(unix_aika);
		if(unix_aika + odotettava_aika <= aika)
		{
		    unix_aika = aika;
		    tap=1;
		}
	}
}

c010n [15.11.2009 22:10:07]

#

aika_nyt funktiosta on huomautettu ennemmin ainakin kolme kertaa. Ei kukaan viitsi neuvoa jos vastauksia ei edes lueta(tai haluta ymmärtää).

mika132 [15.11.2009 22:23:06]

#

No yritin ymmärtää, kyllä, mutta en vain ymmärtänyt. Oppaasta luin, "keskiarvo" nimellä, että saadaan funktion arvo johonkin tiettyyn paikkaan, mutta ei näköjään sitten saada tuolla tavalla. Miten? :O

c010n [15.11.2009 23:18:15]

#

Pelkkä lukeminen ei riitä, se pitää myös ymmärtää. Vaikka aika_nyt funktio palauttaisi jonkun järkevän arvon ohjelmasi ei siltikään toimisi sillä asetat while-silmukassa joka kierroksella vertailtavan ja verrattavan ajan samaan arvoon(nollaan). Muutenkaan koodin ei ole nähdäkseni tehty muita muutoksia kuin sisennystä muutettu. Lisäksi aika_paalla muuttujaa ei ole asetettu missään, jonka vuoksi et saa edes ohjelmaa kääntymään. Lisäksi koodista puuttuu viitteet SDL:n headereihin ja koko main-funktio. Muita epäloogisuuksia en viitsi edes luetella. Selkeintä olisi jos opettelisit ensin tekstipohjaisten ohjelmien kanssa, kunnes ymmärrät putkan oppaassa opetetut asiat.

mika132 [15.11.2009 23:33:44]

#

Siis jos haluat voin heittää sinulle koko koodi nivaskan, mutta en usko, että selvität ihan heti sitä nimittäin funktiot ovat omassa tiedostossaa main.cpp on omansa josta käytetään sitten funktioita ja tekoaly on omassa tiedostossaa sen laajuuden takia, jotta eri tiedostot pysyvät siisteinä JA kaikki on alustettuna start nimisessä tiedostossa joka avataan main.cpp tiedoston alussa, niinkuin kaikki muutkin tiedostot.

Ja kaikki alustuvat tiedän sen siitä, että hahmo piirretään sinne mihin alustuksessa se on määrätty.

Eli kaikki on kunnossa joista äsken puhuit viestisi lopussa ainut ongelma on, että vaikka kuinka luen tuota funktio kohtaa oppaasta niin jää joku pikku asia ohi jonka johdosta en saa tuota toimimaan. Siksi pyydänkin apua, koska en sitä pientä yksityiskohtaa saa päähäni jonka ansiosta osaisin tehdä tuon niin se tulisi päähäni jos saisin tietää miten tuo kohta tehdään.

Grez [15.11.2009 23:53:26]

#

mika132 kirjoitti:

Eli kaikki on kunnossa joista äsken puhuit

No mitäs sitten edes kyselet, jos kerran kuitenkin tiedät paremmin?

Mitä nyt katsoin, niin omastakin mielestä tuolla on kaikki ne virheet, mitä c010n mainitsi.

mika132 [16.11.2009 00:03:25]

#

c010n kirjoitti:

Pelkkä lukeminen ei riitä, se pitää myös ymmärtää. Vaikka aika_nyt funktio palauttaisi jonkun järkevän arvon ohjelmasi ei siltikään toimisi sillä asetat while-silmukassa joka kierroksella vertailtavan ja verrattavan ajan samaan arvoon(nollaan). Muutenkaan koodin ei ole nähdäkseni tehty muita muutoksia kuin sisennystä muutettu. Lisäksi aika_paalla muuttujaa ei ole asetettu missään, jonka vuoksi et saa edes ohjelmaa kääntymään. Lisäksi koodista puuttuu viitteet SDL:n headereihin ja koko main-funktio. Muita epäloogisuuksia en viitsi edes luetella. Selkeintä olisi jos opettelisit ensin tekstipohjaisten ohjelmien kanssa, kunnes ymmärrät putkan oppaassa opetetut asiat.

Tarkoitin tuota tummennettua aluetta, kun sain sen käsityksen, että c010n luuli, etten ole alustanut mitään ja että tuo on pää tiedostoni, mutta ei ole.

Ja while silmukkani selitettynä.

while (aika_paalla == true) //tiedätte kyllä
{
	aika = aika_nyt(unix_aika);//pistetään aika muuttuja unix_aika arvoon
	if(unix_aika + odotettava_aika >= aika) //jos unix aika + odotettava aika on enemmän kuin aika
	{
	    unix_aika = aika + odotettava_aika;//muutetaan unix_aika uuteen arvoon
	    tap=1;//pistetään ns. tapahtumien aloittava muuttuja yhteen.
	}
}

Jonkun syyn takia peli vetää ei vastatuksi taistelun alkaessa. Eli menee täysin lukkoon ei voi sammuttaa, muuta kuin tehtävähallinnan kautta.

Grez [16.11.2009 00:07:22]

#

No jos lihavoin sen toisen puolikkaan, niin ehkä viimeinkin ymmärrät mitä sieltä pitää korjata:

c010n kirjoitti:

Pelkkä lukeminen ei riitä, se pitää myös ymmärtää. Vaikka aika_nyt funktio palauttaisi jonkun järkevän arvon ohjelmasi ei siltikään toimisi sillä asetat while-silmukassa joka kierroksella vertailtavan ja verrattavan ajan samaan arvoon(nollaan). Muutenkaan koodin ei ole nähdäkseni tehty muita muutoksia kuin sisennystä muutettu. Lisäksi aika_paalla muuttujaa ei ole asetettu missään, jonka vuoksi et saa edes ohjelmaa kääntymään. Lisäksi koodista puuttuu viitteet SDL:n headereihin ja koko main-funktio. Muita epäloogisuuksia en viitsi edes luetella. Selkeintä olisi jos opettelisit ensin tekstipohjaisten ohjelmien kanssa, kunnes ymmärrät putkan oppaassa opetetut asiat.

mika132 [16.11.2009 00:14:44]

#

Missä minä ne samaan arvoon laitan? :O

Grez [16.11.2009 00:26:05]

#

//Vaikka aika_paalla ei ole näkyvästi alustettu, niin
//oletan että aika_paalla on true, koska muutenhan koko
//Whileen ei mentäisi

//Silmukan sisällä aika_paalla muuttujaa ei koskaan aseteta
//falseksi, joten silmukka on ikuinen
while (aika_paalla == true)
{
	//unix_aika on 1. suorituskierroksella 0, 2. 5, 3. 10 jne.
	aika = aika_nyt(unix_aika);
	//aika on nyt sama kuin unix_aika

	if(unix_aika + odotettava_aika >= aika)
	//Ehto on aina tosi, koska
	//unix_aika ja aika ovat aina samat ja
	//odotettava_aika on positiivinen
	{
		unix_aika = aika + odotettava_aika;
		//unix_aika on 1. suorituskerran jälkeen 5, 2. 10, 3. 15 jne.
		tap=1;
		//tap on tämän jälkeen 1
	}
}

Ihan vinkkinä: tutustu tuohon funktioon mitä Metabolix ehdotti, unohda kaikki noi sun aika, unix_aika -muuttujat ja aika_nyt-funktio ja mieti kuvio uusiksi.

Metabolix kirjoitti:

SDL_GetTicks-funktio palauttaa millisekuntien määrän SDL:n alustuksesta (ohjelman alun SDL_Init-kutsusta).

Macro [16.11.2009 09:14:28]

#

float aika_nyt(const float a)
{
    return (a);
}

Tässä ei ole mitään järkeä. Jos se palauttaa saman mitä sinne on kirjoitettu, niin siitä ei ole hyötyä. Funkion pitäisi palauttaa UNIX-aika, eikä mitään muuta.

Kuvitellaampa se näin:

int unix_aika() {
	// Täällä otetaan nykyinen aika unix aikana.
	// Jos et lukenut Wikipedian artikkelia, niin Unix aika on aika sekuntteina 1.1.1970 00:00:00 lähtien.
}

int main() {
	// Lisätään aika-muuttujaan se aito ja oikea UNIX-aika
	int aika = unix_aika();

	// Alustetaan muuttuja aika2
	int aika2 = unix_aika();

	// Odotusaika sekunteina
	int odotus = 8;

	// "Ikuinen" silmukka
	while(True) {
		// Päivitetään aika2-muuttujaa nykyiseen aikaan
		aika2 = unix_aika();

		// Jos ollaan odotettu odotus verran.
		if(aika2 >= aika + odotus) {
			//Tehdään asiat, jotka ovat sallittuja odotus-ajan jälkeen
			std::cout << "Kahdeksan sekunttia meni jo!" << std::endl;
		}
	}
}

Jollet nyt ymmärrä tarkoitusta, niin kannattaa vaihtaa alaa.

mika132 [16.11.2009 17:44:17]

#

Siis tuon tarkoituksen ymmärränkin, mutta tuohon se sitten päättyykin. Suomeksi sanottuna edelleenkin. En tiedä miten saan UNIX ajan selville. Tuo funktio ei sitä itse tee automaattisesti. Ja olen käyttänyt UNIX aikaa PHP:ssä ja PHP:ssä siihen oli valmiit jutut, siksi en nyt tajua mitä tuo unix_aika funktio vielä tarvitsee.

Macro [16.11.2009 18:23:45]

#

Hakusanoilla löytyy paljon ohjeita. Kuten varmaan huomaat, unix_aika ei ole C++:n oma funktio, vaan tein sen esimerkkinä.

mika132 [16.11.2009 19:13:40]

#

Luulin sen jo toimivan, mutta väärin luulin selvästikkin, nimittäin pistin konsoliin kirjoitettavaksi aika2 ja aika arvon. Nyt kuitenkin kävi niin, että. aika arvo on 1258391424 kun taas aika muuttujan arvo on 25839e+009

Tuo aika2 arvo muuttuu noin 1-2min välein. Lisä ongelmana on vielä se, että tuo laittaa nyt tuota suoritusta noin 10 millisekunnin välein. Tiedän sen siitä, kun konsoliin tulee tuo samaa arvo jatkuvast.

Ja koodi:

#include "time.h"

int unix_aika(float t1) {
	time_t timet=time(NULL);
	t1=timet;
	return (t1);
}

int AsetaAika(float r1) {
	if (suoritettu <= 0)
	{
	time_t timett=time(NULL);
	r1=timett;
	return (r1);
	}
	if (suoritettu >= 1)
	{

	}
}


void Lyo(SDL_Surface *kentta_1, SDL_Surface *koko_hahmo_1_lyonti, SDL_Surface *koko_hahmo_1)
{
	PiirraKuva(kentta_1, naytto, 0, 0);
	PiirraKuva(koko_hahmo_1_lyonti, naytto, vasX, vasY);
	PiirraKuva(koko_hahmo_1, naytto, hahmo_x_sijainti, hahmo_y_sijainti);
	SDL_Flip(naytto);
}

void VastustajanTekoaly(int hahmo_x_sijainti, int hahmo_y_sijainti, int vasX, int vasY, SDL_Surface *kentta_1, SDL_Surface *koko_hahmo_1_lyonti, SDL_Surface *koko_hahmo_1)
{
	int erotus_x = hahmo_x_sijainti - vasX;
	int erotus_y = hahmo_y_sijainti - vasY;

	if (erotus_x <= -60)
	{
		vasX=vasX-1;
	}
	else
	if (erotus_x >= 60)
	{
		vasX=vasX+1;
	}
	if (erotus_x >= -61 && erotus_x <= 59)
	{
		if (tap == 1)
		{
		hahmo_x_sijainti=hahmo_x_sijainti+100;
		Lyo(kentta_1, koko_hahmo_1_lyonti, koko_hahmo_1);
		tap=0;
		}
	}
    while(aika_paalla == true) {

        aika = AsetaAika(r1);
        aika2 = unix_aika(t1);

        if(aika2 >= aika + odotus)
        {
            std::cout << "Kahdeksan sekunttia meni jo!" << aika2 << "  JA:  " << aika << std::endl;
            suoritettu=0;
        }

        if(aika2 <= aika + odotus - 1)
        {
            suoritettu=1;
        }
    }
}

Macro [16.11.2009 19:32:56]

#

25839e+009 tarkoittaa lukua 25839000000000. Kannattaa koittaa komentorivi ohjelmana tuota minkä lähetin. Liitä kuitenkin tuo unix_aika funktio sinne.

Teuro [16.11.2009 19:47:09]

#

mika132 kirjoitti:

#include "time.h"

int unix_aika(float t1) {
	time_t timet=time(NULL);
	t1=timet;
	return (t1);
}

Mitä kummaa tästä on jo sanottu, että tuo funktio ei kaipaa mitään syötettä. Luo mielummin funktion sisällä paikallinen muuttuja t1, johon sijoitat tuon ajan. Lopuksi palautat tuon luodun muuttujan, aivan kuten olet tehnyt.

mika132 kirjoitti:

int AsetaAika(float r1) {
	if (suoritettu <= 0)
	{
	time_t timett=time(NULL);
	r1=timett;
	return (r1);
	}
	if (suoritettu >= 1)
	{

	}
}

Vielä isompi mitä kummaa? Mistä tulee muuttuja suoritettu? r1 muuttuja pitäisi luoda paikallisesti. Ja ihme tuo viimeinen if-lause oikein on? Eihän sen sisällä edes tehdä mitään.

mika132 [16.11.2009 20:17:03]

#

Se tulee alustus tiedostosta, ja tuo tapa koodata on jäänyt minulle PHP:stä kun tulee välillä lisättyä noihin jotain joten teen niitä valmiiksi vaikka ne olisivatkin tyhjiä.

Muutin nyt noista tuon sisällyksen pois. Eli nyt on vain esim: AsetaAika()

mutta edelleen se härppää samaa. Eli päivittää koko ajan vaikka pitäisi vain 8 sek välein.

Ja vika on siinä, että aika muuttujaan ei tule sitä arvoa kun pitäisi vaan kirjain numero sekotus. Niinkuin edellisessä viestissä näytin.

Teuro [16.11.2009 20:27:20]

#

No ajapa tämä koodin pätkä läpi ja yritä ymmärtää sen pointti.

#include <ctime>
#include <iostream>

double unix_aika(){
    time_t timet = time(NULL);
	double t1 = timet;

    return t1;
}

std::string anna_teksti(){
	return "taas tuli uusi!";
}

int main(int maara, char **argumentit){
	double porras = 1;
	int kierrokset = 10;
	double t1, t2;
	t1 = unix_aika();
	t2 = t1 + porras;

	std::cout << "t1 = " << t1 << " t2 = " << t2 << std::endl;
	std::cout << "t2 - t1 = " << (t2 - t1) << std::endl;

	while(kierrokset){
		t1 = unix_aika();

		if(t1 == t2){
			std::cout << anna_teksti() << std::endl;
			t2 = t1 + porras;
			--kierrokset;
		}
	}

	return EXIT_SUCCESS;
}

mika132 [16.11.2009 20:53:30]

#

Koodini kun ei ole lähellekkään tuon tapainen edes.

main.cpp:

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include "windows.h"
#include <cmath>
#include <io.h>
#include <SDL.h>
#include <SDL_rotozoom.h>
#include "SDL_ttf.h"
#pragma comment(lib, "SDL_ttf.lib")
#pragma comment(lib, "SDLmain.lib")
#pragma comment(lib, "SDL.lib")
#pragma comment(lib, "SDL_gfx.lib")
#include "start.hfe"
#include "functions.hfe"
#include "Data/tekoaly.ggy"


int main(int argc, char *argv[]) {

	std::cout <<"Alustetaan Garfiikka moottoria." << std::endl;
    if( SDL_Init(SDL_INIT_VIDEO) < 0 )
    {
        fprintf(stderr, "SDL:n alustus ei onnistunut: %s\n", SDL_GetError());
        return 0;
    }
	std::cout <<"Grafiikka moottori alustettu." << std::endl;
	SDL_WM_SetCaption("Street Fights", NULL);
	std::cout <<"Alustetaan näppäimistö." << std::endl;

	SDL_Event tapahtuma;
	SDL_Event tapahtumaa;
	Uint8 *button;
	button = SDL_GetKeyState(NULL);
	std::cout <<"Näppäimistö alustettu." << std::endl;

	std::cout <<"Alustetaan näyttö" << std::endl;
    naytto = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
	std::cout <<"Näyttö alustettu" << std::endl;
	std::cout <<"Ladataan pelin sisältö." << std::endl;
    LataaPeli();
	SDL_SetColorKey(osoitin, SDL_SRCCOLORKEY, SDL_MapRGB(osoitin->format,0,0,0));
	SDL_SetColorKey(koko_hahmo_1, SDL_SRCCOLORKEY, SDL_MapRGB(koko_hahmo_1->format,255,255,255));

	std::cout <<"Pelin sisältö ladattu." << std::endl;
	std::cout <<"Aloitetaan peli." << std::endl;
	odotus=8;
	AlkuValikko();
	while (pois == false)
	{
		if (huone == 0)
		{
			AlkuValikkoToiminnot();
		}
		if (huone == 1)
		{
			Huone2Kuvat();
			Huone2Logiikka(tapahtuma);
		}
		if (huone == 2)
		{
			Huone3Piirto();
			SDL_Flip(naytto);

			int hiiren_x, hiiren_y;
			hiiri=SDL_GetMouseState(&hiiren_x,&hiiren_y);
			if (SDL_GetMouseState(&hiiren_x,&hiiren_y) & SDL_BUTTON(1))
			{
				TarkistaPiste(hiiren_x, hiiren_y, pika_peli_nappi, naytto, 287, 113, 180, 333, 3);
			}
		}
		if (huone == 3)
		{
			SDL_Delay(3000);
			Huone4Piirto();
			SDL_Flip(naytto);
			Huone4Toiminnot(button);
			VastustajanTekoaly(hahmo_x_sijainti, hahmo_y_sijainti, vasX, vasY, kentta_1, koko_hahmo_1_lyonti, koko_hahmo_1);
		}

		SDL_PollEvent(&tapahtuma);
		if ( tapahtuma.type == SDL_QUIT )
		{
			pois = true;
		}
		if ( tapahtuma.key.keysym.sym == SDLK_ESCAPE )
		{
			pois = true;
		}
		if ( tapahtuma.key.keysym.sym == SDLK_RETURN )
		{
			huone=2;
		}
	}

    SDL_Quit();
    return 0;
}

tekoaly.ggy:

#include "time.h"

int unix_aika() {
	time_t timet=time(NULL);
	t1=timet;
	return (t1);
}

int AsetaAika() {
	if (suoritettu <= 0)
	{
	time_t timeta=time(NULL);
	r1=timeta;
	return (r1);
	}
}


void Lyo(SDL_Surface *kentta_1, SDL_Surface *koko_hahmo_1_lyonti, SDL_Surface *koko_hahmo_1)
{
	PiirraKuva(kentta_1, naytto, 0, 0);
	PiirraKuva(koko_hahmo_1_lyonti, naytto, vasX, vasY);
	PiirraKuva(koko_hahmo_1, naytto, hahmo_x_sijainti, hahmo_y_sijainti);
	SDL_Flip(naytto);
}

void VastustajanTekoaly(int hahmo_x_sijainti, int hahmo_y_sijainti, int vasX, int vasY, SDL_Surface *kentta_1, SDL_Surface *koko_hahmo_1_lyonti, SDL_Surface *koko_hahmo_1)
{
	int erotus_x = hahmo_x_sijainti - vasX;
	int erotus_y = hahmo_y_sijainti - vasY;

	if (erotus_x <= -60)
	{
		vasX=vasX-1;
	}
	else
	if (erotus_x >= 60)
	{
		vasX=vasX+1;
	}
	if (erotus_x >= -61 && erotus_x <= 59)
	{
		if (tap == 1)
		{
		hahmo_x_sijainti=hahmo_x_sijainti+100;
		Lyo(kentta_1, koko_hahmo_1_lyonti, koko_hahmo_1);
		tap=0;
		}
	}

    while(aika_paalla == true) {
        aika2 = unix_aika();
		aika = AsetaAika();

        if(aika2 >= aika + odotus)
        {
            std::cout << "Kahdeksan sekunttia meni jo!" << aika2 << "  JA:  " << aika << "  :  " << suoritettu<< "  :  " << odotus<< std::endl;
            suoritettu=0;
        }
        else
        if(aika2 <= aika + odotus - 1)
        {
			std::cout << "Kahdeksan sekunttia meni jo!" << aika2 << "  JA:  " << aika << "  :  " << suoritettu<< "  :  " << odotus<< std::endl;
            suoritettu=1;

        }
    }
}

Teuro [16.11.2009 21:20:43]

#

Eli pointti ei osunut maaliin? No hyvä yritän uudelleen. Pointtina oli osoittaa, että

Tuosta esimerkistä voidaan nimittäin helpolla koodata graafinen. Logiikka ei muutu mihinkään, vaan ainoastaan tuon tekstin tuottava ja tulostava osa muunnetaan tukemaan grafiikkaa.

mika132 [16.11.2009 21:38:47]

#

Vaikka ymmärtäisin 100% mikä on vikana en osaa korjata sitä. Enkä osaa hyödyntää koodiasi ollenkaan. Kun yritin meni tuo vain enemmän sekaisin, joten vedin takapakkia.

Grez [16.11.2009 21:54:23]

#

Koodin ymmärtäminen on siis selkeästi yksi asia, joka sinun täytyy opetella. Et voi mitenkään korjata omaakaan koodiasi kun et ymmärrä mitä se tekee. Et pysty hyödyntämään koodiesimerkkejä, muuta kuin copy&paste -tyylillä, jos et pysty ymmärtämään mitä ne tekevät. Ja copy&paste -koodaus tuottaa aina paskaa.

Esimerkiksi tuo sinun koodisi lopussa oleva while -looppi on ns. umpikuja. Siinä vaiheessa kun ohjelman suoritus pääsee ko. looppiin, niin sillä ei ole mitään mahdollisuutta päästä sieltä ulos -> Ohjelmasi "jumiutuu".

Arvaa onko turhauttavaa kun olen tuostakin jo sanonut, mutta minkäänlaista korjaantumista ei ole havaittavissa.

Sanon vielä kertaalleen: Ei ole mahdollista ohjelmoida kunnollista vähänkään laajempaa ohjelmaa, jos ei ymmärrä mitä tekee.

Kuka tahansa täällä auttaneista voisi ottaa koodisi ja korjata sen toimivaksi, mutta olemme ymmärtäneet että siitä ei olisi mitään hyötyä kenellekään, koska et ymmärtäisi miksi ne korjaukset on tehty ja kysyisit huomenna seuraavasta kohdasta yhtä (anteeksi nyt vaan) typeriä kysymyksiä.

Teuro [16.11.2009 22:10:20]

#

Tämä ei ole tarkoitetttu ivailuksi, mutta kykenetkö täyttämään alla olevan koodin kommentit kuntoon?

/**
	* Sisällytetään ... koodiin, jotta saadaan ... toimimaan
*/
#include <iostream>

/**
	* Aloitetaan ...
*/

int main(int maara, char **argumentit){
	/**
		* Verrataan saatiinko yhtään...
	*/

	if(maara > 0){
		/**
			* Käydään for silmukkaa ... kertaa läpi
			* Silmukka aloitetaan indeksistä ... , koska ... parametri on aina ... täydellisenä
		*/

		for (int a = 1; a < maara; ++a){
			/**
				* Tulostetaan ... ja rivinvaihto
			*/
			std::cout << argumentit[a] << std::endl;
		}
	/**
		* Käyttäjä ei antanut yhtään ...
	*/
	}else{
		std::cout << "Komentoriviparametrejä ei annettu yhtään kappaletta!" << std::endl;
	}

	/**
		* Palautetaan ... kutsujalle
	*/
	return EXIT_SUCCESS;
}

mika132 [16.11.2009 22:31:47]

#

No tässä kommentoituna sen mitä osasin.

/**
    * Sisällytetään kirjastot koodiin, jotta saadaan peli toimimaan
*/
#include <iostream>

/**
    * Aloitetaan pää funktio eli main.
*/

int main(int maara, char **argumentit){
    /**
        * Verrataan saatiinko yhtään muuttujaan maara.
    */

    if(maara > 0){
        /**
            * Käydään for silmukkaa maara muuttujan arvon verran läpi
            * Silmukka aloitetaan indeksistä (en tajunnut) , koska (en tajunnut) parametri on aina (en tajunnut) täydellisenä
        */

        for (int a = 1; a < maara; ++a){
            /**
                * Tulostetaan taulu argumentti arvona muuttuja a ja rivinvaihto
            */
            std::cout << argumentit[a] << std::endl;
        }
    /**
        * Käyttäjä ei antanut yhtään komentoriviparametrejä.
    */
    }else{
        std::cout << "Komentoriviparametrejä ei annettu yhtään kappaletta!" << std::endl;
    }

    /**
        * Palautetaan (en ole tuollaista koskaan käyttänyt) kutsujalle
    */
    return EXIT_SUCCESS;
}

Sain kelloni toimimaan.

mika132 [16.11.2009 23:16:29]

#

Pehana. Ei se sitten ihan toiminutkaan. Se oli vain hetken luulo johde, kun olin vahinkossa koodnn lyönyt SDL_Delay:n.

Miten se SDL_Ticet() toimii? Miten sen arvoa siis voidaan käyttää hyväski keskellä peliä?

vehkis91 [17.11.2009 01:06:53]

#

No mietippä sitä... Tässä ketjussa on jo monta kertaa mainittu siitä miten aikaa voi käyttää hyödykseen. Sun pitää vaan vähän soveltaa...

Teuro [17.11.2009 07:15:27]

#

No tässä on vielä muunnettuna tuo aiemmin tekemäni ajastin, mutta nyt käsittelyssä on grafiikka. Ensin piirtofunktio, joka käyttää globaalia pintaa *ruutu, joka taasen alustetaan SDL_alusta() funktiossa.

void piirra(){
	std::string orig;
	TTF_Font *fontti = TTF_OpenFont("C:\\Windows\\Fonts\\arial.ttf", 30);
	SDL_Color vari = {198, 128, 128};
	SDL_Surface *teksti;

	std::stringstream virta;

	virta << SDL_GetTicks() << std::endl;
	virta >> orig;

	teksti = TTF_RenderText_Solid(fontti, orig.c_str(), vari);

	SDL_BlitSurface(image_cache::common().get("tausta.png"), 0, ruutu, 0);
	SDL_BlitSurface(teksti, NULL, ruutu, NULL);

	SDL_Flip(ruutu);
}

Seuraavaksi pääfunktio

int main (int maara, char **argumentit){
	bool peli_jatkuu = true;

	try{
		SDL_alusta();
	}catch(std::exception &e){
		std::cout << e.what();
	}

	unsigned int t1 = anna_aika();
	unsigned int odotus = 1.5;
	unsigned int t2 = t1 + odotus * 1000;

	while(peli_jatkuu){
		peli_jatkuu = kasittele_viestit();
		t1 = anna_aika();

        if(t1 >= t2){
            piirra();
            t2 = t1 + odotus * 1000;
        }
	}

    return EXIT_SUCCESS;
}

ja lopuksi vielä tuo anna_aika() funktio.

unsigned int anna_aika(){
	return SDL_GetTicks();
}

Eli tarvitaan vielä kuvavarastoa, sekä jonkinlainen taustakuva. Pääsilmukan peli_jatkuu muuttujan sisältö tulee kasittele_viestit() funktiolta.

bool kasittele_viestit(){
	SDL_Event event;
    while (SDL_PollEvent(&event)) {
		if (event.type == SDL_QUIT){
            return false;
        }
        if (event.type == SDL_KEYDOWN){
        	switch (event.key.keysym.sym) {
				case SDLK_ESCAPE:
				case SDLK_q:
					return false;
				default:
					break;
			}
        }
    }
    return true;
}

Näillä eväillä pitäisi tuon edellisen ajastimen koodi saada muunnettua graafiseksi.

mika132 [17.11.2009 16:35:16]

#

Perahana, kun tuli mahtava olo. Tutkein hetken koodia ja piirtelin kuvia miten koodi toimii ja sitten huomasin vian. Kiitos auttajille, mutta vika oli AsetaAika(); funktiossa, koska se sijaitsi väärässä paikassa. Nyt ajastin toimii täydellisesti. :D


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta