#! /usr/bin/env python
# -*- coding: Utf-8 -*-

#######################################################
# Agyuparbaj jatek - egygepes verzio - 2 jatekos      #
# (C) Gerard Swinnen, Verviers (Belgique) - July 2004 #
# Licence : GPL                                       #
#######################################################

from Tkinter import *
from math import sin, cos, pi
from random import randrange

class Canon:
    """Agyurajz"""
    def __init__(self, boss, id, x, y, irany, szin):
        self.boss = boss            # a vaszon hivatkozasa
        self.appli = boss.master    # az alkalmazasablak hivatkozasa 
        self.id = id                # az agyu azonositoja (string)
        self.szin = szin            # az agyuhoz asszocialt szin
        self.x1, self.y1 = x, y     # az agyu forgastengelye
        self.irany = irany          # lovesirany (-1:balra, +1:jobbra)
        self.lagyucso = 30          # agyucso hossza
        self.angle = 0              # alapertelmezett dolesszog (loves szoge)
        # a vaszon szelessegenek es magassaganak meghatarozasa :
        self.xMax = int(boss.cget('width'))
        self.yMax = int(boss.cget('height'))
        # agyucso rajzolasa (vizszintes) :
        self.x2, self.y2 = x + self.lagyucso * irany, y
        self.cso = boss.create_line(self.x1, self.y1,
                                     self.x2, self.y2, width =10)
        # agyutest rajzolasa (szines kor) :
        self.rc = 15                # a kor sugara 
        self.test = boss.create_oval(x -self.rc, y -self.rc, x +self.rc,
                                      y +self.rc, fill =szin)
        # rejtett lovedek elorajzolasa (vasznon kivuli pont) :
        self.lovedek = boss.create_oval(-10, -10, -10, -10, fill='red')
        self.anim = False           # az animacio- 
        self.explo = False          # es a robbanas-flagek

    def iranyzas(self, angle):
        "az agyu dolesszogenek beallitasa"
        # rem: a <angle> parametert stringkent fogadja.
        # At kell valos szamma alakitani, majd azt radianna :
        self.angle = float(angle)*pi/180
        # rem: inkabb a coords metodust hasznaljuk egeszekkel :       
        self.x2 = int(self.x1 + self.lagyucso * cos(self.angle) * self.irany)
        self.y2 = int(self.y1 - self.lagyucso * sin(self.angle))
        self.boss.coords(self.cso, self.x1, self.y1, self.x2, self.y2)
 
    def elmozdit(self, x, y):
        "az agyut egy uj x, y pozicioba viszi x, y"
        dx, dy = x -self.x1, y -self.y1     # az elmozdulas erteke
        self.boss.move(self.cso, dx, dy) 
        self.boss.move(self.test, dx, dy)
        self.x1 += dx
        self.y1 += dy
        self.x2 += dx
        self.y2 += dy

    def tuz(self):
        "lovedek kilovese - csak ha az elozo befejezte a repuleset"
        if not (self.anim or self.explo):
            self.anim =True
            # recuperer a jelenlevo osszes agyu leirasanak  :
            self.guns = self.appli.dictionnaireCanons()
            # a lovedek kiindulasi pozicioja (ez az agyu torka) :
            self.boss.coords(self.lovedek, self.x2 -3, self.y2 -3,
                                        self.x2 +3, self.y2 +3)
            v = 17              # kezdosebesseg
            # kezdosebesseg fuggoleges es vizszintes komponensei :
            self.vy = -v *sin(self.angle)
            self.vx = v *cos(self.angle) *self.irany
            self.animal_lovedek()
            return True     # => a lovedek elindult
        else:
            return False    # => a lovedeket nem lehetett kiloni

    def animal_lovedek(self):
        "lovedek animacioja (ballisztikus palya)"
        if self.anim:
            self.boss.move(self.lovedek, int(self.vx), int(self.vy))
            c = self.boss.coords(self.lovedek)     # eredmeny koordinatak
            xo, yo = c[0] +3, c[1] +3              # lovedek kozeppontjanak koordinatai
            self.test_akadaly(xo, yo)              # akadalyba utkozott ?
            self.vy += .4                          # fuggoleges gyorsulas
            self.boss.after(20, self.animal_lovedek)
        else:
            # animacio befejezodott - lovedek elrejtese es az agyuk elmozditasa :
            self.animacio_vege()
   
    def test_akadaly(self, xo, yo):
        "Eldontjuk: a lovedek celba talalt-e vagy elerte-e a jatekter hatarat"
        if yo >self.yMax or xo <0 or xo >self.xMax:
            self.anim =False
            return
        # megvizsgaljuk az agyuk szotarat annak eldontesere, hogy  valamelyikuk koordinatai
        # nincsenek-e kozel a lovedek koordinataihoz :
        for id in self.guns:              # id = kulcs a szotarban.
            gun = self.guns[id]           # a megfelelo ertek
            if xo < gun.x1 +self.rc and xo > gun.x1 -self.rc \
            and yo < gun.y1 +self.rc and yo > gun.y1 -self.rc :
                self.anim =False
                # megrajzoljuk a lovedek robbanasat (narancssarga kor) :
                self.explo = self.boss.create_oval(xo -12, yo -12,
                             xo +12, yo +12, fill ='yellow', width =0)
                self.hit =id       # az eltalalt celtargy hivatkozasa
                self.boss.after(150, self.robbanas_vege)
                break         
   
    def robbanas_vege(self):
        "robbanas torlese; a lovedek re-inicializalasa; pontszam kezelese"
        self.boss.delete(self.explo)    # robbanas torlese
        self.explo =False               # uj loves engedelyezese
        # jelezzuk a sikert a master-ablaknak :
        self.appli.goal(self.id, self.hit)
        
    def animacio_vege(self):
        "vegrehajtando akciok, amikor a lovedek elerte a roppalyaja veget"
        self.appli.agyuk_szetszorasa()          # agyuk elmozditasa
        # lovedek elrejtese (a vasznon kivulre kuldjuk) :
        self.boss.coords(self.lovedek, -10, -10, -10, -10)


