【转载】Pyqt 编写的俄罗斯方块

  1 #!/usr/bin/env python
  2 # -*- coding: utf-8 -*-
  3 from __future__ import print_function
  4 from __future__ import unicode_literals
  5 from __future__ import division
  6 from __future__ import absolute_import
  7 try:
  8     str = unicode
  9 except NameError:
 10     pass
 11
 12 import random, sys, sip
 13 try:
 14     sip.setapi("QString" ,2)
 15 except ValueError:
 16     pass
 17
 18 from PyQt4 import QtCore, QtGui
 19
 20
 21 NoShape, ZShape, SShape, LineShape, TShape, SquareShape, LShape, MirroredLShape = range(8)
 22
 23 random.seed(None)
 24
 25
 26 class TetrixWindow(QtGui.QWidget):
 27     def __init__(self, parent = None):
 28         QtGui.QWidget.__init__(self, parent, QtCore.Qt.Window)
 29
 30         self.board = TetrixBoard()
 31         self.indictor = TetrixIndictor()
 32
 33         nextPieceLabel = QtGui.QLabel(self)
 34         nextPieceLabel.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Raised)
 35         nextPieceLabel.setAlignment(QtCore.Qt.AlignCenter)
 36         self.board.setNextPieceLabel(nextPieceLabel)
 37
 38         scoreLcd = QtGui.QLCDNumber(6)
 39         scoreLcd.setSegmentStyle(QtGui.QLCDNumber.Filled)
 40         levelLcd = QtGui.QLCDNumber(2)
 41         levelLcd.setSegmentStyle(QtGui.QLCDNumber.Filled)
 42         linesLcd = QtGui.QLCDNumber(6)
 43         linesLcd.setSegmentStyle(QtGui.QLCDNumber.Filled)
 44
 45         startButton = QtGui.QPushButton(self.trUtf8("开始(&S)"))
 46         startButton.setFocusPolicy(QtCore.Qt.NoFocus)
 47         quitButton = QtGui.QPushButton(self.trUtf8("退出(&X)"))
 48         quitButton.setFocusPolicy(QtCore.Qt.NoFocus)
 49         pauseButton = QtGui.QPushButton(self.trUtf8("暂停(&P)"))
 50         pauseButton.setFocusPolicy(QtCore.Qt.NoFocus)
 51
 52         startButton.clicked.connect(self.board.start)
 53         pauseButton.clicked.connect(self.board.pause)
 54         quitButton.clicked.connect(self.close)
 55         self.board.scoreChanged.connect(scoreLcd.display)
 56         self.board.levelChanged.connect(levelLcd.display)
 57         self.board.linesRemovedChanged.connect(linesLcd.display)
 58         self.board.act.connect(self.indictor.showIndictor)
 59
 60         layout1 = QtGui.QHBoxLayout()
 61         layout3 = QtGui.QVBoxLayout()
 62         layout3.addWidget(self.board)
 63         layout3.addWidget(self.indictor)
 64         layout3.setSpacing(0)
 65         layout1.addLayout(layout3)
 66         layout2 = QtGui.QVBoxLayout()
 67         layout2.addWidget(self.createLabel(self.trUtf8("下一个方块")))
 68         layout2.addWidget(nextPieceLabel)
 69         layout2.addWidget(self.createLabel(self.trUtf8("级别")))
 70         layout2.addWidget(levelLcd)
 71         layout2.addWidget(self.createLabel(self.trUtf8("成绩")),)
 72         layout2.addWidget(scoreLcd)
 73         layout2.addWidget(self.createLabel(self.trUtf8("总共消去行数")))
 74         layout2.addWidget(linesLcd)
 75         layout2.addWidget(startButton)
 76         layout2.addWidget(quitButton)
 77         layout2.addWidget(pauseButton)
 78         layout1.addLayout(layout2)
 79         layout1.setStretch(0, 75)
 80         layout1.setStretch(1, 25)
 81         self.setLayout(layout1)
 82
 83         self.setWindowTitle(self.trUtf8("俄罗斯方块(Tetrix)"))
 84         self.resize(self.logicalDpiX() / 96 * 275, self.logicalDpiY() / 96 * 380)
 85
 86         r = self.geometry()
 87         r.moveCenter(QtGui.qApp.desktop().screenGeometry().center())
 88         self.setGeometry(r)
 89
 90     def createLabel(self, text):
 91         lbl = QtGui.QLabel(text)
 92         lbl.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignBottom)
 93         return lbl
 94
 95
 96 class TetrixIndictor(QtGui.QWidget):
 97     """位于主游戏区下方的一个扁小的控件,用于显示当前位置落下时的位置。
 98     现在主要的问题是游戏区的大小超出了人类的眼睛的焦点区。
 99     或许可以让整个游戏界面更小一些。"""
