Kirjautuminen

Haku

Tehtävät

Koodivinkit: JavaScript: Vihollisten väistelyä pelikentällä

Kirjoittaja: Juhko

Kirjoitettu: 08.02.2009 – 08.02.2009

Tagit: pelinteko

Merkkipohjainen peli, jossa ohjataan ukkoa (@) pelikentällä ja väistellään vihollisia (%). Kun ukko törmää viholliseen, alkaa uusi peli.

Peli täytyy pysäyttää "Pysäytä" -nappulasta, kun haluaa siirtyä toiselle sivulle. Tähän on syynä se, että fokus asetetaan näppäimistönlukukentälle jatkuvasti, eikä osoitekenttään (tai minnekään muualle) pysty kirjoittamaan.

Saa käyttää ja muokata vapaasti, eikä tekijää tarvitse mainita.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 TRANSITIONAL//EN">
<html>

	<head>
		<title></title>
	</head>
	<body>

<b><font size="6">JavaScript-merkkigrafiikkapeli</font></b>
<hr>

<script type="text/javascript">

var world_width=40;
var world_height=20;
var enemies=10;
var x = 20;
var y = 10;
var rx = x;
var ry = y;
var erx;
var ery;
var i;
var i2;
var enemyX = new Array();
var enemyY = new Array();
var rnd = 2; //satunnaislukugeneraattori
var rnd2 = 2;
var turn = 0; //siirretään vain joka toinen vuoro
var scores = 0; //pisteet

moveTimer=setTimeout(move,1); //liikutusajastin

//piirretään kenttä (reunoille seinää, muualle tyhjää)
document.write('<font size="4">');
document.write("<pre>");
for(i2=1;i2<world_height+1;i2=i2+1)
{
	for(i=1;i<world_width+1;i=i+1)
	{
		if(i==1||i2==1||i==world_width||i2==world_height)
			document.write("<a id='" + i + "," + i2 + "'>#</a>");
		else
			document.write("<a id='" + i + "," + i2 + "'> </a>");
	}
	document.write("<br>");
}
document.write("</pre>");
document.write("</font>");

document.getElementById(x+","+y).innerHTML="@"; //piirretään ukko

//luodaan ja piirretään viholliset
for(i=1;i<enemies+1;i++)
{
	do {
		rnd = rnd + 11
		if(rnd > world_width - 1) rnd = rnd - world_width;
		rnd2 = rnd2 + 4;
		if(rnd2 > world_height - 1) rnd2 = rnd2 - world_height;
		if(rnd > world_width - 1) rnd = 2;
		if(rnd2 > world_height - 1) rnd2 = 2;
		enemyX[i]=rnd;
		enemyY[i]=rnd2;
		document.getElementById(enemyX[i]+","+enemyY[i]).innerHTML="%";
	} while((enemyX[i]==x) && (enemyY[i]==y))
}

