lauantai 28. syyskuuta 2019

TYHJÄ PAPERI KERTOO. Osa 1010. Yksinkertaista peliohjelmointia. Osa 5. Jätkänsakki eli ristinolla - graafisella liittymällä

No, vihdoinkin pääsin jatkamaan tätä bloggausta. Koko ajan on ollut kaikkea pientä, joka on keskeyttänyt kirjoittamisen. Niin, mihin jäinkään? Jätkänsakki Pythonin grafiikkakirjaston Tkinterin avulla.

Kun olin saanut tämän tehtävän tehtyä, putkahti mieleeni ajatus, että tämä onkin ehkä paras tapa oppia Tkinterin käyttöä. Kun ensin tekee pelin komentorivisovelluksena, on valmiina ongelma, miten  saada siihen toisenlainen käyttöliittymä. Toisin sanoen ensin toteutetaan pelin logiikka ja vasta sitten käyttöliittymä. Tavallisestihan ohjelmistoprojekteissa toimitaan päinvastoin.

     *     *     *

Graafinen käyttöliittymä poikkeaa toiminnallisesti komentorivisovelluksesta, eikä muuten voisi ollakaan, vaikka logiikka on muutoin sama.

Komentoriviltä annettavien komentojen sijaan nyt syöttö tapahtuu painikkeita painamalla. Koordinaatteja ei tarvitse antaa. Kun X tai O on voittanut, voitto ilmoitetaan dialogissa.

Jotkin asiat eivät selvinneet ilman taustatyötä. Vaikka Pythonissa ei ole staattisia muuttujia, sellaisen pystyy kuin pystyykin luomaan Tkinterin avulla. Tällaista muuttujaa tarvitaan, jotta pelaajien vuoroista on mahdollista pitää kirjaa.

Pythonin ominaisuutena on, että komponenttien kuten buttonien tai labelien avulla on mahdollista välittää  tai vastaanottaan tietoa niiden text-ominaisuuden avulla. Tämän avulla sain muutettua painikeiden EMPTY-tekstin X:ksi tai O:ksi sekä buttonin disabled-option päällä, ettei sitä voinut enää toistamiseen painaa.

Erona on myös se, että tällä kertaa sijoitin painikkeet dynaamisesti taulukkoon tai listaan. Kaksi proseduuria tai aliohjelmaa otin myös käyttöön. Toinen tarkistaa, onko tullut voittorivia ja toinen hoitaa klikkauksen jälkeisen tapahtuman.

from tkinter import *
from tkinter import messagebox

root = Tk()
root.geometry('500x400')
root.title("TicTacToe")    
root.vuoro_X = 0
btn = [0,0,0,0,0,0,0,0,0]
btn_text = ["","","","","","","","",""]

for i in range(9):
    btn_text[i] = StringVar()
    btn_text[i].set("\nempty\n")
    btn[i] = Button(root, textvariable=btn_text[i], command=lambda i1=i:clicked(btn[i1],btn_text[i1]))