100
101     def __init__(self, parent = None):
102         QtGui.QWidget.__init__(self, parent)
103         self.begin = self.end = None
104         self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
105
106     def showIndictor(self, curX, piece):
107         self.begin = curX + piece.minX()
108         self.end = curX + piece.maxX()
109         self.update()
110
111     def paintEvent(self, event):
112         QtGui.QWidget.paintEvent(self, event)
113         if self.begin is None:
114             return
115         board = self.parent().board
116         pieceWidth = board.contentsRect().width() // TetrixBoard.BoardWidth
117         brush = QtGui.QBrush(QtCore.Qt.yellow)
118         painter = QtGui.QPainter(self)
119         painter.setBrush(brush)
120         painter.drawRect(board.contentsRect().left() + self.begin * pieceWidth, 0, 121                          (self.end - self.begin + 1) * pieceWidth, self.height() - 1 )
122
123     def sizeHint(self):
124         return QtCore.QSize(self.parent().board.width(), 8)
125
126
127 class TetrixBoard(QtGui.QFrame):
128     BoardWidth = 11
129     BoardHeight = 22
130
131     scoreChanged = QtCore.pyqtSignal(int)
132     levelChanged = QtCore.pyqtSignal(int)
133     linesRemovedChanged = QtCore.pyqtSignal(int)
134     act = QtCore.pyqtSignal(int, "PyQt_PyObject")
135
136     def __init__(self, parent = None):
137         super(TetrixBoard, self).__init__(parent)
138         self.setStyleSheet("background-color:black;border:2px solid darkGreen;")
139
140         self.timer = QtCore.QBasicTimer()
141         self.nextPieceLabel = None
142         self.isWaitingAfterLine = False
143         self.curPiece = TetrixPiece()
144         self.nextPiece = TetrixPiece()
145         self.curX = 0
146         self.curY = 0
147         self.numLinesRemoved = 0
148         self.numPiecesDropped = 0
149         self.score = 0
150         self.level = 0
151         self.board = None
152
153         #self.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Sunken)
154         self.setFrameStyle(QtGui.QFrame.Box)
155         self.setFocusPolicy(QtCore.Qt.StrongFocus)
156         self.isStarted = False
157         self.isPaused = False
158         self.clearBoard()
159
160         self.nextPiece.setRandomShape()
161
162     def focusOutEvent(self, event):
163         if self.isStarted and not self.isPaused:
164             self.pause()
165         QtGui.QFrame.focusOutEvent(self, event)
166
167     def shapeAt(self, x, y):
168         return self.board[(y * TetrixBoard.BoardWidth) + x]
169
170     def setShapeAt(self, x, y, shape):
171         self.board[(y * TetrixBoard.BoardWidth) + x] = shape
172
173     def timeoutTime(self):
174         return 1000 // (1 + self.level)
175
176     def squareWidth(self):
177         return self.contentsRect().width() // TetrixBoard.BoardWidth
178
179     def squareHeight(self):
180         return self.contentsRect().height() // TetrixBoard.BoardHeight
181
182     def setNextPieceLabel(self, label):
183         self.nextPieceLabel = label
184         #label.setScaledContents(True)
185         label.setMinimumSize(label.width(), label.width())
186
187     def sizeHint(self):
188         return QtCore.QSize(TetrixBoard.BoardWidth * 15 + self.frameWidth() * 2,
189                 TetrixBoard.BoardHeight * 15 + self.frameWidth() * 2)
190
191     def minimumSizeHint(self):
192         return QtCore.QSize(TetrixBoard.BoardWidth * 15 + self.frameWidth() * 2,
193                 TetrixBoard.BoardHeight * 15 + self.frameWidth() * 2)
194
195     def start(self):
196         if self.isPaused:
197             return
198
199         self.isStarted = True
200         self.isWaitingAfterLine = False
201         self.numLinesRemoved = 0
202         self.numPiecesDropped = 0
203         self.score = 0
204         self.level = 1
205         self.clearBoard()
206
207         self.linesRemovedChanged.emit(self.numLinesRemoved)
208         self.scoreChanged.emit(self.score)
209         self.levelChanged.emit(self.level)
210
211         self.newPiece()
212         self.timer.start(self.timeoutTime(), self)
213
214     def pause(self):
215         if not self.isStarted:
216             return
217
218         self.isPaused = not self.isPaused
219         if self.isPaused:
220             self.timer.stop()
221         else:
222             self.timer.start(self.timeoutTime(), self)
223
224         self.update()
225
226     def paintEvent(self, event):
227         super(TetrixBoard, self).paintEvent(event)
228
229         painter = QtGui.QPainter(self)
230         rect = self.contentsRect()
231
232         if self.isPaused:
233             painter.drawText(rect, QtCore.Qt.AlignCenter, self.trUtf8("暂停"))
234             return
235
236         boardTop = rect.bottom() - TetrixBoard.BoardHeight * self.squareHeight()
237
238         for i in range(TetrixBoard.BoardHeight):
239             for j in range(TetrixBoard.BoardWidth):
240                 shape = self.shapeAt(j, TetrixBoard.BoardHeight - i - 1)
241                 if shape != NoShape:
242                     self.drawSquare(painter,
243                             rect.left() + j * self.squareWidth(),
244                             boardTop + i * self.squareHeight(), shape)
245
246         if self.curPiece.shape() != NoShape:
247             for i in range(4):
248                 x = self.curX + self.curPiece.x(i)
249                 y = self.curY - self.curPiece.y(i)
250                 self.drawSquare(painter, rect.left() + x * self.squareWidth(),
251                         boardTop + (TetrixBoard.BoardHeight - y - 1) * self.squareHeight(),
252                         self.curPiece.shape())
253
254     def keyPressEvent(self, event):
255         if not self.isStarted or self.isPaused or self.curPiece.shape() == NoShape:
256             super(TetrixBoard, self).keyPressEvent(event)
257             return
258
259         key = event.key()
260         if key == QtCore.Qt.Key_Left:
261             self.tryMove(self.curPiece, self.curX - 1, self.curY)
262         elif key == QtCore.Qt.Key_Right:
263             self.tryMove(self.curPiece, self.curX + 1, self.curY)
264         elif key == QtCore.Qt.Key_Down:
265             self.tryMove(self.curPiece.rotatedRight(), self.curX, self.curY)
266         elif key == QtCore.Qt.Key_Up:
267             self.tryMove(self.curPiece.rotatedLeft(), self.curX, self.curY)
268         elif key == QtCore.Qt.Key_Space:
269             self.dropDown()
270         elif key == QtCore.Qt.Key_D:
271             self.oneLineDown()
272         else:
273             super(TetrixBoard, self).keyPressEvent(event)
274
275     def timerEvent(self, event):
276         if event.timerId() == self.timer.timerId():
277             if self.isWaitingAfterLine:
278                 self.isWaitingAfterLine = False
279                 self.newPiece()
280                 self.timer.start(self.timeoutTime(), self)
281             else:
282                 self.oneLineDown()
283         else:
284             super(TetrixBoard, self).timerEvent(event)
285
286     def clearBoard(self):
287         self.board = [NoShape for i in range(TetrixBoard.BoardHeight * TetrixBoard.BoardWidth)]
288
289     def dropDown(self):
290         dropHeight = 0
291         newY = self.curY
292         while newY > 0:
293             if not self.tryMove(self.curPiece, self.curX, newY - 1):
294                 break
295             newY -= 1
296             dropHeight += 1
297
298         self.pieceDropped(dropHeight)
299
300     def oneLineDown(self):
301         if not self.tryMove(self.curPiece, self.curX, self.curY - 1):
302             self.pieceDropped(0)
303
304     def pieceDropped(self, dropHeight):
305         for i in range(4):
306             x = self.curX + self.curPiece.x(i)
307             y = self.curY - self.curPiece.y(i)
308             self.setShapeAt(x, y, self.curPiece.shape())
309
310         self.numPiecesDropped += 1
311         if self.numPiecesDropped % 25 == 0:
312             self.level += 1
313             self.timer.start(self.timeoutTime(), self)
314             self.levelChanged.emit(self.level)
315
316         self.score += dropHeight + 7
317         self.scoreChanged.emit(self.score)
318         self.removeFullLines()
319
320         if not self.isWaitingAfterLine:
321             self.newPiece()
322
323     def removeFullLines(self):
324         numFullLines = 0
325
326         for i in range(TetrixBoard.BoardHeight - 1, -1, -1):
327             lineIsFull = True
328
329             for j in range(TetrixBoard.BoardWidth):
330                 if self.shapeAt(j, i) == NoShape:
331                     lineIsFull = False
332                     break
333
334             if lineIsFull:
335                 numFullLines += 1
336                 for k in range(i, TetrixBoard.BoardHeight - 1):
337                     for j in range(TetrixBoard.BoardWidth):
338                         self.setShapeAt(j, k, self.shapeAt(j, k + 1))
339
340                 for j in range(TetrixBoard.BoardWidth):
341                     self.setShapeAt(j, TetrixBoard.BoardHeight - 1, NoShape)
342
343         if numFullLines > 0:
344             self.numLinesRemoved += numFullLines
345             self.score += 10 * numFullLines
346             self.linesRemovedChanged.emit(self.numLinesRemoved)
347             self.scoreChanged.emit(self.score)
348
349             self.timer.start(200, self)
350             self.isWaitingAfterLine = True
351             self.curPiece.setShape(NoShape)
352             self.update()
353
354     def newPiece(self):
355         self.curPiece = self.nextPiece
356         self.nextPiece = TetrixPiece()
357         self.nextPiece.setRandomShape()
358         self.showNextPiece()
359         self.curX = TetrixBoard.BoardWidth // 2
360         self.curY = TetrixBoard.BoardHeight - 1 + self.curPiece.minY()
361         self.act.emit(self.curX, self.curPiece)
362
363         if not self.tryMove(self.curPiece, self.curX, self.curY):
364             self.curPiece.setShape(NoShape)
365             self.timer.stop()
366             self.isStarted = False
367
368     def showNextPiece(self):
369         if self.nextPieceLabel is None:
370             return
371
372         dx = self.nextPiece.maxX() - self.nextPiece.minX() + 1
373         dy = self.nextPiece.maxY() - self.nextPiece.minY() + 1
374
375         self.pixmapNextPiece = QtGui.QPixmap(dx * self.squareWidth(), dy * self.squareHeight())
376         painter = QtGui.QPainter(self.pixmapNextPiece)
377         painter.fillRect(self.pixmapNextPiece.rect(), self.nextPieceLabel.palette().background())
378
379         for i in range(4):
380             x = self.nextPiece.x(i) - self.nextPiece.minX()
381             y = self.nextPiece.y(i) - self.nextPiece.minY()
382             self.drawSquare(painter, x * self.squareWidth(),
383                     y * self.squareHeight(), self.nextPiece.shape())
384
385         self.nextPieceLabel.setPixmap(self.pixmapNextPiece)
386
387     def tryMove(self, newPiece, newX, newY):
388         for i in range(4):
389             x = newX + newPiece.x(i)
390             y = newY - newPiece.y(i)
391             if x < 0 or x >= TetrixBoard.BoardWidth or y < 0 or y >= TetrixBoard.BoardHeight:
392                 return False
393             if self.shapeAt(x, y) != NoShape:
394                 return False
395
396         self.curPiece = newPiece
397         self.curX = newX
398         self.curY = newY
399         self.update()
400         self.act.emit(self.curX, self.curPiece)
401         return True
402
403     def drawSquare(self, painter, x, y, shape):
404         colorTable = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC,
405                       0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00]
406
407         color = QtGui.QColor(colorTable[shape])
408         painter.fillRect(x + 1, y + 1, self.squareWidth() - 2,
409                 self.squareHeight() - 2, color)
410
411         painter.setPen(color.light())
412         painter.drawLine(x, y + self.squareHeight() - 1, x, y)
413         painter.drawLine(x, y, x + self.squareWidth() - 1, y)
414
415         painter.setPen(color.dark())
416         painter.drawLine(x + 1, y + self.squareHeight() - 1,
417                 x + self.squareWidth() - 1, y + self.squareHeight() - 1)
418         painter.drawLine(x + self.squareWidth() - 1,
419                 y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1)
420
421
422 class TetrixPiece(object):
423     coordsTable = (
424         ((0, 0),     (0, 0),     (0, 0),     (0, 0)),
425         ((0, -1),    (0, 0),     ( - 1, 0),    ( - 1, 1)),
426         ((0, -1),    (0, 0),     (1, 0),     (1, 1)),
427         ((0, -1),    (0, 0),     (0, 1),     (0, 2)),
428         (( - 1, 0),    (0, 0),     (1, 0),     (0, 1)),
429         ((0, 0),     (1, 0),     (0, 1),     (1, 1)),
430         (( - 1, -1),   (0, -1),    (0, 0),     (0, 1)),
431         ((1, -1),    (0, -1),    (0, 0),     (0, 1))
432     )
433
434     def __init__(self):
435         self.coords = [[0,0] for _ in range(4)]
436         self.pieceShape = NoShape
437
438         self.setShape(NoShape)
439
440     def shape(self):
441         return self.pieceShape
442
443     def setShape(self, shape):
444         table = TetrixPiece.coordsTable[shape]
445         for i in range(4):
446             for j in range(2):
447                 self.coords[i][j] = table[i][j]
448
449         self.pieceShape = shape
450
451     def setRandomShape(self):
452         self.setShape(random.randint(1, 7))
453
454     def x(self, index):
455         return self.coords[index][0]
456
457     def y(self, index):
458         return self.coords[index][1]
459
460     def setX(self, index, x):
461         self.coords[index][0] = x
462
463     def setY(self, index, y):
464         self.coords[index][1] = y
465
466     def minX(self):
467         m = self.coords[0][0]
468         for i in range(4):
469             m = min(m, self.coords[i][0])
470
471         return m
472
473     def maxX(self):
474         m = self.coords[0][0]
475         for i in range(4):
476             m = max(m, self.coords[i][0])
477
478         return m
479
480     def minY(self):
481         m = self.coords[0][1]
482         for i in range(4):
483             m = min(m, self.coords[i][1])
484
485         return m
486
487     def maxY(self):
488         m = self.coords[0][1]
489         for i in range(4):
490             m = max(m, self.coords[i][1])
491
492         return m
493
494     def rotatedLeft(self):
495         if self.pieceShape == SquareShape:
496             return self
497
498         result = TetrixPiece()
499         result.pieceShape = self.pieceShape
500         for i in range(4):
501             result.setX(i, self.y(i))
502             result.setY(i, -self.x(i))
503
504         return result
505
506     def rotatedRight(self):
507         if self.pieceShape == SquareShape:
508             return self
509
510         result = TetrixPiece()
511         result.pieceShape = self.pieceShape
512         for i in range(4):
513             result.setX(i, -self.y(i))
514             result.setY(i, self.x(i))
515
516         return result
517
518 if __name__ == ‘__main__‘:
519     app = QtGui.QApplication(sys.argv)
520     window = TetrixWindow()
521     window.show()
522     if hasattr(app, "exec"):
523         result = getattr(app, "exec")()
524     else:
525         result = getattr(app, "exec_")()
526     sys.exit(result)