class VezerloPult(Frame):
    """Egy agyuhoz asszocialt vezerlopult""" 
    def __init__(self, boss, canon):
        Frame.__init__(self, bd =3, relief =GROOVE)
        self.score =0
        self.appli =boss                # az alkalmazas hivatkozasa
        self.canon =canon               # az asszocialt agyu hivatkozasa
        # lovesszog beallito rendszer :
        self.celzas =Scale(self, from_ =75, to =-15, troughcolor =canon.szin,
                         command =self.iranyzas)
        self.celzas.set(45)               # loves kezdoszoge
        self.celzas.pack(side =LEFT)
        # Az agyut azonosito cimke :
        Label(self, text =canon.id).pack(side =TOP, anchor =W, pady =5)
        # Tuzgomb :
        self.bTuz =Button(self, text ='Tűz !', command =self.tuzel)
        self.bTuz.pack(side =BOTTOM, padx =5, pady =5)
        Label(self, text ="pont").pack()
        self.pontok =Label(self, text=' 0 ', bg ='white')
        self.pontok.pack()
        # az agyu iranyanak megfeleloen balra vagy jobbra pozicionalni :
        if canon.irany == -1:
            self.pack(padx =5, pady =5, side =RIGHT)
        else:
            self.pack(padx =5, pady =5, side =LEFT)

    def tuzel(self):
        "az asszocialt agyu tuzelesenek inditasa"
        self.canon.tuz()
        
    def iranyzas(self, angle):
        "az asszocialt agyu dolesszogenek beallitasa"
        self.canon.iranyzas(angle)

    def pontHozzaadasa(self, p):
        "pontszam novelese vagy csokkentese, <p> ponttal"
        self.score += p
        self.pontok.config(text = ' %s ' % self.score)

class Application(Frame):
    '''Az alkalmazas foablaka'''
    def __init__(self):
        Frame.__init__(self)
        self.master.title('>>>>> Bum ! Bum ! <<<<<')
        self.pack()
        self.jatek = Canvas(self, width =400, height =250, bg ='ivory',
                          bd =3, relief =SUNKEN)
        self.jatek.pack(padx =8, pady =8, side =TOP)

        self.guns ={}           # a jelen levo agyuk szotara
        self.pult ={}           # a jelen levo vezerlopultok szotara
        # 2 agyu-objektum letrehozasa (+1, -1 = ellenkezo irany) :
        self.guns["Billy"] = Canon(self.jatek, "Billy", 30, 200, 1, "red")
        self.guns["Linus"] = Canon(self.jatek, "Linus", 370,200,-1, "blue")
        # Ezekkel az agyukkal asszocialt 2 vezerlopult letrehozasa :
        self.pult["Billy"] = VezerloPult(self, self.guns["Billy"])
        self.pult["Linus"] = VezerloPult(self, self.guns["Linus"])

    def agyuk_szetszorasa(self):
        "az agyuk veletlenszeru elmozditasa"
        for id in self.guns:
            gun =self.guns[id]
            # az agyu iranyatol fuggoen balra vagy jobbra mozditas :
            if gun.irany == -1 :
                x = randrange(320,380)
            else:
                x = randrange(20,80)
            # a tulajdonkeppeni elmozditas :
            gun.elmozdit(x, randrange(150,240))
  
    def goal(self, i, j):
        "az <i> agyu jelzi, hogy eltalalta a <j> ellenfelet"
        if i != j:
            self.pult[i].pontHozzaadasa(1)    
        else:
            self.pult[i].pontHozzaadasa(-1)
            
    def dictionnaireCanons(self):
        "a jelen levo agyukat leiro szotarat adja meg visszateresi ertekkent" 
        return self.guns

if __name__ =='__main__':
    Application().mainloop()