def isWon():
    #vaaka    
    if btn_text[0].get() == "\n    X    \n" and btn_text[1].get() 
        == "\n    X    \n" and btn_text[2].get() == "\n    X    \n":
        messagebox.showinfo('Ristinolla','X VOITTI PELIN!')
    if btn_text[0].get() == "\n    0    \n" and btn_text[1].get() 
        == "\n    0    \n" and \btn_text[2].get() == "\n    0   \n":
        messagebox.showinfo('Ristinolla','O VOITTI PELIN!')
    if btn_text[3].get() == "\n    X    \n" and btn_text[4].get() 
        == "\n    X    \n" and btn_text[5].get() == "\n    X    \n":
        messagebox.showinfo('Ristinolla','X VOITTI PELIN!')
    if btn_text[3].get() == "\n    0    \n" and btn_text[4].get() 
        == "\n    0    \n" and btn_text[5].get() == "\n    0    \n":
        messagebox.showinfo('Ristinolla','O VOITTI PELIN!')
    if btn_text[6].get() == "\n    X    \n" and btn_text[7].get() 
        == "\n    X    \n" and btn_text[8].get() == "\n    X    \n":
        messagebox.showinfo('Ristinolla','X VOITTI PELIN!')
    if btn_text[6].get() == "\n    0    \n" and btn_text[7].get() 
        == "\n    0    \n" and btn_text[8].get() == "\n    0    \n":
        messagebox.showinfo('Ristinolla','O VOITTI PELIN!')

    #pysty
    if btn_text[0].get() == "\n    X    \n" and btn_text[3].get() 
        == "\n    X    \n" and btn_text[6].get() == "\n    X    \n":
        messagebox.showinfo('Ristinolla','X VOITTI PELIN!')
    if btn_text[0].get() == "\n    0    \n" and btn_text[3].get() 
        == "\n    0    \n" and btn_text[6].get() == "\n    0    \n":
        messagebox.showinfo('Ristinolla','O VOITTI PELIN!')
    if btn_text[1].get() == "\n    X    \n" and btn_text[4].get() 
        == "\n    X    \n" and btn_text[7].get() == "\n    X    \n":
        messagebox.showinfo('Ristinolla','X VOITTI PELIN!')
    if btn_text[1].get() == "\n    0    \n" and btn_text[4].get() 
        == "\n    0    \n" and btn_text[7].get() == "\n    0    \n":
        messagebox.showinfo('Ristinolla','O VOITTI PELIN!')
    if btn_text[2].get() == "\n    X    \n" and btn_text[5].get() 
        == "\n    X    \n" and btn_text[8].get() == "\n    X    \n":
        messagebox.showinfo('Ristinolla','X VOITTI PELIN!')
    if btn_text[2].get() == "\n    0    \n" and btn_text[5].get() 
        == "\n    0    \n" and btn_text[8].get() == "\n    0    \n":
        messagebox.showinfo('Ristinolla','O VOITTI PELIN!')

    #ristiin
    if btn_text[0].get() == "\n    X    \n" and btn_text[4].get() 
        == "\n    X    \n" and btn_text[8].get() == "\n    X    \n":
        messagebox.showinfo('Ristinolla','X VOITTI PELIN!')
    if btn_text[0].get() == "\n    0    \n" and btn_text[4].get() 
        == "\n    0    \n" and btn_text[8].get() == "\n    0    \n":
        messagebox.showinfo('Ristinolla','O VOITTI PELIN!')
    if btn_text[2].get() == "\n    X    \n" and btn_text[4].get() 
        == "\n    X    \n" and btn_text[6].get() == "\n    X    \n":
        messagebox.showinfo('Ristinolla','X VOITTI PELIN!')
    if btn_text[2].get() == "\n    0    \n" and btn_text[4].get() 
        == "\n    0    \n" and btn_text[6].get() == "\n    0    \n":
        messagebox.showinfo('Ristinolla','O VOITTI PELIN!')
    
def clicked(button,btn_text):
    res = ""
    if root.vuoro_X == True:     
        res = "\n    X    \n"
        root.vuoro_X = False
    else:            
        res = "\n    0    \n" 
        root.vuoro_X = True
    btn_text.set(res)
    button.configure(state=DISABLED)
    isWon()

btn[0].grid(column=0, row=1)
btn[0].place(relx=0.25,rely=0.25,anchor=W)

btn[1].grid(column=1, row=1)
btn[1].place(relx=0.5,rely=0.25,anchor=CENTER)

btn[2].grid(column=2, row=1)
btn[2].place(relx=0.75,rely=0.25,anchor=E)

btn[3].grid(column=0, row=2)
btn[3].place(relx=0.25,rely=0.5,anchor=W)

btn[4].grid(column=1, row=2)
btn[4].place(relx=0.5,rely=0.5,anchor=CENTER)

btn[5].grid(column=2, row=2)
btn[5].place(relx=0.75,rely=0.5,anchor=E)

btn[6].grid(column=0, row=3)
btn[6].place(relx=0.25,rely=0.75,anchor=W)

btn[7].grid(column=1, row=3)
btn[7].place(relx=0.5,rely=0.75,anchor=CENTER)

btn[8].grid(column=2, row=3)
btn[8].place(relx=0.75,rely=0.75,anchor=E) #keskelle

root.mainloop()

Linkki:

Python TutorialW3Schools

perjantai 27. syyskuuta 2019

TYHJÄ PAPERI KERTOO. Osa 1009. Yksinkertaista peliohjelmointia. Osa 4. Jätkänsakki eli ristinolla - komentoriviltä

