Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Reaaliaikaisen datan seuraaminen

WKoA [23.03.2010 15:11:03]

#

Hei,

Olen siis tehnyt kokeellisen RPG "pelin", jossa pelaaja pystyy liikkumaan 10*10 kokoisella kartalla. Pelaajan paikka on keskellä 3*3 kokoista kuvaa, siten että pelaajan oma sijainti on keskellä tuota 3*3 ruutua. Ongelmani on seuraavanlainen: mikäli pelissä onkin kaksi pelaajaa ja toinen vain "idlaa", niin olisi kuitenkin kiva kun tämän "idlaavan" pelaajankin ruudulla näkyy kun toinen pelaaja jolkuttelee ohi.

Ehdotuksia toteutustavasta otetaan kiitollisena vastaan. Ei mielellään mitään Java-toteutusehdotuksia, vaan ihan javascript, php, ajax yms. tekniikoita käyttäen.

Macro [23.03.2010 15:21:56]

#

Voit laittaa esimerkiksi sivulle Ajax-koodin, joka hakee sivua peli.php vaikka 500 millisekunin välein. Pelaajan liikkeet kirjataan joka etenemisellä vaikka tietokantaan:

"sijainnit":

PelaajaMistäNykyinenSijainti
WKoA13, 113, 2
Macro1, 12, 2

Tietokanta voisi näyttää äskeiseltä. Sitten peli.php sivulla haet aina pelaajan sijainnin, ja päivität sen ruutuun. Ajax hoitaa reaaliaikaisuuden.

peli.php:n voisi toteuttaa niin, että se hakee taulusta online kaikki paikalla olevat pelaajat. Pelaajan istunto voi vanheta vaikka viiden minuutin kuluessa viimeisestä siirrosta. Tulostat PHP:n kanssa taulukon, jossa joka solussa tarkistat onko jonkin pelaajan koordinaatit tässä. PHP:ssä taulukon voi tulostaa näin:

<?php
echo "<table>";
for($x = 0; $x < 10; $x++) {
	echo "<tr>";
	for($y = 0; $y < 10; $y++) {
		echo "<td>($x, $y)</td>";
	}
	echo "</tr>";
}
echo "</table>";

Kun tarkastat onko kukaan pelaaja kyseisessä ruudussa, voit tehdä sen näin:

<?php
$yhteys = mysql_connect("localhost", "root", "") or die(mysql_error());
mysql_select_db("peli") or die(mysql_error());

echo "<table>";
for($x = 0; $x < 10; $x++) {
	echo "<tr>";
	for($y = 0; $y < 10; $y++) {
		$pelaaja = (mysql_num_rows(mysql_query("SELECT * FROM sijainnit WHERE nykyinensijainti = '$x, $y'"))) ? true : false;
		$vari = ($pelaaja) ? "#FF0000" : "#FFFFFF";

		echo "<td style=\"background-color: $vari\">($x, $y)</td>";
	}
	echo "</tr>";
}
echo "</table>";

Lisäksi monella pelaajalla voi olla sijaintitaulukossa tietoa, vaikkei olisi sisälläkään. Kannattaa lisätä vaikka aikaleima joka siirtoon. Sitten voit poistaa vaikka yli kaksi tuntia vanhat siirrot. Sen voi myös tehdä siten, että päivität siirtoa, mikäli pelaaja liikkuu.

Metabolix [23.03.2010 15:34:10]

#

Tässä on pieni peli, jossa pelaajat voivat hiirellä siirrellä kirjaimia. Tässä on sen JS-koodi (käyttää jQuery-kirjastoa) ja tästä näet PHP-lähdekoodin, jossa keskeiset asiat ovat alkupuolella odotussilmukka ja myöhemmin tietokannan lukitus, jotta muutokset eivät menisi ristiin. Lukituksen voi hoitaa paljon optimaalisemminkin (esim. käyttämällä SQL:ää), mutta joka tapauksessa joudut tarkkaan huolehtimaan, että jokainen muutos pääsee perille ja lähetetään jokaiselle pelaajalle, vaikka useampi HTTP-pyyntö sattuisi palvelimelle juuri samaan aikaan.

Ideana siis on, että asiakas tekee aina AJAX-pyynnön, ja jos pyyntö ei sisällä tietoa liikkumisesta, palvelin jää odottamaan, että joku muu tekee jotain. Jotta selain ei päättäisi katkaista yhteyttä, palvelimen on hyvä odottaa vain rajallinen aika, esimerkiksi puolisen minuuttia, ja lähettää sitten tyhjä vastaus. Jos pelaaja päättääkin odotuksensa aikana liikkua, JS-puolella voidaan perua pyyntö ja lähettää uusi. Pitää kuitenkin huolehtia, ettei vahingossa peruta omaa liikepyyntöä.

(Edit: kommentoinpa nyt koodinkin pääpiirteittäin, kun tuli julkaistua.)

WKoA [23.03.2010 17:10:23]

#

Tietokantani on nyt mallia: (pelaaja ID), (paikka x), (paikka y).
En mielestäni tule tarvitsemaan ns. "vanhaa sijaintia", vaan tuo liikkuminen hoidetaan oman funktion läpi, joka tarkoittaa, ettei kaksi pelaajaa voi olla samassa pisteessä.

Ja tuo istunnon vanheneminen täytyy toteuttaa järkevästi, jottei porukka pelaajia tuki tarpeellisia kulkureittejä idlaamalla ja seisoskelemalla paikallaan.

Ja pelaajakohtaiset paikkatiedot haetaan siten, että haetaan ainoastaan "näkökentässä" olevat paikat ja mahdolliset pelaajat. Kun jos karttaa laajennetaan 10000*10000 kokoiseksi ja pelaajia olisi rutosti, niin ei mene iäisyys pelaajatietojen hakemiseen.

...saa nähdä tuleeko kevättä =D

Macro [23.03.2010 18:42:54]

#

10000*10000 on ihan hervoton koko. Jos tulostat sen yllämainitsemallani tavalla, niin ainakaan toisen palvelimella et saa sitä koskaan tehtyä. Lisäksi pelaajalla kestäisi ikuisuus odottaa pelikentän latautumista.

Metabolix [23.03.2010 21:03:31]

#

Macro: Kaikkea ei tarvitse tehdä huonoimmalla tavalla. Tieto menee todella paljon pienempään tilaan, kun esitetään se isompina paloina: "ruohoa alueella (120,450)-(145,480)". Lisäksi pelin kannalta olennaista on usein vain, että seinät, esineet ja selkeät maanmerkit ovat oikeissa kohdissa, joten pelaajat voivat vaikka arpoa suuren osan muusta maailmasta esimerkiksi 100×100-paloista koostuvan kartan perustella. (Luvut ovat toki arvioita, koska en tiedä, millaisia ruudut kysyjän pelissä ovat kooltaan.)

WKoA [24.03.2010 08:22:08]

#

Ja samahan se on minkä kokoinen kartta on... siis että jos aina pelikartasta ladataan vain se pelaajan "näkökenttä", niin ei kai sillä koko kartan koolla ole merkitystä, kun ei sitä koskaan ladata kokonaan. Ja toki tuo Metabolixin asia, että jos on suurempia esim. nurmialueita, niin ei tarvitse jokaista ruutua latailla erikseen. Mutta ei kai sillä ole loppupeleissä merkitystä jos ladataan vain muutaman kymmentä aluetta, eikä koko karttaa.

Vastaus

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

Tietoa sivustosta