Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Флудильня :) (не знаешь где спросить? спрашивай здесь!)

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

Открыть новую тему     Написать ответ в эту тему

bckpkol

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Код:
 
import pygame, sys
from pygame.locals import *
from collections import deque
from copy import copy
from math import floor,ceil,pi,sin,cos,hypot,asin,atan
from random import randrange
def bezier(t,A,B,C):
    #if imaginary:
    #    A,C=C,A
    P0=(A-B)*t+B
    P1=(B-C)*t+C
    return (P0-P1)*t+P1
def getangle(x0,y0,x1,y1,x2,y2):
    ly0=y0-y1
    lx0=x0-x1
    ly1=y2-y1
    lx1=x2-x1
    try:
        f0=ly0/lx0
        f1=ly1/lx1
        num=f1-f0
        den=1-f1*f0
        t=num/den
    except ZeroDivisionError:
        return pi/2
    return atan(t)
pygame.init()
clocker=pygame.time.Clock()
xr=400#rel
yr=300#abs
xcannon=xr/2
scannon=32
ycannon=yr-scannon
DISPLAYSURF = pygame.display.set_mode((xr, yr))
pixObj = pygame.PixelArray(DISPLAYSURF)
def spiral(sa,sb,distance):
    global reshalf
    yield sa,sb,1
    for y in range(1,distance):
        mf=cos(y*pi/2/(distance-1))
        #mf=1/(y+1)
        #print(mf)
        for x in range(4):
            for z in range(y):
                a=sa
                b=sb
                if x==0:
                    b-=y-z
                    a+=z
                elif x==1:
                    a+=y-z
                    b+=z
                elif x==2:
                    b+=y-z
                    a-=z
                elif x==3:
                    a-=y-z
                    b-=z
                yield a,b,mf
def rel(a,c,b,d):
    e=b-a
    f=d-c
    return (e,f)
def crossrel(a,c,b,d):
    e=b-a
    f=d-c
    return (-f,e)
def bar(th,x,y,prev):
    xa,ya=crossrel(x,y,*prev)
    #print('was',xa,ya)
    xv,yv=x,y
    steep=abs(xa)>abs(ya)
    if steep:
        xv,yv=yv,xv
        xa,ya=ya,xa
    appd=xa/ya
    #print('became',xa,ya,appd)
    ret=[]
    for dis in range(th):
        f=1-(dis/th)
        d1=dis
        d2=-1-d1
        if steep:
            ret.append((yv+d1,xv+(appd*d1),f))
            ret.append((yv+d2,xv+(appd*d2),f))
        else:
            ret.append((xv+(appd*d1),yv+d1,f))
            ret.append((xv+(appd*d2),yv+d2,f))
    #print('ret',ret)
    return ret
def drawPixel(x,y,opaque,col,s2):
    global pixObj,xr,yr
    if 0<=x<xr and 0<=y<yr:
        temp=pygame.Color(pixObj[int(x)][int(y)])[1:]
        #print(temp)
        pixObj[int(x)][int(y)]=tuple((min(opaque*channel[0]+(1-opaque)*channel[1],255) for channel in zip(col,temp)))