Toinen peli jota olen vuosien varrella - eli siitä lähtien kun 4-kymppisenä 1. kerran ohjelmoin - tehnyt muutamia kertoja on jätkänsakki eli ristinolla. Edellisestä kerrasta on kuitenkin 10 vuotta, joten hetken aikaa täytyi tätäkin pähkiä. Komentorivisovelluksena en ole tätä aiemmin tehnyt, mikä sekin hetken aikaa mietitytti.

Koodi ei ole tiivistä, eikä esimerkillistä. Halusin vain saada aikaan toimivan pelin!












   *     *    *

#Pelaaja viittaa ristikon kohtaan koordinaateilla, jotka on tallennettu 2-ulotteiseen taulukkoon.

ristinolla = [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]

#Aluksi tulostetaan pelin nimi - ja aloitusnäkymä komentoriville.

print("RISTINOLLA")
j=0
for i in range(3):
    print(" --------"+" --------"+" -------")
    print("|",ristinolla[i+j],"|",ristinolla[i+1+j],\
        "|",ristinolla[i+2+j])
    j=j+2           
    print(" --------"+" --------"+" -------")
valinta = ""
vuoro_X = True

#Pelaaminen tapahtuu while-toistorakenteen sisällä. Tyhjällä välilyönnillä peli lopetetaan, jollei se ole loppunut sitä ennen X:n tai O:n voittoon.

while valinta != " ":

#Ennen seuraavaa siirtoa tarkistetaan tilanne. Tätä koodia voisi paljon tiivistää!

    #vaaka - X
    if ristinolla[0] == "  X   " and ristinolla[1] == "  X   " and \
       ristinolla[2] == "  X   ":
        print("X VOITTI PELIN!")
        break
    if ristinolla[3] == "  X   " and ristinolla[4] == "  X   " and \
       ristinolla[5] == "  X   ":
        print("X VOITTI PELIN!")
        break
    if ristinolla[6] == "  X   " and ristinolla[7] == "  X   " and \
       ristinolla[8] == "  X   ":
        print("X VOITTI PELIN!")
        break
    #pysty    
    if ristinolla[0] == "  X   " and ristinolla[3] == "  X   " and \
       ristinolla[6] == "  X   ":
        print("X VOITTI PELIN!")
        break
    if ristinolla[1] == "  X   " and ristinolla[4] == "  X   " and \
       ristinolla[7] == "  X   ":
        print("X VOITTI PELIN!")
        break
    if ristinolla[2] == "  X   " and ristinolla[5] == "  X   " and \
       ristinolla[8] == "  X   ":
        print("X VOITTI PELIN!")
        break
    #ristikkain
    if ristinolla[0] == "  X   " and ristinolla[4] == "  X   " and \
       ristinolla[8] == "  X   ":
        print("X VOITTI PELIN!")
        break
    if ristinolla[2] == "  X   " and ristinolla[4] == "  X   " and \
       ristinolla[6] == "  X   ":
        print("X VOITTI PELIN!")
        break
    #vaaka - O
    if ristinolla[0] == "  O   " and ristinolla[1] == "  O   " and \
       ristinolla[2] == "  O   ":
        print("O VOITTI PELIN!")
        break
    if ristinolla[3] == "  O   " and ristinolla[4] == "  O   " and \
       ristinolla[5] == "  O   ":
        print("O VOITTI PELIN!")
        break
    if ristinolla[6] == "  O   " and ristinolla[7] == "  O   " and \
       ristinolla[8] == "  O   ":
        print("O VOITTI PELIN!")
        break
    #pysty    
    if ristinolla[0] == "  O   " and ristinolla[3] == "  O   " and \
       ristinolla[6] == "  O   ":
        print("O VOITTI PELIN!")
        break
    if ristinolla[1] == "  O   " and ristinolla[4] == "  O   " and \
       ristinolla[7] == "  O   ":
        print("O VOITTI PELIN!")
        break
    if ristinolla[2] == "  O   " and ristinolla[5] == "  O   " and \
       ristinolla[8] == "  O   ":
        print("O VOITTI PELIN!")
        break    
    #ristikkain
    if ristinolla[0] == "  O   " and ristinolla[4] == "  O   " and \
       ristinolla[8] == "  O   ":
        print("O VOITTI PELIN!")
        break
    if ristinolla[2] == "  O   " and ristinolla[4] == "  O   " and \
       ristinolla[6] == "  O   ":
        print("O VOITTI PELIN!")
        break
