• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Pygame曾经风靡全国的游戏,复活了,你小时候玩过嘛纸牌红心大战游戏

武飞扬头像
顾木子吖
帮助1

导语

还记得那些年,我们玩过的Windows小游戏吗?

学新通

说起Windows自带的游戏,相信许多80、90后的朋友都不陌生。

在很早的那个游戏贫瘠的年代,《纸牌》、《扫雷》等游戏帮助我们在微机课上带来了许多欢

乐的时光。但在这些游戏中,有一款游戏似乎玩懂的人,甚至知道玩法的人并不多。这款游戏

就是《红心大战》。

最近小编心血来潮仔细钻研了一下之后,发现这款游戏玩起来却比其他的几款游戏更带感

一些。因为这款游戏的玩法简单概括就是两个字:“坑人”,而且是明着坑的那种。

那大家猜到了哈——今天跟着木木子一起开启《红心大战》纸牌小游戏吧!

学新通

正文

一、 红心大战用户手册

1.打开游戏:双击hongxindazhan.py 主程序运行即可!

2.开始游戏:键入玩家姓名,创建新ID,点确认进入游戏。

3.游戏流程:

  1.  
    1)换牌:
  2.  
    选择三张手牌,点击上方按钮完成交换;
  3.  
    2)出牌:
  4.  
    轮到玩家出牌时,选择手牌单击便可打出。(具体出牌规则详见附录)
  5.  
    注:当此时机不能打出此牌时,下方提示栏会显示无法打出原因。

4.统分阶段:一轮游戏过后,会弹出得分表,显示玩家和三名电脑每轮积分和总积分,并显示

玩家当前名次。(具体胜负判定规则详见附录)

5.菜单栏:

  1.  
    1)游戏栏:
  2.  
    新游戏(F2):单击开启新游戏。
  3.  
    得分(F4):单击显示得分表。
  4.  
    背景音乐:单击切换音乐开关。
  5.  
    选项(F5):单击修改电脑出牌速度。
  6.  
    退出:单击退出游戏。
  7.  
    2)帮助栏:
  8.  
    规则介绍(F1):单击显示简要规则和获胜条件。
  9.  
    名言:单击弹出一则名言。

6.背景音乐:更换:可用自己的wav格式音乐重命名为‘m1.wav’替换程序目录下的同名文件。

二、红心大战游戏规则:

  1.  
    1、在玩游戏前,需要决定庄家。在电脑中,庄家坐南。 2、拿到一手牌(共计13张)后,庄家首先须选出三张牌传给其他对手。第一局把牌传给左手
  2.  
     
  3.  
    边的玩家;第二局把牌传给右手边的玩家;第三局把牌传给坐在对面的玩家;第四局不传牌,
  4.  
     
  5.  
    依此类推。接到庄家的传牌后,也需要任意传回给庄家三张牌。在电脑中,如要选牌,单击相
  6.  
     
  7.  
    应牌张即可。如要取消选定的牌,请再次单击。
  8.  
     
  9.  
    3、抓有梅花2 的玩家必须首先出梅花2,谓首攻。
  10.  
    4、然后按顺时针方向出牌。每位玩家依次必须跟同花色牌。如果已经没有与发牌花色相同的
  11.  
     
  12.  
    牌,则可以出任何一张牌。唯一例外是不能在第一圈牌中出红桃或黑桃Q(通常称为“猪”)。注
  13.  
     
  14.  
    意:出的同一花色牌中最大的牌会赢取这一圈,赢牌的玩家在下一圈中先出牌。只有前面出过
  15.  
     
  16.  
    红桃以后,才可以拿红桃领出(除非手中只剩下红桃一种花色的牌张)。
  17.  
     
  18.  
    5,、每一轮游戏结束时,每张红心计1 分,“黑桃皇后(猪)”计13 分。游戏将持续到有人得
  19.  
     
  20.  
    100 分或更多分或者庄家退出游戏时结束。如果在一轮牌中赢得了所有的红心和“黑桃皇
  21.  
     
  22.  
    后”(称之为“全收”),则“全收”者得零分,其余玩家每人得26 分。该游戏的得分越低越好。
学新通

三、准备中

1)环境安装

▲环境安装 本文用到的运行环境:Python3.7、Pycharm社区版2020、tkinter模块、部分

自带模块直接导入不需要安装。(如果需要安装包软件、激活码或者遇到问题的话可以私信我

哈!) 模块安装:pip install -i https://pypi.douban.com/simple/ 模块名 

2)背景选择

