用python尝试做游戏(一)

用python尝试做游戏

  • 胡诌一下
    • 大概脉络
    • 界面显示
      • tkinter
      • 自我烦恼于界面刷新
      • Entry的简单代码示例 获取数据
      • messageBox窗口部件
      • 贪吃蛇????
    • 简单的人机交互部分 键盘鼠标
      • python 实时捕获按键处理 (跟随上面的实践)
      • curses --- 终端字符单元显示的处理
      • 关于bind的具体实践内容

胡诌一下

感觉现在游戏不好玩,自己写写玩玩,如果有人看欢迎讨论指点。
非计算机专业,只学了基础c,和简单的数据结构与算法。对 为什么选python 不是以为他好做游戏或者什么,我上课的神经网络方面的大作业有得用python,然后简单看了看,python也能搞界面,所以顺便学学python。
也非总结,自己记录一下,可能比较混乱。

其中很多是从网上大佬学的,我尽量备注来源,然后我没注意时间戳,所以如果摘抄有原作搞错,告诉我,我改。

大概脉络

对不对不知道 试试咯
不懂架构和美工,不过个人感觉
1.界面图像 tkinter
2.鼠标、键盘操作
3.数据存储、读取
4.数据运算
5.功能操作
都搞完,应该差不多单机能看看。
先这样

界面显示

tkinter