#Nyt ollaan vasta kohdassa, jossa pelaaja (ensin X ja sitten O) tekevät siirtonsa.     
    valinta = input("Valitse ruutu (kirjoita esim. 1,2): ")
    if valinta == "0,0": valinta = 0
    elif valinta =="0,1": valinta = 1
    elif valinta == "0,2": valinta = 2
    elif valinta == "1,0": valinta = 3
    elif valinta == "1,1": valinta = 4
    elif valinta == "1,2": valinta = 5
    elif valinta == "2,0": valinta = 6
    elif valinta == "2,1": valinta = 7
    elif valinta == "2,2": valinta = 8
    if valinta == " ":
        break
    else:
        if vuoro_X == True:     
            ristinolla[int(valinta)] ="  X   "
            vuoro_X = False
        else:            
            ristinolla[int(valinta)] ="  O   "
            vuoro_X = True
        j=0

#Siirron jälkeen muuttunut näkymä tulostetaan ennen seuraavaa siirtoa.
        for i in range(3):
            print(" --------"+" --------"+" -------")
            print("|",ristinolla[i+j],"|",ristinolla[i+1+j],"|",\
                ristinolla[i+2+j])
            j=j+2           
        print(" --------"+" --------"+" -------")

Linkki:

Python TutorialW3Schools

torstai 26. syyskuuta 2019

RUNO ON VAPAA. Osa 1545 - hei! nyt!




hei! nyt! maailma
on tulossa ovesta
sisään: taas sotaa

suomen hallituskin
hyökkäilee venäjälle
vasemmistokin

revit paperin
suljet television
hei! nyt! tulee taas

ja niin minua
viedään vaikka unelmat
ovat jo ohi



Linkit:

crowded house - don't dream it's over. (radio helmi 26.07.2019)

- CARPE DIEM - Tartu hetkeen - 707 - Häpeällinen vasemmisto


En muista hävenneeni ja olleeni ärtyneempi aikoihin kuin katsellessani televisiota eilen. Tosin en katsele kovin paljon televisiota tai edes ajankohtaisohjelmia niin kuin ennen.

Mielessäni palaan ensimmäiseen sateenkaarihallitukseen vuonna 1995, jonne Vasemmistoliitto väkisin tunki itsensä claes anderssoineen. Se oli häpeällistä ja se vihastutti. Oppositiopolitiikan mahdollisuus menettiin ja mahdollisuus alkaa tosissaan ajaa huono-osaisten ja työntekijöiden asioita Suomessa. Sama linja on jatkunut tähän päivään asti.

Tilanne on nyt vielä astetta huonompi kuin 25 vuotta sitten. Nyt huono-osaisten ja pienipalkkaisten työntekijöiden kuten hoiva-alan naisten kanssa samassa rintamassa on Äiti-luonto, mikä on ihan eri asia kuin viimeaikainen ilmastonmuutos-jargon, jolle ei todellisuudesta löydy minkäänlaista vastinetta.

      *     *     *

Jos ja kun nykyhallitus purematta nielee armeijan suurhankinnat, miltä tällä hetkellä näyttää, on turha ihmetellä, että niin Vasemmistoliitto, SDP kuin Vihreät jossain aikataulussa pyyhkiytyy pois puoluekartalta. Tällainen politiikka ei sovi 2020 -luvun Suomeen. Ei kerta kaikkiaan.

Jos vakavaa politiikkaa halutaan alkaa tehdä, ensin luovutaan siitä, mikä on kaikkein turhinta ja haitallisinta ihmisen ja ympäristön kannalta.

     *     *     *

Vaihtoehtona on tie, jota on kuljettu pitkään. Eli pohjoisen herrakansan aseman pönkittäminen. Ja maailman yksi militaristisimmista valtioista. Niin, ja tietysti maan sisäisen kolonialistisen järjestelmän rakentaminen ja vahvistaminen, mikä perustuu siihen, että teollisuus ja palvelut tarvitsee halpaa työvoimaa. Ja työvoimaahan saadaan sillä tavoin kuin tähänkin asti: aina silloin tällöin rajat avataan kenen tahansa vapaasti tulla maahan niin kuin tehtiin vuonna 2015! Seuraava kerta on jo näköpiirissä...

Linkki:

A-Studio. Yle TV1 25.09.2019

RUNO ON VAPAA. Osa 1544 - vain parin sanan tähden




hissin edessä
odotin ja odotin
et koskaan tullut

oi, joi! odotin
et vastannut kun soitin
mihin katosit