function move()
{
	var liikuttu=1;
	moveTimer=setTimeout(move,1);
	rx=x;
	ry=y;
	liikuttu=0;
	if(document.controller.keys.value=="w") {y=y-1;liikuttu=1}
	if(document.controller.keys.value=="s") {y=y+1;liikuttu=1}
	if(document.controller.keys.value=="a") {x=x-1;liikuttu=1}
	if(document.controller.keys.value=="d") {x=x+1;liikuttu=1}

	//ukon törmäystunnistus
	if(document.getElementById(x+","+y).innerHTML=="#") {x=rx; y=ry}

	//näppäimistökäsittelijä
	document.controller.keys.value="";
	document.controller.keys.focus();

	if(liikuttu == 1) //jos pelaaja liikkui
	{
		turn = 1 - turn; //siirtääkö vai eikö siirtää
		for(i=1;i<enemies+1;i++) //selataan kaikki viholliset
		{
			document.getElementById(enemyX[i]+","+enemyY[i]).innerHTML=" "; //tyhjää vihollisen edelliselle paikalle
			erx=enemyX[i]; //vihollisen nykyiset koordinaatit
			ery=enemyY[i];
			if(turn == 0) {

				//liikutetaan vihollista pelaajaa kohti
				if(enemyX[i] < x) enemyX[i] = enemyX[i] + 1;
				if(enemyX[i] > x) enemyX[i] = enemyX[i] - 1;
				if(enemyY[i] < y) enemyY[i] = enemyY[i] + 1;
				if(enemyY[i] > y) enemyY[i] = enemyY[i] - 1;

				//vihollisen törmäystunnistukset
				if(document.getElementById(enemyX[i]+","+enemyY[i]).innerHTML=="%") //toinen vihollinen
				{
					enemyX[i]=erx; //palautetaan edelliselle paikalle
					enemyY[i]=ery;
				}
				if(document.getElementById(enemyX[i]+","+enemyY[i]).innerHTML=="#") //seinä
				{
					enemyX[i]=erx; //palautetaan edelliselle paikalle
					enemyY[i]=ery;
				}

			}
			document.getElementById(enemyX[i]+","+enemyY[i]).innerHTML="%";
		}
		scores++; //kasvatetaan pistemäärää
		document.getElementById("scoreCaption").innerHTML = scores;
	}

	//jos törmätään viholliseen, näytetään pistemäärä ja aloitetaan uusi peli
	if(document.getElementById(x+","+y).innerHTML=="%") {
		alert("Peli loppui, pisteet " + scores + ". Paina OK aloittaaksesi uuden pelin.");
		newGame();
	}
	//ukon pyyhintä ja piirto
	document.getElementById(rx+","+ry).innerHTML=" ";
	document.getElementById(x+","+y).innerHTML="@";

}

function newGame() {

	rnd = 2; //satunnaislukugeneraattori
	rnd2 = 2;

	//reunoille seinät, muualle tyhjää
	for(i2=1;i2<world_height+1;i2=i2+1)
	{
		for(i=1;i<world_width+1;i=i+1)
		{
			if(i==1||i2==1||i==world_width||i2==world_height)
				document.getElementById(i+","+i2).innerHTML="#";
			else
				document.getElementById(i+","+i2).innerHTML=" ";
		}
	}

	//piirretään ukko
	x=20;
	y=10;
	document.getElementById(x+","+y).innerHTML="@";

	scores=0; //pisteet

	//vihollisten paikat
	for(i=1;i<enemies+1;i++)
	{
		rnd = rnd + 11
		if(rnd > world_width - 1) rnd = rnd - world_width;
		rnd2 = rnd2 + 4;
		if(rnd2 > world_height - 1) rnd2 = rnd2 - world_height;
		if(rnd > world_width - 1) rnd = 2;
		if(rnd2 > world_height - 1) rnd2 = 2;
		enemyX[i]=rnd;
		enemyY[i]=rnd2;
		document.getElementById(enemyX[i]+","+enemyY[i]).innerHTML="%";
	}

}

function clearKeys() {
	//tyhjennetään näppäimistökenttä
	document.controller.keys.value="";
	moveTimer=setTimeout("clearKeys()",1);
}

</script>

<hr>
<form name="controller">
<input type="button" value="Uusi peli" onClick="newGame()">
<input type="button" value="Pys&auml;yt&auml;" onClick="clearTimeout(moveTimer); moveTimer=setTimeout('clearKeys()',1)">
<input type="button" value="Jatka" onClick="clearTimeout(moveTimer); moveTimer=setTimeout('move()',1)">
<br><br>
Suunta: johon haluat liikkua: <input type="text" name="keys" size="2">
</form>
Pisteet: <a id="scoreCaption">0</a>
<hr>
Peliohje: Ohjaat ukkoa (@) pelikent&auml;ll&auml; n&auml;pp&auml;imill&auml; W,S,A,D. Peli loppuu, kun t&ouml;rm&auml;&auml;t viholliseen (%). Mit&auml; kauemmin pysyt pelikent&auml;ll&auml;, sit&auml; enemm&auml;n pisteit&auml; saat.

	</body>
</html>

Kommentit

jlaire [08.02.2009 17:01:52]

Lainaa #

Ihan hyvä vinkki. Muutama asia, jotka itse tekisin eri tavalla:

setTimeout("move()",1);

Miksei näin: setTimeout(move, 1); ?

Sinun käyttämääsi tapaa näkee harmillisen usein. Se on epäselvempi ja aiheuttaa turhan kutsun eval:iin.

i==1|i2==1|i==world_width|i2==world_height

Toimiihan tuokin, mutta | on bittioperaattori ja aiheuttaa turhia tyyppimuunnoksia (eikä koskaan jätä parametreja evaluoimatta). Looginen tai on ||.

if(turn == 0) {turn = 1;} else {turn = 0;}

Lyhyemmin: turn = 1 - turn;.

Tuo satunnaislukugeneraattoriviritelmä meni vähän ohi. Kannattaa tutustua Math.random:iin.

Tämä on aika kätevä näppäimistön käyttämiseen. Löytyy myös jQuery-pluginina.

Pekka Karjalainen [08.02.2009 17:48:18]

Lainaa #

Tämä ohjelma toi muistoja mieleen. Hyvä Juhko!

Juhko [08.02.2009 18:00:23]

Lainaa #

Mukavaa, että pidätte ohjelmasta. :)

Juu, korjasin muutaman "virheen": setTimeout("move()",1) -> setTimeout(move,1) | -> || ja turn = 1 - turn;.

Pekka Karjalainen [09.02.2009 14:24:14]

Lainaa #

Jos tällainen JS-pelien teko kiinnostaa Juhkoa enemmän, voipi hän kokeilla seuraavaan peliin tehdä taulukon (HTML:n table-elementin), jonka kenttiin laittaa eri kuvia vaihtamalla image-tägien arvoja. Kun taulukon laidat säätää vielä nollalevyisiksi, siitä tulee ihan oikea tile-pohjainen grafiikkamoottori. Ukkeleista voi tehdä osittain läpinäkyviä png-kuvia, niin niiden yhdistäminen taustakuvaan käy näpsäkästi.

(Vakavampimielinen selainpeli syntynee kuitenkin paremmin esim. Actionscriptin avulla. Adobe jakelee nykyään sitä ilmaisversiota nimeltä Flex...)

P.S. Vielä lyhyempi: turn ^= 1;

Kusmariini [17.02.2009 11:08:26]

Lainaa #

perhanan vaikee toi peli muute =(

Juhko [17.02.2009 13:53:34]

Lainaa #

Joo, se onkin pelin pahin puute, aluksi se on vaikee mutta sitten kun pääsee pakoon, voi helposti kerätä parikin tuhatta pistettä. Tuohonhan voisi soveltaa vaikka jotakin hippakilpailun tekoälyä. :)

Le-Co-Las [27.02.2009 18:21:35]

Lainaa #

enpä oo ennen moista JS.llä nähnyt kiitoksia. tätä pitää ehdottomasti firitellä... : )

rax [27.02.2009 22:15:41]

Lainaa #

Helppohan tämä peli on, kun pääsee reunoille.
Sitten menee kokoajan reunoja pitkin ja elämä kulkee hyvin
-b

jo123 [04.03.2009 22:34:01]

Lainaa #

Joo! Kun pääsee reunoille voi vaan kierrellä niitä ja elämä jatkuu. XD

Clacier [22.10.2009 23:27:13]

Lainaa #

mahtava. :))

Juhko [23.10.2009 19:03:57]

Lainaa #

Kiitokset.

siika [13.11.2009 22:01:25]

Lainaa #

Mahtava :D

Kalle [02.08.2014 09:34:47]

Lainaa #

Woo! Mä vedin 5655 pistettä!
Aivan mahtava peli!

TapaniS [27.06.2015 10:30:00]

Lainaa #

Heh, ei tuo vielä mitään! Enkat on nyt 6654!

Hulppea peli!

Kirjoita kommentti

Muista lukea kirjoitusohjeet.
Tietoa sivustosta