时间: 2024-08-10 16:36:17

【转载】Pyqt 编写的俄罗斯方块的相关文章

javascript 60行编写的俄罗斯方块游戏

转自 http://www.zuidaima.com/share/1759652641295360.htm <!doctype html><html><head></head><body> <div id="box" style="width:252px;font:25px/25px 宋体;background:#000;color:#9f9;border:#999 20px ridge;text-shadow

转载:pyqt线程间通过 信号/槽 通信

转自:http://blog.sina.com.cn/s/blog_613d5bb701016qzv.html 信号(singal)与槽(slot)用于对象相互通信,信号:当某个对象的某个事件发生时,触发一个信号,槽:响应指定信号的所做的反应,其实信号槽类似于.NET里面的委托.事件,比如Repeater控件类,当行数据绑定后,触发一个ItemDataBound事件,不管使用者使用会监听该事件并做额外处理,其控件类内部都会触发该事件,这种机制很多程度提高了类的封装性和完整性. PyQt的窗体控件

[转载]自己编写 php 在线问卷调查程序

    <html> <head> <title>问卷调查</title> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <style type="text/css"> <!-- body { background-color: #330104; text-align: cent

JS编写的俄罗斯方块

IEEE Spectrum 杂志发布了一年一度的编程语言排行榜,这也是他们发布的第四届编程语言 Top 榜. 据介绍,IEEE Spectrum 的排序是来自 10 个重要线上数据源的综合,例如 Stack Overflow.Twitter.Reddit.IEEE Xplore.GitHub.CareerBuilder 等,对 48 种语言进行排行. 与其他排行榜不同的是,IEEE Spectrum 可以让读者自己选择参数组合时的权重,得到不同的排序结果.考虑到典型的 Spectrum 读者需求

程序员技术宅万圣节自制“南瓜俄罗斯方块”

南瓜灯是万圣节必备的东西,但如果把南瓜和经典视频游戏俄罗斯方块结合在一起,会产生什么新东西呢?Pumpktris(南瓜俄罗斯方块)!国外程序员技术宅 Nathan 童鞋就 DIY 了一个 Pumpktris,把做好的电路板放在南瓜中,南瓜柄当游戏控制器,完全可以打一把! Nathan 还把制作“南瓜俄罗斯方块”的过程制作成文,星密码货源网编译如下. 创意 写下所有疯狂.一闪而过的想法,这是我的习惯之一,然后回头再检查,而不是当时做判断,这样也不会把创意忘掉.在10月份初,我在回想去年的一个创意,

如何编写有效测试用例

转载 如何编写有效测试用例 测试用例,是一份关于具体测试步骤的文档,它描述了测试的输入参数.条件及配置.预期的输出结果等,以判断被测软件的工作是否正常. 设计.书写和执行测试案例是测试活动中重要的组成部分,测试案例通常由测试案例管理系统或工具进行管理. 一.编写测试用例的原则 测试用例的重要性是毋庸置疑的,它是软件测试全部过程的核心,是测试执行环节的基本依据.测试用例编写应该遵循的原则: 测试用例要达到最大覆盖软件系统的功能点. 测试用例对测试功能点.测试条件.测试步骤.输入值和预期结果应该有准

想开发iPhone App?来看看这个6个适合新手的项目吧

当你准备开始学习编程语言,你的选择很容易会向那些已经被很多人使用的大家伙们倾斜——比如 Java,C++,Javascript和Python.但除了这些之外,世界上还有很多其它的编程语言(包括一些奇怪的家伙),为什么不试着学习Swift来制作一些iPhone和iPad app呢?下面的6个项目将帮助你开始上手. 首先你需要了解一下Swift 如果你对Swift语言还不熟悉,没关系,它是苹果开发的一种编程语言,用于开发iOS和OS X 应用程序.它从其它很多编程语言身上汲取了优点,但与它最相像的还

Python代码样例列表

├─algorithm│       Python用户推荐系统曼哈顿算法实现.py│      NFA引擎,Python正则测试工具应用示例.py│      Python datetime计时程序的实现方法.py│      python du熊学斐波那契实现.py│      python lambda实现求素数的简短代码.py│      Python localtime()方法计算今天是一年中第几周.py│      Python math方法算24点代码详解.py│      Pyth

Objective-C——强引用、弱引用(Strong、Weak)

(转载) 编写Objective-C代码的很大一部分工作是管理可执行代码保持的对象引用,还有被引用对象保持的对另外一个对象的引用.在ARC出现之前,Objective-C在IOS中使用手动内存管理,在OS X中还可使用垃圾回收机制.这两个方法都有他们各自的优缺点.现在Objective-C使用ARC,其结合了这两种方法最好的一面. ARC,中文简称自动引用计数,是一种编译器机制,在编译期间编译器将手动内存管理的调用插入到代码中.这段内存管理代码通过判断一旦对象没有任何进来的强引用,它将被释放,如