最原始的绿色背景。(仅展示背景,其余图片比较多不展示)参考为最上面第二个图片👆

学新通

四、代码演示

仅展示主程序源码。每行代码都有注释所以直接展示!全部的源码见文末!

  1.  
    from Tkinter import *
  2.  
    from tkFont import *
  3.  
    import winsound
  4.  
    from tkMessageBox import *
  5.  
    from inner import *
  6.  
    from dialog import *
  7.  
    #游戏主界面创建
  8.  
    class GameFrame:
  9.  
    def __init__(self,game,bgimg):#game,Game类对象;bgimg,背景图片
  10.  
    self.master = game.root
  11.  
    #创建画布,绘制背景
  12.  
    self.c = Canvas(self.master,width = 1024,height = 640)
  13.  
    self.c.create_image(514,322,image=bgimg)
  14.  
    self.c.pack()
  15.  
    #创建状态条
  16.  
    self.status = Label(self.master,text=" 欢迎参加红心大战!",
  17.  
    bd=1,relief=SUNKEN,anchor=W)
  18.  
    self.status.pack(fill = X)
  19.  
    #打开开始对话框
  20.  
    startdialog = StartDialog(self.master,"红心大战")
  21.  
    if startdialog.isCancel:
  22.  
    game.cancel()
  23.  
    else:
  24.  
    self.gamemodetext = ['向左传','向右传','交叉换牌']
  25.  
    self.name = [startdialog.name,'西','北','东']
  26.  
    self.handXY = [[346.5,490,1,0],[20,135,0,1],
  27.  
    [586.5,20,-1,0],[913,375,0,-1]]
  28.  
    self.nameXY = [[-20,130,SE],[0,-20,SW],[91 20,0,NW],[91,130 20,NE]]
  29.  
    self.middleXY = [[466.5,330],[411,255],[466.5,180],[522,255]]
  30.  
    self.img = 53 * ['']
  31.  
    for i in range(52):
  32.  
    self.img[i] = PhotoImage(file = 'card\\%s.pgm' % (i))
  33.  
    self.img[52] = PhotoImage(file = 'back.pgm')
  34.  
     
  35.  
    self.scorelist = []
  36.  
    self.cards = []
  37.  
    self.gamemode = 0
  38.  
    self.speed = 100
  39.  
    self.wait = self.speed
  40.  
    self.isChanging = False
  41.  
    self.iswait = False
  42.  
    #绘制名字
  43.  
    for i in range(4):
  44.  
    self.c.create_text(self.handXY[i][0] self.nameXY[i][0],
  45.  
    self.handXY[i][1] self.nameXY[i][1],
  46.  
    fill = 'white',text = self.name[i],
  47.  
    anchor = self.nameXY[i][2],
  48.  
    font = Font(size=15,weight="bold"))
  49.  
    #创建手牌
  50.  
    self.l = 52 * ['']
  51.  
    for i in range(52):
  52.  
    self.l[i] = Label(self.master,image=self.img[52],bd = -1)
  53.  
    for i in range(13):
  54.  
    self.l[i]['text'] = str(i)
  55.  
    self.l[i].bind("<Button-1>",self.cardEvent)
  56.  
    #创建中央牌
  57.  
    self.ml = 4 * ['']
  58.  
    for i in range(4):
  59.  
    self.ml[i] = Label(self.master,image=self.img[52],bd = -1)
  60.  
     
  61.  
    self.b = Button(self.master,width=15,command=self.buttonEvent)
  62.  
    #一轮游戏开始
  63.  
    self.oneGameStart()
  64.  
    def oneGameStart(self):
  65.  
    #创建Onegame对象,用来获取出牌信息
  66.  
    self.onegame = OneGame()
  67.  
    #获取玩家手牌,显示
  68.  
    hand = self.onegame.getPlayerHand(0)
  69.  
    for i in range(13):
  70.  
    self.l[i]['image'] = self.img[hand[i].id]
  71.  
    for i in range(4):
  72.  
    for j in range(13):
  73.  
    self.moveCard(i,j,0)
  74.  
    #游戏模式为0,1,2时进入换牌阶段
  75.  
    if self.gamemode != 3:
  76.  
    self.changeHands()
  77.  
    else:
  78.  
    self.onegame.changeCards([],3)
  79.  
    self.isChanging = False
  80.  
    self.leftCards = 13
  81.  
    #进入出牌阶段,玩家前的电脑出牌
  82.  
    self.playpreCards()
  83.  
    def changeHands(self):
  84.  
    #换牌阶段相应初始化
  85.  
    self.select = []#所选的牌
  86.  
    self.isChanging = True
  87.  
    self.isOK = False
  88.  
    s = [1,3,2]
  89.  
    self.status['text'] = ' 请选三张牌传给' self.name[s[self.gamemode]] '。'
  90.  
    #提示按钮显示
  91.  
    self.b['text'] = self.gamemodetext[self.gamemode]
  92.  
    self.b.place(x = 460,y = 400)
  93.  
    self.b['state'] = DISABLED
  94.  
    def cardEvent(self,event):
  95.  
    #牌的事件
  96.  
    #获取牌的位置
  97.  
    i = int(event.widget['text'])
  98.  
    if not self.isChanging:
  99.  
    #出牌阶段的牌事件
  100.  
    #等待中不出牌
  101.  
    if self.iswait:
  102.  
    return
  103.  
    #出不了的牌不出
  104.  
    if not self.onegame.available(i):
  105.  
    self.status['text'] = self.onegame.errorString
  106.  
    return
  107.  
    self.onegame.playCard(i)
  108.  
    #所出牌显示到中央
  109.  
    event.widget.place_forget()
  110.  
    self.ml[self.turn]['image'] = event.widget['image']
  111.  
    self.ml[self.turn].place(x = self.middleXY[0][0],y = self.middleXY[0][1])
  112.  
    self.turn = 1
  113.  
    self.leftCards -= 1
  114.  
    #玩家后的电脑出牌
  115.  
    self.iswait = True
  116.  
    self.playlaterCards()
  117.  
    self.status['text'] = ' 正在等候……'
  118.  
    self.wait = 500 5 * self.speed
  119.  
    #等待一段时间后,中央牌清空,玩家前的电脑出牌
  120.  
    self.master.after(self.wait,self.playpreCards)
  121.  
    self.wait = self.speed
  122.  
    else:
  123.  
    #换牌阶段的牌事件,弹起的落下,落下的弹起
  124.  
    if not self.isOK:
  125.  
    if i in self.select:
  126.  
    self.select.remove(i)
  127.  
    self.moveCard(0,i,0)
  128.  
    self.b['state'] = DISABLED
  129.  
    else:
  130.  
    if len(self.select) < 3:
  131.  
    self.select.append(i)
  132.  
    self.moveCard(0,i,1)
  133.  
    if len(self.select) == 3:
  134.  
    self.b['state'] = NORMAL
  135.  
    def buttonEvent(self):
  136.  
    #提示按钮事件
  137.  
    if not self.isOK:
  138.  
    #换牌前获取电脑换的牌进行交换
  139.  
    self.select = self.onegame.changeCards(self.select,self.gamemode)
  140.  
    hand = self.onegame.getPlayerHand(0)
  141.  
    for i in range(13):
  142.  
    self.l[i]['image'] = self.img[hand[i].id]
  143.  
    self.moveCard(0,i,0)
  144.  
    for i in self.select:
  145.  
    self.moveCard(0,i,1)
  146.  
    self.status['text'] = ' 请按"确定"接受传来的牌。'
  147.  
    self.b['text'] = '确定'
  148.  
    self.isOK = True
  149.  
    else:
  150.  
    #换牌后进行确认,进入出牌阶段,玩家前的电脑出牌
  151.  
    for i in self.select:
  152.  
    self.moveCard(0,i,0)
  153.  
    self.b.place_forget()
  154.  
    self.isChanging = False
  155.  
    self.leftCards = 13
  156.  
    self.playpreCards()
  157.  
    def playpreCards(self):
  158.  
    if self.leftCards == 0:
  159.  
    #牌出完了进行统分,显示得分对话框
  160.  
    for i in range(4):
  161.  
    hand = self.onegame.p[i].scoreHand
  162.  
    for j in range(len(hand)):
  163.  
    self.l[i*13 j]['image'] = self.img[hand[j].id]
  164.  
    self.moveCard(i,j,0)
  165.  
    score = self.onegame.getScore()
  166.  
    self.scorelist.append(score)
  167.  
    if len(self.scorelist) != 1:
  168.  
    for i in range(4):
  169.  
    self.scorelist[-1][i] = self.scorelist[-2][i]
  170.  
    self.status['text'] = ' 得分'
  171.  
    scoredialog = self.showScoreDialog()
  172.  
    #得分确认后初始化,开始新一轮游戏
  173.  
    if scoredialog.isover:
  174.  
    self.scorelist = []
  175.  
    self.gamemode = 0
  176.  
    else:
  177.  
    self.gamemode = (self.gamemode 1) % 4
  178.  
    for i in range(52):
  179.  
    self.l[i].place_forget()
  180.  
    self.l[i]['image'] = self.img[52]
  181.  
    for i in range(4):
  182.  
    self.ml[i].place_forget()
  183.  
    self.oneGameStart()
  184.  
    else:
  185.  
    #获取玩家之前的电脑出牌,进行显示
  186.  
    for i in range(4):
  187.  
    self.ml[i].place_forget()
  188.  
    self.turn = 0
  189.  
    preCards = self.onegame.preCard
  190.  
    if len(preCards) == 0:
  191.  
    self.end()
  192.  
    else:
  193.  
    for i in range(len(preCards)):
  194.  
    p,j = preCards[i][0],preCards[i][1]
  195.  
    self.cards.append([self.turn,p,j])
  196.  
    self.master.after(self.wait,self.showMiddleCard)
  197.  
    if p == 3:
  198.  
    self.master.after(self.wait,self.end)
  199.  
    self.wait = self.speed
  200.  
    else:
  201.  
    self.wait = self.speed
  202.  
    self.turn = 1
  203.  
    def playlaterCards(self):
  204.  
    #获取玩家之后的电脑出牌,进行显示
  205.  
    laterCards = self.onegame.laterCard
  206.  
    for i in range(len(laterCards)):
  207.  
    p,j = laterCards[i][0],laterCards[i][1]
  208.  
    self.cards.append([self.turn,p,j])
  209.  
    self.master.after(self.wait,self.showMiddleCard)
  210.  
    self.wait = self.speed
  211.  
    self.turn = 1
  212.  
    def moveCard(self,i,j,state):#i,玩家;j,第几张牌;state,弹起还是放下
  213.  
    #牌的移动
  214.  
    self.l[i*13 j].place_forget()
  215.  
    x0 = self.handXY[i][0] self.handXY[i][2]*j*20
  216.  
    y0 = self.handXY[i][1] self.handXY[i][3]*j*20
  217.  
    self.l[i*13 j].place(x = x0,y = y0 - state * 20)
  218.  
    def newGame(self):
  219.  
    #新游戏
  220.  
    self.scorelist = []
  221.  
    self.gamemode = 0
  222.  
    for i in range(52):
  223.  
    self.l[i].place_forget()
  224.  
    self.l[i]['image'] = self.img[52]
  225.  
    for i in range(4):
  226.  
    self.ml[i].place_forget()
  227.  
    self.oneGameStart()
  228.  
    def showScoreDialog(self):
  229.  
    #显示分数对话框
  230.  
    scoredialog = ScoreDialog(self.master,self.scorelist,self.name)
  231.  
    return scoredialog
  232.  
    def showMiddleCard(self):
  233.  
    #中央牌显示
  234.  
    i = self.cards[0][0]
  235.  
    p = self.cards[0][1]
  236.  
    j = self.cards[0][2]
  237.  
    del self.cards[0]
  238.  
    self.l[p*13 j].place_forget()
  239.  
    hand = self.onegame.getPlayerHand(p)
  240.  
    self.ml[i]['image'] = self.img[hand[j].id]
  241.  
    self.ml[i].place(x = self.middleXY[p][0],
  242.  
    y = self.middleXY[p][1])
  243.  
    def end(self):
  244.  
    #电脑出完牌至玩家出牌的切换
  245.  
    self.iswait = False
  246.  
    self.status['text'] = ' 请出一张牌。'
  247.  
     
  248.  
    #游戏窗口创建,并建立游戏菜单项
  249.  
    class Game:
  250.  
    def __init__(self):
  251.  
    #建立根窗口,设置
  252.  
    self.root = Tk()
  253.  
    self.root.title("红心大战")
  254.  
    self.root.geometry(' 150 10')
  255.  
    self.root.resizable(False, False)
  256.  
    #播放背景音乐
  257.  
    self.s = winsound.PlaySound('m1.wav',
  258.  
    winsound.SND_ASYNC winsound.SND_LOOP)
  259.  
    #建立菜单
  260.  
    m = Menu(self.root)
  261.  
    self.root['menu'] = m
  262.  
    gamemenu = Menu(m)
  263.  
    helpmenu = Menu(m)
  264.  
    m.add_cascade(label = '游戏',menu = gamemenu)
  265.  
    m.add_cascade(label = '帮助',menu = helpmenu)
  266.  
    gamemenu.add_command(label="新游戏 F2",command = self.gameEvent1)
  267.  
    gamemenu.add_separator()
  268.  
    gamemenu.add_command(label="得分... F4",command = self.gameEvent2)
  269.  
    gamemenu.add_command(label="选项... F5",command = self.gameEvent4)
  270.  
    self.v = IntVar()
  271.  
    self.v.set(1)
  272.  
    gamemenu.add_checkbutton(label="背景音乐",variable = self.v,
  273.  
    command = self.gameEvent3)
  274.  
    gamemenu.add_separator()
  275.  
    gamemenu.add_command(label="退出",command = self.cancel)
  276.  
    helpmenu.add_command(label="规则介绍... F1",command = self.helpEvent1)
  277.  
    helpmenu.add_command(label="名言...",command = self.helpEvent2)
  278.  
     
  279.  
    self.root.bind('<F2>',self.gameEvent1)
  280.  
    self.root.bind('<F4>',self.gameEvent2)
  281.  
    self.root.bind('<F5>',self.gameEvent4)
  282.  
    self.root.bind('<F1>',self.helpEvent1)
  283.  
    self.root.protocol("WM_DELETE_WINDOW",self.cancel)
  284.  
    #导入背景图片
  285.  
    bgimg = PhotoImage(file = 'bg.gif')
  286.  
    #创建主界面
  287.  
    self.frame = GameFrame(self,bgimg)
  288.  
    #主循环
  289.  
    self.root.mainloop()
  290.  
    def gameEvent1(self,event=None):
  291.  
    #游戏菜单项”新游戏“
  292.  
    flag = askokcancel('新游戏','你确定要放弃当前游戏开始新游戏么?')
  293.  
    if flag:
  294.  
    self.frame.newGame()
  295.  
    def gameEvent2(self,event=None):
  296.  
    #游戏菜单项”得分“
  297.  
    self.frame.showScoreDialog()
  298.  
    def gameEvent3(self):
  299.  
    #游戏菜单项”背景音乐“
  300.  
    if self.v.get() == 0:
  301.  
    winsound.PlaySound(self.s,winsound.SND_PURGE)
  302.  
    else:
  303.  
    self.s = winsound.PlaySound('m1.wav',
  304.  
    winsound.SND_ASYNC winsound.SND_LOOP)
  305.  
    def gameEvent4(self,event=None):
  306.  
    #游戏菜单项”选项“
  307.  
    optionDialog = OptionDialog(self.root,self.frame.speed / 100 - 1)
  308.  
    if not optionDialog.isCancel:
  309.  
    self.frame.speed = 100 optionDialog.v.get() * 100
  310.  
    def helpEvent1(self,event=None):
  311.  
    #帮助菜单项”规则介绍“
  312.  
    HelpDialog(self.root)
  313.  
    def helpEvent2(self):
  314.  
    #帮助菜单项”名言“
  315.  
    SayDialog(self.root)
  316.  
    def cancel(self):
  317.  
    #关闭音乐,退出游戏
  318.  
    winsound.PlaySound(self.s,winsound.SND_PURGE)
  319.  
    self.root.destroy()
  320.  
     
  321.  
     
  322.  
    def main():
  323.  
    Game()
  324.  
     
  325.  
     
  326.  
    if __name__ == '__main__':
  327.  
    main()
