Пошаговая игра Пушка для двоих.

Заготовка: выстрелы, переход хода есть, нужно доделать определение попадания (с использованием уже имеющегося hittest)
Также нужно сделать препятствия между пушками, с рикошетом (метод для расчета рикошета готов), и добавить возможность перемещения пушек (move в пушках создан).
Для дальнейшего совершенствования игры сделать экран с горизонтальной прокруткой и прицеливанием не мышью, а с указанием силы выстрела и угла. Добавить ветер.
Добавить разрушаемый ландшафт.

from random import randrange as rnd, choice
from tkinter import *
import math
import time

root = Tk()
fr = Frame(root)
root.geometry('800x600+600+100')
canv = Canvas(root, bg = 'white')
canv.pack(fill=BOTH,expand=1)

colors = ['blue','green','red','brown']

class ball():
    def __init__(self, balls, x=40,y=450):
        self.x = x
        self.y = y
        self.r = 8
        self.color = choice(colors)
        self.points = 3
        self.id = canv.create_oval(self.x-self.r,self.y-self.r,self.x+self.r,self.y+self.r,fill=self.color)
        #self.id_points = canv.create_text(self.x,self.y,text = self.points)
        self.live = 70
        self.nature = 1
        self.balls = balls
        self.bum_time = 100
        self.bum_on = 0
        self.surprize = 0
        self.surprize_time = 0
        
    def paint(self):
        canv.coords(self.id,self.x-self.r,self.y-self.r,self.x+self.r,self.y+self.r)
        #canv.coords(self.id_points,self.x,self.y)
        #canv.itemconfig(self.id_points,text = self.points)
        
    def jump(self):
        if self.vx**2+self.vy**2 > 10:
            self.vy = -self.vy*0.7
            self.vx = self.vx*0.7
            self.y = 499

    def move(self):
        if self.y <= 500:
            self.vy += 0.07
            self.y += self.vy
            self.x += self.vx
            self.vx *= 0.999
            self.v = (self.vx**2+self.vy**2)**0.5
            self.an = math.atan(self.vy/self.vx)
            self.paint()
        else:
            self.live -= 1
            if self.live < 0:
                self.bum()
                #self.kill()
        if self.x > 780:
            self.vx = - self.vx/2
            self.x = 779
        elif self.x < 20:
            self.vx = - self.vx/2
            self.x = 21
        if self.bum_on and self.nature:
            self.bum_time -= 1
            if self.bum_time <= 0:
                self.bum()
        if not self.nature:
            self.live -= 0.1
            if self.r > 0.1:
                self.r -= 0.1
            else:
                self.kill()
            self.vy += 0.2
            if self.live < 0:
                self.kill()
        if self.surprize:
            self.surprize_time += 1
            if self.surprize_time > 13:
                self.surprize_time  = 0
                self.fire()
                
        
            
    def hittest(self,ob):
        if abs(ob.x - self.x) <= (self.r + ob.r) and abs(ob.y - self.y) <= (self.r + ob.r):
            return True
        else:
            return False
            
    def ricochet(self,w):
        self.v = (self.vx**2 + self.vy**2)**0.5
        self.an = math.atan(self.vy/self.vx)

        if self.x == w.x:
            self.x += 1
                
        if w.x-(self.x+self.vx):
            an_rad = math.atan((w.y-(self.y+self.vy))/(w.x-(self.x+self.vx)))
            an_res = an_rad - (self.an - an_rad )
            
            vx2 = 0.8*self.v*math.cos(an_res)
            vy2 = 0.8*self.v*math.sin(an_res)
            if self.an > 0 and self.vx < 0 and self.vy < 0 or self.an < 0 and self.vx < 0:
                vx2 = -vx2
                vy2 = -vy2
            self.vx = -vx2
            self.vy = -vy2
            self.move()
            self.points += 1
            
    def kill(self):
        canv.delete(self.id)
        #canv.delete(self.id_points)
        try:
            self.balls.pop(self.balls.index(self))
        except:
            pass
            
    def fire(self):
        n = 5
        for z in range(1,n+1):
            new_ball = ball(self.balls)
            new_ball.r = 5
            v = 5+rnd(5)
            an = z*2*math.pi/n+rnd(-2,3)/7
            new_ball.vx = v*math.cos(an)
            new_ball.vy = v*math.sin(an)
            new_ball.x = self.x + new_ball.vx*3
            new_ball.y = self.y + new_ball.vy*3
            new_ball.nature = 0
            new_ball.points = 1
            new_ball.live = rnd(10)+30
            new_ball.color = choice(colors)
            self.balls += [new_ball]
            
    def bum(self):
        if self.nature:
            self.fire()
            self.kill()
        

