zoukankan      html  css  js  c++  java
  • python 实现漂亮的烟花,樱花,玫瑰花

    显着无聊收集了下用python绘制烟花,绘制樱花,烟花+樱花,飘零雪花,玫瑰花的python绘制代码,可以来练手什么的哦。

    同时python实现八音符,坦克大战,贪吃蛇,FlappyBird等都可以参考哦=> code

    一、python实现烟花

    效果图:

    代码如下 :

    import tkinter as tk
    from PIL import Image, ImageTk
    from time import time, sleep
    from random import choice, uniform, randint
    from math import sin, cos, radians
    
    # 模拟重力
    GRAVITY = 0.05
    # 颜色选项(随机或者按顺序)
    colors = ['red', 'blue', 'yellow', 'white', 'green', 'orange', 'purple', 'seagreen', 'indigo', 'cornflowerblue']
    
    '''
    particles 类
    
    粒子在空中随机生成随机,变成一个圈、下坠、消失
    
    属性:
        - id: 粒子的id
        - x, y: 粒子的坐标
        - vx, vy: 在坐标的变化速度
        - total: 总数
        - age: 粒子存在的时长
        - color: 颜色
        - cv: 画布
        - lifespan: 最高存在时长
    
    '''
    
    
    class Particle:
    
        def __init__(self, cv, idx, total, explosion_speed, x=0., y=0., vx=0., vy=0., size=2., color='red', lifespan=2,
                     **kwargs):
            self.id = idx
            self.x = x
            self.y = y
            self.initial_speed = explosion_speed
            self.vx = vx
            self.vy = vy
            self.total = total
            self.age = 0
            self.color = color
            self.cv = cv
            self.cid = self.cv.create_oval(
                x - size, y - size, x + size,
                y + size, fill=self.color)
            self.lifespan = lifespan
    
        def update(self, dt):
            self.age += dt
    
            # 粒子范围扩大
            if self.alive() and self.expand():
                move_x = cos(radians(self.id * 360 / self.total)) * self.initial_speed
                move_y = sin(radians(self.id * 360 / self.total)) * self.initial_speed
                self.cv.move(self.cid, move_x, move_y)
                self.vx = move_x / (float(dt) * 1000)
    
            # 以自由落体坠落
            elif self.alive():
                move_x = cos(radians(self.id * 360 / self.total))
                # we technically don't need to update x, y because move will do the job
                self.cv.move(self.cid, self.vx + move_x, self.vy + GRAVITY * dt)
                self.vy += GRAVITY * dt
    
            # 移除超过最高时长的粒子
            elif self.cid is not None:
                cv.delete(self.cid)
                self.cid = None
    
        # 扩大的时间
        def expand (self):
            return self.age <= 1.2
    
        # 粒子是否在最高存在时长内
        def alive(self):
            return self.age <= self.lifespan
    
    '''
    循环调用保持不停
    '''
    def simulate(cv):
        t = time()
        explode_points = []
        wait_time = randint(10, 100)
        numb_explode = randint(6, 10)
        # 创建一个所有粒子同时扩大的二维列表
        for point in range(numb_explode):
            objects = []
            x_cordi = randint(50, 550)
            y_cordi = randint(50, 150)
            speed = uniform(0.5, 1.5)
            size = uniform(0.5, 3)
            color = choice(colors)
            explosion_speed = uniform(0.2, 1)
            total_particles = randint(10, 50)
            for i in range(1, total_particles):
                r = Particle(cv, idx=i, total=total_particles, explosion_speed=explosion_speed, x=x_cordi, y=y_cordi,
                             vx=speed, vy=speed, color=color, size=size, lifespan=uniform(0.6, 1.75))
                objects.append(r)
            explode_points.append(objects)
    
        total_time = .0
        # 1.8s内一直扩大
        while total_time < 1.8:
            sleep(0.01)
            tnew = time()
            t, dt = tnew, tnew - t
            for point in explode_points:
                for item in point:
                    item.update(dt)
            cv.update()
            total_time += dt
        # 循环调用
        root.after(wait_time, simulate, cv)
    
    
    def close(*ignore):
        """退出程序、关闭窗口"""
        global root
        root.quit()
    
    
    if __name__ == '__main__':
        root = tk.Tk()
        cv = tk.Canvas(root, height=400, width=600)
        # 选一个好看的背景会让效果更惊艳!
        image = Image.open("./image.jpg")//这里自己选择好背景图片哦
        photo = ImageTk.PhotoImage(image)
    
        cv.create_image(0, 0, image=photo, anchor='nw')
        cv.pack()
    
        root.protocol("WM_DELETE_WINDOW", close)
        root.after(100, simulate, cv)
        root.mainloop()
    

    二、动态樱花

    效果如下:

    代码如下:

    import turtle as T
    import random
    import time
    
    # 画樱花的躯干(60,t)
    def Tree(branch, t):
        time.sleep(0.0005)
        if branch > 3:
            if 8 <= branch <= 12:
                if random.randint(0, 2) == 0:
                    t.color('snow')  # 白
                else:
                    t.color('lightcoral')  # 淡珊瑚色
                t.pensize(branch / 3)
            elif branch < 8:
                if random.randint(0, 1) == 0:
                    t.color('snow')
                else:
                    t.color('lightcoral')  # 淡珊瑚色
                t.pensize(branch / 2)
            else:
                t.color('sienna')  # 赭(zhě)色
                t.pensize(branch / 10)  # 6
            t.forward(branch)
            a = 1.5 * random.random()
            t.right(20 * a)
            b = 1.5 * random.random()
            Tree(branch - 10 * b, t)
            t.left(40 * a)
            Tree(branch - 10 * b, t)
            t.right(20 * a)
            t.up()
            t.backward(branch)
            t.down()
    
    # 掉落的花瓣
    def Petal(m, t):
        for i in range(m):
            a = 200 - 400 * random.random()
            b = 10 - 20 * random.random()
            t.up()
            t.forward(b)
            t.left(90)
            t.forward(a)
            t.down()
            t.color('lightcoral')  # 淡珊瑚色
            t.circle(1)
            t.up()
            t.backward(a)
            t.right(90)
            t.backward(b)
    
    # 绘图区域
    t = T.Turtle()
    # 画布大小
    w = T.Screen()
    t.hideturtle()  # 隐藏画笔
    t.getscreen().tracer(5, 0)
    w.screensize(bg='wheat')  # wheat小麦
    t.left(90)
    t.up()
    t.backward(150)
    t.down()
    t.color('sienna')
    
    # 画樱花的躯干
    Tree(60, t)
    # 掉落的花瓣
    Petal(100, t)
    w.exitonclick()
    
    

    三、烟花配合樱花齐放

    import turtle
    import random
    import time
    from PIL import Image, ImageTk
    # from time import sleep
    import tkinter as tk
    from time import sleep
    from random import choice, uniform, randint
    from math import sin, cos, radians
    
    # 模拟重力
    GRAVITY = 0.05
    # 颜色选项(随机或者按顺序)
    colors = ['red', 'blue', 'yellow', 'white', 'green', 'orange', 'purple', 'seagreen', 'indigo', 'cornflowerblue']
    
    
    # 画樱花的躯干(60,t)
    def Tree(branch, t):
        time.sleep(0.0005)
        if branch > 3:
            if 8 <= branch <= 12:
                if random.randint(0, 2) == 0:
                    t.color('snow')  # 白
                else:
                    t.color('lightcoral')  # 淡珊瑚色
                t.pensize(branch / 3)
            elif branch < 8:
                if random.randint(0, 1) == 0:
                    t.color('snow')
                else:
                    t.color('lightcoral')  # 淡珊瑚色
                t.pensize(branch / 2)
            else:
                t.color('sienna')  # 赭(zhě)色
                t.pensize(branch / 10)  # 6
            t.forward(branch)
            a = 1.5 * random.random()
            t.right(20 * a)
            b = 1.5 * random.random()
            Tree(branch - 10 * b, t)
            t.left(40 * a)
            Tree(branch - 10 * b, t)
            t.right(20 * a)
            t.up()
            t.backward(branch)
            t.down()
    
    # 掉落的花瓣
    def Petal(m, t):
        for i in range(m):
            a = 200 - 400 * random.random()
            b = 10 - 20 * random.random()
            t.up()
            t.forward(b)
            t.left(90)
            t.forward(a)
            t.down()
            t.color('lightcoral')  # 淡珊瑚色
            t.circle(1)
            t.up()
            t.backward(a)
            t.right(90)
            t.backward(b)
    
    
    class Particle:
    
        def __init__(self, cv, idx, total, explosion_speed, x=0., y=0., vx=0., vy=0., size=2., color='red', lifespan=2,
                     **kwargs):
            self.id = idx
            self.x = x
            self.y = y
            self.initial_speed = explosion_speed
            self.vx = vx
            self.vy = vy
            self.total = total
            self.age = 0
            self.color = color
            self.cv = cv
            self.cid = self.cv.create_oval(
                x - size, y - size, x + size,
                y + size, fill=self.color)
            self.lifespan = lifespan
    
        def update(self, dt):
            self.age += dt
    
            # 粒子范围扩大
            if self.alive() and self.expand():
                move_x = cos(radians(self.id * 360 / self.total)) * self.initial_speed
                move_y = sin(radians(self.id * 360 / self.total)) * self.initial_speed
                self.cv.move(self.cid, move_x, move_y)
                self.vx = move_x / (float(dt) * 1000)
    
            # 以自由落体坠落
            elif self.alive():
                move_x = cos(radians(self.id * 360 / self.total))
                # we technically don't need to update x, y because move will do the job
                self.cv.move(self.cid, self.vx + move_x, self.vy + GRAVITY * dt)
                self.vy += GRAVITY * dt
    
            # 移除超过最高时长的粒子
            elif self.cid is not None:
                cv.delete(self.cid)
                self.cid = None
    
        # 扩大的时间
        def expand (self):
            return self.age <= 1.2
    
        # 粒子是否在最高存在时长内
        def alive(self):
            return self.age <= self.lifespan
    
    '''
    循环调用保持不停
    '''
    def simulate(cv):
        # time.sleep(0.0005)
        t1 = time.time()
        explode_points = []
        wait_time = randint(10, 100)
        numb_explode = randint(6, 10)
        # 创建一个所有粒子同时扩大的二维列表
        for point in range(numb_explode):
            objects = []
            x_cordi = randint(50, 550)
            y_cordi = randint(50, 150)
            speed = uniform(0.5, 1.5)
            size = uniform(0.5, 3)
            color = choice(colors)
            explosion_speed = uniform(0.2, 1)
            total_particles = randint(10, 50)
            for i in range(1, total_particles):
                r = Particle(cv, idx=i, total=total_particles, explosion_speed=explosion_speed, x=x_cordi, y=y_cordi,
                             vx=speed, vy=speed, color=color, size=size, lifespan=uniform(0.6, 1.75))
                objects.append(r)
            explode_points.append(objects)
    
        total_time = .0
        # 1.8s内一直扩大
        while total_time < 1.8:
            sleep(0.01)
            tnew = time.time()
            t1, dt = tnew, tnew - t1
            for point in explode_points:
                for item in point:
                    item.update(dt)
            cv.update()
            total_time += dt
        # 循环调用
        root.after(wait_time, simulate, cv)
    
    def close(*ignore):
        """退出程序、关闭窗口"""
        global root
        root.quit()
    
    if __name__ == '__main__':
        root = tk.Tk()
        cv = tk.Canvas(root, height=520, width=750)
        cv.pack()
        image = Image.open("./image.jpg")
        photo = ImageTk.PhotoImage(image)
        w = turtle.TurtleScreen(cv)
        t = turtle.RawTurtle(w)
        # 选一个好看的背景会让效果更惊艳!
        cv.create_image(0, 0, image=photo)
        # root.mainloop()
        t.hideturtle()  # 隐藏画笔
        t.getscreen().tracer(5, 0)
        w.screensize(bg='black')  # wheat小麦
        t.left(90)
        t.up()
        t.backward(150)
        t.down()
        t.color('sienna')
        # 画樱花的躯干
        Tree(60, t)
        # 掉落的花瓣
        Petal(200, t)
        root.protocol("WM_DELETE_WINDOW", close)
        root.after(100, simulate, cv)
        root.mainloop()
    

    四、飘过的雪花 

    from turtle import *
    from random import *
    from math import *
    
    def tree(n,l):
        pd()#下笔
        #阴影效果
        t = cos(radians(heading()+45))/8+0.25
        pencolor(t,t,t)
        pensize(n/3)
        forward(l)#画树枝
    
        if n>0:
            b = random()*15+10 #右分支偏转角度
            c = random()*15+10 #左分支偏转角度
            d = l*(random()*0.25+0.7) #下一个分支的长度
            #右转一定角度,画右分支
            right(b)
            tree(n-1,d)
            #左转一定角度,画左分支
            left(b+c)
            tree(n-1,d)
            #转回来
            right(c)
        else:
            #画叶子
            right(90)
            n=cos(radians(heading()-45))/4+0.5
            pencolor(n,n*0.8,n*0.8)
            circle(3)
            left(90)
            #添加0.3倍的飘落叶子
            if(random()>0.7):
                pu()
                #飘落
                t = heading()
                an = -40 +random()*40
                setheading(an)
                dis = int(800*random()*0.5 + 400*random()*0.3 + 200*random()*0.2)
                forward(dis)
                setheading(t)
                #画叶子
                pd()
                right(90)
                n = cos(radians(heading()-45))/4+0.5
                pencolor(n*0.5+0.5,0.4+n*0.4,0.4+n*0.4)
                circle(2)
                left(90)
                pu()
                #返回
                t=heading()
                setheading(an)
                backward(dis)
                setheading(t)
        pu()
        backward(l)#退回
    
    bgcolor(0.5,0.5,0.5)#背景色
    ht()#隐藏turtle
    speed(0)#速度 1-10渐进,0 最快
    tracer(0,0)
    pu()#抬笔
    backward(100)
    left(90)#左转90度
    pu()#抬笔
    backward(300)#后退300
    tree(12,100)#递归7层
    done()
    

    五、给你一朵玫瑰花

    效果图:

    代码:

    
    
    from turtle import *
    import time
    
    setup(1000,800,0,0)
    speed(0)
    penup()
    seth(90)
    fd(340)
    seth(0)
    pendown()
    
    speed(5)
    begin_fill()
    fillcolor('red')
    circle(50,30)
    
    for i in range(10):
        fd(1)
        left(10)
    
    circle(40,40)
    
    for i in range(6):
        fd(1)
        left(3)
    
    circle(80,40)
    
    for i in range(20):
        fd(0.5)
        left(5)
    
    circle(80,45)
    
    for i in range(10):
        fd(2)
        left(1)
    
    circle(80,25)
    
    for i in range(20):
        fd(1)
        left(4)
    
    circle(50,50)
    
    time.sleep(0.1)
    
    circle(120,55)
    
    speed(0)
    
    seth(-90)
    fd(70)
    
    right(150)
    fd(20)
    
    left(140)
    circle(140,90)
    
    left(30)
    circle(160,100)
    
    left(130)
    fd(25)
    
    penup()
    right(150)
    circle(40,80)
    pendown()
    
    left(115)
    fd(60)
    
    penup()
    left(180)
    fd(60)
    pendown()
    
    end_fill()
    
    right(120)
    circle(-50,50)
    circle(-20,90)
    
    speed(1)
    fd(75)
    
    speed(0)
    circle(90,110)
    
    penup()
    left(162)
    fd(185)
    left(170)
    pendown()
    circle(200,10)
    circle(100,40)
    circle(-52,115)
    left(20)
    circle(100,20)
    circle(300,20)
    speed(1)
    fd(250)
    
    penup()
    speed(0)
    left(180)
    fd(250)
    circle(-300,7)
    right(80)
    circle(200,5)
    pendown()
    
    left(60)
    begin_fill()
    fillcolor('green')
    circle(-80,100)
    right(90)
    fd(10)
    left(20)
    circle(-63,127)
    end_fill()
    
    penup()
    left(50)
    fd(20)
    left(180)
    
    pendown()
    circle(200,25)
    
    penup()
    right(150)
    
    fd(180)
    
    right(40)
    pendown()
    begin_fill()
    fillcolor('green')
    circle(-100,80)
    right(150)
    fd(10)
    left(60)
    circle(-80,98)
    end_fill()
    
    penup()
    left(60)
    fd(13)
    left(180)
    
    pendown()
    speed(1)
    circle(-200,23)
    
    exitonclick()
    

    六、HTML+JS 网页樱花

    <!doctype html>
    <html>
    <head>
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="Cache-Control" content="no-cache" />
    <meta http-equiv="Expires" content="0" />
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no" />
    <style type="text/css">
    canvas{
        position: absolute;
        left: 0;
        top: 0;
    }
    </style>
    </head>
    <body bgcolor="#000000">
    <canvas id="tree"></canvas>
    <canvas id="flower"></canvas>
    <script>
    //两个canvas
    var tree = document.getElementById("tree");
    tree.width = window.innerWidth;
    tree.height = window.innerHeight ;
    var tCxt = tree.getContext("2d");
    var flower = document.getElementById("flower");
    flower.width = window.innerWidth;
    flower.height = window.innerHeight ;
    var cxt = flower.getContext("2d");
    
    var flowerList = [];//樱花列表
    var rootTop = 450 ;//树起点
    var flowerColor = "rgba(255,192,203,.3)" ;//花色
    var flowerColorDeep = "rgba(241,158,194,.5)" ;//花色深
    var treeColor2 = "rgba(255,192,203,.5)" ;//树枝颜色
    var treeColor = "#FFF" ;//树干颜色
    var fallList = [];//飘落樱花列表
    var g = 0.01 ;//重力加速度
    var gWind = 0.005;//风力加速度
    var limitSpeedY = 1;//速度上限
    var limitSpeedX = 1 ;//速度上限
    
    cxt.shadowColor= "#FFF" ;
    cxt.shadowBlur = 10 ;
    
    function drawTree(x,y,deg,step,type){
        var deg1 = step%2 == 0 ? 0.1 : -0.1 ;
        var x1 = x + Math.cos(deg+deg1) * (step+4) * 0.8 ;//以步长来判断枝干长度 x轴偏移大一些
        var y1 = y + Math.sin(deg+deg1) * (step-1) * 0.8 ;//以步长来判断枝干长度 Y轴压缩一些
        tCxt.beginPath();
        tCxt.lineWidth = step/3;
        tCxt.moveTo(x,y);
        tCxt.lineTo(x1,y1);
        tCxt.strokeStyle = (step > 5 ) ? treeColor : treeColor2 ;//细纸条都换成花的颜色
        tCxt.stroke();
        if(step > 20){//树干相交的位置有间隙,以一个圆填充
            tCxt.fillStyle = treeColor ;
            tCxt.arc(x,y,step/6,0,Math.PI*2);
            tCxt.fill();
        }
        if(step < 3 || (step < 23 && Math.random() > 0.1)){
            //末梢位置 画花瓣
            var color = [flowerColorDeep,flowerColor,flowerColor][Math.round(Math.random()+0.2)] ;
            var r = 2+Math.random()*2
            tCxt.fillStyle = color ;
            tCxt.arc(x1+Math.random()*3,y1+Math.random()*3,r,0,Math.PI)
            tCxt.fill();
            flowerList.push({x:x,y:y,sx:(Math.random()-0.5),sy:0,color:color,r:r,deg:deg});//保存下画樱花的位置
        }
        step -- ;
        if(step > 0){
            drawTree(x1,y1,deg,step,type);
            if(step%3 == 1 && step > 0 && step < 30)
                drawTree(x1,y1,deg+0.2 + 0.3 * Math.random(),Math.round(step/1.13));//右分叉
            if(step%3 == 0 && step > 0 && step < 30)
                drawTree(x1,y1,deg-0.2 - 0.3 * Math.random(),Math.round(step/1.13));//左分叉
        }
    }
    
    drawTree(tree.width/2,rootTop,-Math.PI/2,30,1);//执行
    
    var len = flowerList.length ;
    function step(){
        if(Math.random() > 0.3)    fallList.push(flowerList[Math.floor(Math.random()*len)]);//随机取出一个,花瓣复制到飘落花瓣的列表中
    
        cxt.clearRect(0,0,tree.width,tree.height);
        for(var i = 0 ;i < fallList.length ; i ++){
            if(fallList[i].sy < limitSpeedY) fallList[i].sy += g ;
            fallList[i].sx += gWind ;
            fallList[i].x += fallList[i].sx ;
            fallList[i].y += fallList[i].sy ;
            if(fallList[i].y > rootTop+30){//飘到树根+30的花瓣移除
                fallList.splice(i,1);
                i -- ;
                continue ;
            }
            cxt.beginPath();
            cxt.fillStyle = fallList[i].color ;
            fallList[i].deg += fallList[i].sx*0.05 ;//跟速度相关的旋转花瓣
            cxt.arc(fallList[i].x,fallList[i].y,fallList[i].r,fallList[i].deg,fallList[i].deg+Math.PI*1.3);
            cxt.fill();
        }
        requestAnimationFrame(step);
    }
    requestAnimationFrame(step);
    </script>
    </body>
    </html>
    
    
     
    关注公众号 海量干货等你
  • 相关阅读:
    分类在使用runtime做方法交换时
    打包自己Framework中含有第三方库的解决方案分CocoaPods与手动导入两种方式
    iOS 百分比圆环曲线swift4.0实现
    最新swift4.0 图片进行尺寸大小及体积压缩
    swift 密码由6-16数字和字母组合组成
    Android 7.0 之后相机/文件读写等权限获取方式改变,导致开启相机闪退
    Android Manifest 中 uses-feature 和 uses-permission的作用 关系和区别
    Android studio 3.1.3真机调试报错,no target device found
    如何用Java实现条件编译
    Missing android.support.FILE_PROVIDER_PATHS meta-data 报错原因分析
  • 原文地址:https://www.cnblogs.com/sowhat1412/p/12734322.html
Copyright © 2011-2022 走看看