#
# Copyright 2023, Ali Arya
# Anyone Can Code: Algorithmic Thinking
# Example 6.8p
#

# graphics.py
# http://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/graphics.html 
# http://www.pas.rochester.edu/~rsarkis/csc161/python/pip-graphics.html

# graphic library
from graphics import *
# for timer and sleep functions
import time
import random
import math

#particle system example

#Note that the GraphicObject class in Graphics.py uses the object coordinates as centre not top-left

#######################################################
## classes

#######################################################
class GameObject:
    # when using Graphics.py, x and y are included in the Image object
    __image = None
    __visible = 0
    def __init__(self, fname, x, y, v):
        self.__image = Image(Point(x,y),fname)
        if v>=0 and v<=100:
            self.__visible = v
    def Move(self, dx, dy):
        self.__image.move(dx,dy)
    def Draw(self,window):
        self.__image.draw(window)
    def GetV(self):
        return self.__visible
    def SetV(self, v):
        self.__visible = v
    def GetX(self):
        return self.__image.x
    def GetY(self):
        return self.__image.y

#######################################################
class ParticleSystem:
    __source = None
    __particles = []
    def __init__(self):
        for i in range(20):
            p = GameObject("prize.png",320,240,random.randint(1,99))
            self.__particles.append(p)
        self.__source = GameObject("player.png",320,240,100)
    def Update(self,dx,dy):
        self.__source.Move(dx,dy)
        for i in range(20):
            self.__particles[i].Move(random.randint(-2,2), random.randint(-2,2))
            v = self.__particles[i].GetV()
            v -= 1
            self.__particles[i].SetV(v)
            if v == 0:
                dx = self.__source.GetX() - self.__particles[i].GetX()
                dy = self.__source.GetY() - self.__particles[i].GetY()
                self.__particles[i].Move(dx,dy)
                self.__particles[i].SetV(100)

    def Draw(self, window):
        for i in range(20):
            self.__particles[i].Draw(window)
        self.__source.Draw(window)
#######################################################
class Game:
    ps = None
    window = None
    map = None
    quit = False

    def __init__(self):
        self.window = GraphWin('Game', 640, 480) # give title and dimensions
        self.map = Image(Point(320,240),"map.png")
        self.map.draw(self.window)
        self.ps = ParticleSystem()
        self.ps.Draw(self.window)
    def Update(self):
        dx = 0
        dy = 0
        key = self.window.checkKey()
        if key=='Escape':
            self.quit = True
        if key=='Up':
            dy -= 3 
        if key=='Down':
            dy += 3
        if key=='Right':
            dx += 3
        if key=='Left':
            dx -= 3
        self.ps.Update(dx,dy)
    def Run(self):
        while self.quit == False:
            self.Update()
            #in Graphics.py there is no need to constantly draw at each frame
            time.sleep(0.05)

#######################################################
#main code
game = Game()
game.Run()

