Python 3.x--tkinter(四):第一个游戏☞弹弹弹的小球

这几天有点不舒服,脑补了些奇奇怪怪的东西,如果有一天真的残废了,会以何种状态面对生活呢?
生命脆弱,人生也无常。
珍惜呀?!
珍惜,说的轻巧,但人的劣性往往是失去了才想到拥有的美好……
不管怎样还是记着高中老班的话,万事平常心呢
毕竟,人生如戏……

嗯…朋友生日,一天飞快没了,晚上静静地理一下第一个tkinter游戏

弹弹弹的小球

一、创建游戏画布

这里写图片描述

from tkinter import *
import random
import time #调用时间函数让游戏有真实感
tk = Tk()
tk.title("Game") #给窗口命名
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
canvas = Canvas(tk, width = 500, height = 400, bd = 0,\
highlightthickness = 0)
canvas.pack()#画布调整大小
tk.update()#为动画做好初始化

代码说明:

1.第六行:resizable函数窗口的大小不可调整,两个参数分别表示水平和垂直方向,(0,0)的意思是“窗口的大小在水平方向上和垂直方向上都不能改变”
2.第七行:调用wm_attributes,将画布的窗口始终放到所有其他窗口之前(-topmost)
3.第八行:多了 bd = 0,highlightthickness = 0,作用是画布之外没有边框,可以使游戏屏幕看上去更加美观。

二、创建球

这里写图片描述

class Ball:
    def __init__(self,canvas,color): #参数为画布和小球的颜色
        self.canvas = canvas#画布保存在变量中
        self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
        self.canvas.move(self.id, 245,100)#将球移动到画布中心
    def draw(self):
        pass

ball = Ball(canvas,  'red')

while 1:
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)

代码说明:

1.创建Ball类,初始化对象,即创建对象设置属性,此外init函数是在对象被创建的同时就设置属性的一种方法,Python会在创建新对象是自动调用这个函数
2.第四行:保存tkinter画小球返回的ID,为后期移动屏幕上的小球做准备,参数分别表示为:(10,10)表示左上角x,y坐标,(25,25)表示右下角x,y坐标,填充色
3.Ball类中的最后两行,创建draw函数,目的是让小球弹起来,现在函数体只是一个pass关键字,即没有任何操作。
4.紧接着创建一个红色的小球
5.while循环为动画循环,又叫游戏的‘主循环’,让tkinter在关闭窗口前间隔为0.01秒的频率一直重画屏幕
6.由于IDE的关系最好都输入下面一行的代码,让窗口进入事件循环,使得程序运行起来。

tk.mainloop()

三、动起来的小球

这里写图片描述

    def draw(self):
        self.canvas.move(self.id,0,-1)

while 1:
    ball.draw()

代码说明:

1.修改draw函数,使用self.canvas调用画布上的move函数,其中参数0,-1表示小球在屏幕上水平、上下移动的像素;0指不要水平移动,-1指向上移动1个像素
2.在主循环中调用draw函数

四、弹来弹去的小球

这里写图片描述

修改Ball类

代码如下:

     def __init__(self,canvas,color): 
        self.canvas = canvas
        self.id = canvas.create_oval(10, 10, 25, 25, fill=color)#(10,10)
        self.canvas.move(self.id, 245,100)
        starts = [-3,-2,-1,1,2,3]
        random.shuffle(starts)
        self.x = starts[0]
        self.y = -3
        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()

代码说明:

1.第五行,创建变量starts
2.第六行,random.shuffle将starts列表随机混排
3.第七行,将x 的值设为列表中第一个元素,第八行,将y的值设置为3,即上下移动的比较快
4.第九行,调用画布函数winfo_height获取画布当前的高度,并将其赋值给变量canvas_height

 def draw(self):
        self.canvas.move(self.id,self.x,self.y)
        pos = self.canvas.coords(self.id)
        if pos[1] <= 0:
            self.y = 2
        if pos[3] >= self.canvas_height:
            self.y = -3
        if pos[0] <= 0:
            self.x = 2
        if pos[2] >= self.canvas_width:
            self.x = -3

代码说明:

1.第二行,传入变量x(水平移动)和y(上下移动)替代原来的数字0和-1
2.第三行,将画布函数coords赋值给创建的pos变量;画布函数coords:通过ID来返回画布上任何画出图画的当前x和y坐标,让小球通过屏幕壁进行来回反弹;coords函数返回四个数字组成的列表表示坐标(x1,y1,x2,y2),即:图形左上角和右下角的x,y坐标
3.四个判断句为边界判断,即,若到达边界则将变量重置。