jeesus, kun kaipaan
mä yksin nukkua saan
susta uneksin

sua suudella
haluan en muuta kuin
suudella joskus

sanoa sanat
jotka olen halunnut
aina sanoa





Linkit:

rolling stones - miss you. (radio helmi 26.09.2019)

tiistai 24. syyskuuta 2019

TYHJÄ PAPERI KERTOO. Osa 1008. Yksinkertaista peliohjelmointia. Osa 3. Hirsipuu - graafiseksi


Päivän pähkimisellä sain portattua komentoriviltä pelattavan hirsipuu-pelin applikaatioksi. Mistään mutkikkaasta operaatiosta ei periaatteessa ollut kysymys. Kaikkihan oli tietyllä tavalla jo valmiina ja piti vain tietää, miten työkaluja käytti. Miten päin vasaraa piti kädessä.

Pythonissa on Tkinter-niminen kirjasto, jonka avulla graafisen liittymän voi rakentaa. Aluksi ajattelin että voin tehdä sen peleihin tarkoitetun Arcade-kirjaston avulla, mutta siinä ei ollut jostain syystä käytettävissä yksinkertaista tekstikenttää ja painiketta, joten otin käyttöön Tkinterin, joka sopi tähän tarkoitukseen.

En ollut aiemmin tehnyt mitään itsenäisesti Tkinterillä, joten tilanteeseen liittyi hieman haastetta. Käytin pohjana yhtä esimerkkiä, jossa yksinkertaisesti painiketta painamalla saadaan teksti tulostettua näytölle. Omassa appissa täytyi tehdä hieman enemmän.

Helpoimmillaan kaikki olisi voinut mennä niin että käytän aiemmin tehtyä sovellusta suoraan apuna. Toisin sanoen painiketta painamalla sovellus tarkistaa, kuuluuko tekstikenttään kirjoitettu merkki arvottuun sanaan vai ei. Jos kirjain kuuluu sanaan, merkki tulostuu oikealle paikalleen viivalle aivan samalla tavalla kuin komentorivillä tapahtui.

    *      *      *

Graafisen liittymän komponentit vaativat kuitenkin hieman viilausta alkuperäiseen koodiin. Esimerkiksi sanan arpominen taulukosta ei voinut tapahtua aiemmin tehdyn appin tai metodin sisällä while -luupissa vaan se täytyi siirtää metodin ulkopuolelle. - Aina kun painiketta painoi, appi arpoi uuden sanan, mikä ei ollut tarkoitus. Päädyin sen sijaan siihen, että arpominen tapahtui silloin, kun sovellus käynnistettiin. Näinhän oli alkuperäisessä komentorivisovelluksessakin.

Muutoin muutokset olivat pieniä. Toinen vastaavanlainen viilaus oli merkkien tulostaminen näytölle. Sitä varten tarvittiin uusi toistolause, joska merkkijonoa ei voinut tulostaa kerralla suoraan näytölle.














Ja tällainen oli lopputulos:

from tkinter import *
import random

root = Tk()
root.geometry('500x400')
root.title("Hirsipuu")    
index = random.randint(0,3)

def arvoSana(myEntry,index):
    sanat = ["hammas","paikka","vastaanotto","pora"]
    sana = sanat[index]
    sanan_pituus = len(sana)
    askelvali = 40

    if sanan_pituus == 12:
        kirjaimet = ['','','','','','','','','','','','']
    elif sanan_pituus == 11:
        kirjaimet = ['','','','','','','','','','','']
    elif sanan_pituus == 10:
        kirjaimet = ['','','','','','','','','','']
    elif sanan_pituus == 9:
        kirjaimet = ['','','','','','','','','']
    elif sanan_pituus == 8:
        kirjaimet = ['','','','','','','','']
    elif sanan_pituus == 7:
        kirjaimet = ['','','','','','','']
    elif sanan_pituus == 6:
        kirjaimet = ['','','','','','']
    elif sanan_pituus == 5:
        kirjaimet = ['','','','',''] 
    else:
        kirjaimet = ['','','',''] 

    for i in range(sanan_pituus):
        askelvali = askelvali + 30
        myCanvas.create_line(askelvali,100,askelvali+10,100)

    for i in range(sanan_pituus):
        if myEntry == sana[i]:
            if kirjaimet[i] == "":
                kirjaimet.pop(i)
                kirjaimet.insert(i,myEntry)

    askelvali=40
    for i in range(sanan_pituus):
        askelvali = askelvali + 30
        myCanvas.create_text(askelvali,90,anchor=W,
            text=kirjaimet[i])

