Python实现带图形界面的炸金花游戏(升级版)
作者:Hann Yang
旧版本的代码请见上一篇博文:
本文尝试在旧版本的基础上,“升级”以下几个部分:
一、图形的旋转,模拟四个玩家两两面对围坐在牌桌上
旋转方法 rotate(angle) 本文只用到转动角度这一个参数,角度正值表示逆时针转动;负值表示顺时针转动。
method rotate in module PIL.Image:
rotate(angle, resample=0, expand=0, center=None, translate=None, fillcolor=None) method of PIL.Image.Image instance
Returns a rotated copy of this image. This method returns a copy of this image, rotated the given number of degrees counter clockwise around its centre.
:param angle: In degrees counter clockwise.
:param resample: An optional resampling filter. This can be one of :py:data: `PIL.Image.NEAREST` (use nearest neighbour), :py:data:`PIL.Image.BILINEAR` (linear interpolation in a 2x2 environment), or :py:data:`PIL.Image.BICUBIC`
(cubic spline interpolation in a 4x4 environment).
If omitted, or if the image has mode "1" or "P", it is set to :py:data: `PIL.Image.NEAREST`. See :ref:`concept-filters`.
:param expand: Optional expansion flag. If true, expands the output image to make it large enough to hold the entire rotated image.
If false or omitted, make the output image the same size as the input image. Note that the expand flag assumes rotation around the center and no translation.
:param center: Optional center of rotation (a 2-tuple). Origin is the upper left corner. Default is the center of the image.
:param translate: An optional post-rotate translation (a 2-tuple).
:param fillcolor: An optional color for area outside the rotated image.
:returns: An :py:class:`~PIL.Image.Image` object.
如不是正方形图片,转动角度不是180度的话,就会被截掉一部分。效果如下:
演示代码:
import tkinter as tk from PIL import Image,ImageTk def load(i=0): img = Image.open("pokers.png").resize((375,150)) box = img.rotate(90*i) res = ImageTk.PhotoImage(image=box) img.close() return res if __name__ == '__main__': root = tk.Tk() root.geometry('800x480') root.title('图片旋转') cv = tk.Canvas(root, width=1600, height=800, bg='darkgreen') cv.pack() png = [None]*4 coord = ((i,j) for j in (120,345) for i in (200,600)) for i,xy in enumerate(coord): png[i] = load(i) cv.create_image(xy, image=png[i]) cv.create_text(xy[0],xy[1]+95, text=f'逆时针转动{i*90}度',fill='white') root.mainloop()
为保存全图在转动之前,设置一个正方形框 box = img.crop((0,0,375,375)).rotate(-90*i),顺时针转动的效果如下:
演示代码:
import tkinter as tk from PIL import Image,ImageTk def load(i=0): img = Image.open("pokers.png").resize((375,150)) box = img.crop((0,0,375,375)).rotate(-90*i) res = ImageTk.PhotoImage(image=box) img.close() return res if __name__ == '__main__': root = tk.Tk() root.geometry('800x800') root.title('图片旋转') cv = tk.Canvas(root, width=1600, height=800, bg='darkgreen') cv.pack() png = [] coord = ((i,j) for j in (200,600) for i in (200,600)) for i,xy in enumerate(coord): png.append(load(i)) cv.create_image(xy, image=png[i]) root.mainloop()
然后再用crop()方法来截取出黑色背景除外的部分,就是所需的转动四个方向上的图像;最后把这些图片再次分割成一张张小纸牌,存入一个三维列表备用。
二、增加变量,使得比大小游戏有累积输赢过程
在玩家文本框后各添加一个文本框,动态显示每一局的输赢情况;各玩家的值存放于全局变量Money列表中,主要代码如下:
ALL, ONE = 1000, 200 #初始值、单次输赢值 Money = [ALL]*4 #设置各方初始值 ... ... cv.create_text(tx,ty, text=f'Player{x+1}', fill='white') #玩家1-4显示文本框 txt.append(cv.create_text(tx+60,ty, fill='gold',text=Money[x])) #显示框 ... ... Money[idx] += ONE*4 #每次赢ONE*3,多加自己的一份 for i in range(4): Money[i] -= ONE #多加的在此扣减 cv.itemconfig(txt[i], text=str(Money[i])) #修改各方的值 cv.update()
三、界面增加下拉式菜单,菜单项调用的绑定函数
显示效果见题图左上角,主要代码如下:
btnCmd = '发牌',dealCards,'开牌',playCards,'洗牌',Shuffle Menu = tk.Menu(root) menu = tk.Menu(Menu, tearoff = False) for t,cmd in zip(btnCmd[::2],btnCmd[1::2]): menu.add_radiobutton(label = t, command = cmd) menu.add_separator() #菜单分割线 menu.add_command(label = "退出", command = ExitApp) Menu.add_cascade(label="菜单",menu = menu) root.config(menu = Menu)
四、导入信息框库,增加提示信息框的使用
使用了2种信息框类型:提示showinfo()和确认选择askokcancel()
tkinter.messagebox库共有8种信息框类型,其使用方法基本相同,只是显示的图标有区别:
Help on module tkinter.messagebox in tkinter:
NAME
tkinter.messagebox
FUNCTIONS
askokcancel(title=None, message=None, **options)
Ask if operation should proceed; return true if the answer is ok
askquestion(title=None, message=None, **options)
Ask a question
askretrycancel(title=None, message=None, **options)
Ask if operation should be retried; return true if the answer is yes
askyesno(title=None, message=None, **options)
Ask a question; return true if the answer is yes
askyesnocancel(title=None, message=None, **options)
Ask a question; return true if the answer is yes, None if cancelled.
showerror(title=None, message=None, **options)
Show an error message
showinfo(title=None, message=None, **options)
Show an info message
showwarning(title=None, message=None, **options)
Show a warning message
DATA
ABORT = 'abort'
ABORTRETRYIGNORE = 'abortretryignore'
CANCEL = 'cancel'
ERROR = 'error'
IGNORE = 'ignore'
INFO = 'info'
NO = 'no'
OK = 'ok'
OKCANCEL = 'okcancel'
QUESTION = 'question'
RETRY = 'retry'
RETRYCANCEL = 'retrycancel'
WARNING = 'warning'
YES = 'yes'
YESNO = 'yesno'
YESNOCANCEL = 'yesnocancel'
另:发牌、开牌、洗牌按钮可否点击,由两个全局变量控制,当不能使用时弹出提示信息框。但更好方式通常是设置按钮的state状态,在 tk.DISABLED 和 tk.NORMAL 之间切换,用以下代码:
if btn[0]['state'] == tk.DISABLED: btn[0]['state'] = tk.NORMAL else: btn[0]['state'] = tk.DISABLED #使得按钮灰化,无法被按下 #或者在初始按钮时使用: tk.Button(root,text="点不了",command=test,width=10,state=tk.DISABLED)
“诈金花”完整源代码
运行结果:
到此这篇关于Python实现带图形界面的炸金花游戏(升级版)的文章就介绍到这了,更多相关Python炸金花内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!