五、球拍来了

class Paddle:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_rectangle(0, 0, 100, 10, fill=color)  
        self.canvas.move(self.id, 200, 300) 

    def draw(self):
        pass

代码说明:

在Ball 类后面添加paddle类,创建球拍,paddle类代码和Ball类几乎一样

paddle = Paddle(canvas, "blue")
ball = Ball(canvas, paddle, 'red')

while 1:
        ball.draw()
        paddle.draw()
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)

tk.mainloop()

代码说明:

1.第一行,创建Paddle类的对象
2.然后在主循环中调用球拍的draw函数

这个时候只是单纯地增加了球拍,还无法判断是否击中球拍,以及无法判断输赢

六、横走的球拍

在上面的基础上,增加了键盘操控,可以使用左右键移动球拍,使球拍可以反弹,当小球落地则小球和球拍停止移动,此时游戏结束。

这里写图片描述

总代码如下:

from tkinter import *
import random
import time #调用时间函数让游戏有真实感

class Ball:
    def __init__(self,canvas,paddle,color): #初始化对象,即创建对象设置属性,此外__init__函数是在对象被创建的同时就设置属性的一种方法,Python会在创建新对象是自动调用这个函数
        self.canvas = canvas
        self.id = canvas.create_oval(10, 10, 25, 25, fill=color)#(10,10)表示左上角x,y坐标,(25,25)表示右下角x,y坐标,填充色
        self.canvas.move(self.id, 245,100)#将球移动到画布中心
        self.paddle = paddle
        starts = [-3,-2,-1,1,2,3]
        random.shuffle(starts)
        self.x = starts[0]
        self.y = -3
        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()
        self.hit_bottom = False
    def hit_paddle(self, pos):#判断小球是否撞到球拍上面的函数
        paddle_pos = self.canvas.coords(self.paddle.id)#将拍子的坐标放到变量paddle_pos中
        if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
            if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]:
                return  True
            return False
    def draw(self):
        self.canvas.move(self.id,self.x,self.y)#0表示不要水平移动,-1表示在屏幕上向上移动1个像素
        pos = self.canvas.coords(self.id)#coords画布函数,通过ID返回画布上任何画好的东西的当前x,y坐标
        if pos[1] <= 0:
            self.y = 2
        if pos[3] >= self.canvas_height:
            self.hit_bottom = True#当小球移动到底部时,=True,则停止游戏
        if self.hit_paddle(pos) == True:#判断小球是否撞到球拍上面
            self.y = -3
        if pos[0] <= 0:
            self.x = 2
        if pos[2] >= self.canvas_width:
            self.x = -3

class Paddle:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_rectangle(0, 0, 100, 10, fill=color)  # (10,10)表示左上角x,y坐标,(25,25)表示右下角x,y坐标,填充色
        self.canvas.move(self.id, 200, 300)  # 将球移动到画布中心
        self.x = 0
        self.canvas_width = self.canvas.winfo_width()
        self.canvas.bind_all('<KeyPress-Left>', self.turn_left)#按键时调用函数,< >内为 事件名字,让对象对操作有反应
        self.canvas.bind_all('<KeyPress-Right>', self.turn_right)
    def draw(self):
        self.canvas.move(self.id, self.x, 0)
        pos = self.canvas.coords(self.id)
        if pos[0] <= 0:
            self.x = 0#move函数在变量x的方向上撞到边界则停止
        elif pos[2] >= self.canvas_width:
            self.x = 0

    def turn_left(self,evt):#改变向左向右的方向
        self.x = -2
    def turn_right(self,evt):
        self.x = 2

tk = Tk()
tk.title("Game") #给窗口命名
tk.resizable(0,0)#窗口的大小不可调整,第一个参数表示长,0,0的意思是“窗口的大小在水平方向上和垂直方向上都不能改变”
tk.wm_attributes("-topmost",1)#将画布的窗口始终放到所有其他窗口之前
canvas = Canvas(tk,width=500, height=400, bd=0, highlightthickness=0)#后两个参数作用:确保画布之外没有边框,使得屏幕更美观
canvas.pack()
tk.update()#为动画做好初始化

paddle = Paddle(canvas, "blue")
ball = Ball(canvas, paddle, 'red')
while 1:
    if ball.hit_bottom == False:
        ball.draw()
        paddle.draw()
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)

tk.mainloop()
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值