class gun():
    def __init__(self):
        self.f2_power = 10
        self.x = 400
        self.y = 450
        self.f2_on = 0
        self.on = 1
        self.an = 1
        self.points = 0
        self.id = canv.create_line(self.x,self.y,self.x,self.y-20,width=7, smooth = 1)
        self.id_points = canv.create_text(30,30,text = self.points,font = '28')
        
        self.bullet = 0
        
        self.vx = 0
        
    def fire_start(self,event):
        if self.on:
            self.f2_on = 1

    def stop(self):
        self.f2_on = 0
        self.on = 0

    def fire_end(self,event):
        if self.on:
            self.bullet += 1
            new_ball = ball(self.balls)
            new_ball.r += 5
            new_ball.x = self.x
            new_ball.y = self.y
            new_ball.vx = self.f2_power*math.cos(self.an)/9
            new_ball.vy = self.f2_power*math.sin(self.an)/9
            if not rnd(5):
                new_ball.surprize = 1
            self.balls += [new_ball]
            self.f2_on = 0
            self.f2_power = 35
        
    def move(self,event=0):
        if event:
            if event.keycode == 39 and self.vx < 4:
                self.vx += 1
            elif event.keycode == 37 and self.vx > -4:
                self.vx -= 1
        else:
            self.x += self.vx
            if self.x < 50:
                self.x = 50
                self.vx = 0
            elif self.x > 750:
                self.x = 750
                self.vx = 0
        self.aiming()

    def aiming (self,event=0):
        if event:
            if abs(event.x - self.x) < 0.0001:
                event.x += 0.1
            self.an = math.atan((event.y-self.y)/(event.x-self.x))     
            if event.x < self.x:
                self.an += math.pi
        
            
        if self.f2_on:
            canv.itemconfig(self.id,fill = 'orange')
        else:
            canv.itemconfig(self.id,fill = 'black')
        canv.coords(self.id,self.x,self.y,self.x+max(self.f2_power,20)*math.cos(self.an),self.y+max(self.f2_power,20)*math.sin(self.an))
        
    def power_up(self):
        if self.f2_on:
            if self.f2_power < 100:
                self.f2_power += 1
            canv.itemconfig(self.id,fill = 'orange')
        else:
            canv.itemconfig(self.id,fill = 'black')
            
    def bum(self, event = 0):
        for b in self.balls[::-1]:
            if b.nature:
                b.bum()
                break
                

        
class target():
    def __init__(self, targets):
        self.points = 1
        self.targets = targets
        x = self.x = rnd(50,750)
        y  = self.y = rnd(-250,150)
        r= self.r = rnd(10,40)
        self.live = 5 + rnd(5)
        self.change_color = 0
        color = self.color = 'red'
        self.id = canv.create_oval(x-r,y-r,x+r,y+r, fill = self.color)
        self.id_live = canv.create_text(x,y,text=self.live)
        
    def paint(self):
        x = self.x 
        y = self.y  
        r = self.r  
        canv.coords(self.id, x-r,y-r,x+r,y+r)
        canv.coords(self.id_live,x,y)
        
    def hit(self, points = 1):
        self.live -= points
        canv.itemconfig(self.id_live,text=self.live)
        canv.itemconfig(self.id, fill = 'orange')
        self.change_color = 10
        if self.live < 1:
            self.kill()
            
    def move(self):
        self.y += 0.6
        self.paint()
        if self.y > 450:
            self.kill()
        
    def kill(self):
        self.targets.pop(self.targets.index(self))
        canv.delete(self.id)
        canv.delete(self.id_live)
        

class game():
    def __init__(self):
        self.moving = []
        self.gamer1 = gun()
        self.gamer2 = gun()
        self.gamer1.x = 30
        self.gamer2.x = 770
        self.gamer1.balls = self.moving
        self.gamer2.balls = self.moving
        self.active_gamer = self.gamer1
        
        canv.bind('<Button-1>',self.fire_start)
        canv.bind('<ButtonRelease-1>',self.fire_end)
        canv.bind('<Motion>',self.aiming)
        root.bind('<Key>',self.move)
        self.go = 1
        
    def fire_start(self,event):
        self.active_gamer.fire_start(event)
        
    def fire_end(self,event):
        self.active_gamer.fire_end(event)
        self.active_gamer.stop()
        
    def aiming(self,event):
        self.active_gamer.aiming(event)

    def power_up(self,event):
        self.active_gamer.power_up(event)
    
    def move(self,event):
        self.active_gamer.move(event)
        
    def round(self):
        if self.active_gamer == self.gamer1:
            self.active_gamer = self.gamer2
            print ('g1')
        else:
            self.active_gamer = self.gamer1            
            print ('g2')

        self.active_gamer.on = 1
        
        while self.active_gamer.on or self.moving:
            for m in self.moving:
                m.move()
            self.active_gamer.aiming()
            self.active_gamer.power_up()
            canv.update()
            time.sleep(0.007)
            
            

game1 = game()
while 1:
    game1.round()





Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *