1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| import sys
if sys.version[0] =='2': # test de la version de Python utilisée
from Tkinter import * # module Tkinter pour Python2
else:
from tkinter import * # module Tkinter pour Python 3
from math import pi, sin, cos
from random import randrange
class Canon(object):
"""Petit canon graphique"""
def __init__(self, boss, x, y, angle=25):
self.boss = boss # référence du canevas
self.x1, self.y1 = x, y # axe de rotation du canon
# dessiner la buse du canon, à l'horizontale pour commencer :
self.lbu = 50 # longueur de la buse
self.x2, self.y2 = x + self.lbu, y
self.buse = boss.create_line(self.x1, self.y1, self.x2, self.y2,
width =10)
# dessiner ensuite le corps du canon par-dessus :
r = 15 # rayon du cercle
boss.create_oval(x-r, y-r, x+r, y+r, fill='red', width =3)
# dessiner un obus (réduit à un simple point, avant animation) :
self.obus =boss.create_oval(x, y, x, y, fill='red')
self.anim =False # interrupteur d'animation
# retrouver la largeur et la hauteur du canevas :
self.xMax =int(boss.cget('width'))
self.yMax =int(boss.cget('height'))
def orienter(self, angle):
"choisir l'angle de tir du canon"
# il faut le traduire en nombre réel, puis convertir en radians :
self.angle = float(angle)*2*pi/360
self.x2 = self.x1 + self.lbu*cos(self.angle)
self.y2 = self.y1 - self.lbu*sin(self.angle)
self.boss.coords(self.buse, self.x1, self.y1, self.x2, self.y2)
def feu(self):
"déclencher le tir d'un obus"
if not self.anim:
self.anim =True
# position de départ de l'obus (c'est la bouche du canon) :
self.boss.coords(self.obus, self.x2 -3, self.y2 -3,
self.x2 +3, self.y2 +3)
v =15 # vitesse initiale
# composantes verticale et horizontale de cette vitesse :
self.vy = -v *sin(self.angle)
self.vx = v *cos(self.angle)
self.animer_obus()
def animer_obus(self):
"animation de l'obus (trajectoire balistique)"
if self.anim:
self.boss.move(self.obus, int(self.vx), int(self.vy))
c = tuple(self.boss.coords(self.obus)) # coord. résultantes
xo, yo = c[0] +3, c[1] +3 # coord. du centre de l'obus
if yo > self.yMax or xo > self.xMax:
self.anim =False # arrêter l'animation
self.vy += .5
self.boss.after(30, self.animer_obus)
def test_obstacle(self, xo, yo):
"évaluer si l'obus a atteint une cible ou les limites du jeu"
if yo >self.yMax or xo <0 or xo >self.xMax:
self.anim =False
return
# analyser le dictionnaire des canons pour voir si les coord.
# de l'un d'entre eux sont proches de celles de l'obus :
for id in self.guns: # id = clef dans dictionn.
gun = self.guns[id] # valeur correspondante
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
# dessiner l'explosion de l'obus (cercle jaune) :
self.explo = self.boss.create_oval(xo -12, yo -12,
xo +12, yo +12, fill ='yellow', width =0)
self.hit =id # référence de la cible touchée
self.boss.after(150, self.fin_explosion)
break
if __name__ == '__main__':
# code d'application avec image/personalisation et decors
f = Tk()
f.title("Projet")
can = Canvas(f,width =720, height =600, bg ='cyan')
can.grid(row=0,column=0,rowspan=5,columnspan=14,padx=5,pady=5)
can.pack(padx =10, pady =10)
aigle= PhotoImage(file='aigle.png')
soleil = PhotoImage(file='soleil.png')
nuage = PhotoImage(file='nuage.png')
item5 = can.create_image(500, 500, image= aigle)
item = can.create_image(672, 100, image = soleil)
item2 = can.create_image(340, 100, image = nuage)
item3 = can.create_image(540, 100, image = nuage)
item4 = can.create_image(140,100, image = nuage)
c1 = Canon(can, 50, 580)
s1 =Scale(f, label='hausse', from_=90, to=0, command=c1.orienter)
s1.pack(side=LEFT, pady =5, padx =20)
s1.set(25) # angle de tir initial
Button(f, text='Feu !', command =c1.feu).pack(side=LEFT)
f.mainloop()
#notre but et ce que nous voulons ameliorer:
#ajouter un score qui permet lorsque l'obus touche l'aigle d'ajouter un point
#lors du contact avec l'image, durant une demi-seconde un cercle de couleur jaune apparait au dessus de l'image ce qui representera une explosion.
#apres contact et l'explosion, l'image sera deplace aleatoirement |
Partager