学新通

学新通五、效果展示

1)游戏开始

学新通

2)游戏界面

学新通

3)左上角帮助菜单

学新通

4)游戏结束排名

学新通

总结

科技日新月异,台式“大砖头”转眼变成便携平板,当年偷偷“摸鱼”玩这些内置游戏的人

或成为职场新人,或为人父母,都开始了各自的新阶段,这些游戏也完成自己的使命!

少年时期的游戏你最喜欢哪一款?话说之前写过多期游戏了,需要源码的记得找我拿!

完整的素材、安装环境、源码等看文末即可啦!

🎉往期推荐阅读——

目1.0  超级玛丽

程序员自制游戏:超级玛丽100%真实版,能把你玩哭了~【附源码】

项目1.1   扫雷

 Pygame实战:据说这是史上最难扫雷游戏,没有之一,你们感受下......

项目1.2   魂斗罗

Pygame实战:多年后“魂斗罗”像素风归来 不止是经典与情怀@全体成员

项目1.3  太空机甲游戏

Pygame实战:牛,几千行代码实现《机甲闯关冒险游戏》,太牛了(保存起来慢慢学)

🎄文章汇总——

项目1.0 Python—2021 |已有文章汇总 | 持续更新,直接看这篇就够了

(更多内容 源码都在文章汇总哦!!欢迎阅读~)

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggcikb
系列文章
更多 icon
同类精品
更多 icon
继续加载