myCanvas = Canvas(root)

myLabel = Label(root,text='Anna kirjain:',width=20,font=20)
myLabel.pack()

myEntry = Entry(root)
myEntry.place(x=10,y=50)
myEntry.pack()

myButton = Button(root,text="Kokeile",command=lambda: helloWorld(myEntry.get(),index))
myButton.pack()

myCanvas.pack()
root.mainloop()

Linkki:

Python TutorialW3Schools

maanantai 23. syyskuuta 2019

TYHJÄ PAPERI KERTOO. Osa 1007. Yksinkertaista peliohjelmointia. Osa 2. Hirsipuu


Ehkä kaikkein yksinkertasimman pelin, hirsipuupelin, ja sen yksinkertaisimman version voi toteuttaa komentorivillä ajettavana sovelluksena, jossa sanat - tai vain yksi sana - on tallennettu taulukkoon tai muuttujaan.

Kun yksinkertainen algoritmi on selvillä, siitä voi lähteä kehittämään Arcade -applikaatiota, jossa on graafinen käyttöliittymä.

Hirveän paljon miettimättä tällä kertaa päädyin tällaiseen ratkaisuun Python-kielellä. Ongelmia tuotti se, ettei tässä kielessä taulukon kokoa voi määrittää etukäteen vaan se luodaan aina dynaamisesti.

      *     *     *
import random

index = random.randint(0,4)
sanat = ["secret","game","play","python","library","television"]
sana = sanat[index]
pituus = len(sana)
maara = 0

if pituus == 12:
    kirjaimet = ['_','_','_','_','_','_','_','_','_','_','_','_']
elif pituus == 11:
    kirjaimet = ['_','_','_','_','_','_','_','_','_','_','_']
elif pituus == 10:
    kirjaimet = ['_','_','_','_','_','_','_','_','_','_']
elif pituus == 9:
    kirjaimet = ['_','_','_','_','_','_','_','_','_']
elif pituus == 8:
    kirjaimet = ['_','_','_','_','_','_','_','_']
elif pituus == 7:
    kirjaimet = ['_','_','_','_','_','_','_']
elif pituus == 6:
    kirjaimet = ['_','_','_','_','_','_']
elif  pituus == 5:
    kirjaimet = ['_','_','_','_','_'] 
elif :
    kirjaimet = ['_','_','_','_'] 

print(kirjaimet)

while maara < pituus:
    kirjain = input("Arvaa sanan kirjain: ")
    maara = 0
    for i in range(pituus):
        if kirjain == sana[i]:
            if kirjaimet[i] == "_":
                kirjaimet.pop(i)
                kirjaimet.insert(i,kirjain)
    for i in range(pituus):
        if kirjaimet[i] != '_':
            maara = maara +1
    print (str(kirjaimet))

      *      *      *

Ratkaisu ei ole kovin elegantti, mutta toimii hyvin. Sanojen pituus voi vaihdella 4 - 12 merkin välillä. Alussa pelaajalle tulostetaan rivi viivoja, minkä perusteella hän tietää sanan merkkien määrän. Jos merkin arvaus osuus oikeaan, kirjain näytetään oikealla paikallaan rivillä. Peli päättyy siihen, kun kaikki merkit on arvattu.

Sana arvotaan satunnaisesti taulukosta ja sanoja voi taulukkoon työntää tietysti niin paljon kuin haluaa, jolloin siitä tulee mukavaa haastetta myös tekijälle itselleen.

Linkki:

Python Tutorial. W3Schools

TYHJÄ PAPERI KERTOO. Osa 1006. Yksinkertaista peliohjelmointia, kiitos

En ole koskaan ollut kiinnostunut, en ainakaan myönnä, kovin paljon peliohjelmoinnista. Se on tuntunut liian vaikealta ja haastavalta. Pikkupelien tekeminen on sen sijaan ollut kivaa. Sitten päätin että opettelen vähän enemmän, tavalla tai toisella. Ja sillä tiellä olen. Vielä en ole päässyt kovin pitkälle. Edes alkuun...