fancyPass=False
fancyPrev=None
def fancyDrawPixel(x,y,opaque,col,s2):
    global pixObj,xr,yr,fancyPass,fancyPrev
    if 0<=x<xr and 0<=y<yr:
        if opaque<=0:
            return
        opfancy=opaque**2
        opaa=min(1,opaque*2)
        fancy=col
        fancyPass=(s2//4)%2
        if fancyPass:
            fancy=tuple((int(min(sc*((sc+1)/512),255)) for sc in fancy))
        temp=pygame.Color(pixObj[int(x)][int(y)])[1:]
        fancy=tuple((opaa*channel+(1-opaa)*channel/2 for channel in fancy))
        pixObj[int(x)][int(y)]=tuple((max(min(opfancy*channel[0]+(1-opfancy)*channel[1],255),0) for channel in zip(fancy,temp)))
         
precalc=dict()
def drawBezierSegment(x0,y0,x1,y1,phase,rot,offset,th,override=drawPixel,step=1,color=(0,0,0),prev=None):
    xs=abs(x1-x0)
    ys=abs(y1-y0)
    ml=round(xs+ys)*4
    mh=hypot(xs,ys)
    #first=True
    #.5,.5,1.5,1.5
    #1,0,2,-1
    #0,1,-1,2
    #-.5,-.5,1,-1
    #print(rot)
    xa=round(cos(rot),3)>0
    ya=round(sin(rot),3)<0
    xo=round(cos(offset),3)<0
    yo=round(sin(offset),3)>0
    xf=cos(phase)
    yf=sin(phase)
    #print(xa,ya,xf,yf,xo,yo)
    if xa^ya^yo^xo:
        xf,yf=-xf,-yf
##    if yo:
##        xf,yf=-yf,-xf
##    if xo:
##        xf,yf=yf,xf
#    if ((round(xa,3)<0)^(round(xf,3)<0)^(round(ya,3)<0)^(round(yf,3)<0))&(round(yf,3)<=0):
#        print('0')
#        xf,yf=xf+.5,yf+.5
#    else:
#        xf,yf=xf-.5,yf-.5
#        print('1')
#        xf,yf=-xf,-yf
    xf,yf=xf+.5,yf+.5
    xts=(x1-x0)
    yts=(y1-y0)
    xm=xts*xf+(x1+x0)/2
    ym=yts*yf+(y1+y0)/2
    #cp=(th-1)/2
    #if first:
    #    print(x0,xm,x1,y0,ym,y1)
    #    first=False
    #if th not in precalc and override in (drawPixel,fancyDrawPixel,):
    #    precalc[th]=tuple(spiral(0,0,th))
    #    #print('once')
    xc=yc=-step
    s2=0
    for s in range(ml):#increase res if needed
        t=1-s/ml
        x=bezier(t,x0,xm,x1)
        y=bezier(t,y0,ym,y1)
        if hypot(x-xc,y-yc)<step:
            continue
        #print('at least it does something')
        if override in (drawPixel,fancyDrawPixel,):
            #print('drawing')
            if prev is not None:
                #print('second',(th,x,y,prev))
                if (th,x,y,prev) not in precalc:
                    precalc[(th,x,y,prev)]=bar(th,x,y,prev)
            elif (th,x,y,prev) not in precalc:
                #print('first',(th,x,y,prev))
                precalc[(th,x,y,prev)]=tuple(spiral(x,y,th))
        else:
            precalc[(th,x,y,prev)]=((x,y,1),)
        for pixel in precalc[(th,x,y,prev)]:
            override(*pixel,color,s2)
            yield (*pixel,color,s2)
        xc,yc=x,y
        prev=(x,y)
        s2+=1
        #drawPixel(x,y,1,(0,0,0))
def castRay(maxim,pos,dir):
    target=0
    if dir>0:
        target=maxim
    mvm=(target-pos)
    try:
        return mvm/dir,mvm
    except ZeroDivisionError:
        return float('inf'),mvm
def traceRay(tx,ty):
    global xr,yr,xcannon,ycannon
    x,y=xcannon,ycannon
    yield(x,y)
    for depth in range(5):
        castx,movex=castRay(xr,x,tx)
        casty,movey=castRay(yr,y,ty)
        if castx<casty:
            x=x+movex
            y=round(y+movex/tx*ty)
        else:
            y=y+movey
            x=round(x+movey/ty*tx)
        yield(x,y)
        if x in (0,xr):
            tx=-tx
        elif y in (0,yr):
            ty=-ty
linecache=dict()
spircache=dict()
def linear(line,step):
    xl=line[0][0]-line[1][0]
    yl=line[0][1]-line[1][1]
    il=int((xl*xl+yl*yl)**.5/step)
    for p in range(il):
        f=p/il
        af=1-f
        x=line[1][0]*f+line[0][0]*af
        y=line[1][1]*f+line[0][1]*af
        yield x,y
def lines(co,th,color,step,visible=True):
    global linecache,spircache
    ret=[]
    for line in zip(co[:-1],co[1:]):
        lineargs=(line,step)
        if lineargs not in linecache:
            linecache[lineargs]=tuple(linear(*lineargs))
        if visible:
            if th not in spircache:
                spircache[th]=tuple(spiral(0,0,th))
            for pixel in ret:
                for offs in spircache[th]:
                    drawPixel(pixel[0]+offs[0],pixel[1]+offs[1],1,color,0)
        ret.extend(linecache[lineargs])
    return ret
curveargs=dict()
def placebo(*args,**kwargs):
    pass
trC=dict()
def toRelative(x,y):
    global xr,yr,trC
    if (x,y) in trC:
        return trC[(x,y)]
    trC[(x,y)]=(x/xr,y/yr)
    return trC[(x,y)]
frC=dict()
def fromRelative(x,y):
    global xr,yr,frC
    if (x,y) in frC:
        return frC[(x,y)]
    frC[(x,y)]=(x*xr,y*yr)
    return frC[(x,y)]
def drawBezierCurve(angle,co,th,override=drawPixel,step=1,color=(0,0,0),relative=False,tray=True):
    global curveargs,yr
    #print('drawing :-j')
    if relative:
        co=[fromRelative(*s) for s in co]
        th=int(th*yr)
    if override not in (drawPixel,fancyDrawPixel,):
        th=1
        tray=False
    curveparam=(angle,tuple((tuple(s) for s in co)),step,tray)
    if curveparam not in curveargs:
        curveargs[curveparam]=[]
        phase=0
        rot=0
        offset=0
        prev=None
        ppix=None
        for a,b in zip(co[:-1],co[1:]):
            if prev is not None:
                rot+=abs(getangle(*prev,*a,*b))
                rot%=pi*2
                phase%=pi*2
                rp=round(rot*2/pi)
                pp=round(phase*2/pi)
                while pp<rp:
                    offset-=angle
                    phase+=angle
                    rp=round(rot*2/pi)
                    pp=round(phase*2/pi)
#                while pp>rp:
#                    offset+=angle
#                    phase-=angle
#                    rp=round(rot*2/pi)
#                    pp=round(phase*2/pi)
            for pixabs in drawBezierSegment(*a,*b,phase,rot,offset,th,override=override,step=step,color=color,prev=ppix):
                curveargs[curveparam].append(pixabs)
            phase+=angle
            prev=a
        if tray:
            for pixel in spiral(*co[-1],th*16):
                curveargs[curveparam].append((*pixel,color,0))
                override(*pixel,color,0)
    else:
        for pixabs in curveargs[curveparam]:
            override(*pixabs)
    return curveargs[curveparam]
pathscache=dict()
def getinterpco(angle,co,relative):
    global pathscache
    curveparam=(angle,tuple((tuple(s) for s in co)),relative)
    if curveparam not in pathscache:
        pathscache[curveparam]=[tuple((int(sc) for sc in dsc[:2])) for dsc in drawBezierCurve(angle,co,1,override=placebo,step=1,relative=relative,tray=False)]
    return pathscache[curveparam]
pygame.display.set_caption('Стрелялка')
with open('level1.txt','r') as f:
    curves=eval(f.read())
hpi=pi/2
colors=[(0,255,0),(0,255,255),(255,0,0),(255,0,255),(255,255,0)]
ray=(1,0)
circcos=[getinterpco(hpi,co,True) for co in curves]
#pygame.draw.circle()
circinds=[deque() for co in curves]
addtick=0
speed=1
sz=16
szr=sz//2
while True:
    if addtick>=sz:
        addtick=0
        for i in range(len(circinds)):
            circinds[i].appendleft(randrange(len(colors)))
    for event in pygame.event.get():
        if event.type == QUIT or speed>255:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.MOUSEMOTION:
            ray=rel(xcannon,ycannon,*event.pos)
        if event.type == pygame.MOUSEBUTTONUP:
            pass
    DISPLAYSURF.fill((255,255,255))
    drawBezierCurve(hpi,[(xcannon-scannon,ycannon),(xcannon+scannon,ycannon)],3,color=(0,0,0),step=.3,tray=False)
    drawBezierCurve(hpi,[(xcannon,ycannon-scannon),(xcannon,ycannon+scannon)],3,color=(0,0,0),step=.3,tray=False)
    for i,curve in enumerate(curves):
        drawBezierCurve(hpi,curve,.01,color=colors[i%len(colors)],step=.3,override=fancyDrawPixel,relative=True)
    for i,co in enumerate(circcos):
        for pos,c in enumerate(circinds[i]):
            posi=pos*sz+addtick
            if posi<len(co):
                pygame.draw.circle(DISPLAYSURF,colors[c],co[posi],szr)
                #print('ball at',i,'color',colors[c],'place',co[posi])
            else:
                speed+=1
    lines(tuple(traceRay(*ray)),2,color=(255,128,0),step=5)
    pygame.display.update()
    addtick+=speed
    clocker.tick(30)
 

Всего записей: 47 | Зарегистр. 22-12-2010 | Отправлено: 09:59 21-09-2017 | Исправлено: bckpkol, 11:13 21-09-2017
Открыть новую тему     Написать ответ в эту тему

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Флудильня :) (не знаешь где спросить? спрашивай здесь!)


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru