<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Suomipelit.com &#187; ohjelmointi</title>
	<atom:link href="http://www.suomipelit.com/avainsana/ohjelmointi/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.suomipelit.com</link>
	<description>Pohjolan pelaava kansa</description>
	<lastBuildDate>Tue, 03 Aug 2010 07:26:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>QBasicin perusteet</title>
		<link>http://www.suomipelit.com/2006/11/09/qbasicin-perusteet/</link>
		<comments>http://www.suomipelit.com/2006/11/09/qbasicin-perusteet/#comments</comments>
		<pubDate>Thu, 09 Nov 2006 10:00:06 +0000</pubDate>
		<dc:creator>Tomppu</dc:creator>
				<category><![CDATA[Käytännön oppaat]]></category>
		<category><![CDATA[alkeet]]></category>
		<category><![CDATA[basic]]></category>
		<category><![CDATA[ohjelmointi]]></category>
		<category><![CDATA[perusteet]]></category>
		<category><![CDATA[qbasic]]></category>

		<guid isPermaLink="false">http://www.suomipelit.com/?p=1306</guid>
		<description><![CDATA[QBasic-ohjelmointikielellä voi ohjelmoida yksinkertaisia ohjelmia, nopeasti ja helpohkosti.
Tämä artikkeli sisältää QBasicin perusteet.]]></description>
			<content:encoded><![CDATA[<p>QBasic-ohjelmointikielellä voi ohjelmoida yksinkertaisia ohjelmia, nopeasti ja helpohkosti.<br />
Tämä artikkeli sisältää QBasicin perusteet.</p>
<h2>Alkusanat</h2>
<p>Tervetuloa QBasicin hämärään maailmaan! Olettaisin, että hallitset jo ohjelmoinnin perusteet, mutta aloittelijankin pitäisi tämän oppaan avulla päästä vauhtiin. QBasic-ohjelmointikielellä aiomme ohjelmoida yksinkertaisia ohjelmia, nopeasti ja helpohkosti. Tässä tutoriaalissa käytämme kehitysympäristönä Microsoftin vanhaa, mutta ehkä jollain tavalla toimivaa, QBasic-tulkkia, jonka voi ladata esimerkiksi osoitteesta <a href="http://www.fluid.tue.nl/student/colleges/NLS/progs/QBASIC.EXE">http://www.fluid.tue.nl/student/colleges&#8230;</a></p>
<h2>Kehitysympäristön käyttö kiteytettynä</h2>
<p><a href="http://www.suomipelit.com/tiedostot/2010/03/kehymp.png" rel="lightbox[1306]"><img class="alignright size-full wp-image-1317" title="QBasicin kehitysympäristö" src="http://www.suomipelit.com/tiedostot/2010/03/kehymp.png" alt="" width="240" height="180" /></a>QBasic-kehitysympäristön käyttö nykykoneilla saattaa olla vähän tuskaista. Tämän takia suosittelenkin käyttämään esimerkiksi DOSBoxia, jolle on olemassa omat tutoriaalinsa. Emulaattorin käyttö ei ole suinkaan välttämätöntä. Käytit sitten emulaattoria tai et, suorita QBasic.exe. Kun haluat testata ohjelmaasi, niin paina F5 tai näpäytä hiirellä Run/Start. Tallentaaksesi tiedoston klikkaa File/Save (as).</p>
<h2>Ensimmäinen ohjelma</h2>
<p>Tämäkin tutoriaali alkaa Hello World -ohjelmalla, joka siis tulostaa ruudulle tekstin Hello world! Koodipuoli näyttää tältä:</p>
<pre>
<div class="codecolorer-container blitzbasic default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="blitzbasic codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">PRINT</span> <span style="color: #009900;">&quot;Hello World!&quot;</span></div></td></tr></tbody></table></div>
</pre>
<p>PRINT-komennolle annetaan parametrit, jotka se tulostaa ruudulle. Äskeisessä tapauksessa parametri oli merkkijono &#8220;Hello World!&#8221;</p>
<p>Varmasti tämän jälkeen haluat tyylikkään ja itsenäisemmän näköisen softan, joka saadaan aikaiseksi helposti tyhjentämällä ruutu ennen kirjoittamista. QBasicissa on komento nimeltä CLS, joka hoitaa homman kotiin. Jos laitat CLS-komennon ruudulle kirjoittamisen jälkeen, ohjelmasi luonnollisesti piirtää tekstin ensin ja tyhjentää ruudun vasta tämän jälkeen. Jos vahingossa teit tämän virheen, käyttäjälle ei näy muuta kuin tyhjää, joten tarkkana täytyy olla.</p>
<pre>
<div class="codecolorer-container blitzbasic default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="blitzbasic codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">CLS</span> 'Tyhjentää ruudun<br />
<span style="color: #0000ff;">PRINT</span> <span style="color: #009900;">&quot;Hello World!&quot;</span> 'Kirjoittaa ruudulle</div></td></tr></tbody></table></div>
</pre>
<p>Maistuiko tämäkin puulta? Mielenkiintoa lisää huomattavasti hyvin yksinkertainen komento LOCATE, joka määrää PRINT-komennon kirjoittamispaikan. Oletuksenahan se aloittaa sen vasemmasta ylänurkasta (x=1,y=1), mutta LOCATEn kahden parametrin avulla voidaan kertoa, mihin teksti oikeastaan kirjoitetaan. Et ehkä arvaakaan, kuinka helposti ja nopeasti tällä saadaan peliympäristö aikaiseksi. Locaten ensimmäinen parametri on y-koordinaatti, joka kertoo kirjoituskorkeuden eli rivin. Toinen parametri on x-koordinaatti, joka viestii PRINT-komennolle tekstin vaakasuuntaisen sijainnin (sarakkeen). Parametrit annetaan ehkä aluksi epäloogiselta tuntuvalla tavalla, siis ensin y- ja sitten x-koordinaatti, mutta ilmeisesti se on perusteltu sillä, että on loogista antaa ensin rivi ja sen jälkeen sarake. Toimivat arvot ovat x-suunnassa välillä 1-80 ja y-suunnassa 1:n ja 25:n välillä.</p>
<p>Haluamme nyt kirjoittaa tekstin &#8220;Hello World&#8221; vaikkapa koordinaatteihin x=63, y=3, jolloin kirjoitamme LOCATE 3, 63 ennen PRINT-käskyä:</p>
<pre>
<div class="codecolorer-container blitzbasic default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="blitzbasic codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">CLS</span> 'Ruudun tyhjennys<br />
<span style="color: #0000ff;">LOCATE</span> <span style="color: #CC0000;">3</span>, <span style="color: #CC0000;">63</span> 'Asetetaan piirtokohta riville <span style="color: #CC0000;">3</span>, sarkaimelle <span style="color: #CC0000;">63</span><br />
<span style="color: #0000ff;">PRINT</span> <span style="color: #009900;">&quot;Hello World!&quot;</span> 'Kirjoittaminen</div></td></tr></tbody></table></div>
</pre>
<p>Noita arvoja voi sitten huoletta sovellella ja muutella, kunhan pysyvät niissä määrätyissä rajoissa.</p>
<h2>Muuttujat</h2>
<p>Muuttuja on &#8220;arvonsäilyttämispaikka&#8221;, johon voidaan varata arvo ja jota voidaan muutella ja lukea. Voisimme esimerkiksi määritellä muuttujan ika, jonka arvoksi annetaan vaikkapa oma ikäsi. Muuttujat olisi suositeltava myös esitellä, minkä yhteydessä tulee sille antaa tyyppi. Tämä kertoo, minkälaisia arvoja se voi saada. Tässä artikkelissa käytämme usein muuttujia, jotka ovat tyypiltään on kokonaislukuja (integer).</p>
<pre>
<div class="codecolorer-container blitzbasic default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="blitzbasic codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Tyyppi &nbsp; &nbsp; &nbsp; merkintä &nbsp;Min. arvo &nbsp; &nbsp; &nbsp; Max. arvo<br />
Kokonaisluku INTEGER &nbsp; &nbsp;-<span style="color: #CC0000;">32</span> <span style="color: #CC0000;">768</span> &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #CC0000;">32</span> <span style="color: #CC0000;">767</span><br />
Kokonaisluku LONG &nbsp; &nbsp; &nbsp; -<span style="color: #CC0000;">2</span> <span style="color: #CC0000;">147</span> <span style="color: #CC0000;">483</span> <span style="color: #CC0000;">647</span> <span style="color: #CC0000;">2</span> <span style="color: #CC0000;">147</span> <span style="color: #CC0000;">483</span> <span style="color: #CC0000;">647</span><br />
Merkkijono &nbsp; <span style="color: #000066; font-weight: bold;">STRING</span> &nbsp; &nbsp; <span style="color: #CC0000;">32</span> <span style="color: #CC0000;">767</span> merkkiä<br />
Liukuluku &nbsp; &nbsp;DOUBLE</div></td></tr></tbody></table></div>
</pre>
<pre>
<div class="codecolorer-container blitzbasic default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="blitzbasic codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">DIM</span> ika AS INTEGER 'Määrittelee <span style="color: #009900;">&quot;ika&quot;</span>-nimisen muuttujan tyypin kokonaisluvuksi<br />
<span style="color: #0000ff;">DIM</span> nimi AS <span style="color: #000066; font-weight: bold;">STRING</span> 'Määritellään muuttuja, joka on merkkijono<br />
<span style="color: #0000ff;">DIM</span> pituus AS DOUBLE 'Määritellään muuttuja <span style="color: #009900;">&quot;pituus&quot;</span>, joka on liukulukumuuttuja<br />
<br />
ika = <span style="color: #CC0000;">7</span> 'asetetaan sen arvoksi <span style="color: #CC0000;">7</span><br />
nimi = <span style="color: #009900;">&quot;Erkki&quot;</span><br />
pituus = <span style="color: #CC0000;">187.3</span><br />
<span style="color: #0000ff;">PRINT</span> <span style="color: #009900;">&quot;Nimi: &quot;</span>, nimi 'Tulostetaan teksti <span style="color: #009900;">&quot;Nimi: &quot;</span> ja sen perään nimi<br />
<span style="color: #0000ff;">PRINT</span> <span style="color: #009900;">&quot;Ika: &quot;</span>, ika 'Tulostetaan <span style="color: #009900;">&quot;Ika: &quot;</span> ja ika:n arvo<br />
<span style="color: #0000ff;">PRINT</span> <span style="color: #009900;">&quot;Pituus: &quot;</span>, pituus 'Ja vastaavasti pituus</div></td></tr></tbody></table></div>
</pre>
<h2>Ehtolauseet&#8230; jotain syötävää?</h2>
<p>Ehtolauseet ovat yksinkertaista kauraa. Niiden avulla voit tarkastella asioiden totuusarvoja. Yksinkertaista, eikö vain? QBasicin IF-lauseen rakenne näkyy seuraavassa.</p>
<pre>
<div class="codecolorer-container blitzbasic default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="blitzbasic codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000066; font-weight: bold;">IF</span> muuttuja1 = muuttuja2 <span style="color: #000066; font-weight: bold;">THEN</span> 'itse ehto<br />
'Jos ehtolause on tosi, menään tänne<br />
<span style="color: #000066; font-weight: bold;">ELSE</span> 'Jos ehdon totuusarvo on epätosi, siirrytään ELSE-osioon,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'jonka voi jättää pois halutessaan<br />
<br />
<span style="color: #000066; font-weight: bold;">END IF</span> 'Ilmoitetaan tulkille, että ehtolause loppuu tähän</div></td></tr></tbody></table></div>
</pre>
<p>Operaattoreilla saadaan erilaisia ehtoja.</p>
<pre>
<div class="codecolorer-container blitzbasic default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="blitzbasic codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Nimi &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Merkki &nbsp; &nbsp; Esimerkki, joka palauttaa truen<br />
---------------------------------------------------------<br />
Yhtäsuuri kuin: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #CC0000;">7</span> = <span style="color: #CC0000;">4</span>+<span style="color: #CC0000;">3</span><br />
Pienempi kuin: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #CC0000;">2</span> &lt; <span style="color: #CC0000;">7</span><br />
Suurempi kuin: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &gt; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #CC0000;">5</span> &gt; <span style="color: #CC0000;">2</span><br />
Yhtäsuuri tai suurempi kuin: &gt;= &nbsp; &nbsp; &nbsp; <span style="color: #CC0000;">3</span> &gt;= <span style="color: #CC0000;">3</span><br />
Yhtäsuuri tai pienempi kuin: &lt;= &nbsp; &nbsp; &nbsp; -<span style="color: #CC0000;">6</span> &lt;= <span style="color: #CC0000;">9</span><br />
Erisuuri kuin: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;&gt; &nbsp; &nbsp; &nbsp; <span style="color: #CC0000;">1000</span> &lt;&gt; <span style="color: #CC0000;">5</span></div></td></tr></tbody></table></div>
</pre>
<h2>Silmukat</h2>
<p>Yksinkertaisin ja alkeellisessa peliohjelmoinnissa ehkäpä yleisin silmukka on DO-silmukka, joka suorittaa annettavaa tehtävää, kunnes suoritetaan<br />
EXIT DO.</p>
<pre>
<div class="codecolorer-container blitzbasic default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="blitzbasic codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">DIM</span> x AS INTEGER 'Määritellään muuttuja x kokonaislukumuuttujaksi<br />
DO 'Silmukan alkupää<br />
&nbsp; x = x + <span style="color: #CC0000;">1</span> 'Lisätään x:ään yksi<br />
<br />
&nbsp; <span style="color: #0000ff;">PRINT</span> <span style="color: #009900;">&quot;x=&quot;</span>, x 'Printataan x:n arvo<br />
&nbsp; <span style="color: #000066; font-weight: bold;">IF</span> x &gt; <span style="color: #CC0000;">8</span> <span style="color: #000066; font-weight: bold;">THEN</span> 'Jos x on suurempi kuin <span style="color: #CC0000;">8</span>, niin...<br />
&nbsp; &nbsp; <span style="color: #0000ff;">PRINT</span> <span style="color: #009900;">&quot;Päästiinhän tänne.&quot;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">EXIT</span> DO '...päästään pois silmukasta<br />
&nbsp; <span style="color: #000066; font-weight: bold;">END IF</span> 'if-lauseen loppu<br />
LOOP 'Silmukan loppupää</div></td></tr></tbody></table></div>
</pre>
<p>Kun silmukan sisään päästään, lisätään x:ään yksi, minkä jälkeen printataan sen arvo ruudulle. Ensimmäisillä kerroilla ehto x&lt;8 ei ole tosi, joten mennään ehtolauseen ohi. Loopin lopussa hypätään takaisin alkuun. Silmukasta ei päästä pois ennen kuin x:n arvo on noussut kahdeksaan tai yli, jolloin kirjoitetaan ruudulle turhaa tekstiä ja suoritetaan EXIT DO. Tämä siis lopettaa silmukan ja näin hypätään silmukasta pois.</p>
<p>FOR-silmukalla voidaan toistaa jotain operaatiota n kertaa, missä n kerrotaan määrittelyssä. Kyseisen silmukan rakenne on hyvin yksinkertainen: FOR [juoksumuuttujan alustus] TO [loppuarvo] STEP [hyppyväli]. Silmukkaa suoritetaan, kunnes juoksumuuttuja on yhtäsuuri kuin loppuarvo. Joka kierros juoksumuuttujaan lisätään hyppyväli. Juoksumuuttujaa ei tulisi hyvän ohjelmointityylin mukaisesti muuttaa kesken silmukkaa, koska FOR-silmukan ideana on, että silmukan alussa tiedetään, kuinka monta kertaa silmukkaa tullaan toistamaan.</p>
<pre>
<div class="codecolorer-container blitzbasic default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="blitzbasic codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">DIM</span> i AS INTEGER<br />
<span style="color: #000066; font-weight: bold;">FOR</span> i=<span style="color: #CC0000;">0</span> <span style="color: #000066; font-weight: bold;">TO</span> <span style="color: #CC0000;">10</span> <span style="color: #000066; font-weight: bold;">STEP</span> <span style="color: #CC0000;">1</span><br />
&nbsp; <span style="color: #0000ff;">PRINT</span> <span style="color: #009900;">&quot;i, juoksulukumuuttujan arvo: &quot;</span>, i<br />
<span style="color: #000066; font-weight: bold;">NEXT</span> i</div></td></tr></tbody></table></div>
</pre>
<h2>INPUT? Mikäs se on?</h2>
<p>Nyt olet varmasti halukas ottamaan syötteen vastaan komentorivitulkilta. Vähän vaikeasti oli ehkä sanottu, mutta käytännössä edellinen virke tarkoitti sitä, että voit pyytää käyttäjää kirjoittamaan tekstiä, jota voit myöhemmin käsitellä. Tätä varten on tehty INPUT-komento, jolle annetaan parametriksi yksi tai useampi muuttuja, joihin arvo asetetaan. Seuraavaksi voisimme kokeilla ohjelmaa, jolle syötetään varpaankynnen pituus, jonka perusteella ohjelma vastaa pituudesta riippuen.</p>
<pre>
<div class="codecolorer-container blitzbasic default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="blitzbasic codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">DIM</span> pituus AS DOUBLE 'Määritellään pituus-muuttuja<br />
<span style="color: #0000ff;">INPUT</span> <span style="color: #009900;">&quot;Peukalovarpaankyntesi pituus? &quot;</span>, pituus 'Käyttäjä syöttää luvun<br />
<span style="color: #000066; font-weight: bold;">IF</span> pituus &lt; <span style="color: #CC0000;">1.5</span> <span style="color: #000066; font-weight: bold;">THEN</span> 'Jos syötetty pituus on pienempi kuin <span style="color: #CC0000;">1.5</span><br />
&nbsp; <span style="color: #0000ff;">PRINT</span> <span style="color: #009900;">&quot;Sinulla on melkoisen lyhyet kynnet!&quot;</span><br />
<span style="color: #000066; font-weight: bold;">END IF</span><br />
<span style="color: #000066; font-weight: bold;">IF</span> pituus &gt; <span style="color: #CC0000;">1.5</span> <span style="color: #000066; font-weight: bold;">AND</span> pituus &lt; <span style="color: #CC0000;">3</span> <span style="color: #000066; font-weight: bold;">THEN</span> 'Jos pituus on suurempi kuin <span style="color: #CC0000;">1.5</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'ja pienempi kuin <span style="color: #CC0000;">3</span>, niin<br />
&nbsp; <span style="color: #0000ff;">PRINT</span> <span style="color: #009900;">&quot;Kyntesi ovat normaalipituiset.&quot;</span><br />
<span style="color: #000066; font-weight: bold;">END IF</span><br />
<span style="color: #000066; font-weight: bold;">IF</span> pituus &gt; <span style="color: #CC0000;">3</span> <span style="color: #000066; font-weight: bold;">THEN</span><br />
&nbsp; <span style="color: #0000ff;">PRINT</span> <span style="color: #009900;">&quot;Eikö kyntesi jo lohkeile?&quot;</span><br />
<span style="color: #000066; font-weight: bold;">END IF</span></div></td></tr></tbody></table></div>
</pre>
<hr />Tässä oli minun ensimmäisen tutoriaalini ensimmäinen osa, jolle toivottavasti seuraa jatkoa myöhemmin. Kysymyksiä voi lähettää osoitteeseen tomppuy@gmail.com tai nopeammin saanet asiasi selville yksinkertaisesti googlettamalla. Voit myös aloittaa keskustelun allaolevasta linkistä.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.suomipelit.com/2006/11/09/qbasicin-perusteet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fysiikkaa peliohjelmoijille &#8211; Osa 2: Kiihtyvyys ja voimat</title>
		<link>http://www.suomipelit.com/2005/01/15/fysiikkaa-peliohjelmoijille-osa-2-kiihtyvyys-ja-voimat/</link>
		<comments>http://www.suomipelit.com/2005/01/15/fysiikkaa-peliohjelmoijille-osa-2-kiihtyvyys-ja-voimat/#comments</comments>
		<pubDate>Sat, 15 Jan 2005 10:00:09 +0000</pubDate>
		<dc:creator>Suomipelit.com</dc:creator>
				<category><![CDATA[Artikkelit]]></category>
		<category><![CDATA[Käytännön oppaat]]></category>
		<category><![CDATA[c/cpp]]></category>
		<category><![CDATA[fysiikka]]></category>
		<category><![CDATA[liike]]></category>
		<category><![CDATA[ohjelmointi]]></category>
		<category><![CDATA[peliohjelmointi]]></category>

		<guid isPermaLink="false">http://www.suomipelit.com/?p=1238</guid>
		<description><![CDATA[Realistinen fysiikan mallinnus on noussut realistisen grafiikan rinnalle tärkeäksi elementiksi peleissä. Tämä artikkelisarja esittelee fysiikan mallinnuksen perusteet 2D- ja 3D-avaruudessa. Keskitymme erityisesti kiinteiden kappaleiden mekaniikkaan. Tämä on artikkelisarjan toinen osa.]]></description>
			<content:encoded><![CDATA[<p>Realistinen fysiikan mallinnus on noussut realistisen grafiikan rinnalle tärkeäksi elementiksi peleissä. Tämä artikkelisarja esittelee fysiikan mallinnuksen perusteet 2D- ja 3D-avaruudessa. Keskitymme erityisesti kiinteiden kappaleiden mekaniikkaan. Tämä on artikkelisarjan toinen osa.</p>
<h2>1. Tasaisesti muuttuva liike</h2>
<p>Artikkelisarjan edellisessä osassa oletimme, että liike oli tasaista. Tämä ei kuitenkaan päde tositilanteessa vaan myös nopeus muuttuu ajan suhteen. Eli nopeudellakin on derivaatta ajan suhteen. Nopeuden aikaderivaattaa kutsutaan kiihtyvyydeksi (englanniksi acceleration) ja sitä merkitään symbolilla a. Lausetta ”nopeuden derivaatta on kiihtyvyys” voidaan näin ollen merkitä v&#8217;(t)=a. Koska nopeus on sijainnin derivaatta ja kiihtyvyys nopeuden, on kiihtyvyys sijainnin toinen derivaatta. Tätä merkitään: s&#8221;(t)=a. Kiihtyvyyden yksikkö on metriä sekunti toiseen (lyhenne m/s^2). Kiihtyvyys on nopeuden tapaan vektori, jonka suunta esittää kiihtyvyyden suuntaa ja pituus suuruutta.</p>
<p>Vastaavasti kulmanopeuden derivaattaa kutsutaan kulmakiihtyvyydeksi (englanniksi angular acceleration). Kulmakiihtyvyyden symboli on α ja yksikkö radiaania sekunti toiseen (lyhenne rad/s^2). Jos se nyt sattuu jota kuta kiinnostamaan, niin vastaavat kaavat kulmakiihtyvyydelle olisivat ω’(t)=α ja φ’’(t)=α. 2D-avaruudessa kulmakiihtyvyys on paljas luku ja 3D-avaruudessa kolme komponenttinen vektori. Siis samoin kuin kulmanopeuden tapauksessa. Jos lisäisimme kiihtyvyyden ja kulmakiihtyvyyden rakenteisiin niistä tulisi seuraavan näköiset.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">int</span> shape<span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Muoto. 0=ympyrä ja 1=suorakulmio</span><br />
&nbsp; <span style="color: #993333;">float</span> radius<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// ”Säde” metreinä.</span><br />
&nbsp; <span style="color: #993333;">float</span> position<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Sijainti metreinä</span><br />
&nbsp; <span style="color: #993333;">float</span> orientation<span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Asento radiaaneina</span><br />
&nbsp; <span style="color: #993333;">float</span> velocity<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Nopeus metreinä sekunnissa</span><br />
&nbsp; <span style="color: #993333;">float</span> acceleration<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Kiihtyvyys</span><br />
&nbsp; <span style="color: #993333;">float</span> angularAcceleration<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Kulmakiihtyvyys</span><br />
<span style="color: #009900;">&#125;</span> RIGIDBODY2D<span style="color: #339933;">;</span><br />
<br />
<span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">int</span> shape<span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Muoto. 0=pallo ja 1=laatikko</span><br />
&nbsp; <span style="color: #993333;">float</span> radius<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// ”Säde” metreinä.</span><br />
&nbsp; <span style="color: #993333;">float</span> position<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Sijainti metreinä</span><br />
&nbsp; <span style="color: #993333;">float</span> orientation<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Asento kvaterniona</span><br />
&nbsp; <span style="color: #993333;">float</span> velocity<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Nopeus metreinä sekunnissa</span><br />
&nbsp; <span style="color: #993333;">float</span> acceleration<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Kiihtyvyys</span><br />
&nbsp; <span style="color: #993333;">float</span> angularAcceleration<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Kulmakiihtyvyys</span><br />
<span style="color: #009900;">&#125;</span> RIGIDBODY3D<span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
</pre>
<p>Oletetaan aluksi, että kiihtyvyys on vakio ja muutetaan artikkelisarjan edellisessä osassa tehtyä simulointifunktiota ottamaan kiihtyvyys huomioon. Koska tällä kertaa myös nopeus ja kulmanopeus muuttuvat, pitää nekin käyttää integraattorin läpi eli kopioimme ne alkuarvotaulukkoon muiden perään.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">void</span> simulate2D<span style="color: #009900;">&#40;</span>RIGIDBODY2D <span style="color: #339933;">*</span>b<span style="color: #339933;">,</span> <span style="color: #993333;">float</span> t<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">static</span> <span style="color: #993333;">float</span> initialValue<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #993333;">static</span> <span style="color: #993333;">float</span> output<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #993333;">static</span> <span style="color: #993333;">float</span> temp<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #339933;">*</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Kopioi nykyinen sijainti, asento,</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// nopeus ja kulmanopeus alkuarvoksi.</span><br />
&nbsp; initialValue<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>position<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; initialValue<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>position<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; initialValue<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>orientation<span style="color: #339933;">;</span><br />
&nbsp; initialValue<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>velocity<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; initialValue<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>velocity<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; initialValue<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>angularVelocity<span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Integroi aika-askeleen verran. Koska ”derive” tarvitsee</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// kappaleen kiihtyvyyden, Annamme osoittimen kappaleeseen</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// ”userData” -parametrina.</span><br />
&nbsp; integrate<span style="color: #009900;">&#40;</span>output<span style="color: #339933;">,</span> initialValue<span style="color: #339933;">,</span> <span style="color: #0000dd;">6</span><span style="color: #339933;">,</span> t<span style="color: #339933;">,</span> derive<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;temp<span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>b<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Kopioi tulos uudeksi sijainniksi, asennoksi,</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// nopeudeksi ja kulmanopeudeksi</span><br />
&nbsp; b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>position<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>output<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>position<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>output<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>orientation<span style="color: #339933;">=</span>output<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>velocity<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>output<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>velocity<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>output<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>angularVelocity<span style="color: #339933;">=</span>output<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Entäpä “derive” -funktio? Ei kummempia. Toteamme vain sen tosiasian, että nopeuden derivaatta on kiihtyvyys ja kulmanopeuden kulmakiihtyvyys. On kuitenkin huomioitava, että nopeuksia ei voida lukea kappaleesta ”userData” -parametrin kautta, vaan ne pitää lukea funktion saaman ”value” -parametrin kautta. Tämä tietenkin siksi, että jos integraattori kutsuu ”derive” -funktiota jollain muulla x:n arvolla kuin 0, ei nopeus muuttumisen takia enää ole sama kuin alkutilanteessa. Onneksi integraattori kuitenkin toimittaa uudet arvot value parametrin kautta, joten voimme lukea nopeuden sieltä.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">void</span> derive<span style="color: #009900;">&#40;</span> <span style="color: #993333;">float</span> <span style="color: #339933;">*</span>result<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333;">const</span> <span style="color: #993333;">float</span> <span style="color: #339933;">*</span>value<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333;">float</span> x<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>userData <span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Osoitin kappaleeseen saatiin “userData”:n kautta</span><br />
&nbsp; RIGIDBODY2D <span style="color: #339933;">*</span>b<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span>RIGIDBODY2D <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>userData<span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Sijainnin derivaatta on nopeus.</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>value<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>value<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Asennon derivaatta on kulmanopeus</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>value<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Nopeuden derivaatta on kiihtyvyys</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>acceleration<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>acceleration<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Kulmanopeuden derivaatta on kulmakiihtyvyys</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>angularAcceleration<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Tässä olikin kaikki tarvittava tasaisesti muuttuvasta liikkeestä. Todellisuudessa kiihtyvyyskään ei ole vakio, joten jatkakaamme.</p>
<h2>2. Voima</h2>
<p>Myös kiihtyvyys voi muuttua ajan suhteen. Emme kuitenkaan enää jatka derivointiketjua vaan etsimme syytä kiihtyvyydelle. Kiihtyvyyden voi aiheuttaa voima (englanniksi force) ja ainoastaan voima. Voiman symboli on F ja yksikkö on newton (lyhenne n). Voima on vektori, jonka suunta ilmaisee voiman suunnan ja pituus suuruuden. Kun voima vaikuttaa kappaleeseen, antaa se kappaleelle kiihtyvyyttä. Kappale ei kuitenkaan halua muuttaa liiketilaansa suosiolla vaan pistää hanttiin. Se kuinka hyvin kappale vastustaa voimaa riippuu kappaleesta. Tätä ominaisuutta vastustaa liiketilan muutosta kutsutaan hitausmassaksi tai lyhemmin vain massaksi (englanniksi mass). Massan yksikkö on kilogramma (lyhenne kg) ja symboli m. Massan olemassa oloa ei tiede vielä tänäkään päivänä osaa kunnolla selittää, mutta meidän ei tarvitse osata selittää sitä, vaan ainoastaan huomioida sen vaikutukset.</p>
<p>Voiman kappaleelle antama kiihtyvyys lasketaan seuraavalla &lt;b&gt;Newtonin liikeyhtälö&lt;/b&gt;ksi kutsutulla kaavalla:</p>
<p>a=F/m</p>
<p>Eli kiihtyvyys on voima jaettuna massalla. Kaavasta näkee myös sen, että ei ole olemassa kappaletta jonka massa on nolla, koska nollalla ei voi jakaa. Toinen huomattava asia on, että jos olisi olemassa kappale, jonka massa on ääretön, ei se koskaan saisi kiihtyvyyttä. Tällainen kappale olisi varsin kätevä, jos haluaisimme kappaleen johon voimat eivät vaikuta. Koska a=F/m=1/m*F olisi kätevämpää tallentaa massan sijasta sen käänteisluku 1/m. Tällöin massaa ei koskaan pysty asettamaan arvoon nolla ja ääretöntä massaa voisi esittää asettamalla sen käänteisluvuksi nolla. Täydennetäänpä rakenne massan käänteisluvulla. Lisäksi voimme poistaa kiihtyvyyden rakenteesta, koska se voidaan aina tarvittaessa laskea voimista ja massasta.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">int</span> shape<span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Muoto. 0=ympyrä ja 1=suorakulmio</span><br />
&nbsp; <span style="color: #993333;">float</span> radius<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// ”Säde” metreinä.</span><br />
&nbsp; <span style="color: #993333;">float</span> position<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Sijainti metreinä</span><br />
&nbsp; <span style="color: #993333;">float</span> orientation<span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Asento radiaaneina</span><br />
&nbsp; <span style="color: #993333;">float</span> velocity<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Nopeus metreinä sekunnissa</span><br />
&nbsp; <span style="color: #993333;">float</span> inverseMass<span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// 1/massa kilogrammoina</span><br />
<span style="color: #009900;">&#125;</span> RIGIDBODY2D<span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
</pre>
<p>Maailmankaikkeudessa on neljä erilaista voimaa. Ne ovat: vahva ydinvoima, heikko ydinvoima, painovoima ja sähkömagneettinen voima. Kaksi ensimmäistä vaikuttavat (nimensä mukaisesti) ainoastaan atomin ytimen sisällä, joten niitä ei tarvitse ottaa simulaatioissa huomioon. Kaksi muuta sen sijaan pitää ottaa.</p>
<h3>2.1	Painovoima</h3>
<p>Kaikki aineelliset kappaleet vetävät toisiaan puoleensa. Voimaa, jolla aine vetää ainetta puoleensa kutsutaan painovoimaksi (englanniksi gravity). Painovoiman saa aikaan kappaleen ominaisuus, jota kutsutaan gravitaatiomassaksi. Gravitaatiomassaakin kutsutaan lyhemmin vain massaksi. Sitä ovatko gravitaatiomassa ja hitausmassa sama asia ei tiedetä. Yleisesti kuitenkin uskotaan näin olevan, joten talletamme rakenteeseemme vain yhden massan.</p>
<p>Kun kahden kappaleen massat ja keskipisteiden välinen etäisyys tiedetään, voidaan niiden välinen painovoima laskea kaavalla:</p>
<p>F=G*((m1*m2)/r^2)</p>
<p>Jossa m1 ja m2 ovat kappaleiden massat, r niiden keskipisteiden välinen etäisyys ja G gravitaatiovakio, jonka arvo on noin 0,0000000000667259. Koska G on hyvin pieni luku, täytyy kappaleiden massojen olla todella suuret ennen kuin niiden välinen painovoima kasvaa merkittäväksi. Tämän takia painovoima voidaan huoletta jättää huomiotta kaikille planeettaa pienemmille kappaleille.</p>
<p>Valitettavasti suoraan jalkojemme alla sijaitsee yksi planeetta, nimittäin Maa. Koska kaikki normaalit kappaleet ovat enemmän tai vähemmän lähellä Maan pintaa ja Maa on valtavan suuri verrattuna kaikkiin normaaleihin kappaleisiin, voidaan olettaa, että Maan painovoima antaa kaikille kappaleille suurin piirtein samanlaisen kiihtyvyyden. Tätä kiihtyvyyttä kutsutaan putoamiskiihtyvyydeksi ja merkitään yleensä symbolilla g. Putoamiskiihtyvyyden arvo on noin 9.81 (alaspäin). Ei siis tarvitse laskea maan aiheuttamaa painovoimaa ja siitä kiihtyvyyttä, vaan voidaan olettaa kiihtyvyydeksi 9.81 riippumatta kappaleesta. Tämä helpottaa laskelmia hieman.</p>
<h3>2.2	Sähkömagneettinen voima</h3>
<p>Jos kappaleilla on sähkövaraus niiden välillä vallitsee sähkömagneettinen voima.</p>
<p>Sähkömagneettinen voima lasketaan kaavalla:</p>
<p>F=k*(Q1*Q2)/r^2</p>
<p>Tässä Q1 ja Q2 ovat kappaleiden sähkövaraukset ja k sähkömagneettivakio, jonka arvo on noin 8987550000. Sähkömagneettivakio on huomattavasti suurempi kuin gravitaatiovakio, joten sähkömagneettinen voimakin on valtavan paljon vahvempi. Sähkömagneettinen voima on kuitenkin erittäin harvinainen, sillä kappaleilla ei yleensä ole sähkövarausta.</p>
<p>Sähkövaraus on yleinen alkeishiukkasilla ja molekyyleillä. Näin ollen sähkömagneettinen voima pitää yhdessä atomeja ja molekyylejä. Se siis pitää aineen kasassa. Tämän takia sähkömagneettinen voima ilmenee muunlaisina voimina, vaikuttamalla molekyylien välisiin sidoksiin. Tällaisia voimia ovat mm. jousivoima ja kitkavoima.</p>
<h3>2.3	Jousivoima</h3>
<p>Jousi on kappale, joka voi venyä ja venytyksen jälkeen pyrkii palautumaan alkuperäiseen pituuteensa. Tällaisia kappaleita ovat mm. kuminauha ja auton iskunvaimennin. Venytettynä jousi kohdistaa kumpaankin päähänsä voiman, joka lasketaan kaavalla:</p>
<p>F=-kx</p>
<p>Jossa k on jousivakio ja x jousen pituuden ja alkuperäisen pituuden erotus. Jousivakio ei ole mikään universaali vakio vaan se riippuu jousesta. Mitä suurempi vakio, sitä hankalampi jousta on venyttää.</p>
<h3>2.4	Väliaineen vastus</h3>
<p>Jos kappale liikkuu väliaineessa, kuten ilmassa tai vedessä vaikuttaa siihen väliaineen vastus voima. Väliaineen vastukselle voidaan esittää kaksi erilaista kaavaa riippuen siitä aiheuttaako kappaleen liike väliaineeseen pyörteitä. Jos pyörteitä ei esiinny lasketaan voima kaavalla:</p>
<p>F=-k*v</p>
<p>Jos taas pyörteitä esiintyy, lasketaan vastusvoima kaavalla:</p>
<p>F=-k*v^2</p>
<p>Kaavoissa k on jokin väliaineesta riippuva vakio. Itse asiassa tämä vakio riippuu myös kappaleen muodosta, mutta jätettäköön se huomiotta, joten voit olettaa, että k on kaikille kappaleille sama.</p>
<h3>2.5	Esimerkki</h3>
<p>Katsotaanpa millaiselta &#8220;derive&#8221; -funktio näyttäisi, jos kappaleeseen vaikuttaisi koko ajan yhden newtonin voima oikealle.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">void</span> derive<span style="color: #009900;">&#40;</span> <span style="color: #993333;">float</span> <span style="color: #339933;">*</span>result<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333;">const</span> <span style="color: #993333;">float</span> <span style="color: #339933;">*</span>value<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333;">float</span> x<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>userData <span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Yhden newtonin voima oikealle</span><br />
&nbsp; <span style="color: #993333;">const</span> <span style="color: #993333;">float</span> F<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Osoitin kappaleeseen saatiin “userData”:n kautta</span><br />
&nbsp; RIGIDBODY2D <span style="color: #339933;">*</span>b<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span>RIGIDBODY2D <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>userData<span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Sijainnin derivaatta on nopeus.</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>value<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>value<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Asennon derivaatta on kulmanopeus</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>value<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Nopeuden derivaatta on kiihtyvyys,</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Joka lasketaan kaavasta F/m eli m^-1*F</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>inverseMass<span style="color: #339933;">*</span>F<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>b<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>inverseMass<span style="color: #339933;">*</span>F<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Jätetään kulmanopeus toistaiseksi rauhaan</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span><br />
&nbsp;<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Jos kappaleeseen vaikuttaa yhtä aikaa useita voimia, voidaan nämä voimat laskea raa&#8217;asti yhteen ja käyttää kokonaisvoimana saatua tulosta.</p>
<h2>3. Vääntömomentti</h2>
<p>Tähän mennessä käsitellyt asiat koskivat vain kappaleen etenemisliikettä, ei sen pyörimisliikettä. Voima sai siis aikaan kiihtyvyyden. Mikähän saa aikaan kulmakiihtyvyyden? Kulmakiihtyvyyden saa aikaan vääntömomentti (englanniksi torque). Vääntömomentin yksikkö on newtonmetri (lyhenne Nm) ja symboli M. Etenevän liikkeen tavoin kappale vastustaa myös pyörimisliikkeen muutosta. Tätä ominaisuutta vastustaa pyörimisliiketilan muutosta kutsutaan hitausmomentiksi (englanniksi moment of inertia). Hitausmomentin symboli on J ja yksikkö kilogrammaa neliömetrille (lyhenne kgm^2). Kappaleen hitausmomentti riippuu kahdesta asiasta: kappaleen massasta ja muodosta. Itse asiassa hitausmomentti on ensimmäinen asia (piirtämisen lisäksi), johon varsinaisesti tarvitsemme kappaleen muotoa.</p>
<p>Kaikki kappaleet koostuvat atomeista, jotka ovat klassisessa fysiikassa aineen pienimpiä mahdollisia osasia. Atomin hitausmomentti lasketaan kaavalla:</p>
<p>atomin_hitausmomentti=atomin_massa*atomin_etäisyys_kappaleen_keskipisteestä ^ 2</p>
<p>Kappaleen hitausmomentti saadaan laskettua laskemalla yhteen sen kaikkien atomien hitausmomentit. Ongelmaksi kuitenkin muodostuu se, että atomeita on liian paljon käsiteltäväksi ja emme edes voi mitenkään tietää niiden kaikkien sijaintia. Onneksi kuitenkin kappaleille, jotka ovat säännöllisenmuotoisia ja joiden atomit ovat jakautuneet tasaisesti koko kappaleen alalle, voidaan muodostaa kaavat hitausmomentin laskemiseksi. Koska tässä artikkelisarjassa käytimme vain laatikoita ja palloja riittää, että annan valmiit kaavat näille kahdelle kappaleelle. En ota kantaa siihen mistä nämä kaavat tulevat.</p>
<p>2D-avaruudessa hitausmomentti paljas luku. Samoin kuin asento ja kulmanopeuskin eli aloitetaan 2D-tapauksesta.</p>
<p>Ympyrän, jonka massa on m ja säde r hitausmomentti on:</p>
<p>1/2*m*r^2.</p>
<p>Suorakulmion, jonka massa on m ja sivujen pituudet a ja b hitausmomentti on:</p>
<p>1/12*m*(a^2+b^2).</p>
<p>2D-avaruudessa hitausmomentti oli yksi paljas luku, koska pyöriminen tapahtuu aina saman &#8220;akselin&#8221; ympäri. 3D-avaruudessa pyörimisakseli voi vaihdella mielivaltaisesti, joten hitausmomenttikin muuttuu huomattavasti monimutkaisemmaksi. Kohta puolin sinun pitäisi viimeistään huomata kuinka valtavan paljon helpompaa kaikki on 2D-avaruudessa verrattuna 3D-avaruuteen.</p>
<p>3D-avaruudessa hitausmomentti on 3&#215;3 matriisi. Matriisi tarkoittaa taulukkoa, mikäli et sitä vielä tiennyt. Eli 3&#215;3 matriisi on taulukko, jossa on kolme riviä ja kolme saraketta. Matriisi voidaan helpointen tallentaa tietokoneella käyttämällä 9 komponenttista yksiulotteista taulukkoa, johon matriisin alkiot tallennetaan sarakkeittain. Seuraavassa on kaavat tämän matriisin muodostamiseksi pallolle ja laatikolle.</p>
<p>Pallon, jonka massa on m ja säde r hitausmomentti olisi:</p>
<p><a href="http://www.suomipelit.com/tiedostot/2005/01/inertiaPallo.gif" rel="lightbox[1238]"><img class="aligncenter size-full wp-image-1271" title="inertiaPallo" src="http://www.suomipelit.com/tiedostot/2005/01/inertiaPallo.gif" alt="" width="163" height="116" /></a></p>
<p>Laatikon, jonka massa on m ja sivujen pituudet a, b ja c hitausmomentti olisi:</p>
<p><a href="http://www.suomipelit.com/tiedostot/2005/01/inertiaLaatikko.gif" rel="lightbox[1238]"><img class="aligncenter size-full wp-image-1270" title="inertiaLaatikko" src="http://www.suomipelit.com/tiedostot/2005/01/inertiaLaatikko.gif" alt="" width="318" height="122" /></a></p>
<p>Tämä ei kuitenkaan vielä riitä! 3D-avaruudessa hitausmomentti muuttuu sitä mukaa kun kappale pyörii. On siis otettava asento huomioon. Hitausmomentista J voidaan laskea asentokvaternion φ avulla lopullinen asennon huomioon ottava hitausmomentti J2 kaavalla:</p>
<p>J2 = matriisiksi(φ) * J * matriisiksi(φ)^T</p>
<p>Kvaternio, jonka komponentit ovat w, x, y ja z muutetaan matriisiksi kaavalla:</p>
<p><a href="http://www.suomipelit.com/tiedostot/2005/01/kvaternioMatriisi.gif" rel="lightbox[1238]"><img class="aligncenter size-full wp-image-1272" title="kvaternioMatriisi" src="http://www.suomipelit.com/tiedostot/2005/01/kvaternioMatriisi.gif" alt="" width="332" height="73" /></a></p>
<p>Ja sama koodina:</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">void</span> generateQuaternionMatrix<span style="color: #009900;">&#40;</span><span style="color: #993333;">float</span> m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">float</span> q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">float</span> xx<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #993333;">float</span> xy<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #993333;">float</span> xz<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #993333;">float</span> xw<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #993333;">float</span> yy<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #993333;">float</span> yz<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #993333;">float</span> yw<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #993333;">float</span> zz<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #993333;">float</span> zw<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span> <span style="color: #339933;">-</span> <span style="color: #0000dd;">2</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span> yy <span style="color: #339933;">+</span> zz <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> &nbsp; &nbsp; <span style="color: #0000dd;">2</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span> xy <span style="color: #339933;">+</span> zw <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> &nbsp; &nbsp; <span style="color: #0000dd;">2</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span> xz <span style="color: #339933;">-</span> yw <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> &nbsp; &nbsp; <span style="color: #0000dd;">2</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span> xy <span style="color: #339933;">-</span> zw <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span> <span style="color: #339933;">-</span> <span style="color: #0000dd;">2</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span> xx <span style="color: #339933;">+</span> zz <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> &nbsp; &nbsp; <span style="color: #0000dd;">2</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span> yz <span style="color: #339933;">+</span> xw <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> &nbsp; &nbsp; <span style="color: #0000dd;">2</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span> xz <span style="color: #339933;">+</span> yw <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> &nbsp; &nbsp; <span style="color: #0000dd;">2</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span> yz <span style="color: #339933;">-</span> xw <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span> <span style="color: #339933;">-</span> <span style="color: #0000dd;">2</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span> xx <span style="color: #339933;">+</span> yy <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Merkintä &#8220;^T&#8221; taas tarkoittaa matriisin transpoosia, joka lasketaan pyöräyttämällä matriisi vinottaisakselinsa ympäri. Seuraavassa transponointi koodina.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">void</span> transposeMatrix<span style="color: #009900;">&#40;</span><span style="color: #993333;">float</span> m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">float</span> temp<span style="color: #339933;">;</span><br />
&nbsp; DWORD i<span style="color: #339933;">,</span> j<span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><br />
&nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>j<span style="color: #339933;">=</span>i<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span> j<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #0000dd;">3</span><span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; temp<span style="color: #339933;">=</span>m<span style="color: #009900;">&#91;</span>j<span style="color: #339933;">+</span><span style="color: #0000dd;">3</span><span style="color: #339933;">*</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; m<span style="color: #009900;">&#91;</span>j<span style="color: #339933;">+</span><span style="color: #0000dd;">3</span><span style="color: #339933;">*</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #339933;">*</span>j<span style="color: #339933;">+</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #339933;">*</span>j<span style="color: #339933;">+</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>temp<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Nyt on jäljellä enää matriisien kertolaskua. Kaksi 3&#215;3 matriisia voidaan kertoa keskenään seuraavan kaavan mukaisesti.</p>
<p><a href="http://www.suomipelit.com/tiedostot/2005/01/3x3kertolasku.gif" rel="lightbox[1238]"><img class="aligncenter size-full wp-image-1267" title="3x3kertolasku" src="http://www.suomipelit.com/tiedostot/2005/01/3x3kertolasku.gif" alt="" width="448" height="69" /></a></p>
<p><a rel="lightbox[artikkelikuva_66]" href="http://www.suomipelit.com/kaikki/images/artikkelit/66/3x3kertolasku.gif"></a></p>
<p>Ideana oli siis kertoa rivit ja sarakkeet keskenään ja summata tulokset. Tässä sama koodina:</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">void</span> glmMultMatrix3f<span style="color: #009900;">&#40;</span><span style="color: #993333;">float</span> result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">float</span> m1<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">float</span> m2<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">float</span> sum<span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #993333;">int</span> x<span style="color: #339933;">,</span> y<span style="color: #339933;">,</span> i<span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>x<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> x<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #0000dd;">3</span><span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><br />
&nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>y<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> y<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #0000dd;">3</span><span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; sum<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #0000dd;">3</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> sum<span style="color: #339933;">+=</span>m1<span style="color: #009900;">&#91;</span>y<span style="color: #339933;">+</span><span style="color: #0000dd;">3</span><span style="color: #339933;">*</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m2<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #339933;">*</span>x<span style="color: #339933;">+</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; result<span style="color: #009900;">&#91;</span>y<span style="color: #339933;">+</span><span style="color: #0000dd;">3</span><span style="color: #339933;">*</span>x<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>sum<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Huh huh! Olipa monimutkaista. Aina kun tarvitsemme kappaleen hitausmomenttia muutamme kappaleen asennon matriisiksi ja laskemme asento*hitausmomentti*asennon_transpoosi, jolloin saamme oikean hitausmomentin.</p>
<p>Samoin kuin massankin tapauksessa, ei ole olemassa kappaletta, jonka hitausmomentti on nolla ja kappale, jonka hitausmomentti on ääretön, on immuuni vääntömomentille, joten tallennetaan hitausmomentin sijasta sen käänteisluku. 2D-avaruudessa tämä on helppoa, mutta 3D-avaruudessa pitää ottaa käänteismatriisi. 3&#215;3 matriisin käänteismatriisi lasketaan seuraavalla kaavalla:</p>
<p><a href="http://www.suomipelit.com/tiedostot/2005/01/3x3kaanteisluku.gif" rel="lightbox[1238]"><img class="aligncenter size-full wp-image-1266" title="3x3kaanteisluku" src="http://www.suomipelit.com/tiedostot/2005/01/3x3kaanteisluku.gif" alt="" width="336" height="138" /></a></p>
<p><a rel="lightbox[artikkelikuva_66]" href="http://www.suomipelit.com/kaikki/images/artikkelit/66/3x3kaanteisluku.gif"></a></p>
<p>Kaavassa |M| tarkoittaa matriisin determinanttia, joka taas puolestaan lasketaan kaavalla</p>
<p><a href="http://www.suomipelit.com/tiedostot/2005/01/3x3determinantti.gif" rel="lightbox[1238]"><img class="aligncenter size-full wp-image-1265" title="3x3determinantti" src="http://www.suomipelit.com/tiedostot/2005/01/3x3determinantti.gif" alt="" width="299" height="72" /></a></p>
<p>Seuraavassa samat koodina:</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">float</span> determinant<span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">float</span> m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #b1b100;">return</span><br />
&nbsp; &nbsp; <span style="color: #339933;">-</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp;m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp;m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><br />
&nbsp; &nbsp; &nbsp;m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><br />
&nbsp; &nbsp; &nbsp;m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp;m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #993333;">void</span> generateInverseMatrix<span style="color: #009900;">&#40;</span><span style="color: #993333;">float</span> i<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">float</span> m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">float</span> x<span style="color: #339933;">=</span>determinant<span style="color: #009900;">&#40;</span>m<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>x<span style="color: #339933;">==</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; i<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span>x<span style="color: #339933;">;</span><br />
&nbsp; i<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span> m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span>x<span style="color: #339933;">;</span><br />
&nbsp; i<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span>x<span style="color: #339933;">;</span><br />
&nbsp; i<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span> m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span>x<span style="color: #339933;">;</span><br />
&nbsp; i<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span>x<span style="color: #339933;">;</span><br />
&nbsp; i<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span> m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span>x<span style="color: #339933;">;</span><br />
&nbsp; i<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span>x<span style="color: #339933;">;</span><br />
&nbsp; i<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span> m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span>x<span style="color: #339933;">;</span><br />
&nbsp; i<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span>x<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Täydennetään nyt rakenteet hitausmomentilla. 3&#215;3 matriisi on tallennetaan 9 alkioisena taulukkona, johon matriisi tallennetaan sarakkeittain.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">int</span> shape<span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Muoto. 0=ympyrä ja 1=suorakulmio</span><br />
&nbsp; <span style="color: #993333;">float</span> radius<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// ”Säde” metreinä.</span><br />
&nbsp; <span style="color: #993333;">float</span> position<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Sijainti metreinä</span><br />
&nbsp; <span style="color: #993333;">float</span> orientation<span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Asento radiaaneina</span><br />
&nbsp; <span style="color: #993333;">float</span> velocity<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Nopeus metreinä sekunnissa</span><br />
&nbsp; <span style="color: #993333;">float</span> inverseMass<span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// 1/massa kilogrammoina</span><br />
&nbsp; <span style="color: #993333;">float</span> inverseMomentOfInertia<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 1/hitausmomentti</span><br />
<span style="color: #009900;">&#125;</span> RIGIDBODY2D<span style="color: #339933;">;</span><br />
<br />
<span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">int</span> shape<span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Muoto. 0=pallo ja 1=laatikko</span><br />
&nbsp; <span style="color: #993333;">float</span> radius<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// ”Säde” metreinä.</span><br />
&nbsp; <span style="color: #993333;">float</span> position<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Sijainti metreinä</span><br />
&nbsp; <span style="color: #993333;">float</span> orientation<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Asento kvaterniona</span><br />
&nbsp; <span style="color: #993333;">float</span> velocity<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Nopeus metreinä sekunnissa</span><br />
&nbsp; <span style="color: #993333;">float</span> inverseMass<span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// 1/massa kilogrammoina</span><br />
&nbsp; <span style="color: #993333;">float</span> inverseMomentOfInertia<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 1/hitausmomentti</span><br />
<span style="color: #009900;">&#125;</span> RIGIDBODY3D<span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
</pre>
<p>Kulmakiihtyvyys lasketaan vääntömomentista ja hitausmomentista kaavalla:</p>
<p>α=M/J</p>
<p>Eli kulmakiihtyvyys on vääntömomentti jaettuna hitausmomentilla. Huomaat varmaan yhtäläisyyden kaavaan a=F/m. Sama kaava pätee niin 2D- kuin 3D-avaruudessakin. 2D-avaruudssa kaikki olivat paljaita lukuja, joten laskeminen ei tuottane ongelmia. 3D-avaruudessa α ja M ovat kolme komponenttisia vektoreita ja J 3&#215;3 matriisi, joten kaavan laskeminen vaatinee hieman selvitystä. Koska α=M/J=J^-1*M ja meillä sattui sopivasti olemaan J^-1 valmiina, tarvitsee vain kertoa 3&#215;3 matriisilla 3 komponenttinen vektori. Tämä tehdään kaavalla:</p>
<p><a href="http://www.suomipelit.com/tiedostot/2005/01/matvekkerto.gif" rel="lightbox[1238]"><img class="aligncenter size-full wp-image-1273" title="matvekkerto" src="http://www.suomipelit.com/tiedostot/2005/01/matvekkerto.gif" alt="" width="215" height="69" /></a></p>
<p><a rel="lightbox[artikkelikuva_66]" href="http://www.suomipelit.com/kaikki/images/artikkelit/66/matvekkerto.gif"></a></p>
<p>Vielä sama koodina:</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">void</span> multMatrixWithVector<span style="color: #009900;">&#40;</span><span style="color: #993333;">float</span> result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">float</span> m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">float</span> v<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>v<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>v<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>v<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>v<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>v<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>v<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; result<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>v<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>v<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>v<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Maailmassa oli siis 4 perusvoimaa, joiden ilmentymiä kaikki voimat olivat. Onkohan maailmassa sitten 4 perusvääntömomenttiakin? Kenties painovääntömomentti ja sähkömagneettinen vääntömomentti? Ei ole. Vääntömomentti nimittäin johtuu aina voimasta. Voima aiheuttaa vääntömomentin, jos voima ei kohdistu kappaleen keskipisteeseen tai tasaisesti kappaleen kaikkiin pisteisiin. Voimista painovoiman, sähkömagneettisen voiman ja väliaineen vastuksen voidaan katsoa vaikuttavan kappaleen keskipisteeseen (tai tasaisesti sen kaikkiin pisteisiin). Sen sijaan jousivoima vaikuttaa siihen pisteeseen, jossa jousi on kiinni. Jos voima kohdistuu pisteeseen p ja kappaleen keskipiste sijaitsee pisteessä x, lasketaan voiman aiheuttama vääntömomentti kaavasta:</p>
<p><a href="http://www.suomipelit.com/tiedostot/2005/01/momenttivoimasta.jpg" rel="lightbox[1238]"><img class="aligncenter size-full wp-image-1274" title="momenttivoimasta" src="http://www.suomipelit.com/tiedostot/2005/01/momenttivoimasta.jpg" alt="" width="157" height="27" /></a></p>
<p><a rel="lightbox[artikkelikuva_66]" href="http://www.suomipelit.com/kaikki/images/artikkelit/66/momenttivoimasta.jpg"></a><br />
Koska 2D-tapauksessa vektorit olivat kaksikomponenttisia ja kahden vektorin ristitulon voi laskea vain kolme komponenttisilla vektoreilla, pitää kaksi komponenttisista vektoreista tehdä väkisin kolme komponenttisia. Tämä tehdään lisäämällä niihin yksi ylimääräinen komponentti, jonka arvoksi laitetaan nolla. Ristitulon laskemisen jälkeen vastaus saadaan tulosvektorin kolmannesta komponentista, kahden muun ollessa nolla.</p>
<p>Jos voimia on useita, lasketaan vääntömomentti jokaiselle voimalle erikseen ja sitten vääntömomentit lasketaan yhteen.</p>
<h2>4. Vakausongelmat ja vaimennus</h2>
<p>Kuten jo artikkelisarjan ensimmäisessä osassa totesimme, numeerinen integraattori ei anna täydellisen oikeita tuloksia vaan ainoastaan likimääräisiä vastauksia. Tämän takia saattaa jostain syystä käydä niin, että integraattori antaa kokoajan aavistuksen verran liian isoja tuloksia. Tällöin virheet kasaantuvat seuraavan virheen ollen aina edellistä suurempi ja lopulta integraattori sylkee ulos äärettömyyksiä. Sanotaan, että integraattori &#8220;räjähtää&#8221;. Tällainen tilanne, jos ei kaataisi, niin ainakin sotkisi simulaation. Jos taas integraattori antaisi koko ajan aavistuksen verran liian pieniä tuloksia, ei tilanne ole läheskään niin paha. Silloin kappaleen vauhti vain pikkuhiljaa pienenee.</p>
<p>Välttääksemme räjähtämisen pitää keksiä jotain tilanteen vakauttamiseksi. Yksi tällainen keino on vaimennus (englanniksi damping). Vaimennuksen idea on pienentää integraatorin antamia tuloksia aavistuksen, jolloin ne eivät ainakaan ole liian suuria. Tämä estää räjähtämisen, ellei integraattori ammu aivan metsään, kuten Eulerin menetelmä yleensä tekee. Haittapuolena taas on, että tämän seurauksena liike koko ajan hieman pienenee lopulta pysähtyen. Tämä ei kuitenkaan yleensä haittaa sillä kappaleiden liikkeen pysähtyminen vastaa havaintojamme oikean elämän liikkeestä, joka tosiaankin aina lopulta hiljenee. Oikeassa elämässä liikkeen hiljenemisen aiheuttaa kitkavoima, josta puhumme vasta artikkelisarjan viimeisessä osassa. Varsinkin väliaineen vastusta voi käyttää helposti vaimentimena.</p>
<p>Seuraavassa muutama sääntö pitämään virheet mahdollisimman pienenä.</p>
<p>1.	Pidä aika askel pienenä. Integraattori antaa sitä tarkempia vastauksia, mitä pienemmillä x:n arvoilla sitä kutsutaan.<br />
2.	Pidä voimat pienenä. Suuret voimat aiheuttavat suuremman virheen kuin pienemmät.<br />
3.	Älä käytä Eulerin menetelmää!</p>
<p>Yksi hyvä keino simulaation vakauden tarkkailuun on energian säilymislaki. Se sanoo, että energiaa ei voi luoda tai hävittää ainoastaan muuttaa muodosta toiseen. Kappaleen energia voi olla kolmessa eri muodossa. Ne ovat liike-energia, pyörimisenergia ja potentiaalienergia.</p>
<p>Liike-energia lasketaan kaavalla: 1/2*m*v^2</p>
<p>Pyörimisenergia lasketaan kaavalla: 1/2*J*ω^2</p>
<p>Potentiaalienergiaa kappaleella on jokaista voimaa vastaan. Se riippuu siis voimista. Maan vetovoimaa vastaan oleva potentiaalienergia lasketaan kaavalla: mgh. h on kappaleen korkeus maasta. Sillä mistä pisteestä h mitataan, ei ole väliä, sillä emme tarvitse potentiaalienergian absoluuttista arvoa. Meidän täytyy ainoastaan tutkia pysyykö sen arvo muuttumattomana. Jousivoimaa vastaan potentiaalienergia lasketaan kaavalla: kx^2. Kaavassa k on jousivakio ja x jousen pituuden ja oikean pituuden erotus.</p>
<p>Kun lasket nämä kolme eri energiatyyppiä yhteen, pitäisi tuloksen olla koko ajan vakio. Jos näin ei ole antaa integraattori virheellisiä arvoja, kuten lähes aina käy.</p>
<p>Huomaa, että väliaineen vastus ja kitka muuttuvat energiaa lähinnä lämmöksi, jota ei tässä otettu huomioon, joten ne vähentävät energia. Ilman näitä voimia energian pitäisi kuitenkin säilyä.</p>
<h2>5. Esimerkkiohjelma</h2>
<p>Tällä kertaa esimerkkiohjelmamme on jo aavistuksen verran edellistä kiinnostavampi. Esimerkkiohjelma demonstroi jousivoimia, painovoimaa ja niiden vaikutusta kappaleisiin. Simulaattorissa ”katosta” roikkuu kuminauhojen varassa muutamia kappaleita.</p>
<p style="text-align: center;">2D-esimerkkihjelman voit ladata tästä: <a href="http://www.suomipelit.com/tiedostot/2005/01/f22d.zip">f22d.zip</a><br />
<a href="http://www.suomipelit.com/tiedostot/2005/01/f22d.jpg" rel="lightbox[1238]"><img class="aligncenter size-full wp-image-1268" title="2D-esimerkki screenshot" src="http://www.suomipelit.com/tiedostot/2005/01/f22d.jpg" alt="" width="260" height="273" /></a></p>
<p style="text-align: center;">3D-esimerkkiohjelman voit ladata tästä: <a href="http://www.suomipelit.com/tiedostot/2005/01/f23d.zip">f23d.zip</a><br />
<a href="http://www.suomipelit.com/tiedostot/2005/01/f23d.jpg" rel="lightbox[1238]"><img class="aligncenter size-full wp-image-1269" title="3D-esimerkki screenshot" src="http://www.suomipelit.com/tiedostot/2005/01/f23d.jpg" alt="" width="260" height="270" /></a></p>
<h2>6. Loppusanat</h2>
<p>Tässä osassa opit voimista ja niiden vaikutuksesta kappaleen liiketilaan. Seuraavassa osassa puhumme törmäyksistä.</p>
<p>Raportoithan kaikki tästä artikkelista löytämäsi virheet (niin kirjoitus-, kuin asiavirheetkin) osoitteeseen markus.ilmola@pp.inet.fi , niin korjaan ne mahdollisimman nopeasti. Myös kaikki kommentit ja kysymykset ovat tervetulleita.</p>
<p>Lopuksi linkkejä, joissa lisää luettavaa tähän mennessä opituista asioista.</p>
<p>Suomenkielinen selostus erilaisista voimista:<br />
<a href="http://butler.cc.tut.fi/~lassila/johdatus/12_dynamiikka.pdf">http://butler.cc.tut.fi/~lassila/johdatu&#8230;</a></p>
<p>David Baraffin vallan mainio artikkeli &#8220;Physically Based Modeling&#8221;. Osa 1.<br />
<a href="http://www-2.cs.cmu.edu/~baraff/sigcourse/notesd1.pdf">http://www-2.cs.cmu.edu/~baraff/sigcours&#8230;</a></p>
<p>Chriss Checkerin hieman suppeampi artikkeli. Osat 1 ja 2.<br />
<a href="http://www.d6.com/users/checker/pdfs/gdmphys1.pdf">http://www.d6.com/users/checker/pdfs/gdm&#8230;</a><br />
<a href="http://www.d6.com/users/checker/pdfs/gdmphys2.pdf">http://www.d6.com/users/checker/pdfs/gdm&#8230;</a></p>
<hr /><em>Artikkelin kirjoitti alun perin markus.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.suomipelit.com/2005/01/15/fysiikkaa-peliohjelmoijille-osa-2-kiihtyvyys-ja-voimat/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Peliohjelmoinnin peruskäsitteet &#8211; Osa 3</title>
		<link>http://www.suomipelit.com/2002/10/07/peliohjelmoinnin-peruskasitteet-osa-3/</link>
		<comments>http://www.suomipelit.com/2002/10/07/peliohjelmoinnin-peruskasitteet-osa-3/#comments</comments>
		<pubDate>Mon, 07 Oct 2002 10:00:32 +0000</pubDate>
		<dc:creator>Suomipelit.com</dc:creator>
				<category><![CDATA[Artikkelit]]></category>
		<category><![CDATA[Käytännön oppaat]]></category>
		<category><![CDATA[alkeet]]></category>
		<category><![CDATA[c/cpp]]></category>
		<category><![CDATA[ohjelmointi]]></category>

		<guid isPermaLink="false">http://www.suomipelit.com/?p=758</guid>
		<description><![CDATA[Tässä peliohjelmoinnin alkeiskurssin kolmannessa osassa käsitellään pelisilmukkaa, funktioita ja pelin toiminnan ja rakenteen jakamista loogisiin, helosti käsiteltäviin osiin. Samalla tehdään ristinollapelin pääohjelma.]]></description>
			<content:encoded><![CDATA[<p>Tässä peliohjelmoinnin alkeiskurssin kolmannessa osassa käsitellään pelisilmukkaa, funktioita ja pelin toiminnan ja rakenteen jakamista loogisiin, helosti käsiteltäviin osiin. Samalla tehdään ristinollapelin pääohjelma.</p>
<p>Noniin, jatketaanpa sitten peliohjelmoinnin perusteiden harjoittelemista. Tiedän, että sinulla jo sormet syyhyävät päästä koodia näpyttelemään ja väsäämään seuraavaa hittipeliä, mutta usko pois, aika jonka käytät näiden yksinkertaisten ja tylsienkin asioiden opettelemiseen ei ole hukkaan heitettyä.</p>
<p>Viime kerralla käytiin läpi ristinollapelissä tarvittavat tietorakenteet; päädyimme käyttämään taulukkoa pelilautana ja tietuetta pelaajan tietojen tallentamiseen. Nyt jatkamme tästä vähän eteenpäin. Tämän osan aiheena on pelisilmukka ja pelin rakenteen suunnittelu. Eli vieläkään ei saada aikaan valmista peliä, mutta osan lopussa ollaan sitä kuitenkin jo paljon lähempänä.</p>
<h2>Pelin toiminta</h2>
<p>Aloitetaanpa siitä, että mietitään hetkinen mitä tietokone tekee suorittaessaan peliäsi. Tietokoneessahan on prosessori, joka suorittaa käsky kerrallaan ohjelmaa, keskusmuisti ja paljon muita hässäköitä.</p>
<p>Kun prosessori suorittaa ohjelmaa, tapahtuu se erittäin yksinkertaistetussa muodossa seuraavasti: Ensin se hakee muistista yhden käskyn, sitten se suorittaa sen ja tallentaa tuloksen johonkin rekisteriinsä tai keskusmuistiin. Siinä välissä tapahtuu vielä paljon kaikkea muutakin, mutta idea on siinä, että kone suorittaa koodia käskyn kerrallaan alusta loppuun.</p>
<p>Oleellista tuosta on huomata se, että ohjelman täytyy olla aika tarkkaan mietitty, koska tietokone suorittaa sitä ihan orjallisesti. Se ei pysty soveltamaan yhtään vaan kaikki täytyy kertoa sille tarkkaan.</p>
<p>Mutta ei mennä ainakaan vielä ihan niin laitteistonläheisiksi vaan mietitään hetkinen sitä kuinka itse pelaisit ristinollaa kaverisi kanssa:</p>
<ul>
<li>Ensin toinen teistä piirtää ruksin paperiinsa</li>
<li>Sitten toinen</li>
<li>Sitten taas ensimmäinen</li>
</ul>
<p>Ja tuota jatketaan kunnes jompikumpi saa tarvittavan kolmen merkin rivin. Vaikka tuo ohje riittäisi ihmiselle, koneella ei ole tarvittavaa mielikuvitusta sen ymmärtämiseen. Tarkennetaanpa siis määritystämme hieman:</p>
<ol>
<li>Aloitetaan peli: haetaan paperia ja kynä.</li>
<li>Päätetään kumpi aloittaa</li>
<li>Pelaaja laittaa rastin haluamaansa kohtaan</li>
<li>Jos hän yrittää piirtää rastinsa sellaiseen kohtaan, jossa jo on merkki, se ei onnistukaan &#8211; vaan kaveri ärähtää, &#8220;Mitä oikein yrität?&#8221;</li>
<li>Kaverukset tarkistavat, onko jompikumpi jo saanut tarvittavat 3 ruutua</li>
<li>Jos on, peli loppuu</li>
<li>Muuten tarkistetaan, onko ruudukko täynnä</li>
<li>Jos on, peli loppuu</li>
<li>Jos ei, pelaaja vaihtuu ja jatketaan kohdasta 2</li>
</ol>
<p>Tuossa on sama juttu hieman tarkennettuna. Se antaa jo aika hyvän kuvan siitä mitä ohjelman pitää tehdä. Tätä voitaisiin pitää yksinkertaisena suunnitteluna. En tässä käytä mitään hienoja termejä, kun tarkoituksena on yrittää herättää ajatteluasi siihen suuntaan, että pelien suunnittelu ja asioiden huomioiminen onnistuisi kuin luonnostaan.</p>
<h2>Pelisilmukka</h2>
<p>Äskeisestä peliesimerkistä päästäänkin varsin luontevasti siirtymään pelisilmukkaan. Peliähän siis pelataan tietty aika, tarkalleen ottaen siihen asti, että toinen pelaaja voittaa tai tulee tasapeli. Sinä aikana tehdään monta kertaa samat asiat; kumpikin laittelee merkkejään ja tarkistellaan onko joku jo mahdollisesti voittanut. Tässä siis kannattaa käyttää silmukkaa. Oletan, kuten jo ensimmäisessä osassa sanoin, että sinulla on perustiedot ohjelmoinnista. Silmukan käsite lienee siis selvä: jotain ohjelmanpätkää toistetaan kunnes jokin ehto täyttyy, esimerkiksi peli loppuu.</p>
<p>Pseudokoodina, eli ohjelmakoodina, jonka ei ole tarkoitus sellaisenaan toimia vaan antaa suuntaa siitä miten lopullinen ohjelma toimisi, voisimme kirjoittaa pelisilmukan vaikkapa näin:</p>
<pre>pelaaja=1;

while(peli_jatkuu)
{
	while(pelaaja laittaa laittomaan ruutuun)
		laita_merkki_haluamaasi_ruutuun();

	voittaja=tarkista_voittaja();	

	if(voittaja!=0) peli_jatkuu=false;

	else pelaaja=vaihda_pelaaja();
}</pre>
<p>Okei, esimerkissämme ei vielä otettu oikeastaan mitään kantaa siihen, kuinka se käytännössä on mahdollista toteuttaa. Näppäimistön luku, grafiikat ja muu mukava on vielä kokonaan pois. Kyse on siis puhtaasti logiikasta, siitä kuinka ajattelemme pelin parhaiten toimivan. Koodin selitys voisi olla paikallaan.</p>
<p>Silmukassa tehdään aina yhden pelaajan siirto ja sen jälkeen tarkistetaan voittiko kyseinen pelaaja. Sen jälkeen, jos peli edelleen jatkuu, vaihdetaan pelaajaa ja mennään silmukkaa läpi toisen kerran. Tarkista_voittaja() -pseudofunktio palauttaa voittajan numeron (1 tai 2), jos joku voittaa ja 0, jos peli jatkuu. Tasapelitilanteessa se voisi palauttaa vaikkapa kolmosen. Vaihda_pelaaja() asettaa pelaajan numeroksi seuraavan pelaajan numeron. Ja tuo while(pelaaja laittaa laittomaan ruutuun) tarkoittaa sitä, että laita_merkki_haluamaasi_ruutuun() toistetaan niin monta kertaa, että pelaaja lopulta laittaa merkkinsä johonkin sallittuun ruutuun.</p>
<h2>Jaetaan koodi osiin</h2>
<p>Ennen kuin tehdään lopullista versiota tuosta pelisilmukasta, käsitellään hieman funktioita ja sitä kuinka ohjelmaa kannattaa jakaa funktioiksi. Siis mitkä ohjelman osat tarvitsevat oman funktionsa ja miten funktioista saadaan paras hyöty irti. Oletan, että tiedät tekniikan, kuinka funktioita käytetään ja keskityn vain tähän teoriapuoleen.</p>
<p>Funktiojako on sellainen asia, jonka puuttumiseen tai vaillinaiseen ymmärtämiseen törmään useimmiten aloittelevien ohjelmoijien koodia lukiessani. Monesti mukana on joku funktio, esimerkiksi alkutekstien kirjoittamiseen &#8211; tekijä kun on kuullut, että on hienoa käyttää funktioita. Ja niinpä sellainen on pitänyt mukaan ahtaa. Funktioiden merkitys on kuitenkin jostain syystä jäänyt kuulematta. Sen takia paneudun nyt hetkeksi funktioihin. Asia ei ole monimutkainen &#8211; ja se helpottaa ohjelmointityötäsi HUOMATTAVASTI!</p>
<p>Funktioihin jakamiseen on oikeastaan kaksi tärkeää syytä: saman koodin uudelleenkirjoittamisen välttäminen ja koodin jakaminen sellaisiin osiin, jotka on helppo käsitellä, ja ne kummatkin oikeastaan voitaisiin yleistää selkeydeksi. Funktioita käytetään, jotta koodi olisi selkeämpää ja sitä olisi helpompi hallita. Yleensä tällä saavutetaan bugittomampaa koodia, helpommin korjattavaa koodia ja monesti myös paljon paremmin toimivaa koodia.</p>
<p>Jos katsotaan funktioihin jakamista ensin hetki uudelleenkirjoittamisen näkökulmasta, huomataan, että usein ohjelmissamme toistamme samoja operaatioita moneen kertaan. Esimerkiksi, jos käytämme pelissämme grafiikkaa ja meidän täytyy ladata kuvia, lataamme luultavasti pelin aikana monta kuvaa. Kuvanlatausfunktioon tulee helposti muutama kymmenen riviä koodia ja jos se kirjoitetaan joka kerta uudestaan, kun taas tarvitaan kuvaa, pitenee ohjelmamme aivan turhaan. Nimittäin, jos teemme funktion, joka ottaa parametrinaan kuvan tiedostonimen ja palauttaa kuvan (esim. DirectDrawn surfacessa), meidän tarvitsee kirjoittaa vain kerran tuo kymmenkunta riviä, ja aina kuvaa ladattaessa kutsua tuota funktiota.</p>
<p>Tästä pääsemmekin helposti myös siihen selkeyteen ja ylläpidettävyyteen. Ajattele, että sinulla olisi ohjelma, jossa ladataan 20 kuvaa, ja jokaisen kuvan lataamiseen käytettävä koodi olisi aina kirjoitettu siihen kohtaan, jossa kuvaa tarvitaan. Sitten yhtäkkiä huomaisit, että kuvanlatauskoodissasi on virhe. Noh, ei muuta kuin tekisit korjaukset kaikkiin 20 kohtaan. Aikaa menisi ehkä puoli tuntia. Mutta entä, jos kuvia olisi 50 &#8211; tai sata. Siinä menisivät jo hermot. Jos sen sijaan olisit laittanut kuvan latauksen funktioon, tarvitsisi korjata vain sieltä, ja ongelma poistuisi kaikista kuvista. Aikaa menisi ehkä 5 minuuttia. Tietenkin ongelman suuruudesta riippuen.</p>
<p>Toinen juttu on sitten se koodin jakaminen selkeisiin, helposti käsiteltäviin osiin. Kun puhutaan koodin ymmärrettävyydestä, ajatellaan yleensä kommentteja. Aloittelija ei usko edes niitä tarvitsevansa, johtoajatuksena on saada äkkiä jotain toimivaa näkyviin. Mutta selkeys ja ymmärrettävyys on paljon enemmänkin. Se on sitä, että ohjelmakoodi on jaettu funktioihin, jotka tekevät sen mitä niiden oletetaan tekevän. Ne tekevät pieniä osatehtäviä niin, että ohjelmoijan on helppo pääohjelmaa katsoessaan yhdellä silmäyksellä nähdä kuinka sen logiikka toimii. Tätä asiaa haluan erityisesti tässä tutoriaalissa korostaa: kun joku lukee koodiasi, tulisi hänen pystyä saamaan ainakin suurpiirteinen käsitys ohjelmasi toiminnasta vilkaisemalla pääohjelmaasi &#8211; tai ainakin pelisilmukkaasi.</p>
<p>Siksi pelisilmukkaan tulee laittaa vain välttämätön, ja kaikki muu jaettava selkeisiin funktioihin. Ja funktioiden pitää olla sellaisia, että niiden toiminta on loogista.</p>
<h2>Mitä funktioita tarvitaan?</h2>
<p>Noniin, mietitäänpä mitä ristinollapelissämme olisi järkevää laittaa omiin funktioihinsa. Ensinnäkin olisi tärkeää erotella piirtäminen ja pelin muu toiminta. Sen lisäksi voisi olla hyvä erottaa näppäinten luku pelin sääntöjen ja logiikan käsittelystä. Pelisilmukassa voisi olla siis vaikkapa seuraavat funktiot:</p>
<ul>
<li><strong>PISTE Lue_hiiri()</strong> &#8211; lukee hiiren painalluksen ja palauttaa koordinaatit, joihin hiirellä on klikattu</li>
<li><strong>bool Tee_siirto(PISTE p, int pelaaja, PELILAUTA lauta)</strong> &#8211; muuttaa hiiren koordinaatit pelilaudan koordinaateiksi, tarkistaa voiko ko. ruutuun laittaa merkin ja merkitsee ruutuun pelaajan tunnuksen. Jos taas ruutuun ei voi laittaa (siinä on jo jonkun merkki), palauttaa funktio virheen merkiksi false. Tällöin täytyy hiiri lukea uudelleen.</li>
<li><strong>int Tarkista_voittaja(PELILAUTA lauta)</strong> &#8211; käy läpi pelilaudan ja tarkistaa onko joku voittanut. Palauttaa voittajan numeron tai 0, jos kukaan ei vielä ole voittanut. Tasapelistä se palauttaa 3.</li>
<li><strong>void Piirra_pelitilanne(PELILAUTA lauta, int pelaaja)</strong> &#8211; piirtää näytölle pelilaudan, ja kirjoittaa tiedon siitä kumman pelaajan vuoro on.</li>
</ul>
<p>Siinä on jonkin verran tärkeimpiä funktioita. Kuten huomaat, ne ovat varsin loogisia kokonaisuuksia: siirron tarkistaminen, voittajan tarkistaminen, piirtäminen jne. Ei vaadi kovin paljon miettimistä, että keksii jakaa ohjelman juuri tuollaisiin osiin. Parametrit ovat lähinnä suuntaa-antavia, mutta varmaankin aika lähellä lopullisia parametreja.</p>
<p>Ihmettelet ehkä, miksi hiiren lukeminen ja siirron tarkastaminen ei ole samassa funktiossa. Ne kun kuitenkin aika läheisesti liittyvät toisiinsa. Toki ohjelman voisi kirjoittaa niinkin, että hiiri luettaisiin tee_siirto-funktiossa, mutta yleensä suositaan sitä tapaa, että kaikki laitteistonläheinen osa ohjelmasta sijoitetaan erilleen abstraktimmasta osasta. Tämä sen takia, että jos vaikkapa joskus haluat siirtää Windowsissa tekemäsi pelin Linuxiin, on se helppo tehdä, kun ei tarvitse kuin muuttaa niitä laitteistonläheisiä osia &#8211; logiikka pysyy ihan samana.</p>
<h2>Tehdäänpä nyt se silmukka</h2>
<p>Nyt meillä lienee tarpeeksi teoriaa funktioiden jakamisesta, ja voidaan alkaa soveltamaan niitä käytäntöön. Tärkeintä on muistaa, että pyritään kaikessa selkeyteen ja helposti ymmärrettävään koodiin. Harjoitus tekee mestarin, tärkeintä vain on se, että muistaa aina miettiä asioita &#8211; eikä vain tehdä niin kuin ensimmäisenä mieleen tulee.</p>
<p>Eli kerätään edellisissä osissa esitellyt tietotyypit ja tässä osassa mietityt funktiot yhteen ja kasataan ristinollapelillemme pääohjelma (main). Kommenteissa kerrotaan kaikki tarpeellinen.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;height:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* Ristinollapelin pääohjelma - versio 1<br />
&nbsp; &nbsp;Huom! Tämä ei vielä ole toimiva ohjelma, vaan<br />
&nbsp; &nbsp;pelkkä pääohjelma, jonka ympärille myöhemmin<br />
&nbsp; &nbsp;rakennetaan kokonainen peli */</span><br />
<br />
<span style="color: #808080; font-style: italic;">/* Määritellään PELIMERKKI-tietotyyppi */</span><br />
<span style="color: #993333;">typedef</span> <span style="color: #000000; font-weight: bold;">enum</span> <span style="color: #009900;">&#123;</span> RISTI<span style="color: #339933;">,</span> NOLLA <span style="color: #009900;">&#125;</span> PELIMERKKI<span style="color: #339933;">;</span> <br />
<br />
<span style="color: #808080; font-style: italic;">/* Määritellään PELAAJA-tietue (ks. tutoriaalisarjan 2. osa) */</span><br />
<span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> _PELAAJA<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">char</span> nimi<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">40</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; PELIMERKKI nappula<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span> PELAAJA<span style="color: #339933;">;</span> <br />
<br />
<span style="color: #808080; font-style: italic;">/* Määritellään PISTE-tietue, jota käytetään<br />
&nbsp; &nbsp;hiiren lukemiseen */</span><br />
<span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> _PISTE<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">int</span> x<span style="color: #339933;">,</span> y<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span> PISTE<span style="color: #339933;">;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #993333;">int</span> voittaja<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* Voittajan numero - 0=peli ei vielä loppunut */</span><br />
&nbsp; &nbsp; PELAAJA pelaajat<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* Kaksi pelaajaa */</span><br />
&nbsp; &nbsp; <span style="color: #993333;">int</span> pelilauta<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* Pelilauta */</span><br />
&nbsp; &nbsp; PISTE piste<span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* Tätä käytetään hiiren tietojen välitykseen */</span><br />
&nbsp; &nbsp; <span style="color: #993333;">int</span> vuorossa <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* Vuorossa oleva pelaaja (1 tai 2) */</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* Alustetaan pelaajien arvot (kumpi on risti / nolla yms.) */</span><br />
&nbsp; &nbsp; alusta_pelaajat<span style="color: #009900;">&#40;</span>pelaajat<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* Alustetaan pelilauta (nollataan kaikki sen ruudut) */</span><br />
&nbsp; &nbsp; alusta_pelilauta<span style="color: #009900;">&#40;</span>pelilauta<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* Koska pelissä käytetään grafiikan piirtoon ja hiiren lukuun<br />
&nbsp; &nbsp; &nbsp; &nbsp;Allegro-kirjastoa, täytyy sekin alustaa tässä ennen kuin<br />
&nbsp; &nbsp; &nbsp; &nbsp;aloitetaan pelisilmukkaa */</span><br />
&nbsp; &nbsp; alusta_allegro<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* Pelisilmukka: Pyöritään ympäri ja ympäri niin<br />
&nbsp; &nbsp; &nbsp; &nbsp;kauan kunnes voittaja-muuttujan arvo muuttuu<br />
&nbsp; &nbsp; &nbsp; &nbsp;(1=pelaaja 1 voitti, 2=pelaaja 2 voitti ja 3=tasapeli) */</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span>voittaja<span style="color: #339933;">==</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* Tehdään logiikka, jos hiirellä on klikattu johonkin,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;muuten vain piirretään */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>lue_hiiri<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>piste<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* Ks. tee_siirto()-funktion esittely yllä */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>tee_siirto<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>piste<span style="color: #339933;">,</span> pelilauta<span style="color: #339933;">,</span> vuorossa<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* Tarkistetaan voittiko pelaaja tällä<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;siirrollaan ja jatkuuko peli vielä */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; voittaja <span style="color: #339933;">=</span> tarkista_voittaja<span style="color: #009900;">&#40;</span>pelilauta<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* Seuraavan pelaajan vuoro */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vuorossa <span style="color: #339933;">=</span> vaihda_pelaaja<span style="color: #009900;">&#40;</span>vuorossa<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* Jos siirto ei ollut sallittu, tehdään<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;piirto ja aloitetaan taas silmukan alusta */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* Piirretään pelin grafiikat */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; piirra_pelitilanne<span style="color: #009900;">&#40;</span>pelaajat<span style="color: #339933;">,</span> pelilauta<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* Pelin lopetus: Kerrotaan kuka voitti - vai tuliko tasapeli,<br />
&nbsp; &nbsp; &nbsp; &nbsp;tehdään muut lopetustoimet */</span><br />
<br />
&nbsp; &nbsp; kerro_voittaja<span style="color: #009900;">&#40;</span>voittaja<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; lopeta_allegro<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Selitän ohjelmaa hieman, mutta en paljon, koska oikeastaan siinä on vain laitettu käytäntöön sellaisia asioita, joista tuossa edellä on puhuttu. Pääohjelmaan siis kuuluu oikeastaan kolme osaa: Alku, jossa alustetaan käytetyt muuttujat ja tehdään kaikki valmistelut, Pelisilmukka, jossa tehdään itse peli ja Lopetus, jossa viimeistellään pelin suoritus ja tehdään lopetustoimet.</p>
<p>Alku ja loppu tehdään vain kerran, kun taas pelisilmukkaa käydään läpi niin kauan kuin peliä kestää. Siksi erityisesti pelisilmukka on tärkeää suunnitella hyvin ja selkeäksi.</p>
<p>Pelisilmukasta tein sellaisen, että piirto tehdään joka kerta, vaikka peli ei etenisikään, siksi että silloin, kun pelaaja liikuttelee hiirtä näytöllä, mutta ei paina mitään nappia, täytyy piirtää, mutta peli ei kuitenkaan etene. Niinpä suurin osa pelisilmukasta suoritetaan vain silloin, kun hiirtä klikataan.</p>
<p>Myös tee_siirto() aiheuttaa sen, että osa koodista joko suoritetaan tai hypätään yli sen mukaan oliko siirto sallittu. Jos siirto ei ollut sallittu, ei kannata tarkistaa voittajaa tai vaihtaa pelaajaa. Silloin vain piirretään ja sama pelaaja saa taas yrittää uudestaan. Jos vaikka tällä kertaa osuisi oikeaan ruutuun.</p>
<h2>Miten jatketaan?</h2>
<p>Niin, tämä osa alkaa olla tässä. Opettelimme sitä kuinka pelisilmukka tulisi rakentaa ja miten pelin toiminta jaetaan funktioihin. Samalla teimme peliimme pääohjelman rungon, jonka päälle alamme ensi kerralla kasaamaan hieman lihoja &#8211; kirjoittamaan funktioita. Tuo runko ei itsessään vielä tee mitään, eikä sitä pysty edes kääntämään, mutta se on jo askel kohti valmista peliä.</p>
<p>Seuraavassa osassa toteutamme siis pelin logiikkaan liittyvät funktiot tee_siirto(), tarkista_voittaja() ja vaihda_pelaaja(), sekä alustusfunktiot alusta_pelaajat() ja alusta_pelilauta(). Sitä seuraavalla kerralla luomme pikaisen katsauksen grafiikkaan Allegroa hyödyntäen, kuitenkin niin, että Allegron tekniikalla on siinä mahdollisimman pieni osuus, ja saamme pelin valmiiksi.</p>
<p>Ei muuta kuin opetteluintoa, ja hauskaa koodausta! Palautetta saa ja pitää antaa &#8211; vaikkapa suomipelit.com:in keskustelualueella. Yritän sitten artikkelia vielä parannella ja ainakin vastailla kysymyksiisi.</p>
<p><em>Artikkelin kirjoitti alun perin jalaine.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.suomipelit.com/2002/10/07/peliohjelmoinnin-peruskasitteet-osa-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SDL-tutoriaali &#8211; Osa 1</title>
		<link>http://www.suomipelit.com/2002/09/01/sdl-tutoriaali-osa-1/</link>
		<comments>http://www.suomipelit.com/2002/09/01/sdl-tutoriaali-osa-1/#comments</comments>
		<pubDate>Sun, 01 Sep 2002 10:00:27 +0000</pubDate>
		<dc:creator>Suomipelit.com</dc:creator>
				<category><![CDATA[Artikkelit]]></category>
		<category><![CDATA[Käytännön oppaat]]></category>
		<category><![CDATA[c/cpp]]></category>
		<category><![CDATA[kirjasto]]></category>
		<category><![CDATA[ohjelmointi]]></category>
		<category><![CDATA[sdl]]></category>

		<guid isPermaLink="false">http://www.suomipelit.com/?p=818</guid>
		<description><![CDATA[Tällä sivustolla on ollut tähän mennessä muutama tutoriaali Allegron käytöstä, koska se on helppokäyttöinen ja toimii monessa ympäristöstä. Se ei kuitenkaan suinkaan ole ainut saatavilla oleva peliohjelmointikirjasto vaan on olemassa sellainenkin kirjasto kuin SDL, joka on monessa suhteessa vielä Allegroakin parempi. Tässä pienessä tutoriaalissa opetetaan SDL:n asennus ja annetaan pieni perusohjelma alkuun pääsemiseksi.]]></description>
			<content:encoded><![CDATA[<p>Tällä sivustolla on ollut tähän mennessä muutama tutoriaali Allegron käytöstä, koska se on helppokäyttöinen ja toimii monessa ympäristöstä. Se ei kuitenkaan suinkaan ole ainut saatavilla oleva peliohjelmointikirjasto vaan on olemassa sellainenkin kirjasto kuin SDL, joka on monessa suhteessa vielä Allegroakin parempi. Tässä pienessä tutoriaalissa opetetaan SDL:n asennus ja annetaan pieni perusohjelma alkuun pääsemiseksi.</p>
<h2>Mikä on SDL?</h2>
<p>SDL eli Simple Direct media Layer on DirectX:ään verrattavissa oleva kirjasto. SDL-kirjastot löytyvät tällä hetkellä Linuxille, Windowsille (9x,2k,Xp), MacOS:lle ja BeOS:lle. SDL on Open Sourcea, mutta tämä ei tarkoita että SDL:ää käyttävän sovelluksen lähdekoodia pitäisi julkaista (muistaakseni tätä kutsutaan LGPL:ksi). Useimmat Linuxille portatut kaupalliset pelit (Tribes2, Descent3, <a href="http://www.lokigames.com">http://www.lokigames.com</a>) käyttävät SDL:ää</p>
<h2>Miksi minun pitäisi käyttää sitä?</h2>
<p>SDL:llä ohjelmointi on huomattavasti helpompaa kuin DirectX:llä, DirectX:ssä pitää huolehtia ns. Windows-tauhkasta (sovellusikkunoiden hallinasta jne.). DOS-ohjelmointi taas on luonteeltaan hieman erilaista. Mutta DOS? Haloo et kai tosissasi halua tehdä pelejä jotka toimivat DOS:ssa? On olemassa mysös muita kirjastoja kuten allegro, mutta se ei pärjää SDL:lle.<br />
SDL:ään saa ilmaisia lisäkirjastoja (Osoitteesta http://www.libsdl.org), jotka tukevat esim. kehittyneempiä musiikki- (.ogg, .mp3, .xm, midi jne.) ja kuvaformaatteja (.png, .gif, .jpg jne.)</p>
<h2>SDL-kirjastojen asennus</h2>
<p>Ensin tarvitaan SDL-binääri- ja kehityspaketit, jotka löytyvät <a title="http://www.libsdl.org" href="http://www.libsdl.org/" target="_blank">http://www.libsdl.org</a> :sta. Asennus tapahtuu eri käyttöjärjestelmissä hieman eri tavoin:</p>
<p><strong>Windows:</strong><br />
Tarvitset SDL:n peruskirjastot SDL-1.2.3-win32.zip (<a title="http://www.libsdl.org" href="http://www.libsdl.org">http://www.libsdl.org</a>,  Download/SDL 1.2/Runtime Libraries/w32), sekä kehityskirjastot (Visual C++ 6.0) SDL-devel-1.2.3-VC6.zip (<a title="http://www.libsdl.org" href="http://www.libsdl.org" target="_blank">http://www.libsdl.org</a>, Download/SDL 1.2/Development Libraries/w32)</p>
<p>Pura SDL-1.2.3-win32.zip (siis sitä readme-SDL.txt fileä ei tuola tietenkään tarvita) windowsin system-hakemistoon (NT,w2k,Xp system32)</p>
<p>Pura SDL-devel-1.2.3-VC6.zip esim. c:\SDL-1.2.3 -hakemistoon</p>
<p><strong>Linux:</strong><br />
Tarvitset SDL:n peruskirjastot SDL-1.2.3-1.i686.rpm (<a title="http://www.libsdl.org" href="http://www.libsdl.org" target="_blank">http://www.libsdl.org</a>, Download/SDL 1.2/Runtime Libraries/Linux), sekä kehityskirjastot (gcc) SDL-devel-1.2.3-1.i686.rpm (<a title="http://www.libsdl.org" href="http://www.libsdl.org" target="_blank">http://www.libsdl.org</a>, Download/SDL 1.2/Development Libraries/Linux)</p>
<p>Asenna rpm-paketit komennoilla:</p>
<pre>rpm -Uvh SDL-1.2.3-1.i686.rpm</pre>
<p>ja</p>
<pre>rpm -Uvh SDL-1.2.3-1.i686.rpm</pre>
<p>Paketit asentuvat paikkaan X ja kaikki kirjastojen vaatimat conffaukset tehdään automaattisesti.</p>
<h2>Koodaamaan!</h2>
<p>Windows:</p>
<ol>
<li>Luodaan uusi projekti (new Win32 application / empty project )</li>
<li>Viritetään Visual c++ -asetukset kuntoon: Valitse <em>Tools/Options/Directories</em> ja pudotusvalikosta<em> include</em> files ja lisää siihen hakemisto, jossa SDL:n header-tiedostot sijaitsevat (<em>C:\SDL-1.2.3\include</em>). Seuraavaksi valitse <em>library files</em> ja lisää hakemisto jossa SDL-kirjastot ovat (<em>C:\SDL-1.2.3\lib</em>).</li>
<li>Valitse <em>Project/Settings/ C/C++</em> -välilehti, lehdeltä löytyy &#8220;<em>Category</em>&#8221; valikko. Valitse siitä code generation, vaihda &#8220;<em>Use run-time library</em>:&#8221; Multithreaded DLL:ksi.</li>
<li>Valitse P<em>roject/Add to Project/Files</em> ja lisää kirjastot <strong>SDL.lib</strong> ja<strong> SDLmain.lib</strong> (<em>c:\SDL-1.2.3\lib</em>)</li>
<li>Koodia kehiin, kääntämään</li>
</ol>
<p>Linux:<br />
Linuxilla (Mandrake 8.1) emme lähde rakentamaan projektia, käymme siis suoraan käsiksi koodiin:</p>
<p>Koodi kääntyy komennolla: gcc -o main main.cpp -lSDL</p>
<p>Alla oleva koodi kääntyy molemmissa ympäristöissä:</p>
<p>Linuxissa voit joutua muuttamaan rivin</p>
<p style="padding-left: 30px;"><em>#include &lt;SDL.h&gt;</em></p>
<p>seuraavaksi</p>
<p style="padding-left: 30px;"><em>#include &lt;SDL/SDL.h&gt;</em></p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">#include &lt;SDL.h&gt;</span><br />
<br />
SDL_Surface <span style="color: #339933;">*</span>screen_surf<span style="color: #339933;">;</span><br />
<br />
<span style="color: #993333;">void</span> ShowBMP<span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span>file<span style="color: #339933;">,</span> SDL_Surface <span style="color: #339933;">*</span>screen<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> x<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> y<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; SDL_Surface <span style="color: #339933;">*</span>image<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// oma surface kuvalle</span><br />
&nbsp; &nbsp; SDL_Rect dest<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//alue, jolla määritetään kuvan kopioitavan datan mitat</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* Load the BMP file into a surface */</span><br />
&nbsp; &nbsp; image <span style="color: #339933;">=</span> SDL_LoadBMP<span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> image <span style="color: #339933;">==</span> NULL <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Not found &nbsp;%s: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> file<span style="color: #339933;">,</span> SDL_GetError<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* kopioidaan kuvadata ruudulle. */</span><br />
&nbsp; &nbsp; dest.<span style="color: #202020;">x</span> <span style="color: #339933;">=</span> x<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; dest.<span style="color: #202020;">y</span> <span style="color: #339933;">=</span> y<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; dest.<span style="color: #202020;">w</span> <span style="color: #339933;">=</span> image<span style="color: #339933;">-&gt;</span>w<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; dest.<span style="color: #202020;">h</span> <span style="color: #339933;">=</span> image<span style="color: #339933;">-&gt;</span>h<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; SDL_BlitSurface<span style="color: #009900;">&#40;</span>image<span style="color: #339933;">,</span> NULL<span style="color: #339933;">,</span> screen<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>dest<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* paivitetaan ruutu */</span><br />
&nbsp; &nbsp; SDL_UpdateRects<span style="color: #009900;">&#40;</span>screen<span style="color: #339933;">,</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>dest<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* poistetaan kuva muistista */</span><br />
&nbsp; &nbsp; SDL_FreeSurface<span style="color: #009900;">&#40;</span>image<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span> <span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span><span style="color: #339933;">*</span> argv<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//luodaan surface ruudulle</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// kokoruututila |SDL_FULLSREEN flagilla</span><br />
&nbsp; &nbsp; screen_surf <span style="color: #339933;">=</span> SDL_SetVideoMode<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">640</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">480</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">16</span><span style="color: #339933;">,</span> SDL_SWSURFACE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> screen_surf <span style="color: #339933;">==</span> NULL <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Unable to set 640x480 video: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SDL_GetError<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; ShowBMP<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;kuva.bmp&quot;</span><span style="color: #339933;">,</span>screen_surf<span style="color: #339933;">,</span><span style="color: #0000dd;">0</span><span style="color: #339933;">,</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//ladataan kuva</span><br />
&nbsp; &nbsp; SDL_Delay<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">5000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">//odotetaan 5 sekuntia</span><br />
<br />
&nbsp; &nbsp; SDL_Quit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<hr /><em>Artikkelin kirjoitti alun perin nuotimi1.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.suomipelit.com/2002/09/01/sdl-tutoriaali-osa-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Peliohjelmoinnin peruskäsitteet &#8211; Osa 2</title>
		<link>http://www.suomipelit.com/2002/06/02/peliohjelmoinnin-peruskasitteet-osa-2/</link>
		<comments>http://www.suomipelit.com/2002/06/02/peliohjelmoinnin-peruskasitteet-osa-2/#comments</comments>
		<pubDate>Sun, 02 Jun 2002 10:00:41 +0000</pubDate>
		<dc:creator>Suomipelit.com</dc:creator>
				<category><![CDATA[Artikkelit]]></category>
		<category><![CDATA[Käytännön oppaat]]></category>
		<category><![CDATA[alkeet]]></category>
		<category><![CDATA[c/cpp]]></category>
		<category><![CDATA[ohjelmointi]]></category>

		<guid isPermaLink="false">http://www.suomipelit.com/?p=750</guid>
		<description><![CDATA[Tämä toinen osa peliohjelmoinnin peruskäsitteet -kurssista jatkaa siihen mihin ensimmäisessä jäätiin. Siinä käsitellään tietorakenteita ja tiedon käsittelyä pelien kannalta. Tärkeitä perustietoja siis luvassa.]]></description>
			<content:encoded><![CDATA[<p>Tämä toinen osa peliohjelmoinnin peruskäsitteet -kurssista jatkaa siihen mihin ensimmäisessä jäätiin. Siinä käsitellään tietorakenteita ja tiedon käsittelyä pelien kannalta. Tärkeitä perustietoja siis luvassa.</p>
<h2>Mitäs meillä nyt jo on kasassa?</h2>
<p>Niinpä. Tämä kakkososa on jo käytännössä loppu, mutta otetaanpa vielä lyhyt kertaus ennen seuraavaan lukuun jatkamista. Pohdimme tässä osassa siis tietorakenteita, joita ristinollapelissämme tulemme tarvitsemaan, ja päädyimme siihen, että pelilauta on taulukko ja pelaaja tietue. Lisäksi kokeilimme pientä tietueenkäsittelyohjelmaa. Seuraavassa osassa jatkamme pelin rakenteeseen, eli ruvetaan oikeasti ohjelmoimaan peliä, tai paremminkin pelin runkoa, joka kuitenkin jo toimii &#8211; jotenkin :) Kiitoksia seurasta ja kärsivällisyydestä, moi! Jees. Olet nyt varmaankin lukenut ensimmäisen osan tästä peliohjelmointikurssista ja valmis ottamaan askelen eteenpäin. Jos et edellistä osaa ole lukenut, suosittelen siihen palaamista vielä ennen tämän tekstin lukemista. Nimittäin, vaikka se saattaakin tuntua paikoin tylsältä ja epäoleelliselta, on ykkösosan asioiden ymmärtäminen hyvän lopputuloksen kannalta tärkeää. Joka tapauksessa oletan, että olet sen lukenut tai muuten vaan ymmärrät suunnittelun perusasiat.</p>
<p>Tässä osassa mennään siis eteenpäin erittäin tärkeään asiaan. Vaikka vielä ei ainakaan ihan heti ruvetakaan koodaamaan, puhutaan paljon C-kielestä, ja ajatellaan jo toteutuksen kannalta äärimmäisen tärkeää asiaa: tietoa, ja sen tallennusta. Osasta ei luultavasti tule kovin pitkä, koska ristinollassa emme mitään kovin ihmeellisiä tietorakenteita käytä. Mutta mitä tässä enää jaarittelemaan, aloitetaan!</p>
<h2>Tietoa ja tietorakenteita</h2>
<p>Eiköhän aluksi tehdä selväksi mitä tiedolla tässä yhteydessä tarkoitetaan. Tieto kun voi tarkoittaa niin montaa asiaa. Mietipä hetki itse, ja kirjaa vaikka paperille mieleesi tulevia ristinollassa käsiteltyjä tietoja! Tuliko listastasi jotain tämän näköistä?</p>
<ul>
<li>Ei mitään..</li>
</ul>
<p>Jos tuli, ei se mitään. Ajattelet tietoa hieman eri tavalla kuin mitä nyt on tarkoitus ajatella :). Nimittäin kun ajatellaan tietoa pelin kannalta, se tarkoittaa niitä aivan yksinkertaisia asioita, joita tavallisesti emme välttämättä edes kovin paljon ajattele. Ristinollan tapauksessa tällaisia asioita ovat mm. seuraavat:</p>
<ul>
<li>Pelilauta / -tilanne</li>
<li>Pelaajat</li>
<li>Pelimerkit</li>
<li>Pisteet</li>
</ul>
<p>Luultavasti alkuperäinen listasikin muistutti enemmän tätä toista listaa, vai kuinka? Mennään kohta tarkemmin siihen, että minkälaisia tietorakenteita voidaan käyttää näiden tietojen säilyttämiseen, mutta pohditaan ensin mitä nämä tiedot oikeastaan ovat.</p>
<p>Pelilautahan on ruudukko, jossa on joko 3&#215;3 ruutua tai sitten enemmän. Koskapa ekassa osassa utelemiani ajatuksia pelilaudan koosta ei tullut, päätin sitten itse, että kyllä meille tässä vaiheessa riittää 3&#215;3 -ruudukko. Miksi päädyin tähän tulokseen selviää seuraavassa luvussa. (Vähän jännitystä ;). Miksi laitoin pelilaudan ja pelitilanteen samalle riville? Tähän on ihan hyvä syy; pelilautahan ristinollassa kertoo pelitilanteen, koska pelilautaan merkitään missä kohti on kenenkin pelimerkki.</p>
<p>Sitten pelaajat. Jos pelaajien pelimerkkien paikat määritetään pelilaudassa, niin mitä hyötyä on pelaaja-tietotyypistä. Ei paljonkaan, mutta kuitenkin jotain. Onhan johonkin tallennettava pelaajan nimi, pelaajan pelimerkki (onko se x vai 0 vaiko joku muu?) ja muuta hauskaa tietoa pelaajasta.</p>
<p>Pelimerkit ja pisteet voidaan hylätä, koska ne sisältyvät jo edellisiin tietotyyppeihin eikä niitä sen vuoksi tarvitse erikseen olla &#8211; eikä ristinollassa muutenkaan lasketa pisteitä!</p>
<h2>Pelilauta taulukkoon</h2>
<p>Kaikkein yleisin tietotyyppi heti muuttujan jälkeen on taulukko. Hmm.. Tiedät varmaan mikä taulukko on, mutta otetaanpa esimerkki:</p>
<pre style="padding-left: 60px;">+-+-+-+
| | | |
+-+-+-+
| | | |
+-+-+-+
| | | |
+-+-+-+</pre>
<p>Tuohan siis on 3&#215;3 -taulukko, juuri sellainen mitä ristinollassa tulemme tarvitsemaan. Sen luominen C-kielellä tapahtuu seuraavasti:</p>
<pre>int pelilauta[3][3];</pre>
<p>Näin. Miksikö tein tuosta taulukosta int-tyyppisen? Okei.. Varsinkin, kun pelimerkit ovat kirjaimia, olisi voinut olla helppoa tehdä merkkitaulukko, jolloin taulukkoon olisi voinut tallentaa suoraan pelimerkin. Ajattelin kuitenkin, että voisi olla mielekkäämpää tallentaa taulukkoon aina sen pelaajan numero, kuka on pelimerkkinsä laittanut, ja sitten hakea pelimerkki pelaajatiedoista. Eli tähän tapaan:</p>
<pre style="padding-left: 60px;">+-+-+-+
|1|0|2|
+-+-+-+
|2|2|0|
+-+-+-+
|1|0|1|
+-+-+-+</pre>
<p>Kaikki tyhjät ruudut ovat siis nollia. Aika järkevää, eikö vain? Taulukoista ei nyt tämän enempää. Kunhan päästään toteutukseen, kerron tarkemmin kuinka taulukoita luetaan ja niihin sijoitetaan. Nyt riittää, kun ymmärrät miksi käytämme taulukkoa ja mikä taulukko oikeastaan edes on.</p>
<h2>Monimutkaisempia tietorakenteita</h2>
<p>Okei. Pelilauta on siis taulukko, johon tallennetaan pelitilanne sitä mukaa, kun peli etenee. Mutta mikä on sitten pelaajan tietotyyppi? Mitenkäs olisi tietue? Jos tietue kuulostaa vieraalta, selitän sen nyt. Tietue (struct) on eräänlainen tietokokoelma, jonka sisään voidaan koota kaikenlaista yhteenkuuluvaa tietoa, tietotyypistä riippumatta. Mietitäänpä mitä tietoa pelaajasta haluamme tallentaa.</p>
<ul>
<li>Nimi</li>
<li>Ikä :)</li>
<li>Pelimerkki</li>
<li>Pisteet</li>
</ul>
<p>Esimerkiksi tuollaisia.. Tähän asti luultavasti olet tuollaisia tietoja käsitellyt ihan yksittäisinä muuttujina tai taulukoina, nimihän olisi tietysti merkkijonotaulukko:</p>
<pre>char nimi[50];</pre>
<p>Eikös vain? Ja ikä ihan tavallinen int-muuttuja. Tai jos haluttaisiin enemmän tarkkuutta, kävisi myös floatti tai vaikka double :). Samoin pisteet, mutta pisteitähän emme halunneet tallentaa, joten &#8212; mitenkäs se tuonne taas pääsikään livahtamaan? ;-)</p>
<p>Entäs sitten Pelimerkki? Se voisi olla vaikka char-muuttuja johon tallennetaan x tai 0. Mutta koska emme kuitenkaan aio pelistä tekstipohjaista tehdä, olisi x:ien ja nollien kanssa temppuilu turhaa. Mitä merkkejä ristinollassa siis voi olla? Ristejä ja nollia! Vain kaksi vaihtoehtoa. Niinpä tehdään oma luettelotietotyyppi, kas näin:</p>
<pre>typedef enum { RISTI, NOLLA } PELIMERKKI;</pre>
<p>Nyt voimme luoda PELIMERKKI-tyyppisiä muuttujia jotka voivat sisältää jommankumman noista arvoista RISTI tai NOLLA, esimerkiksi tällä tavoin:</p>
<pre>PELIMERKKI nappula;

nappula=RISTI;</pre>
<p>Huomaatko mitä hyötyä tästä on? Jos et, älä huoli, se selviää myöhemmin, ja onhan toki muitakin yhtä hyviä tapoja, esimerkiksi yksinkertaista int-muuttujaa voi käyttää.<br />
Mutta nyt siihen pääasiaan eli tietueihin. Meillä on tuossa kaikenlaista tietoa, mutta sitä on aika hankala käsitellä tuollaisina palasina, joten kootaanpa muuttujat yhteen, tietueeksi:</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">typedef</span> <span style="color: #000000; font-weight: bold;">enum</span> <span style="color: #009900;">&#123;</span> RISTI<span style="color: #339933;">,</span> NOLLA <span style="color: #009900;">&#125;</span> PELIMERKKI<span style="color: #339933;">;</span><br />
<br />
<span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> _PELAAJA<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">char</span> nimi<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">50</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; PELIMERKKI nappula<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span> PELAAJA<span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
</pre>
<p>Tuossa on nyt pelaajan tiedot yhdessä nätissä kasassa. Samoin kuin PELIMERKKEJä voidaan nyt myös PELAAJia luoda:</p>
<pre>PELAAJA pelaaja_1;

strcpy(pelaaja_1.nimi,"Jarkko");
pelaaja_1.nappula = RISTI;</pre>
<p>Näin yksinkertaisesti se toimii. Kun PELAAJA-tyyppinen tietue, pelaaja_1 (esim), on luotu, voidaan sen sisältämiin kohteisiin (muuttujiin yms.) viitata kirjoittamalla tietueen nimi, piste ja tietueen sisältämän muuttujan nimi. Niinkuin tuossa esimerkissäkin näkyy: pelaaja_1.nappula = RISTI;. Se on näin helppoa. Jos strcpy-funktio hämää, kerron siitä sen verran, että sehän on yksi C:n standardifunktioista, oma suosikkini ;). Se kopioi ensimmäisenä parametrina annettuun merkkijonoon, toisena parametrina annetun merkkijonon, eli tässä tapauksessa nimi-muuttujaan nimen &#8220;Jarkko&#8221;..</p>
<h2>Kootaan palaset</h2>
<p>Jotta tämä ei kaikki jäisi ihan teorian tasolle, tehdäänpä nyt pieni ohjelma tietueita käyttäen. Ei vielä itse ristinollapeliä, mutta jotain mukavaa kuitenkin. Niin, no voihan tätäkin siinä pelissä sitten käyttää, eli sellainen systeemi, joka kyselee pelaajan nimeä ja tallentaa sen sitten pelaaja-tietueeseen. Niinkuin yleensäkin, tee ohjelma ensin itse ja vasta, kun se on valmis tai ei toimi, katso tästä. En ole jaksanut koodia sen kummemmin piilottaa, mutta älä silti kurki ;)</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;height:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* Esimerkkiohjelma 1<br />
&nbsp; &nbsp;------------------<br />
&nbsp; &nbsp;(C) Jarkko Laine 2000<br />
&nbsp;*/</span><br />
<br />
<span style="color: #339933;">#include &lt;stdio.h&gt;</span><br />
<br />
<span style="color: #808080; font-style: italic;">/* Määritellään PELIMERKKI-tietotyyppi */</span><br />
<span style="color: #993333;">typedef</span> <span style="color: #000000; font-weight: bold;">enum</span> <span style="color: #009900;">&#123;</span> RISTI<span style="color: #339933;">,</span> NOLLA <span style="color: #009900;">&#125;</span> PELIMERKKI<span style="color: #339933;">;</span><br />
<br />
<span style="color: #808080; font-style: italic;">/* Määritellään PELAAJA-tietue */</span><br />
<span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> _PELAAJA<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">char</span> nimi<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">40</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; PELIMERKKI nappula<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span> PELAAJA<span style="color: #339933;">;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;PELAAJA pelaaja1<span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* Ykköspelaajan tiedot */</span><br />
&nbsp; &nbsp;<span style="color: #993333;">char</span> merkkijono<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">100</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* Merkkijono syötteiden lukemista varten */</span><br />
<br />
&nbsp; <span style="color: #808080; font-style: italic;">/* Kysytään käyttäjältä nimeä */</span><br />
&nbsp; &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Mikä on nimesi? &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #808080; font-style: italic;">/* Luetaan vastaus fgets() -funktiolla. Se toimii siten, että se lukee<br />
&nbsp; &nbsp; &nbsp; ensimmäisenä parametrina annettuun merkkijonoon syötettä viimeisenä<br />
&nbsp; &nbsp; &nbsp; annetusta tietovirrasta kunnes painetaan enteriä. Kuitenkin enintään<br />
&nbsp; &nbsp; &nbsp; kakkosparametrin verran merkkejä. stdin on standardisyötevirta eli<br />
&nbsp; &nbsp; &nbsp; normaalisti näppäimistö */</span><br />
&nbsp; &nbsp;fgets<span style="color: #009900;">&#40;</span>merkkijono<span style="color: #339933;">,</span><span style="color: #0000dd;">100</span><span style="color: #339933;">,</span>stdin<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #808080; font-style: italic;">/* Kopioidaan syötetty nimi pelaajan nimeksi */</span><br />
&nbsp; &nbsp;strcpy<span style="color: #009900;">&#40;</span>pelaaja1.<span style="color: #202020;">nimi</span><span style="color: #339933;">,</span> merkkijono<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #808080; font-style: italic;">/* Ja tulostetaan kokeeksi käyttäjälle */</span><br />
&nbsp; &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Jaa-a. Nimesi on siis %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span>pelaaja1.<span style="color: #202020;">nimi</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #808080; font-style: italic;">/* Kysellään vielä pelimerkkiä */</span><br />
&nbsp; &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Haluatko käyttää (x) ristiä vai (0) nollaa? &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #808080; font-style: italic;">/* Luetaan koko rivi, koska saattaahan joku hyvinkin kirjoittaa<br />
&nbsp; &nbsp; &nbsp; pitkänkin rimpsun tekstiä :) */</span><br />
&nbsp; &nbsp;fgets<span style="color: #009900;">&#40;</span>merkkijono<span style="color: #339933;">,</span><span style="color: #0000dd;">100</span><span style="color: #339933;">,</span>stdin<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #808080; font-style: italic;">/* Tutkitaan kuitenkin vain ekaa merkkiä.. Tätä voisi hyvinkin laajentaa<br />
&nbsp; &nbsp; &nbsp; paljon paremmaksikin, mutta eiköhän tämä tähän hätään riitä.. */</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>merkkijono<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> \<span style="color: #ff0000;">'x<span style="color: #000099; font-weight: bold;">\'</span>) pelaaja1.nappula = RISTI;<br />
&nbsp; &nbsp;else if(merkkijono[0] == <span style="color: #000099; font-weight: bold;">\'</span>0<span style="color: #000099; font-weight: bold;">\'</span>) pelaaja1.nappula = NOLLA;<br />
<br />
&nbsp; &nbsp;/* Näin, ja sitten vielä tarkistetaan että mikäs se oikein oli tuo<br />
&nbsp; &nbsp; &nbsp; pelaajan valitsema nappula.. Switch-lauseella, ihan huvin vuoksi :) */<br />
&nbsp; &nbsp;switch(pelaaja1.nappula)<br />
&nbsp; &nbsp;{<br />
&nbsp; &nbsp; &nbsp; case RISTI:<br />
&nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; printf(&quot;Valitsit siis RISTIN.<span style="color: #000099; font-weight: bold;">\n</span>&quot;);<br />
&nbsp; &nbsp; &nbsp; } break;<br />
<br />
&nbsp; &nbsp; &nbsp; case NOLLA:<br />
&nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; printf(&quot;Valitsit siis NOLLAN.<span style="color: #000099; font-weight: bold;">\n</span>&quot;);<br />
&nbsp; &nbsp; &nbsp; &nbsp; break;<br />
&nbsp; &nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; &nbsp; default: break;<br />
&nbsp; &nbsp;}<br />
<br />
&nbsp; &nbsp;return 0;<br />
}</span></div></td></tr></tbody></table></div>
</pre>
<p>Semmoisen ohjelman kyhäsin minä.. Sinun ohjelmasi ei tarvitse olla samanlainen, tietoa kun voi hyvinkin kysellä myös muilla funktioilla kuin fgets():illä. Itse vain olen siihen mieltynyt :).</p>
<p><em>Artikkelin kirjoitti alun perin jalaine.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.suomipelit.com/2002/06/02/peliohjelmoinnin-peruskasitteet-osa-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Peliohjelmoinnin peruskäsitteet &#8211; Osa 1</title>
		<link>http://www.suomipelit.com/2002/05/26/peliohjelmoinnin-peruskasitteet-osa-1/</link>
		<comments>http://www.suomipelit.com/2002/05/26/peliohjelmoinnin-peruskasitteet-osa-1/#comments</comments>
		<pubDate>Sun, 26 May 2002 10:00:06 +0000</pubDate>
		<dc:creator>Suomipelit.com</dc:creator>
				<category><![CDATA[Artikkelit]]></category>
		<category><![CDATA[Käytännön oppaat]]></category>
		<category><![CDATA[alkeet]]></category>
		<category><![CDATA[c/cpp]]></category>
		<category><![CDATA[ohjelmointi]]></category>

		<guid isPermaLink="false">http://www.suomipelit.com/?p=737</guid>
		<description><![CDATA[Tässä kurssisarjassa käydään läpi pelien tekemisen perusteita, sellaisia asioita, joita täytyy huomioida ihan jokaisessa pelissä. Lähinnä erilaisia ajattelumalleja ja toimintatapoja suunnittelu- ja toteutusvaiheen tilanteisiin. Esimerkkinä tehdään ristinollapeli alusta loppuun kaikkien taiteen sääntöjen mukaan.]]></description>
			<content:encoded><![CDATA[<p>Tässä kurssisarjassa käydään läpi pelien tekemisen perusteita, sellaisia asioita, joita täytyy huomioida ihan jokaisessa pelissä. Lähinnä erilaisia ajattelumalleja ja toimintatapoja suunnittelu- ja toteutusvaiheen tilanteisiin. Esimerkkinä tehdään ristinollapeli alusta loppuun kaikkien taiteen sääntöjen mukaan.</p>
<h2>Mihin tässä ollaan ryhtymässä</h2>
<p>Selvä, haluat siis tehdä pelin. Hyvä idea sinänsä. Tässä tutoriaalisarjassa yritän opettaa sinulle mahdollisimman monia hyödyllisiä tietoja ja taitoja, jotka auttavat sinua tekemään parempia pelejä, toivottavasti :). Minun täytyy sen verran kuitenkin sinua pudotella maanpinnalle, että tiedät, ettet vielä heti aluksi voi saada aikaiseksi mitään sellaista mitä kaupan hyllyllä näet. Ne on sitten jo ihan eri luokassa, jotain mitä saatat tehdä kun olet 5-6 vuotta pelejä ohjelmoinut &#8211; tai jotain..</p>
<p>Mutta älä säikähdä, voimme silti tehdä vaikka mitä hauskaa, kunhan muistamme ettemme tavoittele liian korkealle, muistathan sananlaskun:</p>
<p style="padding-left: 60px;"><em>Joka kuuseen kurkottaa, se katajaan kapsahtaa</em></p>
<p><em><span style="font-style: normal;">Tässä tapauksessa se tarkoittaa sitä, että aloitetaan ristinollasta. Ajattelin aluksi matopeliä, mutta sain hyviä neuvoja GameDev.net:in keskustelualueilla, ja niiden pohjalta päätin aloittaa vielä vähän helpommasta. Matopeli voisi olla sitten seuraava askel.</span></em></p>
<p>Ainoana perustietona tällä kurssilla edellytän C-kielen alkeiden taitamista. Tarkemmin sanottuna sinun on osattava ainakin seuraavat käsitteet:</p>
<ul>
<li>Funktiot, ja maini</li>
<li>Muuttujat</li>
<li>Taulukot</li>
<li>Tietueet</li>
<li>For, While ja do-while</li>
<li>if, else</li>
</ul>
<p>Jos jotain noista asioista et osaa, on sinun parasta se opetella, koska ne ovat C:n olennaisimpia asioita. Tietueet opetan luultavasti tässä kurssissa ihan alusta asti, mutta silti ne on hyvä osata. Pointterit opetan myös tällä kurssilla, jos niitä tullaan tarvitsemaan. Joka tapauksessa enempi tietämys C-kielestä ei koskaan ole pahaksi!</p>
<p>Tässä kurssissa pyrin painottamaan tiettyjä yleisesti hyväksyttyjä toimintatapoja ja -malleja sekä tyyliseikkoja. Samalla toivon, että tämä kurssi voisi johdattaa sinut alusta asti oikeaoppiseen peliohjelmointiin, kertomalla sinulle minkälaisia tietorakenteita ja moduulisuunnittelullisia seikkoja sinun tulisi ottaa huomioon peliäsi suunnitellessa ja toteuttaussa. Esimerkeissä käytän C:tä ja ilmaista Allegro-kirjastoa, johtuen sen helppokäyttöisyydestä. Kaikki asiat pitäisi kuitenkin pystyä soveltamaan myös missä tahansa muussa ympäristössä. Tämä ensimmäinen osa käsittelee idean kehittelyä ja suunnittelua. Aloitetaan!</p>
<h2>Pistä koneesi pakettiin</h2>
<p>Joskus kauan sitten oli MikroBitissä moniosainen peliohjelmointikurssi, en muista milloin, mutta siitä voi hyvinkin jo kymmenen vuotta olla. Siinä oli aika hyvä neuvo, joka mielestäni sopii tähän yhteyteen vallan mainiosti:</p>
<p style="padding-left: 60px;"><em>Ennen kuin alat koodaamaan, pistä koneesi pakettiin ja lähetä se postissa itsellesi</em></p>
<p>Aivan tarkkaa sanamuotoa en muista, mutta idea oli tuo.. Tietystikin siihen aikaan koneet olivat pienempiä, joten ne pystyi helpommin lähettämään itselleen postissa. Matkaan kului kuitenkin aikaa ainakin viikko, joten jäi aikaa suunnitteluun eikä tullut sännättyä suoraan koneen kimppuun.. Tuskinpa tuota kukaan sananmukaisesti totteli, mutta ehkä joku kuitenkin tajusi pysähtyä hetkeksi miettimään, että &#8220;hei, mitäs oikeastaan aionkaan tehdä?&#8221;</p>
<p>Kaikki alkaa ideasta. Jos sinulla ei ole harmainta aavistustakaan siitä, mitä haluat tehdä, todennäköisesti et mitään saakaan aikaiseksi. Ja huonosta ideasta luultavasti tulee huono peli :). Niinpä siis ihan aluksi kannattaa ainakin muutama hetkonen uhrata ihan sen pohtimiseen, että mitä oikeastaan haluan tehdä. Jos tämän voi tehdä tiimityönä niin aina vain parempi &#8211; yksin niin helposti takertuu yhteen ajatukseen eikä mieti yhtään sen pidemmälle. Kaikkia keskustelussa esiin tulevaa tulee jollain tavoin pohtia ja ottaa huomioon, tässä tutoriaalissa käytän esimerkkinä omaa muunnelmaani Ted Nelsonin esittämästä ideamatriisista, mutta sinä voit vallan mainiosti tehdä suunnitelmasi ihan millä tavalla vain haluat.</p>
<p>Mutta mistä saada ideoita? André LaMothe esittää kirjassaan Windows Game Programming For Dummies seuraavanlaisen listan:</p>
<ul>
<li>Muista peleistä</li>
<li>Elokuvista ja videoista</li>
<li>Todellisista peleistä</li>
<li>Unista ja painajaisista</li>
</ul>
<p>Siinä on siis muutamia ihan hyviä idean lähteitä, mutta varmasti on paljon muitakin hyviä paikkoja etsiä ideoita: kirjat, sarjakuvat ja ihan mikä vaan mikä tulee mieleen. Muista peleistä ideoita otettaessa on muistettava, että ei ole mitään järkeä lähteä koko peliä kopioimaan. Itse suosittelisin mielummin keksimään idean jostain muualta kuin muista peleistä (vaikkakin itse juuri teen BoulderDash-kloonia ;), koska Doom-klooneja on nähty jo aivan tarpeeksi &#8211; eikö?</p>
<h2>Ideasta eteenpäin</h2>
<p>Hankalampaa kuin idean keksiminen, on kuitenkin sen kehittely ja pohtiminen. Jokainen idea ei välttämättä sellaisenaan ole hyvä. Mutta katsotaanpa esimerkkipelimme ideankehittelyn alkuvaiheita.</p>
<p>Kuvitelkaamme, että olemme keksineet aivan mahtavan idean: tehdään tietokoneversio koulutuntien suosikkipelistä jätkänshakista! Tämä on hyvä idea, mutta mikä oikeastaan on jätkänshakki? Ajattelin aluksi, että olisin tässä kohti esittänyt tällaisen ideamatriisitekniikan, jonka Ted Nelson, eräs kuuluisa amerikkalainen tutkija, esitti luennoidessaan joku aika sitten täällä Jyväskylässä.. Se kuitenkaan ei tähän oikein sopinut, joten käydään asiaa hieman eri tavalla läpi.</p>
<p>Koska ideamme on jo hyvin tunnettu peli, ei meidän varmaan kovin paljon tarvitse pelin peruskäsitteitä pohtia. Aloitetaan kuitenkin muutamalla kysymyksellä, joita kannattaa aluksi pohtia.</p>
<ul>
<li>Mitä pelaajat tekevät voittaakseen?</li>
<li>Kuinka monta pelaajaa on mukana?</li>
<li>Mikä pitää pelin kiinnostavana?</li>
</ul>
<p>Joo, nuo tuntuvat varmaan aika tyhmiltä kysymyksiltä, mutta pohditaanpa niitä hetkinen. Pelaajat siis haluavat saada aikaiseksi suoria, mutta kuinka pitkiä suoria? Kaikista perinteisimmässä versiossa suorat ovat kolmen mittaisia:</p>
<pre style="padding-left: 90px;">x| |o
-+-+-
o|x|
-+-+-
o| |x</pre>
<p>Tuohon tapaan siis. Mutta kaikkihan tietävät, että jos kaksi vähänkään parempaa pelaajaa pelaavat tuota peliä keskenään, ei kukaan voi koskaan voittaa! Siksipä pelistä on olemassa laajempi versio, jossa pelataan isommalla ruudukolla ja pyritään 5 merkin suoriin. Miten teemme tässä pelissä? Meillä on siis nyt valinnan paikka, ja annan sinun itse miettiä miten kannattaisi tehdä. Jos valitset 3&#215;3-ruudukon, on luultavasti toteutus hieman helpompi, mutta toisaalta se voi olla pelaajien mielestä tylsempi. Toisaalta taas tekoälyn toteuttaminen tällaiseen ruudukkoon on helpompaa.</p>
<p>Kuinka monta pelaajaa? Tähän kysymykseen ei ainakaan voi olla montaa eri vastausta, eihän? Voi! Tuli tuossa eilen tätä pohtiessani mieleeni ajatus, että mitäs jos pelattaisiin kolmella pelaajalla. Idea tuntui aluksi aika erikoiselta, mutta pohdin sitä eteenpäin.. Tällä saisi kolmaskin kaveri tekemistä eikä tarvitsisi vain katsella odottelemassa. Ensimmäinen ajatukseni olikin, että &#8220;hei, tuohan voisi olla loistava ajatus!&#8221;. Mutta sitten veljeni pudotti minut maanpinnalle sanoen: &#8220;Jarkko, jos se kerran on niin hyvä ajatus, niin miksi kukaan ei sitä olisi aikaisemmin keksinyt?&#8221;. Niinpä, hyvä pointti. Niinpä asetuimme hetkeksi keittiönpöydän äärelle kokeilemaan peliä. Ensin pelasimme niin, että oli kolme pelaajaa ja yritettiin saada 5 ruudun rivejä. Se oli aika hankalaa, koskapa kaksi pelaajaa pystyi aina torjumaan kolmannen pelaajan rivit. Niinpä jonkin aikaa kokeiltuamme päätimme kokeilla neljän ruudun riveillä, ja se oli jo paljon parempi juttu. Kovin pitkälle kokeiluissamme emme vielä päässeet, joten en tiedä vielä tuleeko esimerkkipeliimme kolminpeli vai ei. Laita kommentteja, ja erityisesti tutki asiaa! Päätetään sitten yhdessä miten tästä jatketaan!</p>
<h2>Mikä tekee tästä pelistä hyvän</h2>
<p>Äskeisessä luvussa käsittelimme ideoita, ja ideoiden kehittelemistä ja hiomista. Se saattoi tuntua hieman ylimalkaiselta tai turhalta, kun oli kiire ohjelmoimaan ja tekemään peliä. Kuitenkaan sitä ei pidä ohittaa hätäisesti. Idea on kuitenkin loppujen lopuksi se mikä tekee pelistä hyvän tai huonon. Jos nyt tuntuu siltä, että ohitit ideankehittelyvaiheen turhan hätäisesti, palaa vielä edelliseen lukuun ja ideakaavioidesi pariin!</p>
<p>Nyt kuitenkin alamme jo hieman miettiä sitä miten ideaa lähdetään suunnittelemaan valmiiksi peliksi. Varsinaisia teknisiä ratkaisuja emme tee vielä, koska emme tunne tarpeeksi käsitteitä ja asioita sitä varten. Sen sijaan pohdimme muita tärkeitä, ylemmän tason asioita, sellaisia, jotka ovat ehkä lähinnä käyttäjää ja siten ehkä jopa kaikista tärkeimpiä. Älä käsitä väärin, totta kai näiden suunnitelmien toteutus on tärkeää myöskin, mutta ilman tätä suunnittelua on peliä huomattavasti vaikeampi toteuttaa!</p>
<p>Mikä on se mikä tulee erottamaan tämän pelin massasta? Miksi juuri tämä peli olisi niin hyvä, että kaikkien kannattaisi sitä pelata? Näitä kysymyksiä pohdittaessa kannattaa miettiä myös, että mikä oikeastaan on tietokonepeli. Niin, mikä on tietokonepeli? Ted Nelson (jota luultavasti tässä kurssissa vielä moneen kertaan tulen lainaamaan :) sanoi, että tietokonepelit ovat kaikista parhaita tietokoneohjelmia, todellista interaktiivista ohjelmistoa. Miksi näin? Hän sanoi sen johtuvan siitä, että toisin kuin muita ohjelmia, tietokonepelejä tehdään tunteella ja siksi ehkä hieman paremmin. Mutta mikä on se mikä tekee pelistä interaktiivisen ja paremman kuin jonkin hyödyllisen ohjelman? Se on käyttäjän huomioiminen! On erittäin tärkeää, että pelaaja tuntee, että hän osaa ja pystyy pelaamaan peliä ilman että hänen tarvitsee lukea tuhatsivuista tai edes sivun mittaista ohjekirjaa.</p>
<p>Siis&#8230; Miten tehdä pelistä sellainen että se miellyttää käyttäjää ja että hän tuntee heti olevansa &#8220;kotonaan&#8221; pelin äärellä? Ensimmäiseksi, mikä tulee olemaan pelin kohderyhmä? Kenelle peli on tarkoitettu. Tämä on tärkeä tehdä selväksi heti projektin alkuvaiheissa, koska kaikkia ei voi miellyttää. Siispä mieti, kuka tätä peliä tulee pelaamaan (vastaus voi olla ihan mikä vaan, esimerkiksi naapurin mummo, tai vaikka vain sinä ja pari kaveriasi &#8211; tai ehkä jopa suuri joukko nuoria rullaluisteluammattilaisia :). Kaikista helpointa varmaan on tehdä peliä samanlaisille ihmisille kuin itse olet. Mutta mieti tätä tarkkaan. Tämän päätöksen tehtyäsi voit paljon helpommin miettiä minkä tyylistä grafiikkaa peliin pitäisi tulla, minkälaista musiikkia &#8211; ehkä juonenkäänteitä. Kaikkeen tähän vaikuttaa kohderyhmän valinta.</p>
<p>Sitten, (ei mennä vieläkään ohjelmoinnin puolelle..:), mikä on pelin juoni/tarina tms? Miksi pelaaja pelaa peliä? Tämän kurssin peliin on tosi vaikea keksiä mitään järkevää tarinaa, mutta kyllä sitäkin voi miettiä. Jos keksit jotain hyvää, pistä postia ja kerron siitä seuraavassa osassa. Mutta edetäänpä käyttöliittymään, siihen minkä välityksellä kaikki käyttäjän ja pelin välinen vuorovaikutus tapahtuu. Siihen osaan peliä, joka ensimmäiseksi näkyy käyttäjälle päin.</p>
<h2>Ristinollassakin on käyttöliittymä</h2>
<div id="attachment_1525" class="wp-caption alignright" style="width: 330px"><a href="http://www.suomipelit.com/tiedostot/2002/05/risti1.gif" rel="lightbox[737]"><img class="size-full wp-image-1525" title="Pelialue voidaan jakaa esimerkiksi näin" src="http://www.suomipelit.com/tiedostot/2002/05/risti1.gif" alt="" width="320" height="200" /></a><p class="wp-caption-text">Pelialue voidaan jakaa esimerkiksi näin</p></div>
<p>Miten peliä pelataan? Käytetäänkö näppäimistöä, vai olisiko hiiri parempi? Miten peli esittää tilanteet käyttäjälle? Tässä vaiheessa kannattaa luultavasti pistää ideoita paperille ja piirrellä jokunen kuvakin käyttöliittymästä. Tässä pieni hahmotelma, jonka itse tätä kurssia varten piirtelin.</p>
<p>Okei, tuo ei ole mikään maailman mahtavin kuva, eikä sen ole tarkoituskaan sellainen olla.. Se on itse asiassa aika hutaisten tehty, ja toivoisinkin että sinä miettisit hieman pitempään ja suunnittelisit jotain vähän parempaa. Kuitenkin tuossa on muutamia ihan järkeviä perusajatuksia. Pelialue on siinä oikealla sellainen ruutupaperimainen ruudukko, johon hiirellä klikkaamalla laitellaan ristejä ja nollia. Ja sitten, kun saadaan suora aikaiseksi, voitetaan. Tuttuun tapaan ihan niinkuin koulussa.</p>
<p>Ylhäällä vasemmassa nurkassa lukee tilannetietoja, kuten kenen vuoro on, miten kauan on pelattu ja niin edelleen. Vasemmalla alareunassa on valikot. Siitä voi painaa nappulaa, josta alkaa uusi peli tai nappia josta peli loppuu. Lisäksi voidaan keksiä vielä pari muuta hauskaa nappulaa.</p>
<p>Vielä on muutamia tärkeitä asioita joita täytyy miettiä:</p>
<ul>
<li>Minkälaista grafiikkaa tullaan käyttämään? (liittyy tavallaan tuohon äskeiseen kuvaan.. joskin hieman laajempana asiana)</li>
<li>Onko peli yksin- vai moninpeli?</li>
<li>Missä järjestelmässä ja minkälaisilla koneilla peliä tullaan käyttämään?</li>
</ul>
<p>Pohdittuasi näitä kysymyksiä koita vielä keksiä jokunen muu kysymys, jota pelaaja voisi mielessään ajatella ja etsi niihin järkeviä ja hyviä vastauksia. Kirjoita kaikki nämä asiat paperille ja laita paperi talteen sellaiseen paikkaan, josta voit sitä seurata jatkuvasti pelisi kehittyessä. Se toimikoon eräänlaisena käsikirjoituksena pelisi kehittyessä, kuin sääntökirjana. Toki siihen voi aina tehdä muutoksia, mutta mieluiten vain hyvin pieniä ja kosmeettisia.<br />
Tehtäväsi tämän osan lopussa on pohtia näitä asioita ja kirjoittaa niistä tällaista suunnitteluraporttia, pistää ideat paperille, etteivät ne unohtuisi. Ajattelin, että tästä voisi tehdä hieman interaktiivisemman kurssin kuin tavallisesti. Joten ennen kuin kirjoitan seuraavan osan, toivoisin saavani sinulta palautetta ja erityisesti ideoita siitä, minkälainen sinun pelistäsi tulee. Mitä olet pohtinut? Siis, jos kirjoitat suunnitteluraporttisi koneella, lähetä se ihmeessä minulle, niin voin sitä tutkia ja mahdollisesti kommentoida. Mutta erityisesti, jotta tietäisin mitä asioita kannattaa tämän kurssin edetessä käsitellä, jotta saat kurssista mahdollisimman paljon irti!</p>
<p>Kiitos, että jaksoit seurata koko ensimmäisen osan loppuun asti, nyt vain töihin. Seuraava osa tulee mahdollisimman pian.</p>
<p><em>Artikkelin kirjoitti alun perin jalaine.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.suomipelit.com/2002/05/26/peliohjelmoinnin-peruskasitteet-osa-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows-ohjelmointi</title>
		<link>http://www.suomipelit.com/2002/02/26/windows-ohjelmointi/</link>
		<comments>http://www.suomipelit.com/2002/02/26/windows-ohjelmointi/#comments</comments>
		<pubDate>Tue, 26 Feb 2002 10:00:57 +0000</pubDate>
		<dc:creator>Suomipelit.com</dc:creator>
				<category><![CDATA[Artikkelit]]></category>
		<category><![CDATA[Käytännön oppaat]]></category>
		<category><![CDATA[c/cpp]]></category>
		<category><![CDATA[ohjelmointi]]></category>
		<category><![CDATA[win32]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.suomipelit.com/?p=805</guid>
		<description><![CDATA[Tämä artikkeli toimii pohjatietona alkavalle Microsoft DirectX -artikkelisarjalle. Artikkelissa käsitellään yksinkertaisen Windows-sovelluksen tekeminen WIN32-APIa käyttäen. Vaikka esimerkkikoodi on kirjoitettu C-kielen syntaksia mukaillen, käytetään silti tiedostoissa .cpp-päätettä, jotta ne kääntyvät C++ -kääntäjällä. Näin eri muuttujat saadaan esiteltyä lähempänä kohtaa missä niitä käytetään ja vältetään tärkeimmän koodin hautautuminen C++:n oliopohjaisuuden alle. ]]></description>
			<content:encoded><![CDATA[<p>Tämä artikkeli toimii pohjatietona alkavalle Microsoft DirectX -artikkelisarjalle. Artikkelissa käsitellään yksinkertaisen Windows-sovelluksen tekeminen WIN32-APIa käyttäen. Vaikka esimerkkikoodi on kirjoitettu C-kielen syntaksia mukaillen, käytetään silti tiedostoissa .cpp-päätettä, jotta ne kääntyvät C++ -kääntäjällä. Näin eri muuttujat saadaan esiteltyä lähempänä kohtaa missä niitä käytetään ja vältetään tärkeimmän koodin hautautuminen C++:n oliopohjaisuuden alle.</p>
<p><a href="http://www.suomipelit.com/tiedostot/2010/03/winimg.jpg" rel="lightbox[805]"><img class="alignright size-full wp-image-806" title="Microsoft Windows" src="http://www.suomipelit.com/tiedostot/2010/03/winimg.jpg" alt="" width="256" height="256" /></a>Koska kyseessä on opetustarkoitukseen tehty artikkeli, ei kaikki sen sisältämä koodi ole suoraan oikeaan ohjelmaan soveltuvaa ja muutenkin pääasiana on selkeys, ei tehokkuus.Artikkeli on pyritty jakamaan sopivan kokoisiin osioihin ja jokainen läpikäyty asia on pyritty selvittämään mahdollisimman selkokielisesti ilman aiheelle ominaisia monimutkaisia vieraskielestä johdettuja termejä. Lähdekoodi esimerkit on testattu Microsoft Visual C++ 6.0 ohjelmointiympäristössä.</p>
<p>Esimerkkien kääntymisen onnistuminen vaatii oikein asennetun WIN32 ohjelmointikirjastojen olemassaoloa.</p>
<p>Koko artikkelin lähdekoodeineen voit imuroida tästä: <a href="http://www.suomipelit.com/tiedostot/2002/02/artikkeli000.zip">artikkeli000.zip</a>.Varsinkin DOS-ympäristössä ohjelmointia tehneille Windows on aluksi hieman mystinen viesteineen ja monine muine ihmeellisyyksineen. Näitä kuitenkin tarvitaan, koska Windows on moniajava käyttöjärjestelmä. Pienellä vaivalla edellä mainitut asiat saa kuitenkin hyvinkin läpinäkyväksi itselleen, eikä niistä tarvitse ainakaan alussa hirveämmin välittää. Useimmat pelikoodaajat tarvitsevat ikkunalleen vain pienimuotoisen viestinkäsittelyn ja tuskin koskaan WIN32 APIn hankalampia osia. Ensimmäinen huomattava ero DOS:iin tehtyyn C/C++-ohjelmaan verrattuna Windows-ohjelmassa on main()-funktion puuttuminen. Se on korvattu Windowsin omalla <strong>WinMain()</strong> -funktiolla:</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">INT WINAPI WinMain<span style="color: #009900;">&#40;</span> HINSTANCE hInstance<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HINSTANCE hPreviousInstance<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPSTR &nbsp; &nbsp; lpCmdLine<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INT &nbsp; &nbsp; &nbsp; nCmdShow <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
</pre>
<p>Kuten näkyy, WinMain -funktio eroaa tavallisesta main-funktiosta suhteellisen paljon. Ainoastaan <strong>lpCmdLine</strong> voi näyttää tutummalta. Kyseessä onkin vanhan tutun argv, argc -parin Windows-vastine. Se sisältää ohjelmaa käynnistäessä annetut komentokehoteparametrit. HINSTANCE-muuttujat saavat nimensä Instance Handle -sanaparista. Handle (suomeksi kahva) on nimensä mukaisesti kiinnityskohta ohjelman ilmentymään (engl. instance) Windowsissa. Windowsin täytyy tietää koko ajan mitä ohjelmia on käytössä, joten Windows luo muistiin ilmentymän ohjelmasta ja seuraa sen avulla ohjelman toimintaa. <strong>hInstance</strong> on kahva nykyiseen ilmentymään, eli käynnissä olevaan ohjelmaan. Win32 -ohjelmissa <strong>hPreviousInstance</strong> on kahva ohjelman edelliseen ilmentymään ja on aina arvoltaan NULL. Viimeinen parametri, <strong>nCmdShow</strong>, kertoo kuinka ikkuna näkyy ruudulla (esimerkiksi minimoituna tehtäväpalkkiin tai maksimoituna peittäen koko ruudun).<br />
Usein WinMain()-funktiossa aivan ensimmäiseksi luodaan ikkuna. Koska Windows on moniajava käyttöjärjestelmä, se tarkoittaa hieman suurempaa koodimäärää kuin tavallinen main()-funktio veisi. Seuraava koodi esittelee ensimmäisen käyttämämme WinMain()-funktion, viestinkäsittelijä- sekä ikkunanluontifunktioiden prototyypit.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;height:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">#include &lt;windows.h&gt;</span><br />
<br />
<span style="color: #666666; font-style: italic;">//</span><br />
<span style="color: #666666; font-style: italic;">// Funktioiden prototyyppejä</span><br />
<span style="color: #666666; font-style: italic;">// </span><br />
<br />
LRESULT CALLBACK ViestienKasittelija<span style="color: #009900;">&#40;</span> HWND hWnd<span style="color: #339933;">,</span> UINT Viesti<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; WPARAM wParam<span style="color: #339933;">,</span> LPARAM lParam <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
HRESULT LuoIkkuna<span style="color: #009900;">&#40;</span> HINSTANCE hInstance<span style="color: #339933;">,</span> INT nCmdShow <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <br />
<br />
<span style="color: #666666; font-style: italic;">//--------------------------------------------</span><br />
<span style="color: #666666; font-style: italic;">// Nimi &nbsp;: WinMain()</span><br />
<span style="color: #666666; font-style: italic;">// Kuvaus: Ohjelman pääfunktio.</span><br />
<span style="color: #666666; font-style: italic;">//--------------------------------------------</span><br />
INT WINAPI WinMain<span style="color: #009900;">&#40;</span> HINSTANCE hInstance<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HINSTANCE hPreviousInstance<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPSTR &nbsp; &nbsp; lpCmdLine<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INT &nbsp; &nbsp; &nbsp; nCmdShow <span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Luodaan ikkuna</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; LuoIkkuna<span style="color: #009900;">&#40;</span> hInstance<span style="color: #339933;">,</span> nCmdShow <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Mennään silmukkaan kunnes ohjelma halutaan</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// lopettaa.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; MSG viesti<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span> viesti.<span style="color: #202020;">message</span> <span style="color: #339933;">!=</span> WM_QUIT <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Kurkistetaan onko saapuneita viestejä.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> PeekMessage<span style="color: #009900;">&#40;</span> <span style="color: #339933;">&amp;</span>viesti<span style="color: #339933;">,</span> NULL<span style="color: #339933;">,</span> 0U<span style="color: #339933;">,</span> 0U<span style="color: #339933;">,</span> PM_REMOVE <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Jos viesti on saapunut se pitää käsitellä.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TranslateMessage<span style="color: #009900;">&#40;</span> <span style="color: #339933;">&amp;</span>viesti <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DispatchMessage<span style="color: #009900;">&#40;</span> <span style="color: #339933;">&amp;</span>viesti <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #b1b100;">else</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Ei viestejä. Suoritetaan ohjelmaa.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// </span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Poistetaan ikkunaluokka muistista.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; UnregisterClass<span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;IkkunaLuokanNimi&quot;</span><span style="color: #339933;">,</span> hInstance <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Palautetaan 0 onnistuneen poistumisen merkiksi.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>LuoIkkuna()-funktio luo nimensä mukaisesti ohjelman käyttämän ikkunan, ja se esitellään seuraavaksi. Sitä ennen tutustutaan kuitenkin yllä olevan koodin while-silmukkaan. Kyseessä on ensimmäinen osa Windowsin viestienkäsittelystä. Ennen while-silmukkaa luodaan <strong>viesti</strong>-niminen muuttuja, joka on tyypiltään MSG (lyhennys engl. sanasta Message, viesti). Yllä esittellään nk. <strong>idle-silmukka</strong>, jossa ohjelmakoodia suoritetaan aina kun viestejä ei käsitellä. Ohjelma on Windowsin näkökulmasta toimeton (eli englanniksi idle) aina, kun viestejä ei käsitellä.</p>
<p>Aivan ensimmäiseksi while-lauseessa tarkistetaan viestin sisältö. Jos viestin arvoksi on saatu <strong>WM_QUIT</strong>, ohjelman tulee sammuttaa itsensä. Jos viestin arvo on jokin muu kurkataan (engl. peek, kurkistaa) ikkunan viestijonoa ja hankitaan viesti-muuttujaan uusi sisältö<strong>PeekMessage()</strong>- funktiolla. PeekMessage() ottaa parametreinaan täytettävän viestin osoittimen, tarkistettavan ikkunan kahvan, alimman tarkistettavan viestin arvon, ylimmän tarkistettavan viestin arvon, sekä toiminnon mikä viestille tehdään kun se on tarkistettu. Nyt toisena parametrina on NULL, joka kertoo että haluamme viesti-muuttujaan arvon miltä tahansa ohjelman ikkunalta. Jos laittaisimme siihen alempana olevassa LuoIkkuna()-funktiossa saamamme ikkunan kahvan, tarkistettavaksi saataisiin vain sen ikkunan viestit. Kolmas ja neljäs parametri sallivat viestien suodattamisen, johon ei nyt tarkemmin tutustuta. Viides parametri (PM_REMOVE) ilmoittaa että haluamme poistaa viestin ohjelman viestijonosta sen jälkeen, kun olemme siirtäneet sen viesti-muuttujaan.</p>
<p>Jos PeekMessage()-funktio kertoo että viestejä on saatu, käytämme <strong>TranslateMessage()</strong>-funktiota kääntämään virtual-key -komennot (ohjelmaan määritellyt erikoisnäppäinkomennot, esim. ctrl+F1) kirjainmuotoiseksi viestiksi. Tämän jälkeen <strong>DispatchMessage()</strong>-funktio lähettää käännetyn viestin sopivalle viestinkäsittelijäfunktiolle. Nyt teemme funktion, joka varsinaisesti luo ikkunan. Funktio ottaa parametreinaan kahvan ohjelman ilmentymään sekä tiedon ohjelman tilasta (esim. minimoitu).</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">//--------------------------------------------</span><br />
<span style="color: #666666; font-style: italic;">// Nimi &nbsp;: LuoIkkuna()</span><br />
<span style="color: #666666; font-style: italic;">// Kuvaus: Luo ikkunan. Palauttaa S_OK</span><br />
<span style="color: #666666; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; jos siinä onnistuttiin, FALSE</span><br />
<span style="color: #666666; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; muulloin.</span><br />
<span style="color: #666666; font-style: italic;">//--------------------------------------------</span><br />
HRESULT LuoIkkuna<span style="color: #009900;">&#40;</span> HINSTANCE hInstance<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;INT nCmdShow <span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; HWND hWnd<span style="color: #339933;">;</span> &nbsp; <span style="color: #666666; font-style: italic;">// WindowHandle, eli kahva ikkunan ilmentymään</span><br />
&nbsp; &nbsp; WNDCLASS wc<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Ikkunaluokka</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Täytetään ikkunaluokan tiedot.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">style</span> &nbsp; &nbsp; &nbsp; <span style="color: #339933;">=</span> CS_HREDRAW <span style="color: #339933;">|</span> CS_VREDRAW<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">lpfnWndProc</span> <span style="color: #339933;">=</span> ViestienKasittelija<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">cbClsExtra</span> &nbsp;<span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">cbWndExtra</span> &nbsp;<span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">hInstance</span> &nbsp; <span style="color: #339933;">=</span> hInstance<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">hIcon</span> &nbsp; &nbsp; &nbsp; <span style="color: #339933;">=</span> LoadIcon<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>HINSTANCE<span style="color: #009900;">&#41;</span> NULL<span style="color: #339933;">,</span>IDI_APPLICATION<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">hCursor</span> &nbsp; &nbsp; <span style="color: #339933;">=</span> LoadCursor<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>HINSTANCE<span style="color: #009900;">&#41;</span> NULL<span style="color: #339933;">,</span>IDC_ARROW<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">hbrBackground</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>HBRUSH<span style="color: #009900;">&#41;</span>GetStockObject<span style="color: #009900;">&#40;</span>WHITE_BRUSH<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">lpszMenuName</span> &nbsp;<span style="color: #339933;">=</span> NULL<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">lpszClassName</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;IkkunaLuokanNimi&quot;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Yritetään rekisteröidä ikkunaluokka.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>RegisterClass<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>wc<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> FALSE<span style="color: #339933;">;</span> <br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Palautetaan onnistumisen merkiksi S_OK.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> S_OK<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Tässä kohtaa on syytä pysähtyä hetkeksi ja tarkastella lähemmin mitä saatiin aikaiseksi. Ylläoleva koodi tekee ensin muuttujan wc, joka kuvastaa ikkunaluokkaa. Se siis kertoo Windowsille millaisen ikkunan tulemme piakkoin luomaan. Tarkastellaan wc:n jäsenmuuttujia hieman tarkemmin:</p>
<p><strong>wc.Style:</strong><br />
Style määrittää ikkunaluokan tyylin. Arvot CS_VREDRAW ja CS_HREDRAW kertovat, että haluamme koko ikkunan päivittyvän kun sitä liikutellaan tai kun sen kokoa muutellaan. Tyylimuuttujia on Windowsissa lukematon määrä, ja niihin voi jokainen tutustua omalla ajallaan.</p>
<p><strong>wc.lpfnWndProc</strong><br />
Osoitin ikkunaluokan viestienkäsittelijä-funktioon.</p>
<p><strong>wc.cbClsExtra</strong><br />
Määrittää ikkunaluokan jälkeen varattavien lisätavujen määrän. Useimmiten arvo on 0.</p>
<p><strong>wc.cbWndExtra</strong><br />
Määrittää ikkunan ilmentymän jälkeen varattavien lisätavujen määrän Useimmiten arvo on 0.</p>
<p><strong>wc.hInstance</strong><br />
Kahva ikkunan omistavan ohjelman ilmentymään (<em>HINSTANCE</em>).</p>
<p><strong>wc.hIcon</strong><br />
Kahva ikkunaluokan käyttämään ikoniin. LoadIcon()-funktio lataa nyt Windowsin perusikonin.</p>
<p><strong>wc.hCursor</strong><br />
Kahva ikkunaluokan käyttämään kursoriin. Taas kerran käytetään Windowsin valmiskursoria LoadCursor()-funktion avulla.</p>
<p><strong>wc.hbrBackground</strong><br />
Kahva ikkunaluokaan tausta siveltimeen. Windows käyttää eri kyniä, siveltimiä, fontteja ja paletteja (<em>pen, brush, font ja palette</em>) ikkunoiden piirtelyyn. Tähän aiheeseen ei nyt tarkemmin puututa.  GetStockObject()-funktiolla ladataan vain valmiiksi määritelty väri, tässä tapauksessa valkoinen.</p>
<p><strong>wc.lpszMenuName</strong><br />
Osoitin merkkijonoon joka ilmoittaa ikkunaluokan valikon nimen (<em>valikko täytyy olla resurssina sillä nimellä</em>).</p>
<p><strong>wc.lpszClassName</strong><br />
Ikkunaluokan nimi</p>
<p>Kun sopivat arvot ylläoleviin muuttujiin on asetettu, luokka rekisteröidään Windowsiin RegisterClass()-funktiolla. Jos rekisteröinti onnistuu, voi wc:ssä kuvaamasi ikkunan luoda. Jos ei, on parempi lopettaa ohjelman ajaminen samantien. Ikkunaa ei voi luoda jos sitä ei voi kuvailla.</p>
<p>Lisätään aiemmin esiteltyyn koodiin vielä pari kohtaa, jotka viimeistelevät ikkunan luomisen.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;height:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">//--------------------------------------------</span><br />
<span style="color: #666666; font-style: italic;">// Nimi &nbsp;: LuoIkkuna()</span><br />
<span style="color: #666666; font-style: italic;">// Kuvaus: Luo ikkunan. Palauttaa S_OK</span><br />
<span style="color: #666666; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; jos siinä onnistuttiin, FALSE</span><br />
<span style="color: #666666; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; muulloin.</span><br />
<span style="color: #666666; font-style: italic;">//--------------------------------------------</span><br />
HRESULT LuoIkkuna<span style="color: #009900;">&#40;</span> HINSTANCE hInstance<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;INT nCmdShow <span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; HWND hWnd<span style="color: #339933;">;</span> &nbsp; <span style="color: #666666; font-style: italic;">// WindowHandle, eli kahva ikkunan ilmentymään</span><br />
&nbsp; &nbsp; WNDCLASS wc<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Ikkunaluokka</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Täytetään ikkunaluokan tiedot.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">style</span> &nbsp; &nbsp; &nbsp; <span style="color: #339933;">=</span> CS_HREDRAW <span style="color: #339933;">|</span> CS_VREDRAW<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">lpfnWndProc</span> <span style="color: #339933;">=</span> WndProc<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">cbClsExtra</span> &nbsp;<span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">cbWndExtra</span> &nbsp;<span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">hInstance</span> &nbsp; <span style="color: #339933;">=</span> hInstance<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">hIcon</span> &nbsp; &nbsp; &nbsp; <span style="color: #339933;">=</span> LoadIcon<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>HINSTANCE<span style="color: #009900;">&#41;</span> NULL<span style="color: #339933;">,</span>IDI_APPLICATION<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">hCursor</span> &nbsp; &nbsp; <span style="color: #339933;">=</span> LoadCursor<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>HINSTANCE<span style="color: #009900;">&#41;</span> NULL<span style="color: #339933;">,</span>IDC_ARROW<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">hbrBackground</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>HBRUSH<span style="color: #009900;">&#41;</span>GetStockObject<span style="color: #009900;">&#40;</span>WHITE_BRUSH<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">lpszMenuName</span> &nbsp;<span style="color: #339933;">=</span> NULL<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; wc.<span style="color: #202020;">lpszClassName</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;IkkunaLuokanNimi&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Yritetään rekisteröidä ikkunaluokka.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>RegisterClass<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>wc<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> FALSE<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Yritetään luoda ikkuna.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; hWnd <span style="color: #339933;">=</span> CreateWindow<span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;IkkunaLuokanNimi&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;Esimerkkiohjelma&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WS_OVERLAPPEDWINDOW<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CW_USEDEFAULT<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CW_USEDEFAULT<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CW_USEDEFAULT<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CW_USEDEFAULT<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#40;</span>HWND<span style="color: #009900;">&#41;</span> &nbsp;NULL<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#40;</span>HMENU<span style="color: #009900;">&#41;</span> NULL<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hInstance<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#40;</span>LPVOID<span style="color: #009900;">&#41;</span> NULL <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Jos kahvaa ikkunan ilmentymään ei saada,</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// ikkunan luonti epäonnistui. Palautetaan siis</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// FALSE.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span>hWnd <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> FALSE<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Näytetään ikkuna ja päivitetään sen sisältö.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; ShowWindow<span style="color: #009900;">&#40;</span> hWnd<span style="color: #339933;">,</span> nCmdShow<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; UpdateWindow<span style="color: #009900;">&#40;</span> hWnd <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Palautetaan onnistumisen merkiksi S_OK.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> S_OK<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Varsinainen ikkuna luodaan CreateWindow() -funktiolla, joka ottaa seuraavat parametrit:</p>
<p><strong>lpClassName</strong><br />
Ikkunaluokan nimi. Tässä käytettävä ikkunaluokka on oltava rekisteröity.</p>
<p><strong>lpWindowName</strong><br />
Ikkunan otsikko. Näkyy luotavan ikkunan vasemmassa yläreunassa, sekä tehtäväpalkissa.</p>
<p><strong>dwStyle</strong><br />
Ikkunan tyyppi. Nyt tyyliksi määritetään WS_OVERLAPPEDWINDOW, joka luo ikkunan jonka kokoa voi muuttaa ja jolla on otsikkorivi jossa on ikkuna-valikko (<em>eli valikko joka ilmaantuu ikkunan ikonia painettaessa</em>).</p>
<p><strong>x</strong><br />
Ikkunan paikka X-akselilla. Nyt käytämme Windowsin perusarvoja.</p>
<p><strong>y</strong><br />
Ikkunan paikka Y-akselilla.</p>
<p><strong>nWidth</strong><br />
Ikkunan leveys.</p>
<p><strong>nHeight</strong><br />
Ikkunan korkeus.</p>
<p><strong>hWndParent</strong><br />
Kahva ikkunan isäntä-ikkunaan. Tämä on nyt NULL, koska luomme vain yhden ikkunan.</p>
<p><strong>hMenu</strong><br />
Kahva ikkunan valikkoon. Valikot luodaan ikkunan resurssi-tiedostoon. Taas kerran arvoksi asetetaan nyt NULL, koska emme tarvitse valikkoa.</p>
<p><strong>hInstance</strong><br />
Kahva ikkunaa käyttävän ohjelman ilmentymään (<em>hInstance</em>).</p>
<p><strong>lpParam</strong><br />
Mahdollinen osoitin ikkunan tarvitsemaan lisätietoon. Tätä käytetään MDI-ikkunoita (Multiple Document Interface, Usean Asiakirjan Liittymä, eli monta ikkunaa yhden ison ikkunan sisällä) käytettäessä, joten se on nyt NULL.</p>
<h2>Viestien käsittelyä</h2>
<p>Viestien käsittely on yksi Windows-ohjelmoinnin olennaisimpia osia. Windows-ohjelmat joutuvat käsittelemään viestejä aina kun jotakin ohjelman nappia tai muuta osaa painetaan tai muokataan. Viestien avulla selvitetään esimerkiksi vierityspalkkien liikkeet. Ruudulla näkyvän graafisen osan alla on siis todellinen viestien sekamelska, jota ohjelmat tulkitsevat viestienkäsittelyfunktoillaan.</p>
<h2>Käsittelijäfunktio</h2>
<p>Alla oleva koodi on koko viestienkäsittelyfunktio mitä tässä esimerkissä käytämme. Kaikessa yksinkertaisuudessaan se käsittelee vain ikkunan sulkemisviestin.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">//--------------------------------------------</span><br />
<span style="color: #666666; font-style: italic;">// Nimi &nbsp;: ViestienKasittelija()</span><br />
<span style="color: #666666; font-style: italic;">// Kuvaus: Funktio joka käsittelee ikkunan</span><br />
<span style="color: #666666; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; viestit.</span><br />
<span style="color: #666666; font-style: italic;">//--------------------------------------------</span><br />
LRESULT CALLBACK ViestienKasittelija<span style="color: #009900;">&#40;</span>HWND &nbsp; hWnd<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;UINT &nbsp; Viesti<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WPARAM wParam<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPARAM lParam<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Tutkitaan mikä viesti saatiin ja tehdään</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// jotain sen mukaisesti.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span> Viesti <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">case</span> WM_DESTROY<span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Tuhoamisviesti. Lähetetään</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Lopetusviesti ja palautetaan</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// TRUE, eli &quot;viesti käsitelty&quot;.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PostQuitMessage<span style="color: #009900;">&#40;</span> <span style="color: #0000dd;">0</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; returnTRUE<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Tuntematon viesti. Annetaan windowsin</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// perusviestinkäsittelijän käsitellä viesti.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> DefWindowProc<span style="color: #009900;">&#40;</span> hWnd<span style="color: #339933;">,</span> Viesti<span style="color: #339933;">,</span> wParam<span style="color: #339933;">,</span> lParam <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Yllä oleva funktio toimii käytännössä siten, että ensin katsotaan viestit joista ollaan kiinnostuneita. Jos yhtään kiinnostavaa viestiä ei ole saapunut, annetaan Windowsissa valmiina olevan viestinkäsittelijän käsitellä viesti.</p>
<h2>Loppusanat</h2>
<p>Nyt, kun olet lukenut artikkelin, hallitset pienimuotoisen Windows-sovelluksen tekemisen. Kovin paljoa tätä enempää ei Windows-ohjelmointi osaamista DirectX-ohjelmointiin vaadita. Jotta tiedot kuitenkin painuisivat tarkemmin muistiin on syytä muokkailla annettua esimerkkiohjelmaa. Kuten huomasitkin, kaikissa tapauksissa ei tarkisteta virhetilanteita. Harjoitukseksi jääkin kyseisten tilanteiden etsiminen ja niistä selviytyminen.</p>
<p>Kiitokset Risto Karjalaiselle sekä Jussi Huhtiniemelle avusta artikkelin teossa.</p>
<hr /><em>Artikkelin kirjoitti alun perin Jarkko Parviainen.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.suomipelit.com/2002/02/26/windows-ohjelmointi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grafiikkakurssi 2</title>
		<link>http://www.suomipelit.com/2001/12/03/grafiikkakurssi-2/</link>
		<comments>http://www.suomipelit.com/2001/12/03/grafiikkakurssi-2/#comments</comments>
		<pubDate>Mon, 03 Dec 2001 10:00:55 +0000</pubDate>
		<dc:creator>Suomipelit.com</dc:creator>
				<category><![CDATA[Artikkelit]]></category>
		<category><![CDATA[Käytännön oppaat]]></category>
		<category><![CDATA[2d]]></category>
		<category><![CDATA[alkeet]]></category>
		<category><![CDATA[allegro]]></category>
		<category><![CDATA[c/cpp]]></category>
		<category><![CDATA[grafiikka]]></category>
		<category><![CDATA[ohjelmointi]]></category>

		<guid isPermaLink="false">http://www.suomipelit.com/?p=814</guid>
		<description><![CDATA[Tämä grafiikkakurssi 2 on jatkoa edelliselle grafiikkakurssilleni, 2D-grafiikan alkeet Allegroa käyttäen. Ykkösosassa opetttelimme yksinkertaisia piirtofunktioita ja piirsimme kuvia. Tässä kakkososassa menemme hieman pidemmälle. Opettelemme käyttämään Allegron BITMAP:pejä ja piirustusohjelmilla piirrettyjä pcx- ja bmp-kuvia. Lopuksi luomme pienen katsauksen peleissä käytettyihin kikkoihin.]]></description>
			<content:encoded><![CDATA[<p>Tämä grafiikkakurssi 2 on jatkoa edelliselle grafiikkakurssilleni, 2D-grafiikan alkeet Allegroa käyttäen. Ykkösosassa opetttelimme yksinkertaisia piirtofunktioita ja piirsimme kuvia. Tässä kakkososassa menemme hieman pidemmälle. Opettelemme käyttämään Allegron BITMAP:pejä ja piirustusohjelmilla piirrettyjä pcx- ja bmp-kuvia. Lopuksi luomme pienen katsauksen peleissä käytettyihin kikkoihin.</p>
<h2>Virkistetään muistia</h2>
<p>Oletan, että olet lukenut ykköskurssin grafiikasta ja käyn siksi nämä perusasiat Allegron käyttämisestä vain nopeasti läpi. Jos kaipaat tarkempaa selvitystä, löydät sen artikkelista, 2D-grafiikan alkeet Allegroa käyttäen.</p>
<p><strong>allegro_init();</strong><br />
Tämä funktio alustaa Allegron niin, että se on valmis käytettäväksesi. Muista kutsua tätä ennen kuin käytät muita Allegron funktioita</p>
<p><strong>set_gfx_mode();</strong><br />
Tällä funktiolla asetat grafiikkatilan haluamaksesi.</p>
<p><strong>allegro_exit();</strong><br />
Muista laittaa tämä funktiokutsu ohjelmasi loppuun. Se lopettaa Allegron käytön.</p>
<p><strong>install_keyboard();</strong><br />
Jos haluat käyttää Allegron näppäimistöfunktioita, kutsu tätä funktiota ohjelmasi alussa.</p>
<p>Nuo ovat ne asiat, jotka sinun on ykkösosasta muistettava, muita pohjatietoja et tarvitse. Ja sitten asiaan!</p>
<h2>Mitä ovat bitmapit?</h2>
<p>Kurssin edellisessä osassa en vielä viitsinyt sekoittaa sinua bitmapeillä, mutta silti tietämättäsi (tai tietoisesti) niitä käytit. Nimittäin aina kun kirjoitit johonkin kohtaan screen käytit yhtä bitmappien erikoistyyppiä, joka esittää näyttöä. Mutta eiköhän selvitetä tämä bitmap-asia nyt alusta alkaen&#8230;</p>
<p>Allegrossa oikeastaan kaikkien grafiikkafunktioiden pohjana on BITMAP, joka tarkoittaa bittikarttaa. Oikeastaan sitä voisi ajatella jonkinlaisena piirtopohjana. DirectX:ssä niitä nimitetäänkin pinnoiksi. En halua sinua sekoittaa, mutta toivoin tuon selkeyttävän asiaa. Siis, kun piirrät, piirrät aina jollekin bitmapille, piirtopinnalle.</p>
<p>Voit luoda itse bitmappejä esittelemällä ne ikäänkuin muuttujina seuraavaan tapaan:</p>
<pre>BITMAP *kuva;</pre>
<p>Siis tuossa esiteltiin kuva-niminen bitmappi. Tai itse asiassa siinä esiteltiin osoitin bitmappiin, jota ei vielä ole olemassa. Tätä osoitinajattelua sinun ei kuitenkaan vielä ole pakko ymmärtää, joten jatka vain eteenpäin. Sen koon ja muut sellaiset asiat voit määritellä kahdella tavalla. Ensimmäinen tapa on luoda kuva create_bitmap-funktiolla, esimerkiksi:</p>
<pre>kuva=create_bitmap(320,200);</pre>
<p>Siinä siis luotiin kuvapinta, joka on 320 pikseliä leveä ja 200 korkea. Ja jos puhutaan osoittimista, niin nyt kuva-osoitin osoittaa uuteen bitmappiin, joka on olemassa. Mutta kuva esittää nyt siis joka tapauksessa tuota uutta piirtoalustaa.</p>
<p>Toinen tapa on helpompi, koska se tapahtuu kuvan lataamisen yhteydessä itsestään. Puhutaan siitä kuitenkin lisää vähän myöhemmin.</p>
<p>Ja sitten kun et enää tarvitse kuvaa, kutsu funktiota destroy_bitmap, joka poistaa kuvan muistista. Esimerkiksi näin poistaisimme muistista tuon vähän aikaa sitten luodun kuva-bitmapin:</p>
<pre>destroy_bitmap(kuva);</pre>
<p>Näitä asioita harjoittelemme pian käytännössä. Kyllä ne sitten tulevat paremmin tutuiksi ja toivottavasti myös jokseenkin rutiiniksi.</p>
<h2>Syvemmälle paletteihin</h2>
<p>Myös paletteja katsoimme pikkuisen ja niiden perusperiaatteen taisinkin jo selittää. Puhuimme niistä RGB-structeista ja laittelimme palettiin värejä. Se oli kuitenkin vielä suhteellisen hankalaa.. Nyt katsomme paletteja hieman tarkemmin ja otamme käyttöön helpompia tapoja käyttää paletteja.</p>
<p>Siis muistathan, että jokainen paletin 256 väristä esitetään RGB-structeissa ilmoittamalla niiden punaisen, vihreän ja sinisen värin komponentit.</p>
<p>Paletti on Allegrossa 256 RGB-structin taulukko, joka on nimeltään PALETTE. Jos siis haluat tehdä uuden paletin, esittelet sen muuttujana seuraavasti:</p>
<pre>PALETTE oma_paletti;</pre>
<p>Siis tuossa loimme paletin nimeltä oma_paletti.</p>
<p>Silloin, kun viimeksi paleteista puhuimme, täyttelimme itse muutamia värejä palettiin. Paletin voit kuitenkin täyttää helpomminkin, niin, että sinun ei melkein tarvitse edes huomata käyttäväsi paletteja. Nimittäin kuvanlatausfunktio, johon paneudumme seuraavassa kappaleessa ottaa yhtenä syötteenä osoittimen palettiisi ja täyttää sen kuvan väreillä. Mutta siitä lisää seuraavassa kappaleessa. Tässä kakkoskurssissa ei tämän enempää paleteista puhuta, paitsi että seuraavassa kappaleessa tulee aika paljon palettiasiaa, kolmoskurssissa olen ajatellut kertoa sitten vielä muutamia hauskoja palettikikkailuja.</p>
<h2>Ladataan kuva</h2>
<p>Jees. Alku tähän asti on kaikki ollut oikeastaan johdantoa kuvien lataamiselle. No, onhan noista asioista muutenkin hyötyä, mutta ainakin nyt pääsemme tekemään hauskempia juttuja..</p>
<p>Kuvan, jonka nyt lataamme on oltava 256-värinen BMP- tai PCX-kuva. Lataamme sen omaan bitmappiinsä ja otamme myös kuvan paletin talteen. Tehdään tästä kokonainen ohjelma vaikkakin paloittain.. Nyt se alkaa:</p>
<pre>  #include &lt;allegro.h&gt;
  #include &lt;stdio.h&gt;

  int main(void)
  {
	BITMAP *kuva;</pre>
<p>No niin.. Siinä tulivat alkujutut, jotka ovat jo varmasti tulleet sinulle tutuiksi ja niiden jälkeen kuva-bitmappimme esittely. Jatketaan..</p>
<pre>  	PALETTE paletti;</pre>
<p>Ja sitten luotiin paletti nimeltään paletti. Huomaa, että tässä vaiheessa kuvaa ei oikeastaan ole edes olemassa, sille ei ole varattu muistia, eikä paletissa ole mitään tietoja. Niitä ei siis vielä saa käyttää muuten kuin luomalla uusi kuva, minkä teemme tuossa kohtapuolin.</p>
<pre>	// Allegron alustukset
	allegro_init();
	install_keyboard();
	set_gfx_mode(GFX_AUTODETECT,640,480,0,0); 

	// Ladataan kuva
	kuva=load_bitmap("kuva.pcx",&amp;paletti);</pre>
<p>Siinä tulikin tärkeä rivi. Niin tärkeä, että pysähdytäänpä tähän hetkeksi.</p>
<p>Nimittäin tuo on se funktio, joka lataa kuvan bitmappiin (tässä tapauksessa tuohon minkä nimi on kuva) ja paletin. Funktion palautusarvo on siis BITMAP *, mikä tarkoittaa että se palauttaa kuvan, eikä mitä tahansa kuvaa vaan sen kuvan, jonka nimi on mainittu ensimmäisenä funktion parametrinä lainausmerkeissä (kuva.pcx, voisi olla myös kuva.bmp tai vaikka ihan mikä vaan kunhan se on jotain seuraavista tyypeistä: bmp, pcx, lbm ja tga). Paletin se lataa siihen palettiin, jonka nimi on toisena parametrina. Palettejahan voi esitellä niin monta kuin vain haluaa, mutta vain yhtä kerrallaan käytetään ruudulle piirrettäessä, nimittäin sitä, joka on valittu käytettäväksi paletiksi funktiolla set_palette. Mutta se tulee ohjelmassa seuraavaksi, joten eiköhän jatketa eteenpäin.</p>
<pre>	// valitaan käytettävä paletti
	set_palette(paletti);

	// piirretään kuva näytölle
	blit(kuva,screen,0,0,0,0,kuva-&gt;w,kuva-&gt;h);</pre>
<p>Tuosta blit-rivistä sinun ei tarvitse vielä välittää, laitoin sen tuohon, jotta näkisit että kuva on latautunut oikein. Se siis piirtää kuvan ruudulle, mutta puhutaan siitä seuraavassa kappaleessa, joka on kokonaan omistettu juuri tälle funktiolle. Ohjelman lopun pitäisi olla sinulle aika tuttua:</p>
<pre>	// odotellaan että joku painaa spacea
	while(!key[KEY_SPACE]){}

	// lopetetaan Allegro
	allegro_exit();

	return(0);
}</pre>
<p>Noin, nyt on kuva ladattu ja toivottavasti myös lataamisen toimet ymmärretty. Voinemme siis siirtyä tutkimaan erilaisia tapoja piirtää näitä ladattuja kuvia näytölle.</p>
<h2>Länttäillään kuvat ruudulle</h2>
<p>Kun olemme ladanneet kuvan tai kuvia, on ne tietenkin piirrettävä ruudulle. Tähän tarkoitukseen Allegro tarjoaa kaksi funktiota, itse voit tietenkin kehitellä niitä lisää.. Mutta pitäydytään nyt vielä Allegron funktioissa.</p>
<p>Yksinkertaisin kuvanruudullepiirtofunktio on blit, joka vain länttää kuvan haluamaasi paikkaan toisessa bitmapissä. Eiköhän siis jätetä jaarittelut väliin ja mennä käytäntöön.</p>
<p>Siis&#8230; Blit-funktiolla voit kopioida yhdestä bitmapistä haluamasi kokoisen palan toiseen funktioon. Otetaan esimerkki samantien.</p>
<pre>blit(kuva,screen,0,0,100,100,30,30);</pre>
<p>Tuossa siis kopioidaan kuva-bitmapista kohdasta 0,0 alkaen 30 pikseliä leveä ja 30 pikseliä korkea palanen screen-bitmappiin eli näytölle kohtaan 100,100. Tulikohan tuo tuosta yhtään selvemmäksi? Toivottavasti, sillä nyt mennään eteenpäin.</p>
<p>Blit-funktio on erityisen käyttökelpoinen, jos halutaan piirtää esimerkiksi isoja nelikulmaisia kuvia, esimerkiksi pelien taustoja. Mutta jos haluamme piirtää pallon tai jonkin muun epämääräisen muotoisen kuvan, jättää blit kuvion ympärille ärsyttävät nelikulmaiset reunat. Mutta onneksi on myös toinen funktio, siitä seuraavassa kappaleessa.</p>
<h2>Liikkuvia kuvia, eli spritejä</h2>
<p>No niin. Nyt siis olisi tarkoitus tutustua spriteihin. Käytännössä sprite on bitmappi. Ennenmuinoin, silloin kuusnelosten aikaan, spritet olivat jotain aivan erilaista, mutta ei siitä sen enempää. Jos se aika kiinnostaa, varmaan netistä löytyy paljonkin kuusnelosasiaa, ja täälläkin ehkä joskus saatan niistä jutuista kirjoitella.</p>
<p>Siis. Sprite on Allegrossa bitmappi, ei sen kummempaa. Usein spriteihin liitetään myös ajatus siitä, että ne ovat ikäänkuin pelin liikkuvia objekteja. Näin saattaa usein olla, mutta ei suinkaan aina.</p>
<p>Okei, enköhän ole sekoittanut sinua jo aivan tarpeeksi. Unohda kaikki edelläoleva spritehöpinä. Ei vaineskaan, kyllä ne voit muistaa, mutta niillä ei ole käytännön kanssa paljonkaan tekemistä.</p>
<p>Se mitä tässä kappaleessa varsinaisesti haluan selittää, on Allegron toinen bitmapinpiirtofunktio, draw_sprite. Se on muuten aika samanlainen kuin blit, mutta se sisältää läpinäkyvän värin.. Kaikki mikä bitmapissä on piirretty paletin värillä 0 näkyy läpinäkyvänä eli ei näy. Tämä on tosi hyödyllistä esimerkiksi, jos haluamme piirtää toisen kuvan päälle pelaajan ukon tai auton tai raketin tai vaikka mitä.</p>
<p>Ai että mitenkö se tehdään? Helppoa:</p>
<pre>draw_sprite(screen,kuva,20,20);</pre>
<p>Kas noin. Siinä siis piirrämme bitmapin kuva kokonaan bitmappiin screen, joka sattuu olemaan näyttö, kohtaan 20,20. Tämä on siis yksinkertaisempi funktio ohjelmoijan kannalta kuin blit. Sinun ei tarvitse huolehtia siitä minkä kokoinen bitmappisi on tai minkä kohdan siitä haluat piirtää. Funktio piirtää sen aina kokonaan. Sinun tarvitsee vain kertoa mihin sen haluat piirtää.</p>
<p>Näillä kahdella funktiolla pystyt tekemään vaikka mitä. Lisäksi allegrosta löytyy pari erikoisempaa piirtofunktiota, mutta niistä saat ottaa itse selvää, jos ne kiinnostavat. Lisäksi voit tehdä omia blittisysteemejä, esimerkiksi osittain läpinäkyvä (läpikuultava) blitti on tosi hieno efekti. Kirjoitan varmaan siitä tutoriaalin lähiaikoina.</p>
<p>Nyrkkisääntönä voinemme pitää blitin ja draw_spriten käytössä sitä, että blitillä blittaillaan taustoja ja muita isompia juttuja ja draw_spritellä piirretään peliobjektit kuten pelaaja, vastustaja, pallo&#8230; Joo, eiköhän tuo tullut selväksi. Otetaan tehtävä.</p>
<p><strong>Tehtävä:</strong> Tee ohjelma, joka lataa kaksi kuvaa ja sitten niistä toisen piirtää taustaksi blit-funktiolla ja toisen sen päälle draw_spritellä. Muistathan käyttää paletin 0-väriä draw_spritellä piirrettävän kuvan taustassa.</p>
<h2>Tehtävä</h2>
<p>Äskeisessä tehtävässä siis latasit kaksi kuvaa ja piirsit toisen taustaksi ja toisen siihen päälle draw_spritellä. Kuvia et kuitenkaan pystynyt liikuttelemaan. Nyt korjataan se puute ja lisätään tehtävän ohjelmaan liikettä.</p>
<p>Tarkoituksena on siis, että tausta pysyy edelleen paikallaan, mutta pienempää kuvaa, spriteä pystyy liikuttelemaan taustan päällä nuolinäppäimillä.</p>
<p>Mitä tarvitsemme tämän tehtävän suorittamiseen? Ensinnäkin kaksi muuttujaa säilyttämään spriten paikkaa ruudulla. Olkoot ne vaikka x ja y, inttejä tietysti. Toiseksi tarvitsemme tietysti kuvat, ne voi piirtää vaikka Paint Shop Prolla. Ja kolmanneksi tarvitsemme while-silmukan, jonka aikana luetaan näppäimistösyötettä (nuolet) ja liikutellaan kuviota sen mukaan.</p>
<p>Luulisin, että osaat tehdä sen itsekin, joten olkoon se tehtävä. PS. Jos kaikki ei näytä aivan oikealta, älä huolestu sillä seuraavassa kappaleessa tulee ratkaisu taustaongelmaan :).</p>
<h2>Korjataan taustaongelma</h2>
<p>Kuten ennen tehtävää lupasin, tulee nyt ratkaisu sinua varmaankin pitkään askarruttaneeseen ongelmaan. Eikös vain käynytkin niin, että kun liikutit spriteä, jäi vanha kuva taustakuvaan &#8220;kiinni&#8221; ja seurauksena oli vain sotkua? Jos näin ei käynyt, olet luultavasti huijannut ja piirtänyt taustankin joka kerta uudestaan. Sehän ei toki ole kiellettyä, mutta paljon hitaampaa. Siksi tässä tulee nyt nopeampi ratkaisu.</p>
<p>Idea on yksinkertainen: Ennen kuin piirrät spriten uuteen paikkaan, piirrä vanhan paikan tausta takaisin ja laita talteen uuden paikan tausta. Okei, ei kuulostanut kauhean yksinkertaista, mutta sitä se on. Katsotaan asiaa kaikessa rauhassa esimerkkiohjelman avulla:</p>
<pre>  int main(void)
  {
	BITMAP *tausta; // semmoinen iso kuva jonka päälle piirretään
	BITMAP *sprite;
	BITMAP *spriten_taus; // spriten tausta
	PALETTE pal;

	int x=10;
	int y=50;

         allegro_init();
         install_keyboard();
         set_gfx_mode(GFX_AUTODETECT,320,200,0,0);

	// kuvien lataaminen
         tausta=load_pcx("taus.pcx",&amp;pal);
         set_palette(pal);
         sprite=load_pcx("sprite.pcx",&amp;pal);

	// Ja tässä on nyt sitten sitä uutta asiaa
	spriten_taus=create_bitmap(sprite-&gt;w,sprite-&gt;h);</pre>
<p>Siis. Nyt meillä on bitmappi nimeltään spriten_taus, joka on täsmälleen saman kokoinen kuin sprite. Siihen tallennamme siis spriten taustat. Aluksi otamme taustan talteen kohdasta x,y, johon sprite kohta piirretään.</p>
<pre>	blit(tausta,spriten_taus,x,y,0,0,spriten_taus-&gt;w,spriten_taus-&gt;h);

	draw_sprite(tausta,sprite,x,y);</pre>
<p>Tuossa siis kopioimme taustasta talteen sen kohdan, joka kohta jää spriten sotkemaksi ja piirsimme spriten taustabitmappiin. Nyt sitten se piirtosilmukka:</p>
<pre>	while(!key[KEY_ESC]){
		blit(spriten_taus,0,0,x,y,spriten_taus-&gt;w,spriten_taus-&gt;h);</pre>
<p>Ensin piirretään tausta takaisin spriten päälle ja sitten luetaan näppäimistöltä uudet x- ja y-koordinaatit.</p>
<pre>                if(key[KEY_LEFT]) x--;
                if(key[KEY_RIGHT]) x++;
                if(key[KEY_UP]) y--;
                if(key[KEY_DOWN]) y++;</pre>
<p>Siispä nyt meillä on uudet koordinaatit ja otamme taas taustan talteen ja sitten piirrämme spriten..</p>
<pre>blit(tausta,spriten_taus,x,y,0,0,spriten_taus-&gt;w,spriten_taus-&gt;h);

		draw_sprite(tausta,sprite,x,y);

		// Ja koko komeus näytölle
		blit(tausta,screen,0,0,0,0,tausta-&gt;w, tausta-&gt;h);
    	}

        allegro_exit(0);

	return(0);
    }</pre>
<p>Huhhuh&#8230; Tuo oli raskasta, mutta toivottavasti ei liian vaikeaa. Vielä yksi juttu. Noista kuvista nimittäin. Kun itse tein tämän esimerkin, käytin taustakuvana sellaista kuvaa joka on 320&#215;200 pikselin kokoinen ja spritenä paljon pienempää. Suosittelen samaa myös sinulle. Ja sitten eteenpäin, enää ei ole paljoa jäljellä. Vilkaistaan vielä kaksoispuskurointia ja sitten osaatkin jo vaikka mitä!</p>
<h2>Ja sulavuutta kaksoispuskurilla</h2>
<p>Jaahas! Nyt olemme päässeet siihen vaiheeseen, että on sopivaa puhua kaksoispuskuroinnista. Kokeile allegron esimerkkiohjelmaa ex8.exe. Siitä saat hyvän kuvan kaksoispuskuroinnin hyödyllisyydestä. Ohjelmassa pallo kulkee ruudun poikki ensin ilman kaksoispuskurointia, niin, että se piirretään suoraan näytölle (screen-bitmappiin). Toisella kerralla se piirretään kaksoispuskurointia käyttäen. Huomaat eron, ilman kaksoispuskurointia kuvan katsominen oli suorastaan sietämätöntä, kaksoispuskuroinnin kanssa jo ihan siedettävää.</p>
<p>Mutta arvaas mitä! Tuo hienous on niin helppoa, että ihan naurattaa.. Sinäkin olet jo käyttänyt kaksoispuskurointia, tietämättäsi. Yllätyitkö? Se oli tuossa edellisessä kappaleessa. Siinä teimme kaikki piirtämiset tausta-bitmapillä ja lopussa vain blittasimme sen näytölle. Kuulostaako tutulta? Eikä todellakaan ole vaikeaa. Kaksoispuskurointi tarkoittaa siis sitä, että mitään ei piirretä suoraan näytölle vaan aina ensin kaksoispuskuriin, joka sitten lopuksi yhdellä nopealla blitillä heitetään näytölle.</p>
<p>Nyt varmaan mietit, että miten tuollaisella pikkujutulla voi olla näin suuri vaikutus. Se johtuu vain siitä, että näyttömuistiin piirtäminen on paljon hitaampaa kuin tavalliseen perusmuistiin. Jos käytämme draw_spriteä screen-bitmapin kanssa on se siis paljon hitaampaa kuin vaikkapa tausta-bitmapillä. Siinä on kaksoispuskuroinnin salaisuus.</p>
<h2>Olisikohan nyt pelien aika?</h2>
<p>Oho, tämäkin kurssi meni nopeasti. Kirjoitinkin sen oikeastaan yhdessä päivässä &#8211; niin, ja korjailin hieman nyt pari vuotta kirjoittamisen jälkeen. Korjauksia joudun varmaan vieläkin tekemään, mutta kaipa tämä on valmis. Pääasia on, että nyt hallitset blittailut ja paljon muuta. Mikään ei enää estä sinua tekemästä ensimmäistä peliäsi. Voit tehdä sen vaikka nyt, mutta muista, älä aloita liian vaikeasta!</p>
<p>Tietenkään sinun ei ole pakko jatkaa peliohjelmoinnin suuntaan vaikka sinne sinua jatkuvasti tyrkinkin (anteeksi siitä..), voit ihan yhtä hyvin tehdä vaikka kuvannäyttelyohjelman tai jotain muuta hyödyllistä.</p>
<p>Joka tapauksessa, valitsit sitten minkä tahansa suunnan tästä eteenpäin, toivotan onnea ja toivon voivani auttaa sinua edelleen!</p>
<hr /><em>Artikkelin kirjoitti alun perin jalaine.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.suomipelit.com/2001/12/03/grafiikkakurssi-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2D-Grafiikan alkeet Allegroa käyttäen</title>
		<link>http://www.suomipelit.com/2001/11/07/2d-grafiikan-alkeet-allegroa-kayttaen/</link>
		<comments>http://www.suomipelit.com/2001/11/07/2d-grafiikan-alkeet-allegroa-kayttaen/#comments</comments>
		<pubDate>Wed, 07 Nov 2001 10:00:37 +0000</pubDate>
		<dc:creator>Suomipelit.com</dc:creator>
				<category><![CDATA[Artikkelit]]></category>
		<category><![CDATA[Käytännön oppaat]]></category>
		<category><![CDATA[2d]]></category>
		<category><![CDATA[alkeet]]></category>
		<category><![CDATA[allegro]]></category>
		<category><![CDATA[c/cpp]]></category>
		<category><![CDATA[grafiikka]]></category>
		<category><![CDATA[ohjelmointi]]></category>

		<guid isPermaLink="false">http://www.suomipelit.com/?p=800</guid>
		<description><![CDATA[Tässä varsin helppotajuisessa ja yksinkertaisessa tutoriaalissa käydään läpi 2D-ohjelmointiin liittyviä peruskäsitteitä käyttäen apuna Allegro-peliohjelmointikirjastoa. Aiheina pääasiassa viivoja ja muita muotoja.

Jos olet jo lukenut edellisen tutoriaalini, Helposti C-ohjelmoijaksi, tiedät suurin piirtein mitä alkutasoa tällä kurssilla edellytän. En kovin paljoa, perustietämys C-kielestä riittää. Et tarvitse Windows- tai muita erityisohjelmointitaitoja. Kääntäjänä on edelleen DJGPP, jonka kanssa käytetään Allegro-peliohjelmointikirjastoa. Tavoitteena on, että tämän kurssin lopussa osaat piirtää palloja, viivoja, pikseleitä ja muita hauskoja kuvioita. Grafiikkakurssi kakkosessa siirrytään sitten monimutkaisempiin systeemeihin, sukelletaan spriteihin ja tehdään jotain animaatioitakin. Mutta asia kerrallaan. ]]></description>
			<content:encoded><![CDATA[<p>Tässä varsin helppotajuisessa ja yksinkertaisessa tutoriaalissa käydään läpi 2D-ohjelmointiin liittyviä peruskäsitteitä käyttäen apuna Allegro-peliohjelmointikirjastoa. Aiheina pääasiassa viivoja ja muita muotoja.</p>
<p>Jos olet jo lukenut edellisen tutoriaalini, Helposti C-ohjelmoijaksi, tiedät suurin piirtein mitä alkutasoa tällä kurssilla edellytän. En kovin paljoa, perustietämys C-kielestä riittää. Et tarvitse Windows- tai muita erityisohjelmointitaitoja. Kääntäjänä on edelleen DJGPP, jonka kanssa käytetään Allegro-peliohjelmointikirjastoa. Tavoitteena on, että tämän kurssin lopussa osaat piirtää palloja, viivoja, pikseleitä ja muita hauskoja kuvioita. Grafiikkakurssi kakkosessa siirrytään sitten monimutkaisempiin systeemeihin, sukelletaan spriteihin ja tehdään jotain animaatioitakin. Mutta asia kerrallaan.</p>
<h2>Mikä Allegro?</h2>
<p>Allegrosta en muistaakseni siinä C-kurssissa vielä mitään ehtinyt kertoa. Nyt siis lyhyesti jotain Allegron historiasta ja nykypäivästä sekä siitä miksi sitä kannattaa käyttää.</p>
<p>Allegro on alunperin Shawn Hargreavesin, mutta nykyään suuremman ryhmän kehittämä peliohjelmointikirjasto. Se sisältää todella monia grafiikkafunktioita, äänifunktioita, ohjainlaitteiden hallintafunktioita ja vaikka mitä. Tällä hetkellä siitä on olemassa DOS-versio, ja melkein valmis Windows-versio. Myös X-Windows-versio on työn alla. Näin Allegroa käyttävä peli on helppo siirtää ympäristöstä toiseen. Ja Allegro on ilmainen, samoin kuin DJGPP, vapaaehtoistyönä toteutettu.</p>
<p>Allegron asentamisesta on kerrottu kaikki tarvittava noissa asennusohjeissa, joita löytyy DOS-ohjelmointialueelta. Ja Allegron käytöstä kerrotaan seuraavassa. Erittäin hyvä Allegro-tietolähde on Allegron helppi, jota kannattaa ahkerasti selata. Kun alat tekemään peliä, joka käyttää Allegroa tai jotain sen osaa, ensimmäinen tehtävä on liittää mukaan otsikkotiedosto allegro.h. Se tapahtuu seuraavasti:</p>
<pre>#include &lt;allegro.h&gt;</pre>
<p>Tuo siis kirjoitetaan ohjelman alkuun muiden includejen jälkeen. Nyt kääntäjä tunnistaa Allegron funktiot osana ohjelmaasi eikä herjaa niistä, mutta vielä on yksi juttu joka on tehtävä. Linkitysvaiheessa tulee ongelmia, jos liballeg.a -tiedostoa ei linkitetä mukaan. Sen voi tehdä kahdella tavalla. Jos käännät ohjelmasi komentoriviltä, käytä seuraavaa lausetta:</p>
<pre style="padding-left: 60px;">gcc foo.c -o foo.exe -lalleg</pre>
<p>Siinä <strong>foo.c</strong> on käännettävä tiedosto, ja <strong>-lalleg</strong> kertoo linkkerille, että liballeg.a täytyy linkittää mukaan exeen. Jos taas käytät Rhideä, on sinun kirjoitettava Options/Libraries-valikosta löytyvään ikkunaan ensimmäiseen tyhjään kohtaan alleg ja merkittävä sen vieressä oleva ruutu. Esimerkki:</p>
<pre style="padding-left: 60px;">[X] 0 alleg</pre>
<p>Nyt järjestelmäsi on valmis käyttämään Allegroa! Joten eiköhän tehdä ensimmäinen Allegro-ohjelma!</p>
<h2>Ensimmäinen Allegro-ohjelmasi</h2>
<p>No niin. Tässä tulee yksinkertainen ohjelma, joka ei tee paljon mitään, vain sen olennaisimman. Se tekee alustukset, vaihtaa grafiikkatilaa, odottaa, että joku painaa spacea ja sitten lopettaa. Okei, käydään se läpi rivi riviltä.</p>
<pre>#include &lt;stdio.h&gt;
#include &lt;allegro.h&gt;<span style="color: #339966;"> // allegron otsikkotiedosto</span></pre>
<p>Kuten varmaan jo huomasitkin, tuossa oli se allegro.h, josta hetki sitten tuolla ylempänä puhuttiin. Ja stdio.h:n varmaan tiedätkin, tässä sitä ei olisi tarvittu, mutta laitan sen aina mukaan varmuuden vuoksi &#8211; jos vaikka tekee mieli kirjoittaa tekstiä näytölle.</p>
<pre>int main(void)
{</pre>
<p>Tuosta alkoi sitten pääohjelma, jossa tällä kertaa tapahtuu kaikki. Peleissä ja muissa isommissa ohjelmissa täytyy aina käyttää aliohjelmia!</p>
<pre> <span style="color: #339966;">// Ensin alustetaan Allegro</span>
 allegro_init();</pre>
<p>Allegro_init on sellainen funktio, joka laittaa Allegron käyttökuntoon. Ennen sitä et voi (saa) käyttää mitään muita Allegron funktioita.</p>
<pre> <span style="color: #339966;">// Sitten näppäimistö</span>
 install_keyboard();</pre>
<p>Install_keyboard ottaa näppäimistön Allegron hallintaan. Tarvitsemme tätä, jotta voimme kohta lukea näppistä.</p>
<pre> <span style="color: #339966;">// Sitten laitetaan oikea grafiikkatila</span>
 set_gfx_mode(GFX_VGA,320,200,0,0);</pre>
<p>Tämä on tärkeä rivi erityisesti tässä kurssissa, koska se on ainoa funktiokutsu tässä ohjelmassa, joka jotenkin liittyy grafiikkaan. Se on grafiikkatilan vaihto. Selitän tarkemmin&#8230; Eli ensin on tuo GFX_VGA, joka tarkoittaa, että halutaan käyttää VGA-grafiikkaa. Siihen voisi myös laittaa GFX_AUTODETECT tai GFX_VESA tai jotain muuta sellaista. Sitten on numeroita, 320,200 tarkoittaa, että haluamme resoluution 320&#215;200. Ja lopussa olevien kahden nollan kannattaa aina olla nollia (ainakin yleensä).</p>
<pre><span style="color: #339966;"> // Odotellaan näppäimen paimallusta</span>
 while(!key[KEY_SPACE]){}</pre>
<p>Tässä siis käytetään näppäimistöä. Loopataan While-silmukassa niin kauan kunnes joku painaa SPACEa (KEY_SPACE). Tästä ei tämän enempää, koska tämähän on grafiikkakurssi, ei näppäimistökurssi.</p>
<pre><span style="color: #339966;"> // Lopetetaan Allegro</span>
 allegro_exit();</pre>
<p>Ja jokainen Allegro-ohjelma tulee lopettaa ylläolevaan riviin allegro_exit();, joka lopettaa Allegron ja palauttaa asetukset sellaisiksi kuin ne olivat ennen allegro_init();-kutsua.</p>
<pre> return(0);
}</pre>
<p>Ja tähän ohjelma päättyi. Se oli ensimmäinen Allegro-ohjelma. Kokeile sitä ja yritä saada se käännettyä. Kun ymmärrät miten se toimii, voit siirtyä seuraavaan lukuun!</p>
<h2>Värit palettiin</h2>
<p>Valitsimme tuossa äsken grafiikkatilaksi VGA-tilan 320&#215;200 eli kuten me ohjelmoijat sanomme, tilan 13h :), koska sitä on helpompi käyttää kuin useampivärisiä tiloja.. Nimittäin tässä 13h-tilassa käytettävissämme on vain 256 väriä. Se on kuitenkin enemmän kuin tarpeeksi, ainakin tässä vaiheessa.</p>
<p>Värit on tallennettu palettiin, jossa on nuo 256 väriä tallennettuna. Näitä värejä voit itse muuttaa, valita ne jotka sopivat tarkoitukseesi parhaiten.</p>
<p>Paletin värit on tallennettu RGB-structeihin, jotka ovat muotoa:</p>
<pre>typedef struct RGB
{
   unsigned char r, g, b;
} RGB;</pre>
<p>Siinä r tarkoittaa värin punaista komponenttia, g vihreää ja b sinistä niinkuin ne on PC:llä tapana esittää. Monet piirto-ohjelmat kuten Paint Shop Pro 5 osaavat ilmaista värit suoraan tässä muodossa. Kokeilemalla nuo värit kuitenkin selviävät. Tässä kuitenkin muutama esimerkkiväri, jotka voit laittaa esimerkiksi ohjelmasi alkuun ja käyttää niitä myöhemmin värien asettamiseen.</p>
<pre style="padding-left: 30px;">   RGB black = { 0,  0,  0  };
   RGB white = { 63, 63, 63 };
   RGB green = { 0,  63, 0  };
   RGB grey  = { 32, 32, 32 };
   RGB red   = { 63, 0,  0  };</pre>
<p>Ja PALETTE-tyyppi on 256 RGB-structin taulukko.. Sieltä löytyy siis nuo 256 väriä ylläolevan näköisessä muodossa.</p>
<p>Ennen kuin aletaan piirtämään niin laitetaan muutama väri palettiin. Se tapahtuu allegron funktiolla void set_color(int index, RGB *p);. Siis index on sen värin numero, jota haluamme muuttaa, ja *p osoitin sellaiseen RGB-struktiin, jonka haluamme väriksi sijoittaa. Eiköhän olisi taas esimerkin aika..</p>
<pre>// Esimerkki 2: Ohjelma, joka muuttelee värejä..
#include &lt;allegro.h&gt;
#include &lt;stdio.h&gt;

int main(void)
{
  RGB vihrea = { 0, 63, 0 };

  allegro_init();
  install_keyboard();

  set_gfx_mode(GFX_VGA,320,200,0,0);  

  set_color(1,&amp;vihrea);

  while(!key[KEY_ESC]){}

  allegro_exit();

  return(0);
}</pre>
<p>Tämä oli muuten aivan samanlainen ohjelma kuin tuo edellinenkin, mutta siinä on yksi uusi funktiokutsu, tuo set_color, josta äsken puhuimmekin.. Se muuttaa tässä siis paletin värin numero 1 vihreäksi..</p>
<h2>Tehtävä</h2>
<p>Tutki tuota set_color-funktiota! Muuta yllä oleva ohjelma sellaiseksi, että se muuttaa väriä 0, jolloin taustan väri muuttuu. Kokeile erilaisia värejä! Tutki!</p>
<h2>Ja pisteitä ruudulle</h2>
<p>Äsken muutimme palettia, mutta emme vielä piirtäneet mitään. Niinhän taiteilijatkin tekevät; ensin laitetaan palettiin värit ja sitten vasta aletaan maalaamaan. Katso hetken ajan alla olevaa kuvaa, joka esittää tietokoneen näytön koordinaatistoa.</p>
<pre style="padding-left: 60px;">0,0---------------&gt;n,0
 |
 |
 |
 V
0,n</pre>
<p>Siis, Vasemmassa ylänurkassa on piste 0,0 ja x-koordinaatti kasvaa oikealle mennessä. Esimerkiksi resoluutiolla 320&#215;200 oikean ylänurkan koordinaatit ovat 320,0. Vastaavasti y kasvaa alaspäin mentäessä, joten oikea alanurkka on tuolla samalla resoluutiolla 320,200.</p>
<p>Nyt, kun tiedät miten tietokone käsittää koordinaatiston, voitkin piirtää pisteen vaikkapa keskelle ruutua! Mitkä olisivat silloin x- ja y-koordinaatit? (miettimistauko) Nehän olisivat tietystikin 160,100. Jotta voisit piirtää tuon pisteen, tarvitset pisteenpiirtofunktion. Se on nimeltään putpixel. Huom! Pisteitä sanotaan tietokonekielessä pikseleiksi.</p>
<p>putpixel toimii niin, että ensin annetaan pinta, jolle halutaan piirtää pikseli, tässä tapauksessa se saa olla screen, joka tarkoittaa näyttöä, sitten koordinaatit (x ja y) ja lopuksi väri (paletin arvo väliltä 0-255). Esimerkki tulee tässä:</p>
<pre>   putpixel(screen,0,0,1);</pre>
<p>Tuo siis piirtää vasempaan ylänurkkaan pikselin, joka on väriä numero 1. Jos liittäisimme tämän tuohon edelliseen ohjelmaamme, olisi väri vihreä. Jos emme ole väriä etukäteen asettaneet, se voi olla ihan mikä vain.</p>
<p>Nyt voitkin kokeilla tehdä ohjelman, joka piirtää pikseleitä, vaikkapa satunnaisesti arvottuun paikkaan. Jaa, mutta tuohan olisikin hyvä tehtävä ennen kuin aletaan piirtämään viivoja!</p>
<h2>Toinen tehtävä</h2>
<p>Tee ohjelma, joka piirtää pisteen näytöltä arvottuun paikkaan! Satunnaisluvuista puhuimme C-kurssissa, katso sieltä, jos et muista.</p>
<h2>Pisteistä eteenpäin</h2>
<p>No niin. Pisteet ovat pitemmän päälle aika tylsiä, mutta on tärkeää muistaa, että kaikki mitä tästä eteenpäin teemme perustuu niihin, huomaamme me sitä tai emme. Kuitenkaan ei meidän onneksi tarvitse kuvia piirtää piste kerrallaan vaan voimme käyttää apufunktioita. Tässä kurssissa käsittelemme seuraavat piirtofunktiot:</p>
<ul>
<li>putpixel &#8211; tämä käytiinkin jo läpi</li>
<li>line &#8211; piirtää viivan</li>
<li>triangle &#8211; kolmio</li>
<li>rect ja rectfill &#8211; nelikulmio</li>
<li>circle ja circlefill &#8211; ympyrä</li>
<li>floodfill &#8211; täyttö</li>
</ul>
<p>Ja eiköhän käydä heti töihin. Siispä viivanpiirtoon! Viivan piirtämiseen on Allegrossa ainakin 3 erilaista funktiota, joista kaikkein kehittynein on line. Tästä eteenpäin esittelen funktiot siinä muodossa kuin ne esitellään yleensä ohjelmointidokumenteissa, jotta totut lukemaan sellaistakin tekstiä. Siis tässä tulee line-funktio &#8220;oikeassa&#8221; muodossa esitettynä:</p>
<pre>void line(BITMAP *bmp, int x1, int y1, int x2, int y2, int color);</pre>
<p>Siitä näemme seuraavat asiat: funktio ei palauta mitään arvoa (alussa void), sen nimi on line, se ottaa syötteikseen osoittimen pintaan, johon piirretään, tässä vaiheessa se on screen, joka siis tarkoittaa näyttöä, int-tyyppiset alku- ja loppukoordinaatit sekä värin numeron, joka on välillä 0-255. Kannattaa opetella tulkitsemaan näitä funktioiden prototyyppejä, koska niiden avulla on aika helppoa ymmärtää uusia funktioitan, esimerkiksi niitä allegron funktioita, joita en tässä kurssissa esittele.<br />
Annan yhden piirtoesimerkin, jonka voit liittää alussa tekemäämme värinvaihto-ohjelmaan.</p>
<pre>  line(screen, 5, 5, 56, 100, 1);</pre>
<h2>Tehdään laatikko</h2>
<p>Kokeilepa tehdä funktio, joka piirtää laatikon line-käskyllä. Funktio ottaa syötteenä ylänurkan ja alanurkan koordinaatit ja laatikon värin.</p>
<p>No niin, nyt kun olet tehnyt oman laatikkofunktion, voin kertoa, että Alegrosta löytyy sellainen ihan omasta takaakin:</p>
<pre>void rect(BITMAP *bmp, int x1, int y1, int x2, int y2, int color);</pre>
<p>Siis, tuo piirtää laatikon pinnalle *bmp (screen) alkaen pisteestä x1,y1 (vasen ylänurkka) ja päättyen pisteeseen x2,y2 (oikea alanurkka). Esimerkki tulee tässä:</p>
<pre>rect(screen,3,6,100,107,3);</pre>
<p>Tuo siis piirtää laatikon, joka alkaa pisteestä 3,6 ja loppuu pisteeseen 100,107. Väri on 3.<br />
Rectistä on vielä toinen muunnos, rectfill, joka tekee täytetyn laatikon. Sitä käytetään samalla tavalla kuin rect. Se vain toimii hieman eri tavalla. Esimerkki:</p>
<pre>rectfill(screen,10,10,50,50,4);</pre>
<p>Tuo siis piirsi laatikon pisteestä 10,10 pisteeseen 50,50 ja väritti sen värillä 4.</p>
<h2>Ja sitten tehdäänkin jo ensimmäinen kuva</h2>
<p>Teepä seuraavaksi ohjelma, joka piirtää punaisen mökin käyttäen laatikko- ja viivafunktioita. Tee myös pari ikkunaa ja ovi. Voit myös keksiä muuta hienoa, vaikkapa ikkunalaudan.</p>
<p>Ja mökin pihallahan voisi olla hyvä olla puita, näyttää kodikkaammalta. Mutta puut eivät ole neliön muotoisia, ainakaan yleensä&#8230; Runko ehkä, mutta latvan tulee ehkä olla pyöreä tai kolmion mallinen, jos se on kuusi.</p>
<p>Siispä nyt tarvitaan ympyrän- ja kolmionpiirtotyökalut. Ympyrä piirretään funktiolla:</p>
<pre>void circle(BITMAP *bmp, int x, int y, int radius, int color);</pre>
<p>Muuten tuon funktion kutsuminen tapahtuu samalla tavalla kuin edellä esiteltyjen, paitsi että koordinaattien (keskipiste) jälkeen on ympytän säde kokonaislukuna. Toinen ympyräfunktio circlefill ottaa samat syötteet kuin circle, mutta piirtää täytetyn ympyrän.<br />
Kolmio piirretään funktiolla:</p>
<pre>void triangle(BITMAP *bmp, int x1, y1, x2, y2, x3, y3, int color);</pre>
<p>Tuo piirtää täytetyn kolmion, jonka kärkipisteet ovat nuo x1,y1 jne.</p>
<p>Ja jos haluat tehdä puihin vinoja oksia, täytyy ne tehdä viivoilla. Tällöin ne kuitenkin jäävät pelkiksi ääriviivoiksi. Siispä tarvitaan vielä väritysfunktio. Se on seuraavanlainen:</p>
<pre>void floodfill(BITMAP *bmp, int x, int y, int color);</pre>
<p>Floodfill toimii siten, että annetusta pisteestä x,y niinkauan kunnes osuu seinään, se värittää annetulla värillä. Esimerkiksi, jos haluaisin värittää kuvion, jonka sisällä on piste 10,5 värillä 5, kirjoittaisin seuraavasti:</p>
<pre>floodfill(screen,10,5,5);</pre>
<p>Nyt noilla tiedoilla voit tehdä puihin niitä vinojakin oksia.</p>
<h2>Kirjaimista muodostuu sanoja</h2>
<p>Tämä kurssi lähenee loppuaan: osaat jo lähes kaikki grafiikkakäskyt, joita tässä kurssissa käymme läpi, ainoastaan tekstin kirjoittaminen puuttuu.</p>
<p>Eiköhän siis katsota nyt tuota kirjoittamista! Se tapahtuu Allegron funktioilla:</p>
<pre>void text_mode(int mode);
void textout(BITMAP *bmp, FONT *f, unsigned char *s, int x, int y, int color);</pre>
<p>Siis ensin (ohjelman alussa) määritetään tekstin kirjoitustapa funktiolla text_mode. Jos haluat läpinäkyvän taustan, laita parametriksi jokin negatiivinen luku. Jos taas haluat, että tausta on jotain tiettyä väriä, anna sen värin numero. Siispä kaksi esimerkkiä, yksi kummastakin tapauksesta:</p>
<pre>text_mode(-1);</pre>
<p>Kirjoitetaan läpinäkyvällä taustalla. Tai:</p>
<pre>text_mode(15);</pre>
<p>Tekstin taustaväri on nyt sitten väri numero 15 paletista. Mutta joo.. Kun tekstinpiirtotapa on valittu, on aika kirjoittaa. Kirjoittaminen tapahtuu funktiolla textout. Otetaan tähän ensin esimerkki ja sitten sen selitys:</p>
<pre>textout(screen,font,<span style="color: #339966;">"Jee, nyt tulee tekstiä!!"</span>,10,150,10);</pre>
<p>Siinä siis kirjoitetaan näytölle (screen) Allegron perusfontilla (font) &#8211; fontteja voit myös itse tehdä, mutta siitä ehkä jotain joskus myöhemmin. Näytölle siis tulee pisteestä 10,150 oikealle värillä 10 teksti: &#8220;Jee, nyt tulee tekstiä!!&#8221;.</p>
<p>Kokeile liittää tekstiä vaikka siihen talo-ohjelmaasi.. Esimerkiksi oveen voisi kirjoittaa jonkin nimen.</p>
<h2>Yksinkertainen piirto-ohjelma</h2>
<p>Enempää piirtofunktioita en tässä kurssissa anna, mutta tehdäänpä pieni piirrustusohjelma, sellainen, jossa nuolilla liikuttamalla pystyy piirtämään. Tehdään ensin yhdessä pohja ja sitten päästän sinut kehittelemään ohjelmaa mieleiseksesi.</p>
<p>Mietitäänpä hetki ohjelman rakennetta:</p>
<ul>
<li>Allegron alustukset</li>
<li>Grafiikkatilan vaihto</li>
<li>Näppäimistön luku</li>
<li>Pisteen piirtäminen</li>
</ul>
<p>Noista 1, 2 ja 4 ovat sellaisia, jotka jo osaat tehdä, joten niihin ei tässä sen kummemmin puututa. Näppäimistöstä kuitenkin pari sanaa.</p>
<p>Idea on siis se, että aina kun painetaan nuolinäppäintä, muutetaan x:n ja y:n arvoja ja piirretään uusi pikseli niiden näyttämään kohtaan. Ja näppäimistön lukeminenhan onnistuu helposti Allegron funktioilla:</p>
<pre>  if(key[KEY_LEFT]){
 	x--; <span style="color: #339966;">// Liikutetaan vasemmalle</span>
        putpixel(screen,x,y,vari);
  }
  if(key[KEY_RIGHT]){
 	x++; <span style="color: #339966;">// Liikutetaan oikealle</span>
        putpixel(screen,x,y,vari);
  }
  if(key[KEY_UP]){
 	y--; <span style="color: #339966;">// Liikutetaan ylös</span>
        putpixel(screen,x,y,vari);
  }
  if(key[KEY_DOWN]){
 	x--; <span style="color: #339966;">// Liikutetaan alas</span>
        putpixel(screen,x,y,vari);
  }</pre>
<p>Oikeastaan olisin voinut antaa sinun kehitellä tuonkin systeemin, mutta nyt se on tuossa, joten olkoon. Joka tapauksessa näppäimistöä voi Allegron avulla lukea tuolla tavoin. Kerron tästä muissa kursseissa enemmän, nyt riittää kun osaat käyttää nuolinäppäimiä.</p>
<p>Ja loppu jätetään sitten tehtäväksi. Annan vihjettä sen verran, että muistathan laittaa muuttujille alkuarvot, eli määrittää sen paikan mistä piirtäminen aloitetaan.</p>
<h2>Loppukaneetti</h2>
<p>Nyt on tämä kurssi loppu ja toivottavasti olet oppinut tässä käsitellyt asiat ja ennenmuuta saanut lisää varmuutta ohjelmointiisi. Tähän ei kuitenkaan missään tapauksessa kannata lopettaa, olemme vasta pääsemässä alkuun). Nimittäin nyt on aika siirtyä kohti Grafiikkakurssi kakkosta ja hienompia grafiikkajuttuja! Siispä, onnittelut kurssin suorittamisesta ja onnea jatkossakin!</p>
<hr />Artikkelin kirjoitti alun perin <em>jalaine</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.suomipelit.com/2001/11/07/2d-grafiikan-alkeet-allegroa-kayttaen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pikkuaskelin C-Ohjelmoijaksi</title>
		<link>http://www.suomipelit.com/1999/03/11/pikkuaskelin-c-ohjelmoijaksi/</link>
		<comments>http://www.suomipelit.com/1999/03/11/pikkuaskelin-c-ohjelmoijaksi/#comments</comments>
		<pubDate>Thu, 11 Mar 1999 10:00:28 +0000</pubDate>
		<dc:creator>Suomipelit.com</dc:creator>
				<category><![CDATA[Artikkelit]]></category>
		<category><![CDATA[Käytännön oppaat]]></category>
		<category><![CDATA[alkeet]]></category>
		<category><![CDATA[c/cpp]]></category>
		<category><![CDATA[ohjelmointi]]></category>

		<guid isPermaLink="false">http://www.suomipelit.com/?p=874</guid>
		<description><![CDATA[Tässä kurssissa käydään C-kielen perusasioita läpi ja opetellaan ihan sitä perusohjelmointia. Kurssi on jo aika vanha ja löytyy myös Jarkko Laineen ohjelmointikoulusta, joten se voi olla joillekin tuttu. Jos C-kieltä et vielä tunne, kannattaa tutustua tähän kurssiin.]]></description>
			<content:encoded><![CDATA[<p>Tässä kurssissa käydään C-kielen perusasioita läpi ja opetellaan ihan sitä perusohjelmointia. Kurssi on jo aika vanha ja löytyy myös Jarkko Laineen ohjelmointikoulusta, joten se voi olla joillekin tuttu. Jos C-kieltä et vielä tunne, kannattaa tutustua tähän kurssiin.</p>
<p>Olet nyt siis päättänyt alkaa ohjelmoimaan. Sinua kiinnostavat pelit ja se miten ne tehdään. Haluat päästä esiriipun taakse tai ainakin raottaa sitä nähdäksesi mitä nuo suuret ohjelmoijat oikeastaan tekevät (onko se jotain yliluonnollista? ;-). Siispä toivotan sinut tervetulleeksi tähän suureen seikkailuun, jolle rajat asettaa vain mielikuvituksesi (&#8230;ja koneiden tehot, taidot, taiteellisuus&#8230; :-). Älä pelkää, jos ongelmia tulee vastaan, ovat ihmiset sitä varten, että he auttavat toisiaan. Silloin vain rohkeasti kirjoitat vaikka minulle osoitteeseen: [sähköposti vaihtunut] tai jonnekin muualle kuten DJGPP:n newsgrouppiin tai Suomipelit.com:in keskustelualueelle.</p>
<p>Nyt kuitenkin asiaan (siis siihen mitä otsikossa lukee)&#8230; Miksi ohjelmoisit C:llä? Se on sellainen kysymys, johon ei aivan selvää vastausta löydy, mutta melko hyvin voin sen luultavasti selittää. Ensinnäkin, kaikki nykyaikaiset pelit tehdään C:llä (tai C++:lla, joka on C:n sukuinen ja sen kanssa yhteensopiva kieli). Toiseksi, C-kieli on sellainen, että se tuntuu oikealta ohjelmointikieleltä (toisin kuin Pascal tai Basic), ainakin minusta C:n ohjelmointityyli tuntuu hyvältä. Joo. C on yksinkertaisesti paras, ainakin jos aiot päästä pitkälle. Pascalilla pääsee alkuun, mutta sitten on kuitenkin vaihdettava C:hen, kun alkaa tosissaan ohjelmoida. Suosittelen aloittamaan suoraan C:stä, se on hauskaa eikä ollenkaan niin vaikeaa kuin yleensä annetaan ymmärtää!</p>
<p>DJGPP on DJ Delorien ja kumppaneiden ilmainen C-kääntäjä. Se siis tarkoittaa, että sinun ei tarvitse maksaa satoja tai tuhansia markkoja saadaksesi hyvän kääntäjän. Sellainen on saatavilla aivan ilmaiseksi. Jopa Quake on tehty DJGPP:llä. Kaiken lisäksi DJGPP on erittäin tehokas ja hyvä kääntäjä ja sillä on vankka ja yhtenäinen käyttäjäkunta ympäri maailmaa, joten tietoa ja apua ei ole vaikea löytää. Ainut puute on se, että DJGPP ei VIELÄ osaa tehdä Windows-ohjelmia, mutta sehän ei meitä haittaa. Ne kun muutenkin ovat niin hankalia. DJGPP-linkkejä ja muuta tietoa löytyy täältä ja muualta netistä. Pysy mukana!</p>
<h2>Ensimmäinen ohjelma</h2>
<p>Olemme nyt jo niin pitkällä, että pääsemme kopeloimaan konetta (nopeasti &#8211; eikö?), teemme ensimmäisen C-ohjelman ja käännämme sen.</p>
<p>Kautta aikojen ovat C-ohjelmoijat (myös ne jotka nykyään tekevät Quakeja sun muita huippupelejä) aloittaneet uransa seuraavan ohjelman eri variaatioilla, joista luultavasti tämä perusversio on tavallisin. Eli, tässä on koodi, selitän sen myöhemmin.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* Ensimmäinen C-ohjelmani */</span><br />
<br />
<span style="color: #339933;">#include &lt;stdio.h&gt;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Hello World!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Nyt kirjoita tuo teksti juuri niin kuin se tuossa on (/* &#8230; */- rivin voi jättää pois, se on vain huomautus, eikä kääntäjä välitä siitä). Kirjoittaminen onnistuu aivan tavallisella teksturillakin (esim. DOS:in EDIT), mutta suosittelen Rhideä, joka tekee ohjelmoinnin paljon mukavammaksi. Rhide on Robert Höhnen tekemä (ilmainen) kehitysympäristö DJGPP:lle. Se näyttää käskyt ja numerot yms. eri väreillä ja hoitaa kääntäjän käsittelyn puolestasi. Tallenna sitten ohjelma nimellä hello.c ja käännä se joko komentoriviltä: gcc hello.c -o hello.exe tai Rhidessä: RUN/RUN (valikkoriviltä).</p>
<p>Ja nyt muutama sana tuosta ohjelmasta. Siitä näkyvät C:n perusrakenteet aika hyvin, ei ihme, että siitä lähdetään useimmiten liikkeelle. Äsken mainitsinkin jo ensimmäisellä rivillä olevista /* &#8230; */-merkeistä. Ne ovat siis huomautusmerkkejä, jotka kertovat koneelle, että niiden välissä olevaa tekstiä ei pidä kääntää. Niiden väliin voi siis kirjoittaa tietoa muille ohjelmoijille tai itselle muistettavaksi. Se on muuten ihmeellistä kuinka sitä itsekin viikon päästä on aika ulkona, jos ei ole kunnolla selittänyt mitä missäkin tapahtuu. Ei yksinkertaisesti vain muista mitä päässä on sillä hetkellä liikkunut.</p>
<p>Seuraavana onkin include-rivi. Niitä voi ohjelmassa olla enemmänkin, mutta ne ovat aina juuri tuossa ohjelman alussa. C-kieli itsessään ei sisällä paljonkaan erilaisia käskyjä, minkä takia on olemassa standardikirjastot, joissa on eri tyyppisiä käskyjä. Ja kirjastoja käytettäessä täytyy niiden headerit eli otsikkotiedostot liittää ohjelmakoodiin include-lauseilla. Yksi tällainen headeri on stdio.h, joka sisältää tiedon ja tiedostojen käsittelyyn liittyviä funktioiden prototyyppejä (tässä vaiheessa riittää kun ajattelet niitä käskyinä). Elikä, sinun täytyy siis aina ohjelman alussa valita mitä headereita otat mukaan (mitä kirjastoja käytät, vaikkakaan kaikki headerit eivät liity mihinkään kirjastoon) sen mukaan mitä käskyjä haluat käyttää. Voit tietenkin lisätä aina uudentyyppisen käskyn tullessa mukaan sen vaatiman headerin. Headerit liitetään ohjelmaan siis aina #include-lauseella vertailumerkkien &lt;;&gt; välissä (jos se on include-hakemistossa, esim. C:\DJGPP\INCLUDE) tai lainausmerkkejen välissä (&#8221; &#8220;), jos se on samassa hakemistossa kuin muu lähdekoodi.</p>
<p>int main(void) aloittaa pääohjelman, jollainen täytyy aina C-ohjelmassa olla. Se on toiminnan kannalta korkeimman tason ohjailija, päämies. Se kertoo missä järjestyksessä ohjelma toimii. Myöhemmin kerron myös muista funktioista (aliohjelmista), mutta nyt riittää, että ymmärrät pääohjelman merkityksen (pakollinen, ohjaa toimintaa) ja osaat sellaisen kirjoittaa. Siis&#8230; intin tilalla voisi olla myös void tai char (tai unsigned char jne..), mutta ANSI:n standardin mukaan main-funktion täytyy olla muotoa int main(&#8230;). Funktion esittelylauseen (int main(void)) jälkeen tulee itse funktio, joka alkaa AINA {-merkillä ja loppuu AINA }-merkkiin. Ja sisennyksiä kannattaa käyttää samalla tavalla kuin mallissa, koska ne selkeyttävät ohjelmaa paljon. Myös tyhjää väliä voi ihan vapaasti laittaa koodia selkeyttämään kunhan muuttujat tai käskyt (yms.) pysyvät kokonaisina.</p>
<p>Ja vielä on yksi rivi. printf(&#8220;Hello World!\n&#8221;). Siitä nyt vähän selitystä:</p>
<p><strong>printf()</strong> itsessään on standardifunktio, jonka käyttämiseen tarvitset otsikkotiedoston stdio.h (siis erittäin tavallinen käsky), joka tulostaa tekstiä ruudulle. &#8220;Hello World!\n&#8221; on tämä teksti. Mutta <strong>\n</strong> ei ohjelmaa ajettaessa näy ruudulla, eihän? Se on nimittäin rivinvaihtomerkki. Sen voit lisätä mihin tahansa väliin, mutta muista laittaa se lainausmerkkien väliin.</p>
<p>Erittäin tärkeä on myös lauseen lopussa oleva puolipiste. Jokainen C-kielinen lause lukuunottamatta niitä, jotka esimerkissä ovat puolipisteettömiä, päättyy puolipisteeseen. No niin, nyt olet jo ohjelmoija, osaat tehdä ohjelman, joka kirjoittaa tekstiä ruudulle. Jos et aivan kaikkea tajunnut, kokeilepa muuttaa ohjelmaa ja katso mitä tapahtuu. Kokeile vaikka muuttaa se sellaiseksi, että se kehuu sinua (muistaakseni itse kirjoitutin koneella: &#8220;Jarkko Laine, maailman paras ohjelmoija&#8221; ;-). Hauskaa, eikö vain.</p>
<h2>Muuttujat</h2>
<p>Muuttujat ovat ikään kuin pieniä (tai suuria) lokeroita, joihin voi säilöä tietoa ja myöhemmin sen sitten sieltä katsoa. (Näin minulle ainakin joskus asiaa selitettiin&#8230;). Käytännössä erittäin suuri osa ohjelmoinnista perustuu muuttujiin. On tärkeää pystyä muuttamaan lukuja ja merkkijonoja kesken ohjelman suorituksen. Eihän esimerkiksi ohjelmasta, joka laskee aina vain yhden ja saman laskun ole paljon hyötyä. Tehdäänpä muuten sellainen. Jos haluat kokeilla<br />
taitojasi, tee se itse ensin katsomatta tästä.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">#include &lt;stdio.h&gt;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;1 + 1 = %d&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">1</span> <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Tällaisesta ohjelmasta ei kuitenkaan ole paljon hyötyä. Tosin esimerkkinä se kylläkin on vallan mainio, tuossakin tuli esille semmoinen tärkeä asia, jota en vielä ole selittänyt. Selitän sen nyt. Printf-lauseeseen voi sijoittaa (muuttuvaa) tietoa myös %d -merkillä. Näitä &#8220;prosenttimerkkejä&#8221; on muitakin, mutta niistä lisää myöhemmin. Tässä vaiheessa riittää, kun tiedät, että %d tarkoittaa, että sen paikalle laitetaan jokin kokonaisluku (1,2,5,-1&#8230;). Lainausmerkkien jälkeen pilkulla erottaen kirjoitetaan tieto, joka %d:n tilalle halutaan. Tässä tapauksessa se on 1+1, mutta useimmiten joku muuttuja. Naitä %d:itä voi olla myös enemmän lauseen sisällä (printf(&#8220;luku: %d, toinen luku %d&#8221;, 1, 45);).Tämä tulee vielä monta kertaa esille, joten älä huoli jos et tätä täysin vielä käsittänyt.</p>
<p>Muuttujilla siis tarkoitetaan lokeroa, jolla on kuvaava nimi, esim. pisteet. Tällainen muuttuja voisi pelissä pitää sisällään tietoa pelaajan pisteistä. Jos pelaajia on kaksi, tarvitaan taulukkoa, mutta unohda se vielä. Muuttujalla siis täytyy olla nimi, mutta se ei vielä riitä; sillä on myös oltava tyyppi sen mukaan millaista tietoa säilömään sitä käytetään:</p>
<p><strong>int</strong><br />
kokonaislukumuuttuja, ei murto- eikä desimaalilukuja</p>
<p><strong>char</strong><br />
merkkimuuttuja, voi sisältää yhden merkin (<em>esim &#8216;a&#8217;</em>)</p>
<p><strong>float</strong><br />
liukuluku, jos tarvitset desimaalilukuja, tähän niitä saa</p>
<p><strong>double</strong><br />
kaksoistarkkuuden liukuluku, floatti isommalla arvoalueella</p>
<p>Siinä niistä oli perustyypit, joita tulet varmasti tarvitsemaan. Näistä saa sitten erilaisia muunnelmia: esim. unsigned-määritys tekee inteistä ja chareista etumerkittömiä. Luultavasti et näistä tyypeistä kovinkaan monta tarvitse. Int on varmasti yleisin, käytä vain intiä aina kun se on mahdollista. Muitakin toki saa käyttää (enhän minä sitä voi kieltääkään :-). Charia käytät tietenkin sitten merkkitiedon käsittelyyn, esimerkiksi kirjaimiin (tai merkkijonoihin, taulukkoa käyttäen).</p>
<p>Muuttujan tyypin valinta siis riippuu siitä mitä muuttujaan haluaa tallentaa ja ohjelman luonteesta. Hyötyohjelmassa, jossa nopeus ei ole niin tärkeää, voit huoletta käyttää vaikka long doublea jos haluttaa, mutta peleissä nopeus on valttia ja int täten paras vaihtoehto. Merkit tietysti chariin. OK, vielä pari sanaa muuttujien nimistä.</p>
<p>Voisi luulla, että kaikki nimet käyvät, mutta valitettavasti asia ei aivan niin ole, on olemassa muutama (pieni) sääntö. Tunnus (=nimi) ei saa alkaa numerolla ja se saa sisältää kirjaimia (a-z ja A-Z) ja alaviivoja (_) sekä numeroita. Tunnuksen pituus saa olla enintään 32 merkkiä. Nimien kannattaa olla mahdollisimman selkeitä, ei mitään yksikirjaimisia salakoodeja. Skandinaaviset merkit eivät sovi muuttujien nimiin. Ja vielä yksi tärkeä huomautus: isot ja pienet kirjaimet ovat eri asia, eli Kissa on eri muuttuja kuin kissa tai kissA. Näistä ei sitten muuta. Seuraavaksi sijoitusoperaattorit.</p>
<p>Jos tämä teksti on jotenkin sekavaa, se johtuu vain siitä, että yritän tätä kirjoittaessani samalla epätoivoisesti asentaa Internet Explorer nelosta, mikä tahtoo häiritä tähän keskittymistä. Älä välitä, korvaan menetyksen jossain muussa luvussa, sopiiko? &#8230; Nyt se lataa, katotaan miten käy. Olen yrittänyt tätä hieman jälkeenpäin selventää (korjata) &#8211; toivottavasti onnistuin edes jotenkin :)</p>
<p>Okei, takaisin asiaan. C:ssä on sijoitusoperaattori &#8216;=&#8217;, suomeksi sanottuna: kun haluat laittaa vaikka kokonaislukumuuttujaan numero (int) luvun 10, kirjoitat: numero=10; (ja muistathan puolipisteen!) No niin, nyt pieni tehtävä.</p>
<p><strong>Tehtävä</strong><br />
Mitkä seuraavista kelpaavat muuttujan nimeksi C-kielessä, miksi?</p>
<ul>
<li>summa100</li>
<li>valon_nopeus</li>
<li>22_Pistepirkko</li>
<li>Päiväys</li>
<li>_xyz</li>
<li>vasta-aine</li>
</ul>
<p><strong>Oikea vastaus</strong></p>
<p>summa100, valon_nopeus, _xyz</p>
<p>Eihän ollut vaikeaa? Ja vaikka tehtävä olisi mennytkin väärin niin siitä ainakin opit tuon asian. Eteenpäin!</p>
<p>Varmuuden vuoksi olisi varmaan hyvä katsoa vielä yksi esimerkki ennen kuin mennään eteenpäin. Alussa tekemämme laskuohjelma muuttujia käyttäen, var så god!</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">#include &lt;stdio.h&gt;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span> <span style="color: #993333;">void</span> <span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">int</span> vastaus<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// esitellään muuttuja</span><br />
&nbsp; &nbsp; vastaus <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span> <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot; 1 + 1 = %d &quot;</span><span style="color: #339933;">,</span>vastaus<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Jos ymmärsit tuon, olet ymmärtänyt muuttujien syvimmän olemuksen! Onneksi olkoon!</p>
<h2>Ehtolauseilla muuttujiin eloa</h2>
<p>Muuttujistakaan ei yksinään ole paljon hyötyä. Jotta niistä saataisiin kaikki mahdollinen irti, tarvitaan monenlaisia juttuja, joista yksi on nämä ehtolauseet. Ehtolauseita käytetään tutkimaan, onko jokin asia jonkinlainen, eli katsomaan onko muuttujan arvo haluttu ja sitten reagoimaan sen mukaan. Se Explooreri ei ole muuten vieläkään alkanut kunnolla latautua :(.. Joo, tässä on ensin ehtolause-esimerkki paljaalla suomen kielellä:</p>
<pre>jos ikä on suurempi kuin 18 niin
	saa ajaa autoa</pre>
<p>Ja nyt C:llä:</p>
<pre>if (ika &gt; 18) saa_ajaa_autoa();</pre>
<p>Huomaatko kuinka C on kaunista, tiivistä ja selkeää? Ensin sana if, joka vastaa suomen sanaa jos, sitten suluissa ehto (ikä on suurempi kuin 18). Huomaa, että C-kielessä ei voi käyttää ääkkösiä, joten ä:stä tulee a. Ja ehdon jälkeen tulee seuraus, joka jos se on vain yksi lause, voidaan kirjoittaa suoraan ehdon perään. Vielä pieni huomio tuosta saa_ajaa_autoa()-lauseesta. Se on funktiokutsu eli sinun ei vielä siitä tarvitse tietää paljon mitään. Kerrottakoon kuitenkin, koska sen kaltaisia lauseita käytetään tässä paljon, että funktion nimen tulee olla kaikkien samojen sääntöjen mukainen kuin muuttujanimien (ei ää- tai öö-kirjaimia, ei välilyöntejä yms.) ja sulut kuuluvat tuohon perään. Usein sulkujen sisään laitetaan muuttujia, nyt niitä ei kuitenkaan tarvita. Jos ehtolauseen seuraus on pitempi, täytyy se koota {}-merkkien väliin ja sisentää kauniisti:</p>
<pre>if(a!=10){
  printf("a ei ole 10\n");
}</pre>
<p>Siinä oli siis toinen ehtolause-esimerkki, josta näemme, että vertailumerkkejä on monia erilaisia, yksi niistä on tuo !=. Tässä on sellainen luettelo, jossa näet kaikki eri vertailuoperaattorit:</p>
<p><strong>&gt;</strong><br />
suurempi kuin</p>
<p><strong>&lt;</strong><br />
pienempi kuin</p>
<p><strong>&gt;=</strong><br />
suurempi tai yhtäsuuri kuin</p>
<p><strong>&lt;=</strong><br />
pienempi tai yhtäsuuri kuin</p>
<p><strong>==</strong><br />
yhtäsuuri kuin</p>
<p><strong>!=</strong><br />
erisuuri kuin</p>
<p>Siinä tuli näitä vertailuoperaattoreita. Tarkemmat selitykset kaikista operaattoreista löytyy sieltä liitteistä. Mutta hei! Ei se vertailu siihen vielä loppunutkaan, onhan vielä else! Elikä nyt vielä se autonajoehtolause uudestaan:</p>
<pre>jos ikä on suurempi kuin 18
   niin saa ajaa autoa
mutta jos ei
   niin ei saa ajaa autoa</pre>
<p>Siis uuttahan on tuo jos ei-juttu. Nyt C:llä</p>
<pre>if ( ika &gt; 18 ) saa_ajaa_autoa();
else ei_saa_ajaa_autoa();</pre>
<p>Se on näin yksinkertaista! Jos if-lauseen ehto ei toteudu (jos ika EI ole suurempi kuin 18), toimitaan else-lauseen mukaan (ei saa ajaa autoa). Tässä siis oli perusehtolause if&#8230;then..else. Ja sitten case-lause, jota myöskin saattaa silloin tällöin tarvita.<br />
Ajatellaanpa taas ensin äidinkielellämme:<br />
Tutkitaan ruokalistaa</p>
<pre>     jos makkarakeitto: syödään
     jos perunamuusi: kaadetaan maitoa sekaan
     jos maito: juodaan
     jos paperi: ei syödä</pre>
<p>Aika tyhjänpäiväinen ruokalistantutkiminen, mutta toivon mukaan se selittää jotenkin tätä asiaa. Siis asiahan on niin, että case-lause (jota tuokin esittää) on vertailulause, joka sisältää eri vaihtoehdot muuttujan eri arvoille. Nyt C:llä</p>
<pre>switch ( ruokalista ){
    case makkarakeitto: syodaan();
			break;
    case perunamuusi: maitoa_sekaan();
		      break;
    case maito: juodaan();
		break;
    case paperi: ei_syodak();

    default: break;
}</pre>
<p>Niin. Case-lause alkaa jostain syystä switchillä (kaipa sitä switch-lauseeksikin voisi sanoa :-), jonka perään laitetaan sulkuihin tutkittavan muuttujan nimi. Case-kohdissa on sitten muuttujan arvo, jolla tapahtuu jotain ja kaksoispisteen jälkeen toiminto. &#8220;Mihin tätä?&#8221;, sinä kysyt. Esimerkiksi valikoissa, joissa on erilaisia vaihtoehtoja, tämä on hyödyllinen. Ettei tämä jäisi pelkäksi teoriaksi, otetaan todellinen esimerkki, ohjelma, jota voit kokeilla kääntämällä sen.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">#include &lt;stdio.h&gt;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">int</span> luku<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; luku<span style="color: #339933;">=</span><span style="color: #0000dd;">2</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// kokeile muuttaa tätä muuttujaa</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; clrscr<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// ruuduntyhjennys</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span>luku<span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">case</span> <span style="color: #0000dd;">1</span> <span style="color: #339933;">:</span> &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;ykkönen&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">case</span> <span style="color: #0000dd;">2</span> <span style="color: #339933;">:</span> &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;kakkonen&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">case</span> <span style="color: #0000dd;">5</span> <span style="color: #339933;">:</span> &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;viitonen&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">default</span><span style="color: #339933;">:</span> &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;joku muu..&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Vielä muutama sana tuosta switch- (tai case-)lause-esimerkistä. Ohjelmassa on ainakin yksi sellainen &#8220;käsky&#8221;, jota et varmaan aiemmin ole nähnyt: clrscr();. Se on saman näköinen kuin jonkin aikaa sitten näkemämme saa_ajaa_autoa()-funktiot mikä johtuu juuri siitä, että sekin on funktio, joka löytyy standardikirjastosta stdio. Ai niin, olin unohtaa kertoa mitä se tekee. Jos kokeilit ohjelmaa, huomasit varmaan, että ruutu tyhjeni ohjelman alussa. Tämä johtui juuri tästä clrscr();-käskystä (lyhenne sanoista clear screen).</p>
<p>Muuten kaikki onkin varmaan edellisten selitysten pohjalta selvää. Switch:illä aloitetaan ja case kertoo vaihtoehdot ja niiden seuraukset. Jokainen case-pätkä loppuu käskyyn break;. Tulikohan se tuosta selväksi? Toivottavasti :).</p>
<p>Jess! Siinä olivat ehtolauseet, kokeile ja tutki niitä niin kauan kunnes koet hallitsevasi ne ja sitten mennään eteenpäin.</p>
<h2>Silmukat, narua ja solmuja?</h2>
<p>No niin, nyt ehkä alkaa tämä kirjoitus sujua; explooreri latautuu kauniisti tuolla taustalla ja kello on kymmentä vaille seitsemän aamulla. Tucowsista se lopulta löytyi. Niin, ei kannata suoraan Microsoftilta yrittääkään, se on liian hankalaa. Mutta nyt silmukoihin, ei enää selaintekstiä.</p>
<p>Silmukat ovat sellaisia koodinpätkiä, jotka toistuvat monta kertaa peräkkäin tehden saman asian hieman muuttujien arvoja muutellen uudelleen ja uudelleen. Silmukoita on kolmenlaisia: for-, while- ja do..while -silmukoita. Näitä kaikkia saattaa joissain tapauksissa tarvita. Aloitetaanpa for-silmukasta, joka kuitenkin varmaan on kaikista tavallisin. Ensin suomeksi:</p>
<pre>olkoon x aluksi 0,
sitten kierretään niin kauan kuin x on pienempi kuin 10 (x &lt; 10)
ja kasvatetaan joka kierroksella x:ää yhdellä.
tehdään jotain (joka kierroksella)</pre>
<p>Anteeksi, mutta minä tässä innostuin eilen tuohon suomenkieliseen ohjelmointiin, en sellaista ollut ennen kokeillutkaan. Vielä tämä loppuun, C:llä:</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>x <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> x <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #339933;">;</span> x<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;tehdaan_jotain<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Siis for on silmukan tyyppi. x=0- kohdasssa sijoitetaan äksälle alkuarvo, tässä tapauksessa nolla. Eli, kun silmukka alkaa, on x nolla. x &lt; 10 on vertailu, joka tarkistaa onko aika lopettaa silmukka. Siis, jos tämä ehto ei toteudu &#8211; siis x on 10, päättyy silmukka, muuten (niin kauan kuin x &lt; 10) jatketaan ja toimitaan seuraavan kasvatusohjeen mukaan, tässä tapauksessa x++ (kasvatetaan x:ää yhdellä). Ja joka kierroksella tehdään ne asiat, jotka ovat aaltosulkujen {} välissä, esimerkissä se on funktio tehdaan_jotain(); .</p>
<p>Ennen kuin käymme for-silmukan rakennetta tarkemmin läpi haluan kertoa jotain noista C-kielen lyhyistä ja ytimekkäistä kasvatusoperaattoreista.. Jos olet aikaisemmin ohjelmoinut jollain muulla kielellä, on sinulle varmaan tuttua se, että kun haluat kasvattaa vaikka nyt tuota muuttujaa x yhdellä, kirjoitat x=x+1. Järkevää, eikö? Tuo toimii toki myös C:llä, mutta koska kielen kehittäjät ovat pyrkineet mahdollisimman lyhyeen koodiin, suositeltavaa onkin käyttää C-kielelle (ja nykyään myös Javalle) ominaista ++-operaatiota. Katso hetki alla olevaa taulukkoa.</p>
<p><strong>x++</strong><br />
Lisätään x:ään 1</p>
<p><strong>x&#8211;</strong><br />
Vähennetään x:ästä 1</p>
<p><strong>x+=5</strong><br />
Lisätään x:ään 5</p>
<p><strong>x-=7</strong><br />
Vähennetään x:ästä 7</p>
<p>Taulukosta vielä. Siis x on int-tyypin muuttuja ja nuo ovat mahdolliset operaatiot mitä sille voi suoraan lyhyesti tehdä. Tästä puhutaan vielä, mm. seuraavassa, eli jatketaan for-silmukan tutkimista: for-silmukan runko selityksin, olkaa hyvä!</p>
<pre>for(alustus; jatkuvuusehto; kasvatus)
{
  toiminta;
}</pre>
<p>Ensin alustetaan, sitten tutkitaan ja lopuksi kasvatetaan silmukan muuttujaa. Mutta tästä ei vielä ilmene se mihin silmukkaa käytetään: For-lauseen viimeisen sulun jälkeen tulee tuttu {-merkki ja sitten koodi mikä suoritetaan joka kerralla kun silmukka kierretään läpi. Tämä pätkä kannattaa sisentää ja se päättyy }-merkkiin. Tässä taas pieni kaunis esimerkki:</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>luku<span style="color: #339933;">=</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span> luku <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">11</span><span style="color: #339933;">;</span> luku<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;tulos <span style="color: #339933;">=</span> <span style="color: #0000dd;">2</span> <span style="color: #339933;">*</span> luku<span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%d*2=%d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> luku<span style="color: #339933;">,</span> tulos<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Jos ymmärsit mitä tuossa tapahtuu, olet uskomattoman hyvä oppimaan, onnitteluni! Jos et ymmärtänyt, ei se haittaa; minä selitän. Tuo on ohjelma, joka laskee kahden kertotaulun (1*2=2, 2*2=4 jne.) ja tulostaa laskut näytölle. Tuonhan olisi toki voinut tehdä toisinkin. Olisi laskenut jokaisen laskun erikseen, mutta se olisi vaatinut paljon enemmän turhaa kirjoittamista. Silmukalla tämä oli paljon helpompi tehdä (Muuten siitä explorerista vielä.. ei se ollutkaan niin yksinkertaista. Se minkä tucowsista kopioin, olikin englanninkielinen versio. Nyt pitäisi löytää suomenkielinen&#8230;).</p>
<p>Ensin on for-lause, jossa määritellään silmukka 1:stä 10:een. Nyt varmaan ihmettelet, että miksi siellä sitten on 11 (ai et ihmettele vai? No se on hyvä). Syy on yksinkertainen: haluamme laskea kertolaskun kaikilla luvuilla 1-10. Jos laittaisimme vertailulauseeseen (luku &lt; 11) luvun 10, jäisi kymppi laskuista pois. Kymmenenhän ei ole pienempi kuin kymmenen. Että silleen. Sitten tulee {-merkki ja alkaa silmukan toiminto-osio. Joka kierroksella lasketaan lasku tulos=2*luku;, jossa tulos on jossain aiemmin esitelty int-tyypin muuttuja samoin kuin luku, joka esiintyy myös for-lauseessa. Huomaammekin nyt, että luku on joka kierroksella eri numero: Ensin lasketaan tulos=2*1;, sitten tulos=2*2; jne. Eiköhän se tullut selväksi. Ja koska tiedot täytyy näyttää käyttäjälle, käytämme printf-lausetta, jossa siis %d:n kohdalle tulee muuttujan arvo ja muuttujat ovat lainausmerkkien jäljessä siinä järjestyksessä kuin ne halutaan näyttää.</p>
<p>Jos haluat kokeilla tuota esimerkkiä käytännössä, avaa uusi c-tiedosto, laita sen alkuun tarvittavat includet, tässä tapauksessa stdio.h riittää, ja sitten tuo silmukka main-funktion sisään. Äläkä unohda esitellä muuttujia (ne ovat tyyppiä int).</p>
<p>Siinä oli pieni silmukkaesimerkki. Nyt vielä muutama sana muista silmukkatyypeistä. while-silmukkaa kierretään niin kauan kuin ehto on tosi. Kuulostaa aika samanlaiselta kuin for, eikö. Ainoa ero onkin se.. no katsotaanpa esimerkki: (suomeksi :-)</p>
<pre>niin kauan kuin ikä on 7
  käydään ekaa luokkaa</pre>
<p>Huomasitkin varmaan sen mitä äsken yritin selittää, eli ainoa ero on se, että ehtoon liittyviä argumentteja (muuttujia tms) ei alusteta missään, eikä mitään kasvateta. Nyt C:llä:</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span>ika<span style="color: #339933;">==</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; kaydaan_koulua<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Niin. Tämä tyyppi sopii hyvin esimerkiksi peliin, jonka täytyy pyöriä niin kauan kunnes painetaan esciä. Näytän tästä esimerkin (hieman Allegro-koodia käyttäen):</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>key<span style="color: #009900;">&#91;</span>KEY_ESC<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; peli_asiat<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Ai että selitystä kaivataan? Joo. Tuo silmukka pyörii siis niin kauan kuin esciä ei paineta. key[KEY_ESC] on Allegron juttu, joka tarkoittaa, että esciä on painettu ja ! on C-kielen operaattori, joka tarkoittaa samaa kuin suomeksi ei.</p>
<p>Tässä vielä pieni esimerkki while-silmukasta:</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* Ohjelma, joka laskee kahden kertotaulun<br />
&nbsp; &nbsp;while-silmukkaa käyttäen */</span><br />
<br />
<span style="color: #339933;">#include &lt;stdio.h&gt;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #993333;">int</span> luku<span style="color: #339933;">,</span> vastaus<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;luku<span style="color: #339933;">=</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;vastaus<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span>luku <span style="color: #339933;">&lt;=</span> <span style="color: #0000dd;">10</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; vastaus <span style="color: #339933;">=</span> <span style="color: #0000dd;">2</span> <span style="color: #339933;">*</span> luku<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;2*%d=%d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span>luku<span style="color: #339933;">,</span> vastaus<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; luku<span style="color: #339933;">++;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Siinä olivatkin kaikki C-kielen ehtolauseet. Minä lähden kouluun. Tavataan taas tehtävien jälkeen. Moi!</p>
<h2>Tehtävä</h2>
<p>Tee ohjelma, joka laskee ympyrän alan ja ilmoittaa sen kahden desimaalin tarkkuudella.</p>
<p><strong>Vihje</strong></p>
<p>Kannattaa käyttää kaikissa muuttujissa float-tyyppiä, koska haluamme käyttää desimaalilukuja.</p>
<p>Ympyrän alahan lasketaan kaavalla: Ala=pii*säde², jossa pii on pyöreästi 3.145 tai jotain sellaista.</p>
<p>Jonkin aikaa sitten puhuimme printf-funktion %d-sijoituksista eli siitä, että printf-lauseisiin voi sijoittaa int-tyyppisiä lukuja käyttäen tuota %d-merkkiä. Jos et muista, selaa vähän taaksepäin, sieltä se löytyy..</p>
<p>Myös float-tyyppisiä muuttujia voi tällä tavoin kirjoittaa ruudulle. Silloin ei kuitenkaan käytetä %d:tä vaan %.1f:ää tai jotain sen tapaista.</p>
<p>Siis pisteen jälkeen tulee desimaalien määrä ja sitten f-kirjain. Esimerkiksi, jos haluat kirjoittaa muuttujan a, joka on tyyppiä float, kahden desimaalin tarkkuudella, tapahtuu se seuraavasti:</p>
<pre>printf("%.2f",a);</pre>
<p><strong>Ratkaisuehdotus</strong></p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* Ohjelma, joka laskee ympyrän alan */</span><br />
<br />
<span style="color: #339933;">#include &lt;stdio.h&gt;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #993333;">float</span> pii<span style="color: #339933;">,</span> sade<span style="color: #339933;">,</span> tulos<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;pii<span style="color: #339933;">=</span><span style="color:#800080;">3.145</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Annetaan piille arvo</span><br />
<br />
&nbsp; &nbsp;sade<span style="color: #339933;">=</span><span style="color: #0000dd;">15</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Ympyrän säde</span><br />
<br />
&nbsp; &nbsp;tulos<span style="color: #339933;">=</span>pii<span style="color: #339933;">*</span>sade<span style="color: #339933;">*</span>sade<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// A=pii*r²</span><br />
<br />
&nbsp; &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>Ympyrän ala = pii * %.1f ² = %.2f&quot;</span><span style="color: #339933;">,</span>sade<span style="color: #339933;">,</span>tulos<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<h2>Tehtävä</h2>
<p>Tee ohjelma, joka laskee nollasta 20:een ja kertoo onko luku suurempi vai pienempi kuin 10.</p>
<p><strong>Vihje</strong></p>
<p>Käytä muuttujatyyppiä int. Ja for-silmukka voisi myös olla aika kätevä.</p>
<p><strong>Ratkaisuehdotus</strong></p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* Ohjelma joka laskee nollasta kahteen-<br />
&nbsp; &nbsp;kymmeneen ja kertoo ovatko luvut pienempiä<br />
&nbsp; &nbsp;vai suurempia kuin 10 */</span><br />
<br />
<span style="color: #339933;">#include &lt;stdio.h&gt;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">int</span> t<span style="color: #339933;">;</span><br />
<br />
&nbsp; clrscr<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// tyhjennetään ruutu</span><br />
<br />
&nbsp; <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>t<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> t <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">20</span><span style="color: #339933;">;</span> t<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Luku: %d&quot;</span><span style="color: #339933;">,</span> t<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// tulostetaan luku (t)</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>t<span style="color: #339933;">==</span><span style="color: #0000dd;">10</span><span style="color: #009900;">&#41;</span> <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot; on 10&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// luku=10 (t)</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>t <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #009900;">&#41;</span> <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot; on suurempi kuin 10&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// luku &gt; 10</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">else</span> <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot; on pienempi kuin 10&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// luku &lt; 10 </span><br />
<br />
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// rivinvaihto</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<h2>Taulukoita ja merkkijonoja</h2>
<p>Joo. Nyt olet jo niin pitkällä, että osaat melkein kaikki C-kielen PERUS-asiat. Se tarkoittaa, että kohta voidaan alkaa puhua jostain mielenkiintoisemmasta. Mutta vielä muutama tärkeä asia sitä ennen. Tässä kappaleessa aloitamme viimeisen etappimme, taulukoin ja merkkijonoin.</p>
<p>Olet varmaankin ihmetellyt ja miettinyt tässä muuttujia katsoessasi, että miten on mahdollisra, että tekstille ei ole kuin char-tyyppinen yhden merkin kokoinen muuttuja, mutta kuitenkin on ohjelmia, joissa säilötään pitempiä sanoja ja jopa lauseita muuttujiin. Monissa muissa kielissä se tehdään omalla string -muuttujatyypillä, mutta sellaistahan C:ssä ei ole. Nyt sinusta varmaan tuntuu, että kiertelen ja kaartelen aivan turhaan. Olet varmaan jo otsikosta arvannut mistä tässä on kyse ja alat ikävystyä, anteeksi :(. Okei, asiaan.</p>
<p>C-kielessä merkkijonot ovat char-tyyppisiä taulukoita. Siispä ensin täytynee perehtyä taulukoihin. Taulukko on muuttujoiden muodostama kokonaisuus, lokerikko (jos muuttuja on lokero :). Se voi olla jono, jolloin puhutaan yksiulotteisesta taulukosta tai kaksi- tai useampiulotteinen taulukko. Kaavio varmaan selventäisi asiaa:</p>
<p><a href="http://www.suomipelit.com/tiedostot/2010/03/ckurssi1.gif" rel="lightbox[874]"><img class="aligncenter size-full wp-image-875" title="Yksiulotteinen taulukko" src="http://www.suomipelit.com/tiedostot/2010/03/ckurssi1.gif" alt="" width="233" height="67" /></a></p>
<p>Siinä oli siis pieni kaavio yksiylotteisesta taulukosta, jossa on n solua tai lokeroa tai mieluiten alkiota, niinkuin virallisesti sanotaan. Se alustetaan kuten tavallinen muuttuja, mutta perään laitetaan hakasulkeissa taulukon koko. Esimerkiksi, jos haluamme säilöä viiden pelaajan pistetiedot yhteen taulukkoon (viisisoluinen taulukko), teemme sen seuraavasti:</p>
<pre>int pisteet[5];</pre>
<p>Taulukko on tyyppiä int, koska pistetiedot ovat useimmiten kokonaislukuja ja viitonen perässä kertoo alkioiden lukumäärän eli taulukon koon. Huomaa, että ensimmäisen alkion numero ei ole 1 vaan 0. Kaksiulotteinen taulukko tehtäisiin vastaavasti:</p>
<pre>int monet_pisteet[5][2];</pre>
<p>Tuo taulukko voisi näyttää lokerikoksi ajateltuna tältä:</p>
<p><a href="http://www.suomipelit.com/tiedostot/2010/03/ckurssi2.gif" rel="lightbox[874]"><img class="aligncenter size-full wp-image-876" title="Kaksiulotteinen taulukko" src="http://www.suomipelit.com/tiedostot/2010/03/ckurssi2.gif" alt="" width="228" height="101" /></a><br />
Perään siis vain lisätään toisen ulotteen (ulottuvuuden?) alkioiden määrä. Ja ulotteita (äh, mitä ne nyt on?) voi lisätä niin paljon kuin haluaa &#8211; kuitenkaan kovin montaa ei kannata käyttää.</p>
<p>Nyt meillä on yksiulotteinen taulukko pisteet ja haluamme varmaan jo päästä sitä täyttelemään. Teemme näin: Jos haluamme sijoittaa ykköspelaajan pisteet ensimmäiseen alkioon, sijoitamme ne sinne (yksinkertaista ;)</p>
<pre>pisteet[0]=52000;</pre>
<p>Sinne meni sitten ykköspelaajalle 52000 pistettä. Huomaa edelleen: 0, ei 1. Vastaavasti voisimme antaa viitospelaajalle 10 pistettä:</p>
<pre>pisteet[4]=10;</pre>
<p>Samaan tapaan voi sitten sijoitella arvoja muillekin pelaajille. Nyt osaat tehdä taulukoita ja kuten jo taisin mainitakin, taulukoita voi tehdä kaiken tyyppisiä (int, float, char&#8230;). Ai niin, vielä yksi tärkeä asia. Jos joskus ohjelmasi alkavat antaa ihan ihmeellisiä lukuja, sellaisia joita et varmasti ole taulukkoihisi syöttänyt, on varmaankin kyse ylivuodosta. C nimittäin ei mitenkään vahdi sijoituksiasi, se antaa sinun kaikessa rauhassa sijoittaa 5-alkioisen pistetaulukon alkioon 200, jos niin haluat, mutta laittaa tiedot sitten muualle ja sotkee kaiken. Mitä yritän sanoa on, että huolehdi itse siitä, ettei ohjelmasi sijoittele tietoja olemattomiin alkioihin.</p>
<p>Nyt merkkijonoihin. Selitän tämän nopeasti, koska tämä tosiaankin on erittäin yksinkertainen asia. Tuossa äsken selitin taulukot ja merkkijonot ovat vain niiden yksi muoto. Siispä, jos haluat tallentaa vaikkapa parhaan pelaajan nimen, tarvitset taulukon tyyppiä char:</p>
<pre>char paras[10];</pre>
<p>Nyt sinulla on kymmenen merkin mittainen merkkijono. Helppoa, eikö? Sijoittaminen siihen ei sen sijaan ole niin helppoa, se ei tapahdu suoraan kuten joissain muissa kielissä vaan stdio-funktiolla strcpy, joka toimii seuraavasti:</p>
<pre>strcpy(taulukko,merkkijono);</pre>
<p>Taulukko on siis meidän tapauksessamme tuo paras, jonka loimme äsken. Ja merkkijono on tekstiä (tai toinen taulukko), joka halutaan sijoittaa ensimmäiseen merkkijonoon. Esimerkki varmaankin selventää..</p>
<pre>strcpy(paras,"Teemu S.");</pre>
<p>Tuossa sijoitimme Teemu Selänteen nimen alun merkkijonoon (char-tyypin taulukkoon) paras. Merkkijonon käsittelyyn on myös muita funktioita, mutta selittelen niitä vasta kun tarvitsemme sellaisia. Ei ehkä ihan vielä.<br />
Vähän aikaa sitten puhuimme printf-funktion %d-sijoituksista (int-tyypin muuttujia). Samalla tavalla voit tulostaa myös merkkijonoja käyttäen %s-merkkiä. Tässä täysin toimiva, mutta typerä esimerkki.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">#include &lt;stdio.h&gt;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">char</span> nimi<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">10</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; strcpy<span style="color: #009900;">&#40;</span>nimi<span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;Jarkko&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Jarkon nimi on %s&quot;</span><span style="color: #339933;">,</span>nimi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Lupailin tuossa edellisen kappaleen lopussa interaktiivisuutta, siispä saamanne pitää. Nimittäin stdio-kirjastosta löytyy funktio gets(); jolla voi lukea syötettä näppäimistöltä. Gets-funktiolle annetaan parametrina merkkijono, eli char-tyyppinen taulukko, jonka se sitten täyttää. Ensin pieni esimerkki ja sitten tehtävä.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">char</span> tekstia<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">50</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<br />
gets<span style="color: #009900;">&#40;</span>tekstia<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// kysyy käyttäjältä syötettä</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">// ja tallentaa sen taulukkoon tekstia</span></div></td></tr></tbody></table></div>
</pre>
<p>Tuo ei ollut vielä kokonainen ohjelma, sellaisen saat tehdä itse seuraavassa tehtävässä.</p>
<h2>Tehtävä</h2>
<p>Tee ohjelma, joka kysyy käyttäjän nimen ja tervehtii tätä sillä nimellä.</p>
<p><strong>Vihje</strong></p>
<p>Nimelle kannattaa varata tarpeeksi iso merkkijono, esimerkiksi 50 merkkiä.</p>
<p><strong>Ratkaisuehdotus</strong></p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* Ohjelma joka kysyy käyttäjän nimen<br />
&nbsp; &nbsp;ja tervehtii häntä nimeltä */</span><br />
<br />
<span style="color: #339933;">#include &lt;stdio.h&gt;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">char</span> nimi<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">50</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Mikä on nimesi? &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; gets<span style="color: #009900;">&#40;</span>nimi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>Terve, %s!&quot;</span><span style="color: #339933;">,</span>nimi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<h2>Tehtävä</h2>
<p>Seuraavaa tehtävää varten tarvitset vielä yhden tiedon, jota en aiemmin ole pystynyt kertomaan. Nimittäin, kuten varmaan arvasitkin, ei gets-funktiolla voi kysyä kuin merkkijonoja. Niinpä jos halutaan kysyä käyttäjältä kokonaislukuja, täytyy ottaa gets:illä merkkijono ja muuttaa se sitten int:iksi. Se tapahtuu stdlib-funktiolla atoi();, joka ottaa syötteenä merkkijonon ja palauttaa sen inttinä jos mahdollista. Esimerkki ei liene pahitteeksi..</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">int</span> luku<span style="color: #339933;">;</span><br />
<span style="color: #993333;">char</span> merkkijono<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">50</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<br />
gets<span style="color: #009900;">&#40;</span>merkkijono<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
luku<span style="color: #339933;">=</span>atoi<span style="color: #009900;">&#40;</span>merkkijono<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// tallentaa muuttujaan luku</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// merkkijonon sisältämän luvun</span></div></td></tr></tbody></table></div>
</pre>
<p>Ja nyt sitten se tehtävä!</p>
<p>Tee ohjelma, joka kysyy käyttäjän ikää ja kertoo onko hän tarpeeksi vanha saadakseen äänestää. Vihjeitä en anna tällä kertaa, edellä oleva atoi-juttu saa riittää.</p>
<p><strong>Ratkaisuehdotus</strong></p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* Ohjelma, joka kysyy käyttäjän ikää ja tutkii<br />
&nbsp; &nbsp;onko hän äänioikeutettu vai ei */</span><br />
<br />
<span style="color: #339933;">#include &lt;stdio.h&gt;</span><br />
<span style="color: #339933;">#include &lt;stdlib.h&gt;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #993333;">int</span> ika<span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #993333;">char</span> merkkijono<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">50</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp;<br />
<br />
&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Kuinka vanha olet? &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; gets<span style="color: #009900;">&#40;</span>merkkijono<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// luetaan syöte</span><br />
<br />
&nbsp; ika<span style="color: #339933;">=</span>atoi<span style="color: #009900;">&#40;</span>merkkijono<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// muutetaan se kokonaislukumuotoon</span><br />
<br />
&nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>ika <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">18</span><span style="color: #009900;">&#41;</span> <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>Et saa äänestää vielä!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #b1b100;">else</span> <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>Olet äänioikeutettu.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<h2>Funktiot</h2>
<p>Jess! Tämä on tosi tärkeä luku. Kaikissa (vähänkin isommissa) ohjelmissa tarvitaan funktioita. Mutta toisaalta tämä on myös hauska luku, koska funktioden oppiminen avaa sinulle aivan uudet mahdollisuudet ohjelmiesi kehittelyyn. Nyt siis tarkkana!</p>
<p>Funktiot eli aliohjelmat ovat ohjelmanpätkiä, jotka suorittavat jonkun tietyn usein tarvittavan pienen (tai isomman) tehtävän. Esimerkiksi luolalentelypelissä yhden funktion tehtävänä voisi olla ruudun vierittäminen, toisen tehtävä olisi törmäysten tutkiminen jne.</p>
<p>Ohjelma siis kannattaa pilkkoa tällaisiin pieniin osiin selkeyden ja käytännöllisyyden takia. Selkeyden siksi, että on paljon helpompi lukea ohjelmakoodia, joka on jaoteltu osiin, samoin kuin tietosanakirjasta jossa on otsikot ja aakkosjärjestys on paljon helpompi etsiäö tietoa kuin täysin järjestämättömästä. Käytännöllisyyden sen takia, että on aika hankalaa ja jopa typerää kirjoittaa sama ohjelmanpätkä joka kerta uudestaan vaikkapa 20 tai 100 kertaa. Se lisää koodin pituutta huomattavasti, mikä on huono asia, jos et yritä saada maailman pisimmän ohjelman ennätystä (mikä on melkoisen vaikeaa sekin &#8211; Windows 2000:ssa ohjelmarivejä on 30 miljoonaa, ja Microsoft käyttää funktioita).</p>
<p>Funktioita siis kannattaa käyttää, mutta miten? Tässä tulee vastaus kysymykseesi. Kaikkien taiteen sääntöjen mukaan tulee jokainen funktio esitellä ohjelman alussa heti includejen jälkeen. Itse en tätä vielä vähän aikaa sitten jaksanut tehdä (kääntäjä kyllä kääntää muutenkin..), mutta sitten alkoi tulla ongelmia funktiokutsujen kanssa, kun sen funktion jota kutsutaan piti olla ennen kutsujaa, eikä se tietenkään ollut ja sitten ei sitä löytynyt&#8230; Jotenka minä olen sitä mieltä, että tässä kannattaa tehdä ANSI:n mukaan, siis näin:</p>
<p>1.) Ohjelman alkuun #include-rivien jälkeen esittelyt kaikista funktioista</p>
<pre style="padding-left: 30px;">int laske_lasku(int a, int b);
...</pre>
<pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 19px; white-space: normal; font-size: 13px;">2.) Sitten main-funktio (pääohjelma)</span></pre>
<p>3.) Ja sen jälkeen funktiot, samalla tavalla kuin mainikin:</p>
<p style="padding-left: 30px;">
<pre style="padding-left: 30px;">int laske_lasku(int a, int b)
{
    int c; // Tehdään muuttuja laskun avuksi
    c=a+b; // Lasketaan
    return c;  // Palautetaan c
}</pre>
<p>Siis, funktion rakenne on samanlainen kuin mainissa, joka sekin on melkein tavallinen funktio. Funktion alussa on rivi, joka alkaa tässä tapauksessa int (voisi olla myös char, float, void&#8230;), on esittelyrivi. Alussa ennen mainia on siis aivan sama rivi vain sillä erolla, että siellä alussa se loppuu puolipisteeseen. Se alkaa siis muuttujatyypillä, joka kertoo minkä tyyppisiä palautusarvoja voi funktiolta odottaa. Nyt varmaan odotat minun selittävän mikä palautusarvo on ja senpä taidan tehdäkin. Palautusarvo on luku tms., jonka funktio antaa takaisin kutsujalle return- käskyllä. Sitten tulee funktion nimi, jolla sitä muut funktiot kutsuvat. Ja suluissa kaikki tieto, jota funktiolle annetaan sitä kutsuttaessa. (tässä tapauksessa a ja b). Näitä tietoja voidaan käyttää kuin funktiossa esiteltyjä muuttujia (c=a+b). Näin tehdään siis funktio ja nyt kerron vielä kuinka sitä kutsutaan niin päästään eteenpäin.<br />
Funktiota kutsutaan kirjoittamalla funktion nimi ja suluissa sille annettavat tiedot. Kirjoitetaanpa äsken tehtyä laske_lasku-funktiota kutsuva main-funktio.</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp;<span style="color: #993333;">int</span> luku<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Luku</span><br />
&nbsp; &nbsp; &nbsp;luku<span style="color: #339933;">=</span>laske_lasku<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Tulos: %d&quot;</span><span style="color: #339933;">,</span>luku<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Alussa esitellään muuttuja vastauksen varastoimista varten ja sitten kutsutaan funktiota. Koska se on tyyppiä int ja palauttaa arvon, voimme ottaa palautusarvon muuttujaan (luku=laske&#8230;). Jos funktion tyyppi olisi void, tämä ei onnistuisi (ja luultavasti ei olisi tarpeellistakaan). Sitten on funktion nimi ja suluissa arvot muuttujille: ykkönen menee a:han ja kakkonen b:hen. Ja lopuksi kutsutaan stdio-funktiota printf. Muista laittaa alkuun #include &lt;stdio.h&gt;. Nyt siinä taisi tulla tarpeeksi funktioista. Jos jotain puuttuu tästä, jos et tajunnut kaikkea mitä haluaisit, kerro minulle. Lisään sitten tähän lisää tietoa ja vastaan mielelläni kysymyksiisi suoraankin. Huh! Selvittiin tästäkin.</p>
<h2>Tyypit, structit ja muuta hauskaa</h2>
<p>Niinpä, nyt päästiinkin viimeiseen peruskurssin osaan vai miten sen nyt ilmaisee. Vielä on paljon kerrottavaa, mutta tämän luvun jälkeen voitkin jo valita mihin päin haluat suuntautua, mikä kiinnostaa. Minua kiinnosti ja kiinnostaa edelleen peliohjelmointi, mutta paljon on muitakin mahdollisuuksia. Oppiminenhan jatkuu varmasti yhtä pitkään kuin ohjelmointia harrastaa (ja minä ainakin toivon vielä kahdeksankymppisenä ukkonakin sitä tekeväni), joten matka on pitkä, mutta varmasti kiinnostava. Nyt kuitenkin tämän luvun asioihin.</p>
<p>Tyypit ovat tyyppejä. Siis, yritän selittää tämän jotenkin järkevästi.. No joo, voit siis määrittää omia tyyppejäsi kuten muuttujatyyppejä, vaikkapa näin:</p>
<pre>typedef kokonaisluku int;</pre>
<p>Siinä yksinkertaisesti luotiin tyyppi nimeltä kokonaisluku, joka käyttäytyy aivan samoin kuin int. Sellaista.. En sano tästä enempää vaan siirryn structeihin, jotka ovat varmasti paljon hyödyllisempiä.</p>
<p>Structeihin voit koota yhteen erilaisia muuttujia helpommin hallittaviksi kokonaisuuksiksi, vähän niinkuin olio-ohjelmoinnissa. Esimerkiksi seuraavalla tavalla voidaan esitellää structi: (niin, tämä samoin kuin tyyppien esittely tehdään funktioiden ulkopuolella, vaikka niiden includejen jälkeen)</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> PELAAJA<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #993333;">char</span> nimi<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">20</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #993333;">int</span> pisteet<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #993333;">int</span> x<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #993333;">int</span> y<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span> PELAAJA<span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
</pre>
<p>Siinä oli johonkin yksinkertaiseen peliin sopiva pelaajastructi. Se sisältää tilan pelaajan nimelle (20 merkkiä), pistemäärälle ja koordinaateille, riittää hyvin vaikka tämän tutoriaalin esimerkkipeliin. Eli: structin rakenne on seuraava: ensin typedef struct structin nimi ja aaltosulku {. Sitten vain luetellaan kaikki muuttujat, joita siihen halutaan ja loppuun aaltosulku toisin päin ja structin nimi uudestaan.</p>
<p>Kun sitten jossain vaiheessa haluat käyttää structia, esittelet sellaisen, kuten muuttujankin:</p>
<pre>PELAAJA pl1;</pre>
<p>Siinä tuli PELAAJA-tyyppinen structi nimeltänsä pl1. Nyt pl1:n kaikkiin muuttujiin voi viitata rakenteella: pl1.muuttuja. Selvitelläänpä asiaa täyttämällä pelaajan tiedot:</p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">strcpy<span style="color: #009900;">&#40;</span>pl1.<span style="color: #202020;">nimi</span><span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;Saku Koivu&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Pelaajan nimi</span><br />
pl1.<span style="color: #202020;">pisteet</span><span style="color: #339933;">=</span><span style="color: #0000dd;">10000</span><span style="color: #339933;">;</span><br />
pl1.<span style="color: #202020;">x</span><span style="color: #339933;">=</span><span style="color: #0000dd;">10</span><span style="color: #339933;">;</span><br />
pl1.<span style="color: #202020;">y</span><span style="color: #339933;">=</span><span style="color: #0000dd;">10</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
</pre>
<p>Siinä tuli se juttu. Structit olen todennut pelejä ohjelmoidessani tosi hyödyllisiksi, muussa ohjelmoinnissa en niitä ole vielä käyttänyt. Kannattaa käyttää!<br />
Ai niin, lupasin tuossa luvun otsikossa jotain muutakin hauskaa, mitäköhän se voisi olla. No kerronpa vaikka miten satunnaislukuja saa arvottua helposti.</p>
<p>Ensinnäkin tarvitsee includoida time.h ja stdlib.h. Satunnaislukusysteemi alustetaan komennolla srand ja satunnaisluvun saat komennolla rand. Katso vaikka tästä:</p>
<pre>srand((unsigned int)time((time_t *)NULL));
luku=(rand()%6)+1;</pre>
<p>Jos aiot tehdä seuraavan tehtävän, tarvitset tätä satunnaislukujuttua.</p>
<h2>Tehtävä</h2>
<p>Tee ohjelma, joka &#8220;ajattelee&#8221; jotain lukua ja pyytää käyttäjää arvaamaan sitä kunnes arvaa oikein tai liian monta kertaa. Se voisi myös kertoa onko haluttu luku pienempi vai suurempi kuin arvaus</p>
<p><strong>Vihje</strong></p>
<p>Siinä oli kysymys ja tässä sitten hieman apuja. Niin, kyseessä on aivan perusarvailuleikki, ei kovin loisteliasta, mutta varmasti opettavaista. Kirjoita ohjelmasi ja kokeile sitä, käännä se rohkeasti, pelaile ja kehittele vaikka arvauspeli deluxe. Älä ryntää heti katsomaan vastausta vaan katso se vasta lopuksi nähdäksesi mitä tein eri tavalla. Tässä vielä muutama käsky joita tulet siinä tarvitsemaan, ja sitten ei muuta kuin töihin!</p>
<p><strong>gets(merkkijono);</strong><br />
Tällä saat luettua käyttäjältä rivin tekstiä.</p>
<p><strong>luku = atoi(merkkijono);</strong><br />
Ja tällä saat niin paljon merkkijonosta kuin mahdollista muutettua luvuksi</p>
<p><strong>Ratkaisuehdotus</strong></p>
<pre>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;height:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* Esimerkki ohjelmasta, joka arvuuttelee lukua<br />
&nbsp; &nbsp;käyttäjältä<br />
<br />
&nbsp; &nbsp;(C) Jarkko Laine 1999 */</span><br />
<br />
<span style="color: #666666; font-style: italic;">// INCLUDET ///////////////////////////////////////</span><br />
<span style="color: #339933;">#include &lt;stdio.h&gt;</span><br />
<span style="color: #339933;">#include &lt;stdlib.h&gt;</span><br />
<span style="color: #339933;">#include &lt;time.h&gt;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// PROTOTYYPIT ////////////////////////////////////</span><br />
<span style="color: #993333;">void</span> nayta_alkutekstit<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// PÄÄOHJELMA /////////////////////////////////////</span><br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #993333;">int</span> luku<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// oikea luku</span><br />
&nbsp; &nbsp;<span style="color: #993333;">int</span> arvattu<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// arvattu luku</span><br />
&nbsp; &nbsp;<span style="color: #993333;">char</span> arvaus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">80</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// merkkijono arvausta varten</span><br />
&nbsp; &nbsp;<span style="color: #993333;">int</span> arvaukset<span style="color: #339933;">=</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Kuinka monta kertaa pelaaja on arvannut</span><br />
<br />
&nbsp; &nbsp;nayta_alkutekstit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// kutsutaan omaa funktiotamme,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// joka kirjoittaa tervehdykset</span><br />
<br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">// Alustetaan satunnaislukugeneraattori</span><br />
&nbsp; &nbsp;srand<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span>time<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>time_t <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>NULL<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">// Arvotaan luku</span><br />
&nbsp; &nbsp;luku<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span>rand<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">%</span><span style="color:#800080;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span>arvattu<span style="color: #339933;">!=</span>luku<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #666666; font-style: italic;">// Niin kauan kunnes pelaaja arvaa</span><br />
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>Annapas tulla arvausta! &gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; gets<span style="color: #009900;">&#40;</span>arvaus<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// kysytään käyttäjältä syöte</span><br />
&nbsp; &nbsp; arvattu<span style="color: #339933;">=</span>atoi<span style="color: #009900;">&#40;</span>arvaus<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// muutetaan se intiksi</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>arvattu <span style="color: #339933;">&lt;</span> luku<span style="color: #009900;">&#41;</span> <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>Luku on suurempi...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>arvattu <span style="color: #339933;">&gt;</span> luku<span style="color: #009900;">&#41;</span> <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>Luku on pienempi...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">else</span> <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>Onneksi olkoon! Käytit vain %d arvausta&quot;</span><span style="color: #339933;">,</span>arvaukset<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; arvaukset<span style="color: #339933;">++;</span> <span style="color: #666666; font-style: italic;">// Taas meni yksi arvaus...</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// funktiomme, joka näyttää alkutekstit</span><br />
<span style="color: #993333;">void</span> nayta_alkutekstit<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;clrscr<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// tyhjennetään ruutu</span><br />
&nbsp; &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Tervetuloa arvauspeliin!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;------------------------<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Tehtäväsi on arvata ajattelemani luku väliltä 1-10<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Onnea!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>Siinä se oli&#8230; Yksinkertainen, mutta toimiva ohjelma. Funktioitakin käytettiin mallin vuoksi.</p>
<h2>Mitä nyt?</h2>
<p>Jess! Nyt olet C-guru! Tai et ehkä ihan, mutta tiedät joka tapauksessa niin paljon C-kielestä, että voit jatkaa eteenpäin. Jos olisin oikea opettaja, pitäisin tässä kohdassa kurssikokeen &#8211; mutta jääköön se väliin tällä kertaa.</p>
<p>Nyt voit jatkaa mihin suuntaan haluat. Maailma on mahdollisuuksia täynnä. Ja näiltäkin sivuilta löydät mahdollisuuksia vaikka muille jakaa. Ja niitä tulee koko ajan lisää. Tutki ja ohjelmoi! Äläkä epäröi kysyä. Onnea tutkimusmatkallesi! Kuka ties sinusta tulee uusi Bill Gates tai vaikka Jarkko Laine &#8211; hehheh :)</p>
<p>Huh! Sainpas sen tehtyä. Vajaa kaksi vuotta siihen meni (taukoineen), mutta nyt se on valmis&#8230; Jos löydät virheitä tai epätarkkuuksia, ota yhteyttä sähköpostilla ja kerro minulle. Tai jos sinulla on toiveita siitä minkälaisia kursseja haluat jatkossa nähdä.</p>
<hr /><em>Artikkelin kirjoitti alun perin jalaine.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.suomipelit.com/1999/03/11/pikkuaskelin-c-ohjelmoijaksi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