Olen aina ollut hulluna peleihin, mutta en niinkään tietokone- tai konsolipeleihin, perinteisiin peleihin ja leikkeihin vain. Enkä ole edes montaa kertaa ottanut pelikonsolia käsiini. Yksi syy siihen on ilmeinen: pelien väkivaltaisuus ja sotaisuus, jota en voi sietää. Myös pelien hyperaktiivisuus, hengästyttävä ja liian vauhdikas eteneminen ärsyttää. Typerää että kaikki pitää aina ja kaikessa tehdä tyhjäpäänä nopeasti vaikkakin ehkä taitavasti. Samoja tylsiä kuvioita drillataan yhä uudestaan. Ei kivaa, vaikka sillä tavalla saa tietysti tapettua paljon aikaa. Pienissä peleissä tällainen ei kuitenkaan haittaa.

     *     *     *

Nyt olen löytänyt yksinkertaisen Pythonin pelikirjaston Arcaden (2.1.2), jota esimerkkeineen ajattelin käydä mahdollisimman tarkkaan läpi loppuvuoden aikana. Sanottakoon sitä vaikka sitten minun harrastuksekseni. Joka tapauksessa pelkkä ajatus tuntuu viihdyttävältä, mukavalta ja älyllisesti haastavalta.

Pelien runko tai malli (template) on sekin yksinkertainen:

1. arcade kirjasto otetaan käyttöön:

import arcade

2. määritetään ikkunan koko ja annetaan pelille nimi:

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Starting Template"

3. Määritellään pääluokka (class) peliä varten (ja sitten muut tarvittavat apuluokat):

class MyGame(arcade.Window):

4. MyGame luokkaa tarvitsee (mm. Javasta tutun)  konstruktorin ja metodit / funktiot:

    def __init__(self, width, height, title):
        super().__init__(width, height, title)

        arcade.set_background_color(arcade.color.BLACK)

    def setup(self):
        # Luodaan esim. liikuteltavat hahmot
        pass

    def on_draw(self):
        #Valmistellaan kuvien piirtämistä näytölle

        arcade.start_render()

        #Kutsutaan hahmoa ja piirretään se: draw()

    def update(self, delta_time):
        #Päivitetään näyttö, kun on tehty jotain esim. liikutettu hahmoa
        pass

    def on_key_press(self, key, key_modifiers):
        #ohjataan hahmoa näppäimillä (tai vaihtoehtoisesti hiirellä)
        
    def on_key_release(self, key, key_modifiers):
        pass

    def on_mouse_motion(self, x, y, delta_x, delta_y):
        pass

    def on_mouse_press(self, x, y, button, key_modifiers):
        pass

    def on_mouse_release(self, x, y, button, key_modifiers):
        pass

5. Luodaan MyGamesta ilmentymä ja käynnistetään peli

   def main():
     game = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
     game.setup()
     arcade.run()

if __name__ == "__main__":
    main()

     *     *     *

Kun yllä olevan mallin käynnistää, ei se tietysti tee mitään. Malli on malli, jonka tausta on määritetty mustaksi. Jos BLACK korvataan termillä AMAZON, tausta muuttuu tummanvihreäksi.

Avautuva ikkuna (kutsuna: arcade.Window) on sen kokoinen millaiseksi se on määritetty: leveys 800 pikseliä ja korkeus 600 pikseliä. Ikkunan nimenä on  "Aloitusnäkymä tai Starting template".

Ensimmäinen testi tai kokeilu, jonka tein, on klassikko ohjelmoinnissa eli "Hello World!" -tekstin kirjoittaminen ikkunaan, mikä tapahtuu tällä tavalla:

def on_draw(self):
    arcade.start.render()
    arcade.draw.text("Hello World!", SCREEN_WIDTH/2SCREEN_HEIGHT/2, 
    arcade.color.AMAZON,font_size=50)

Suuri vihreä teksti näkyy nyt ikkunan keskellä.

Linkki:

Arcade 2.1.2 The Python Arcade Library

sunnuntai 22. syyskuuta 2019

RUNO ON VAPAA. Osa 1543 - ei sitä taas




yön kuumuudessa
sulat kuin mallinukke
kännykän päälle

puhut minulle
muovisen olentosi
alta outoja:

"ei sitä taas", sa
not kumisen ontosti
(kumi kärisee)

asfaltti on kuu
ma. haluan sitä niin:
kaivosi vettä

mutta kuumuus
on vienyt kaiken veden.
tyydyn pisaraan 



Linkit:

sandra - in the heat of the night. (radio nova 22.09.2019)