本来想先看看有啥,然后看了一眼Python 3.9.2 文档,太多了。先放弃,碰到问题再看,不然我觉得,不知道那年才能做出哪怕一丢丢东西。平常看不到成果,一定会没有动力。
(Python 3.9.2 文档https://docs.python.org/zh-cn/3/)

看的界面Python GUI
———————————tkinter窗口
(这个老哥的还行 https://www.cnblogs.com/shwee/p/9427975.html)
边看边试试,不懂框架,以后慢慢搞
(然后这个写的也挺详细,就是tkinter窗口的内容,可以参考https://blog.csdn.net/weixin_42272768/article/list/5?t=1)
用python尝试做游戏(一)_第1张图片
这里列了一点儿:

import time  # 引入time模块

import tkinter as tk  # 使用Tkinter前需要先导入

import random
print (random.randint(6,8))


# 第1步,实例化object,建立窗口window
window = tk.Tk()
 
# 第2步,给窗口的可视化起名字
window.title('My Window')
 
def get_screen_size(win):
    return win.winfo_screenwidth(),win.winfo_screenheight()
def center_window(window, width, height):
    screenwidth = window.winfo_screenwidth()
    screenheight = window.winfo_screenheight()
    size = '%dx%d+%d+%d' % (width, height, (screenwidth - width)/2, (screenheight - height)/2)
    window.geometry(size)


center_window(window, 500, 200)


# 第4步,在图形界面上创建 500 * 200 大小的画布并放置各种元素
canvas = tk.Canvas(window, bg='green', height=200, width=500)
canvas.pack()

# 说明图片位置,并导入图片到画布上
image_file = tk.PhotoImage(file='c:/Users/扬/Desktop/game_py/pic.gif')  # 图片位置(相对路径,与.py文件同一文件夹下,也可以用绝对路径,需要给定图片具体绝对路径)
image = canvas.create_image(250, 0, anchor='n',image=image_file)        # 图片锚定点(n图片顶端的中间点位置)放在画布(250,0)坐标处

# 定义多边形参数,然后在画布上画出指定图形
x0, y0, x1, y1 = 100, 100, 150, 150
line = canvas.create_line(x0-50, y0-50, x1-50, y1-50)                   # 画直线
oval = canvas.create_oval(10, 100, 0, 0, fill='yellow')  # 画圆 用黄色填充
arc = canvas.create_arc(x0, y0+50, x1, y1+50, start=0, extent=180)      # 画扇形 从0度打开收到180度结束
rect = canvas.create_rectangle(330, 30, 330+20, 30+20)                  # 画矩形正方形
canvas.pack()
 


# 第5步,定义一个按钮用来移动指定图形的在画布上的位置
def moveit():

    canvas.move(image, 20, 20) # 移动图形,按每次(x=20, y=20)步长进行移动

#删除原理的图像 随机生成新的
def new_ova():
    global oval
    canvas.delete(oval)
    a=random.randint(10,200)
    b=random.randint(10,500)
    print(a,b)
    oval = canvas.create_oval(a, b,a+10,b+10, fill='yellow')  # 画圆矩形内 点(a,b)到(a+10,b+10)用黄色填充
    

 
# 第6步,触发函数,用来一定指定图形
#靠下左对齐
bq1 = tk.Button(window, text='move item',command=moveit).pack(side=tk.LEFT)
bq2 = tk.Button(window, text='new oval',command=new_ova).pack(side=tk.LEFT)
 


# 第7步,主窗口循环显示
window.mainloop()

用python尝试做游戏(一)_第2张图片
move item 是海贼王定向移动。
new oval是小黄点,固定大小,在屏幕上随机生成,(想贪吃蛇了)。这块我想了半天,不知道咋刷新界面,试了大循环里套界面,但是那种是关一个界面新生成一个界面,很怪异。改成了,把原先图像的删了【.delete()】,再画。
这里得注意一点,就是python里的变量名和c的指针不太一样,def 定义函数或者说功能还是说接口,我也不知道啥,反正不影响用,得是全局变量,或者其他方式,我用的global oval。
然后用.create_oval(a, b,a+10,b+10, fill='yellow') # 画圆矩形内 点(a,b)到(a+10,b+10)用黄色填充画图得注意,贼奇葩,反正实验了半天才明白,他是两个点,选个长方形,然后自动在里面画个最大的图像。我可是傻乎乎的改了半个多小时参数,才搞明白,那会儿咋没想着百度一下。。。。

自我烦恼于界面刷新

想做个点击类的,随时间变的,改数字什么的。
(菜鸟的时间 https://www.runoob.com/python/python-date-time.html)

import time  # 引入time模块

def tim_on():
    #开始的时间点
    ticks = time.time()
    #已过时间
    tim_o = 0.  
    i_1 = 0
    while(True):
        time.sleep(1)  #推迟调用线程的运行,1秒。 防止不停的没用计算
        tim_o = time.time() - ticks
        i_1=1+i_1
        if i_1 > 1000: #上限 这里也可以加一个对比,tim_o和 i_1的,因为本身运算需要时间,一次延后一秒,误差累积。先备着,不敢定用不用。
            break
ticks = time.time()
print ("当前时间戳为:", ticks)

结果当前时间戳为: 1459994552.51

简单试了,把窗口生成在循环里,是每次生成一个新窗口,不是刷新窗口。
试了试把循环放在窗口里,也是怪怪的,没成功。或许应该用线程,加中断?
或者监听器???不知道python的线程这块是咋写的,先空下吧。

Entry的简单代码示例 获取数据

from tkinter import *

root = Tk()

Label(root,text="aaa").grid(row=0,column=0)
Label(root,text="bbb").grid(row=1,column=0)

e1 = Entry(root)
e2 = Entry(root)
e1.grid(row=0,column=1,padx=10,pady=5)
e2.grid(row=1,column=1,padx=10,pady=5)


on_hite1 = ''

def show():
    global on_hite1
    on_hite1 = e1.get()
    print("aaa:%s" %on_hite1)
    print("bbb:%s" %e2.get())
    e1.delete(0, "end")
    e2.delete(0, "end")

Button(root,text = "获取",width = 10,command = show)\
                 .grid(row = 3,column = 0,sticky = W,padx =10,pady =5)



mainloop()

反正我感觉避不开类似全局变量的东西,来交换数据
用python尝试做游戏(一)_第3张图片

messageBox窗口部件

用户登录界面 这个蛮多的,我不记得我从哪里看的了 抱歉

import tkinter as tk
from tkinter import messagebox

class verification_window(tk.Frame):

    # 调用时初始化
    def __init__(self):
        global root
        root = tk.Tk()
        # 窗口大小设置为150x150
        root.geometry('150x150+885+465')

   #     root.resizable(0, 0)  # 窗口大小固定

        super().__init__()
        self.username = tk.StringVar()
        self.password = tk.StringVar()
        self.pack()
        self.main_window()

        root.mainloop()

    # 窗口布局
    def main_window(self):
        global root
        username_label=tk.Label(root,text='Username:',font=('Arial',12)).place(x=35,y=10)
        username_input = tk.StringVar
        username_entry=tk.Entry(root,textvariable=self.username).place(x=2,y=35)

        password_label=tk.Label(root,text='Password:',font=('Arial',12)).place(x=35,y=58)
        password_input = tk.StringVar
        password_entry=tk.Entry(root,textvariable=self.password,show='*').place(x=2,y=83)

        # 在按下CONFIRM按钮时调用验证函数
        conformation_button = tk.Button(root,text='CONFIRM',command=self.verification,fg='white',bg='black', activeforeground='white', activebackground='navy',width=8,height=1)
        conformation_button.place(x=6,y=112)

        quit_button = tk.Button(root, text='QUIT', command=root.quit, fg='white', bg='black', activeforeground='white', activebackground='red', width=8, height=1)
        quit_button.place(x=78,y=112)

    # 验证函数
    def verification(self):
        global root

        # 检查用户名和密码 是否在user_dict字典中
        user_dict = {
     987654321:112233,123456789:332211}
        if user_dict.get(int(self.username.get())) == int(self.password.get()):
            # 成功提醒
            messagebox.showinfo(title='Correct', message=f'{int(self.username.get())}, welcome!')  

        else:
            messagebox.showerror(title='Wrong inputs!', message='Please enter correct username or password.')  # 错误提醒

if __name__ == '__main__':
    verification_window()

用python尝试做游戏(一)_第4张图片

搞到这里,大概,半天过去了。(因为环境什么的,本身有,主要是花时间找东西看,然后实验,再加上自己是傻的,绕了半天)

贪吃蛇????

刚刚路上去吃饭的时候突然想,为啥我那会想搞刷新页面,不就是为了动态起来?那贪吃蛇或者其他什么游戏,不就是动的?那他们咋用的,我也用不就行了!

然后瞄了瞄,感觉没啥进度,什么pygame,为主,然后用基础库的也是为了写贪吃蛇而写的,感觉和我想的有偏差。不过看见一个好玩的函数


python.bind


尚未实践
规则:窗体对象.bind(事件类型,回调函数)
这个好像还能与c++互相调用??!!
还有个bind_all
大概用法:
canvas.bind_all("",echo_event)

<Button-1>   :鼠标左击事件 
<Button-2>   :鼠标中击事件 
<Button-3>   :鼠标右击事件
<Double-Button-1>   :双击事件
<Triple-Button-1>   :三击事件

<KeyPress-A>表示A键被按下
<Control-V>表示按下的是Ctrl和V键
<F1>表示按下的是F1键,对于Fn系列的,都可以随便换

简单的人机交互部分 键盘鼠标

python 实时捕获按键处理 (跟随上面的实践)

curses — 终端字符单元显示的处理

3.9.2 Python 标准库 » 通用操作系统服务 »
https://docs.python.org/zh-cn/3.9/library/curses.html
这里有更多更细的内容。不过暂时没有用到,以后会 先打个标记。

关于bind的具体实践内容

def echo_event(evt):
    #打印键盘事件
    if evt.type == "2":
        print("键盘:%s" % evt.keysym)
    #打印鼠标操作
    if evt.type == "4":
        print("鼠标: %s" % evt.num)
    #
    if evt.keysym == 'A':
        canvas.move(image, 20, 20) # 移动图形,按每次(x=20, y=20)步长进行移动

    if evt.num == 1:
        canvas.move(image, 20, 20) # 移动图形,按每次(x=20, y=20)步长进行移动
    print(evt.keysym)
    print(evt.num)
    print(evt.type)

#键盘事件
canvas.bind_all("",echo_event)
#如果绑定指定的键盘,则"" 或者""都可以,具体到指定键的话后面加入下划线和指定的键就好了,如:绑定小写字母t和Left键
canvas.bind_all("",echo_event)
canvas.bind_all("",echo_event)
#鼠标事件
canvas.bind_all("",echo_event)
canvas.bind_all("",echo_event)
canvas.bind_all("",echo_event)
canvas.bind_all("",echo_event)

这里暂时不知道原因,但是结果如下:
用法和上述相同。
然后返回值,事件类型上(.type)键盘是字符2,鼠标是4。 ‘A’和 ‘a’不同。
键盘数据无num值,均为keysym,特殊符号不知,未实验。
然后,鼠标无keysym值,均为num,判断相等时是数值型的1,2,3。

如上述代码,是在之前的那个海贼王的代码中加即可。可以达到使其移动的效果。

def echo_event1():
        canvas.move(image, 0, 20) # 移动图形,按每次(0, -20)步长进行移动

#鼠标事件

canvas.bind_all("",echo_event1)

这种直接触发 也可以

你可能感兴趣的:(python,tkinter,canvas)