در این بخش ادامه بازی خانه سازی را خواهیم داشت. در بخش بعدی این بازی را تمام می کنیم.
# let the piece fall if it is time to fall if time.time() - lastFallTime > fallFreq: # see if the piece has landed if not isValidPosition(board, fallingPiece, adjY=1): # falling piece has landed, set it on the board addToBoard(board, fallingPiece) score += removeCompleteLines(board) level, fallFreq = calculateLevelAndFallFreq(score) fallingPiece = None else: # piece did not land, just move the piece down fallingPiece['y'] += 1 lastFallTime = time.time()
نرخ سقوط طبیعی قطعه ای که به سمت پایین می آید در متغیر lastFallTime ذخیره می شود. اگر زمان کافی از زمان سقوط قطعه گذشته باشد، خطوط 279 تا 288 می توانند قطعه را بدهند. اگر شرط خط 279 درست باشد، یعنی آن قطعه فرود آمده و جای گیر شده است. فراخوانی addToBoard بخشی از ساختمان داده صفحه را ایجاد می کند (به این ترتیب قطعات بعدی می توانند روی آن فرود بیایند) و فراخوانی removeCompleteLines با پاک کردن تمام خطوط روی صفحه و پایین آمدن جعبه ها را کنترل می کند. تابع removeCompleteLines هم چنین تعداد خط های حذف شده را برمی گرداند.این عدد را به امتیاز اضافه می کنیم.
از آن جا که ممکن است امتیاز تغییر کرده باشد، با استفاده از تابع calculateLevelAndFallFreq سطح و فرکانس فعلی قطعات را محاسبه و به روز می کنیم و در آخر، متغیر FallPiece را روی None تنظیم کردیم تا نشان دهیم که قطعه بعدی باید به قطعه پایین رونده جدید تبدیل شود و برای قطعه بعدی جدید باید یک قطعه جدید تصادفی تولید شود. (این کار در خطوط 195 تا 199 در ابتدای حلقه بازی انجام می شود.) اگر قطعه فرود نیامده است، به سادگی موقعیت Y آن را به اندازه یک فضا (space) تنظیم می کنیم و lastFallTime را به زمان فعلی بازنشانی می کنیم (در خط 288).
# drawing everything on the screen DISPLAYSURF.fill(BGCOLOR) drawBoard(board) drawStatus(score, level) drawNextPiece(nextPiece) if fallingPiece != None: drawPiece(fallingPiece) pygame.display.update() FPSCLOCK.tick(FPS)
اکنون حلقه بازی باید وضعیت بازی را در صفحه نمایش بکشد. بیش تر کار کشیدن توسط توابع دیگر انجام می شود، بنابراین کد حلقه بازی فقط باید آن توابع را فراخوانی کند. سپس فراخوانی pygame.display.update باعث می شود صفحه بازی روی صفحه کامپیوتر نمایش داده شود، و فراخوانی متد tickیک درنگ جزئی ایجاد می کند تا بازی خیلی سریع اجرا نشود.
def makeTextObjs(text, font, color): surf = font.render(text, True, color) return surf, surf.get_rect()
تابع makeTextObjs میانبری برای ایجا متن ها است. با داشتن متن، شی Font و یک شی Color متد render را فراخوانی می کند و شی Surface و Rect را برای متن برمی گرداند.
def terminate(): pygame.quit() sys.exit()
متد terminate برای پایان دادن به بازی است.
def checkForKeyPress(): # Go through event queue looking for a KEYUP event. # Grab KEYDOWN events to remove them from the event queue. checkForQuit() for event in pygame.event.get([KEYDOWN, KEYUP]): if event.type == KEYDOWN: continue return event.key return None
تابع checkForKeyPress کاری تقریبا همانند کاری که در بازی Wormy انجام داد، را انجام می دهد. ابتدا checkForQuit را فراخوانی می کند تا رویداد های QUIT را مدیریت کند و در صورت وجود این رویداد، برنامه را پایان دهد. سپس همه رویدادهای KEYUP و KEYDOWN را از صف رویداد بیرون می کشد.این متد رویدادهای KEYDOWN را نادیده می گیردو فقط به رویداد های KEYUP اهمیت می دهد.اگر هیچ رویداد KEYUP در صف رویداد نباشد، آن گاه None را برمی گرداند.
def showTextScreen(text): # This function displays large text in the # center of the screen until a key is pressed. # Draw the text drop shadow titleSurf, titleRect = makeTextObjs(text, BIGFONT, TEXTSHADOWCOLOR) titleRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2)) DISPLAYSURF.blit(titleSurf, titleRect) # Draw the text titleSurf, titleRect = makeTextObjs(text, BIGFONT, TEXTCOLOR) titleRect.center = (int(WINDOWWIDTH / 2) - 3, int(WINDOWHEIGHT / 2) - 3) DISPLAYSURF.blit(titleSurf, titleRect)
به جای توابع جداگانه برای صفحه آغاز و صفحه game over، یک تابع به نام showTextScreen خواهیم داشت. تابع showTextScreen هر متنی را که برای پارامتر text بفرستیم رسم می کند. افزون بر این، متن " Press a key to play " را نمایش می دهد.توجه کنید که خطوط 328 تا 330 ابتدا متن را با رنگ سایه تیره تر می کشد، و سپس خطوط 333 تا 335 دوباره همان متن را می کشد،با 3 پیکسل آفست در سمت چپ و 3 پیکسل به سمت بالا. این کار سایه ایجاد می کند.showTextScreen برای صفحه شروع، صفحه game over و هم چنین برای صفحه pause استفاده خواهد شد. (صفحه pause پسان تر در این فصل توضیح داده شده است.)
while checkForKeyPress() == None: pygame.display.update() FPSCLOCK.tick()
می خواهیم متن تا زمانی که کاربر یک کلید را فشار دهد، روی صفحه بماند. این حلقه مرتبا pygame.display.update و FPSCLOCK.tick را فراخوانی تا زمانی که checkForKeyPress مقداری غیر از None را برگرداند. این اتفاق وقتی که کاربر یک کلید را فشار دهد می افتد.
def checkForQuit(): for event in pygame.event.get(QUIT): # get all the QUIT events terminate() # terminate if any QUIT events are present for event in pygame.event.get(KEYUP): # get all the KEYUP events if event.key == K_ESCAPE: terminate() # terminate if the KEYUP event was for the Esc key pygame.event.post(event) # put the other KEYUP event objects back
تابع checkForQuit را می توان برای رسیدگی به هر رویدادی که باعث خاتمه برنامه شود، فراخوانی کرد. در صورت وقوع رویدادQUIT در صف رویداد (این توسط خطوط 348 و 349 انجام می شود) یا در صورت فشار داده شدن کلید Esc این اتفاق می افتد. بازیکن باید بتواند هر وقت خواست کلید Esc را فشار دهد تا از برنامه خارج شود.از آن جا که فراخوانی pygame.event.get در خط 350 همه رویدادهای KEYUP (از جمله رویدادهایی را برای کلیدهای غیر از کلید Esc) بیرون می کشد، می خواهیم اگر این رویداد برای کلید Esc نباشد آن را دوباره با فراخوانی تابع pygame.event.post وارد صف رویداد کنیم.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.