• 自制2048小游戏(附源码)


    概述

      作者这几天去一趟湖南,这快车真“快”啊,跨越3个省需要接近一天时间。。。坐火车实在无聊就去玩2048,结果一遍一遍的手滑失误,导致心态爆炸。想了想干脆自己做个2048算了,顺便还可以写外挂上分!

    Python Code

    MainWindow:

      1 #!/usr/bin/python
      2 #  -*- coding:utf-8 -*-
      3 '''
      4 Created on Mar 24, 2017
      5 
      6 @author: zhengli
      7 '''
      8 
      9 import copy
     10 import numpy
     11 from PyQt5.QtCore import Qt
     12 from PyQt5.QtGui import (QIcon, QFont)
     13 from PyQt5.QtWidgets import (QAction,  QDesktopWidget, QGridLayout, QMainWindow, QMessageBox, QToolTip, QWidget)
     14 import GameCanvas
     15 
     16 
     17 class App(QMainWindow):
     18     """
     19     Main Window.
     20     """
     21 
     22     # noinspection PyArgumentList
     23     def __init__(self):
     24 
     25         QMainWindow.__init__(self)
     26 
     27         # noinspection PyCallByClass,PyTypeChecker
     28         QToolTip.setFont(QFont('SansSerif', 10))
     29         self.setGeometry(100, 100, 600, 600)
     30         self.frameGeometry().moveCenter(QDesktopWidget().availableGeometry().center())
     31         self.move(self.frameGeometry().topLeft())
     32         self.setWindowTitle('2048')
     33         self.setWindowIcon(QIcon('python.png'))
     34         self.setWindowFlags(Qt.WindowStaysOnTopHint)
     35 
     36         self.action = dict()
     37         self.actionLoad()
     38         self.menuBarLoad()
     39 
     40         self.data = dict()
     41         self.canvas = 0
     42         self.gameImage(4, 4)
     43 
     44         self.statusBar().showMessage('Ready')
     45 
     46         self.show()
     47 
     48     def actionLoad(self):
     49         """
     50         set MainData.action
     51         """
     52         self.action["4X4"] = QAction('4X4', self)
     53         self.action["4X4"].setShortcut('Ctrl+4')
     54         self.action["4X4"].setStatusTip('4X4 game')
     55         self.action["4X4"].triggered.connect(lambda: self.gameImage(4, 4))
     56 
     57         self.action["5X5"] = QAction('5X5', self)
     58         self.action["5X5"].setShortcut('Ctrl+5')
     59         self.action["5X5"].setStatusTip('5X5 game')
     60         self.action["5X5"].triggered.connect(lambda: self.gameImage(5, 5))
     61 
     62         self.action["6X6"] = QAction('6X6', self)
     63         self.action["6X6"].setShortcut('Ctrl+6')
     64         self.action["6X6"].setStatusTip('6X6 game')
     65         self.action["6X6"].triggered.connect(lambda: self.gameImage(6, 6))
     66 
     67     def menuBarLoad(self):
     68         """
     69         set MainWindow.menuBar
     70         """
     71         self.statusBar()
     72         menubar = self.menuBar()
     73 
     74         gameMenu = menubar.addMenu('&Game')
     75         gameMenu.addAction(self.action["4X4"])
     76         gameMenu.addAction(self.action["5X5"])
     77         gameMenu.addAction(self.action["6X6"])
     78 
     79     def gameImage(self, m, n):
     80         """
     81         image draw.
     82         """
     83         # noinspection PyBroadException
     84         try:
     85             data = self.data["%d_%d" % (m, n)]
     86             count = self.data["score_%d_%d" % (m, n)]
     87         except:
     88             self.data["%d_%d" % (m, n)] = numpy.zeros((m, n), dtype=int)
     89             data = self.data["%d_%d" % (m, n)]
     90             self.data["score_%d_%d" % (m, n)] = 0
     91             count = self.data["score_%d_%d" % (m, n)]
     92         self.statusBar().showMessage('Score: %d' % count)
     93 
     94         layout = QGridLayout()
     95         layout.setSpacing(10)
     96 
     97         widget = QWidget()
     98         self.canvas = GameCanvas.GameCanvas(data=data, count=count, parent=widget)
     99         self.canvas.fig.canvas.mpl_connect('button_press_event', self.button_press)
    100         self.canvas.fig.canvas.mpl_connect('button_release_event', self.button_release)
    101 
    102         layout.addWidget(self.canvas)
    103         widget.setLayout(layout)
    104         self.setCentralWidget(widget)
    105 
    106     def button_press(self, event):
    107         """
    108         Get coordinates
    109         """
    110         self.canvas.event_x = event.x
    111         self.canvas.event_y = event.y
    112 
    113     # noinspection PyUnresolvedReferences
    114     def button_release(self, event):
    115         """
    116         :param event:
    117         :return:
    118         """
    119         data_backup = copy.deepcopy(self.canvas.data)
    120         if abs(self.canvas.event_x - event.x) > abs(self.canvas.event_y - event.y):
    121             if event.x > self.canvas.event_x:
    122                 self.canvas.right_operation(data_backup=data_backup)
    123             else:
    124                 self.canvas.left_operation(data_backup=data_backup)
    125         else:
    126             if event.y > self.canvas.event_y:
    127                 self.canvas.up_operation(data_backup=data_backup)
    128             else:
    129                 self.canvas.down_operation(data_backup=data_backup)
    130 
    131         self.canvas.fig.clf()
    132         self.canvas.axes = self.canvas.fig.add_axes([0, 0, 1, 1], frameon=False)
    133         self.canvas.complete_draw()
    134         self.canvas.fig.canvas.draw()
    135 
    136         self.data["score_%d_%d" % (self.canvas.m, self.canvas.n)] = self.canvas.count
    137         self.statusBar().showMessage('Score: %d' % self.canvas.count)
    138 
    139     # noinspection PyUnresolvedReferences
    140     def keyPressEvent(self, event):
    141         """
    142         :param event:
    143         :return:
    144         """
    145         data_backup = copy.deepcopy(self.canvas.data)
    146         if event.key() == Qt.Key_Right:
    147             self.canvas.right_operation(data_backup=data_backup)
    148         elif event.key() == Qt.Key_Left:
    149             self.canvas.left_operation(data_backup=data_backup)
    150         elif event.key() == Qt.Key_Up:
    151             self.canvas.up_operation(data_backup=data_backup)
    152         elif event.key() == Qt.Key_Down:
    153             self.canvas.down_operation(data_backup=data_backup)
    154         elif event.key() == Qt.Key_Escape:
    155             self.canvas.data *= 0
    156             self.canvas.count = 0
    157         elif event.key() == Qt.Key_Delete:
    158             print("yes ")
    159 
    160         self.canvas.fig.clf()
    161         self.canvas.axes = self.canvas.fig.add_axes([0, 0, 1, 1], frameon=False)
    162         self.canvas.complete_draw()
    163         self.canvas.fig.canvas.draw()
    164 
    165         self.data["score_%d_%d" % (self.canvas.m, self.canvas.n)] = self.canvas.count
    166         self.statusBar().showMessage('Score: %d' % self.canvas.count)
    167 
    168     def closeEvent(self, event):
    169         """
    170         exit game.
    171         """
    172         # noinspection PyCallByClass,PyTypeChecker
    173         reply = QMessageBox.question(self, 'Message', "Are you sure to quit?",
    174                                      QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
    175         if reply == QMessageBox.Yes:
    176             event.accept()
    177         else:
    178             event.ignore()
    MainWindow

    GameImage:

      1 #!/usr/bin/python
      2 #  -*- coding:utf-8 -*-
      3 '''
      4 Created on Mar 24, 2017
      5 
      6 @author: zhengli
      7 '''
      8 
      9 import copy
     10 import random
     11 import numpy
     12 from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
     13 from matplotlib.figure import Figure
     14 from matplotlib import collections
     15 
     16 
     17 class GameCanvas(FigureCanvasQTAgg):
     18     """
     19      basic data
     20     """
     21 
     22     def __init__(self, data=None, count=0, parent=None, width=5, height=4, dpi=100):
     23 
     24         self.data = data
     25         self.count = count
     26         self.m = len(data)
     27         self.n = len(data[0])
     28 
     29         self.event_x = 0
     30         self.event_y = 0
     31 
     32         self.fig = Figure(figsize=(width, height), dpi=dpi)
     33         self.axes = self.fig.add_axes([0, 0, 1, 1], frameon=False)
     34         self.complete_draw()
     35 
     36         FigureCanvasQTAgg.__init__(self, self.fig)
     37         self.setParent(parent)
     38 
     39     def complete_draw(self):
     40         """
     41         :return:
     42         """
     43         shape = numpy.array([[0.05, 0.05], [0.05, 0.95], [0.95, 0.95], [0.95, 0.05]])
     44         for i in range(self.m):
     45             for j in range(self.n):
     46                 rectangle = copy.deepcopy(shape)
     47                 rectangle[:, 0] += j
     48                 rectangle[:, 1] += self.m - i
     49                 if 0.1 * numpy.log2(max(2, 2 * self.data[i][j])) < 1:
     50                     alpha = 0.1 * numpy.log2(max(2, 2 * self.data[i][j]))
     51                 else:
     52                     alpha = 1
     53                 patch = collections.PolyCollection([rectangle], alpha=alpha)
     54                 self.axes.add_collection(patch)
     55                 if self.data[i][j] != 0:
     56                     self.axes.text(j + 0.5, self.m - i + 0.5, s=str(self.data[i][j]), color='white', fontsize=45,
     57                                    horizontalalignment='center', verticalalignment='center')
     58         self.axes.autoscale()
     59 
     60     def right_operation(self, data_backup):
     61         """
     62         :param data_backup:
     63         :return:
     64         """
     65         for i in range(self.m):
     66             index, = numpy.where(self.data[i, :] != 0)
     67             if len(index) != 0:
     68                 values = self.data[i, index]
     69                 if len(index) > 1:
     70                     j = len(values) - 1
     71                     while j != 0:
     72                         if values[j] == values[j - 1]:
     73                             self.count += values[j - 1]
     74                             values[j - 1] *= 2
     75                             values = numpy.hstack((values[:j], values[(j + 1):]))
     76                             break
     77                         else:
     78                             j -= 1
     79                 self.data[i, :] *= 0
     80                 for j in range(len(values)):
     81                     self.data[i][-j - 1] = values[-j - 1]
     82         if self.data.min() * (self.data - data_backup).min() == 0:
     83             index, = numpy.where(self.data[:, 0] == 0)
     84             if len(index) != 0:
     85                 i = index[random.randint(1, len(index)) - 1]
     86                 self.data[i][0] = random.randint(1, 2)
     87 
     88     def left_operation(self, data_backup):
     89         """
     90         :param data_backup:
     91         :return:
     92         """
     93         for i in range(self.m):
     94             index, = numpy.where(self.data[i, :] != 0)
     95             if len(index) != 0:
     96                 values = self.data[i, index]
     97                 if len(index) > 1:
     98                     j = 0
     99                     while j != len(values) - 1:
    100                         if values[j] == values[j + 1]:
    101                             self.count += values[j + 1]
    102                             values[j + 1] *= 2
    103                             values = numpy.hstack((values[:j], values[(j + 1):]))
    104                             break
    105                         else:
    106                             j += 1
    107                 self.data[i, :] *= 0
    108                 for j in range(len(values)):
    109                     self.data[i][j] = values[j]
    110         if self.data.min() * (self.data - data_backup).min() == 0:
    111             index, = numpy.where(self.data[:, -1] == 0)
    112             if len(index) != 0:
    113                 i = index[random.randint(1, len(index)) - 1]
    114                 self.data[i][-1] = random.randint(1, 2)
    115 
    116     def up_operation(self, data_backup):
    117         """
    118         :param data_backup:
    119         :return:
    120         """
    121         for j in range(self.n):
    122             index, = numpy.where(self.data[:, j] != 0)
    123             if len(index) != 0:
    124                 values = self.data[index, j]
    125                 if len(index) > 1:
    126                     i = 0
    127                     while i != len(values) - 1:
    128                         if values[i] == values[i + 1]:
    129                             self.count += values[i + 1]
    130                             values[i + 1] *= 2
    131                             values = numpy.hstack((values[:i], values[(i + 1):]))
    132                             break
    133                         else:
    134                             i += 1
    135                 self.data[:, j] *= 0
    136                 for i in range(len(values)):
    137                     self.data[i][j] = values[i]
    138         if self.data.min() * (self.data - data_backup).min() == 0:
    139             index, = numpy.where(self.data[-1, :] == 0)
    140             if len(index) != 0:
    141                 j = index[random.randint(1, len(index)) - 1]
    142                 self.data[-1][j] = random.randint(1, 2)
    143 
    144     def down_operation(self, data_backup):
    145         """
    146         :param data_backup:
    147         :return:
    148         """
    149         for j in range(self.n):
    150             index, = numpy.where(self.data[:, j] != 0)
    151             if len(index) != 0:
    152                 values = self.data[index, j]
    153                 if len(index) > 1:
    154                     i = len(values) - 1
    155                     while i != 0:
    156                         if values[i] == values[i - 1]:
    157                             self.count += values[i - 1]
    158                             values[i - 1] *= 2
    159                             values = numpy.hstack((values[:i], values[(i + 1):]))
    160                             break
    161                         else:
    162                             i -= 1
    163                 self.data[:, j] *= 0
    164                 for i in range(len(values)):
    165                     self.data[-i - 1][j] = values[-i - 1]
    166         if self.data.min() * (self.data - data_backup).min() == 0:
    167             index, = numpy.where(self.data[0, :] == 0)
    168             if len(index) != 0:
    169                 j = index[random.randint(1, len(index)) - 1]
    170                 self.data[0][j] = random.randint(1, 2)
    GameCanvas

    Start:

     1 #!/usr/bin/python
     2 #  -*- coding:utf-8 -*-
     3 '''
     4 Created on Mar 24, 2017
     5 
     6 @author: zhengli
     7 '''
     8 
     9 import MainWindow
    10 import sys
    11 from PyQt5.QtWidgets import QApplication
    12 
    13 if __name__ == '__main__':
    14     app = QApplication(sys.argv)
    15     ex = MainWindow.App()
    16     sys.exit(app.exec_())
    Start

    Demo

    鼠标操作:

    键盘操作:

    声明

    本文由Hamilton算符”原创,未经博主允许不得转载!

  • 相关阅读:
    Grovvy初识
    在eclipse中安装插件
    解决 APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tas
    Axis2 webservice入门--Webservice的发布与调用
    一步一步教你自定义博客园(cnblog)界面
    Enum枚举
    并行与并发
    多线程join(加入)
    守护线程
    停止线程
  • 原文地址:https://www.cnblogs.com/Hamilton-Operator/p/6617229.html
Copyright © 2020-2023  润新知