感觉现在游戏不好玩,自己写写玩玩,如果有人看欢迎讨论指点。
非计算机专业,只学了基础c,和简单的数据结构与算法。对 为什么选python 不是以为他好做游戏或者什么,我上课的神经网络方面的大作业有得用python,然后简单看了看,python也能搞界面,所以顺便学学python。
也非总结,自己记录一下,可能比较混乱。
其中很多是从网上大佬学的,我尽量备注来源,然后我没注意时间戳,所以如果摘抄有原作搞错,告诉我,我改。
对不对不知道 试试咯
不懂架构和美工,不过个人感觉
1.界面图像 tkinter
2.鼠标、键盘操作
3.数据存储、读取
4.数据运算
5.功能操作
都搞完,应该差不多单机能看看。
先这样
本来想先看看有啥,然后看了一眼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)
这里列了一点儿:
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()
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的线程这块是咋写的,先空下吧。
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()
用户登录界面 这个蛮多的,我不记得我从哪里看的了 抱歉
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()
搞到这里,大概,半天过去了。(因为环境什么的,本身有,主要是花时间找东西看,然后实验,再加上自己是傻的,绕了半天)
刚刚路上去吃饭的时候突然想,为啥我那会想搞刷新页面,不就是为了动态起来?那贪吃蛇或者其他什么游戏,不就是动的?那他们咋用的,我也用不就行了!
然后瞄了瞄,感觉没啥进度,什么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系列的,都可以随便换
3.9.2 Python 标准库 » 通用操作系统服务 »
https://docs.python.org/zh-cn/3.9/library/curses.html
这里有更多更细的内容。不过暂时没有用到,以后会 先打个标记。
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)
这种直接触发 也可以