1. 程式人生 > 其它 >20214316陳啟政《python程式設計》實驗四

20214316陳啟政《python程式設計》實驗四

課程:《Python程式設計》
班級:2143
姓名:陳啟政
學號:20214316
實驗教師:王志強
實驗日期:2022年5月28日
必修/選修:公選課

一.華為雲ECS伺服器的購買

此前在程式設計基礎課程上購買過華為雲伺服器,因此在相同配置基礎上購買即可。

二.程式原始碼

import pygame
import random
import os

pygame.init()

GRID_WIDTH = 20
GRID_NUM_WIDTH = 15
GRID_NUM_HEIGHT = 25
WIDTH, HEIGHT = GRID_WIDTH * GRID_NUM_WIDTH, GRID_WIDTH * GRID_NUM_HEIGHT
SIDE_WIDTH 
= 200 SCREEN_WIDTH = WIDTH + SIDE_WIDTH WHITE = (0xff, 0xff, 0xff) BLACK = (0, 0, 0) LINE_COLOR = (0x33, 0x33, 0x33) CUBE_COLORS = [ (0xcc, 0x99, 0x99), (0xff, 0xff, 0x99), (0x66, 0x66, 0x99), (0x99, 0x00, 0x66), (0xff, 0xcc, 0x00), (0xcc, 0x00, 0x33), (0xff, 0x00, 0x33), (0x00, 0x66, 0x99), (0xff, 0xff, 0x33), (0x99, 0x00, 0x33), (0xcc, 0xff, 0x66), (0xff, 0x99, 0x00) ] screen
= pygame.display.set_mode((SCREEN_WIDTH, HEIGHT)) pygame.display.set_caption("俄羅斯方塊") clock = pygame.time.Clock() FPS = 30 score = 0 level = 1 screen_color_matrix = [[None] * GRID_NUM_WIDTH for i in range(GRID_NUM_HEIGHT)] # 設定遊戲的根目錄為當前資料夾 base_folder = os.path.dirname(__file__) def show_text(surf, text, size, x, y, color=WHITE): font_name
= os.path.join(base_folder, 'C:/font/Menlo.ttc') font = pygame.font.Font(font_name, size) text_surface = font.render(text, True, color) text_rect = text_surface.get_rect() text_rect.midtop = (x, y) surf.blit(text_surface, text_rect) class CubeShape(object): SHAPES = ['I', 'J', 'L', 'O', 'S', 'T', 'Z'] I = [[(0, -1), (0, 0), (0, 1), (0, 2)], [(-1, 0), (0, 0), (1, 0), (2, 0)]] J = [[(-2, 0), (-1, 0), (0, 0), (0, -1)], [(-1, 0), (0, 0), (0, 1), (0, 2)], [(0, 1), (0, 0), (1, 0), (2, 0)], [(0, -2), (0, -1), (0, 0), (1, 0)]] L = [[(-2, 0), (-1, 0), (0, 0), (0, 1)], [(1, 0), (0, 0), (0, 1), (0, 2)], [(0, -1), (0, 0), (1, 0), (2, 0)], [(0, -2), (0, -1), (0, 0), (-1, 0)]] O = [[(0, 0), (0, 1), (1, 0), (1, 1)]] S = [[(-1, 0), (0, 0), (0, 1), (1, 1)], [(1, -1), (1, 0), (0, 0), (0, 1)]] T = [[(0, -1), (0, 0), (0, 1), (-1, 0)], [(-1, 0), (0, 0), (1, 0), (0, 1)], [(0, -1), (0, 0), (0, 1), (1, 0)], [(-1, 0), (0, 0), (1, 0), (0, -1)]] Z = [[(0, -1), (0, 0), (1, 0), (1, 1)], [(-1, 0), (0, 0), (0, -1), (1, -1)]] SHAPES_WITH_DIR = { 'I': I, 'J': J, 'L': L, 'O': O, 'S': S, 'T': T, 'Z': Z } def __init__(self): self.shape = self.SHAPES[random.randint(0, len(self.SHAPES) - 1)] # 骨牌所在的行列 self.center = (2, GRID_NUM_WIDTH // 2) self.dir = random.randint(0, len(self.SHAPES_WITH_DIR[self.shape]) - 1) self.color = CUBE_COLORS[random.randint(0, len(CUBE_COLORS) - 1)] def get_all_gridpos(self, center=None): curr_shape = self.SHAPES_WITH_DIR[self.shape][self.dir] if center is None: center = [self.center[0], self.center[1]] return [(cube[0] + center[0], cube[1] + center[1]) for cube in curr_shape] def conflict(self, center): for cube in self.get_all_gridpos(center): # 超出螢幕之外,說明不合法 if cube[0] < 0 or cube[1] < 0 or cube[0] >= GRID_NUM_HEIGHT or \ cube[1] >= GRID_NUM_WIDTH: return True # 不為None,說明之前已經有小方塊存在了,也不合法 if screen_color_matrix[cube[0]][cube[1]] is not None: return True return False def rotate(self): new_dir = self.dir + 1 new_dir %= len(self.SHAPES_WITH_DIR[self.shape]) old_dir = self.dir self.dir = new_dir if self.conflict(self.center): self.dir = old_dir return False def down(self): # import pdb; pdb.set_trace() center = (self.center[0] + 1, self.center[1]) if self.conflict(center): return False self.center = center return True def left(self): center = (self.center[0], self.center[1] - 1) if self.conflict(center): return False self.center = center return True def right(self): center = (self.center[0], self.center[1] + 1) if self.conflict(center): return False self.center = center return True def draw(self): for cube in self.get_all_gridpos(): pygame.draw.rect(screen, self.color, (cube[1] * GRID_WIDTH, cube[0] * GRID_WIDTH, GRID_WIDTH, GRID_WIDTH)) pygame.draw.rect(screen, WHITE, (cube[1] * GRID_WIDTH, cube[0] * GRID_WIDTH, GRID_WIDTH, GRID_WIDTH), 1) def draw_grids(): for i in range(GRID_NUM_WIDTH): pygame.draw.line(screen, LINE_COLOR, (i * GRID_WIDTH, 0), (i * GRID_WIDTH, HEIGHT)) for i in range(GRID_NUM_HEIGHT): pygame.draw.line(screen, LINE_COLOR, (0, i * GRID_WIDTH), (WIDTH, i * GRID_WIDTH)) pygame.draw.line(screen, WHITE, (GRID_WIDTH * GRID_NUM_WIDTH, 0), (GRID_WIDTH * GRID_NUM_WIDTH, GRID_WIDTH * GRID_NUM_HEIGHT)) def draw_matrix(): for i, row in zip(range(GRID_NUM_HEIGHT), screen_color_matrix): for j, color in zip(range(GRID_NUM_WIDTH), row): if color is not None: pygame.draw.rect(screen, color, (j * GRID_WIDTH, i * GRID_WIDTH, GRID_WIDTH, GRID_WIDTH)) pygame.draw.rect(screen, WHITE, (j * GRID_WIDTH, i * GRID_WIDTH, GRID_WIDTH, GRID_WIDTH), 2) def draw_score(): show_text(screen, u'得分:{}'.format(score), 20, WIDTH + SIDE_WIDTH // 2, 100) def remove_full_line(): global screen_color_matrix global score global level new_matrix = [[None] * GRID_NUM_WIDTH for i in range(GRID_NUM_HEIGHT)] index = GRID_NUM_HEIGHT - 1 n_full_line = 0 for i in range(GRID_NUM_HEIGHT - 1, -1, -1): is_full = True for j in range(GRID_NUM_WIDTH): if screen_color_matrix[i][j] is None: is_full = False continue if not is_full: new_matrix[index] = screen_color_matrix[i] index -= 1 else: n_full_line += 1 score += n_full_line level = score // 20 + 1 screen_color_matrix = new_matrix def show_welcome(screen): show_text(screen, u'俄羅斯方塊', 30, WIDTH / 2, HEIGHT / 2) show_text(screen, u'按任意鍵開始遊戲', 20, WIDTH / 2, HEIGHT / 2 + 50) running = True gameover = True counter = 0 live_cube = None while running: clock.tick(FPS) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: if gameover: gameover = False live_cube = CubeShape() break if event.key == pygame.K_LEFT: live_cube.left() elif event.key == pygame.K_RIGHT: live_cube.right() elif event.key == pygame.K_DOWN: live_cube.down() elif event.key == pygame.K_UP: live_cube.rotate() elif event.key == pygame.K_SPACE: while live_cube.down() == True: pass remove_full_line() # level 是為了方便遊戲的難度,level 越高 FPS // level 的值越小 # 這樣螢幕重新整理的就越快,難度就越大 if gameover is False and counter % (FPS // level) == 0: # down 表示下移骨牌,返回False表示下移不成功,可能超過了螢幕或者和之前固定的 # 小方塊衝突了 if live_cube.down() == False: for cube in live_cube.get_all_gridpos(): screen_color_matrix[cube[0]][cube[1]] = live_cube.color live_cube = CubeShape() if live_cube.conflict(live_cube.center): gameover = True score = 0 live_cube = None screen_color_matrix = [[None] * GRID_NUM_WIDTH for i in range(GRID_NUM_HEIGHT)] # 消除滿行 remove_full_line() counter += 1 # 更新螢幕 screen.fill(BLACK) draw_grids() draw_matrix() draw_score() if live_cube is not None: live_cube.draw() if gameover: show_welcome(screen) pygame.display.update()

三.程式在華為雲伺服器上執行截圖

首先下載Xshell,複製彈性公網IP地址建議一個會話,將輸入使用者名稱和密碼後開始使用。

新建資料夾test,在WinScp內將寫好的程式碼上傳至華為雲伺服器,輸入指令後程序開始執行。

四.程式執行視訊

 https://files-cdn.cnblogs.com/files/blogs/743275/python%E8%A7%86%E9%A2%91.rar

五.實驗中的問題

1.pygame的安裝:

在pycharm程式設計遊戲時,需要呼叫pygame庫。因此在首次程式設計時,程式因缺少pygame庫而報錯。

2.版本不相容問題

python3無法識別22.1版本以下的pip命令符,因此需要輸入命令符pip install -u --force-reinstall pip Collecting pip,從而讓系統可以識別21.1.2的命令符。

3.字型問題

因為電腦內缺少可使用的字型,因此需要在ttc內下載相應字型。我在ttc中隨便找了一個Menlo字型,讓程式可以正常執行。

4.視覺化問題

華為雲伺服器中缺少相應的庫,無法產生對應的視覺化視窗。而我最開始使用的PuTTY無法下載此庫,因此更換Xshell之後讓程式成功執行。

六.課程總結

       首先非常感謝王志強老師這一學期為我們的辛苦付出。俗話說“師傅領進門,修行靠個人。”斯言如是,課程中的教學知識和實際應用是兩回事,儘管在課程中能夠理解知識,但是當自己上手實踐時,才體會到不易。尤其是當代碼寫完之後,開始檢測時,出現了許多未曾注意到的的bug。這種情況是無法避免的,正如生活中遇到的挫折。想到這一點,也許再次面對程式的問題,抑或是生活的難題,都會以一種淡然的心態去面對。

       選擇python是因為此前在心底的一個想法,就是想要用程式語言編寫一個自己的遊戲。抱著這樣的心態,我選擇了python課程。12周的時光轉瞬即逝,對於一門課程來說實在是太短,但對於一種學習也已足夠。一本厚厚的python書還有很多知識尚未探索,倘若有時間,我也希望可以繼續嘗試。

       所以,在期末最後一次實驗的時候,我在一眾課題之中,選擇了“遊戲”。可惜的是我沒有什麼水平去製作大工程,只能製作一款俄羅斯方塊來滿足以下自己的好奇心。無論是開始學python還是編寫遊戲,初上手都是無比艱難的。但是當思緒開啟時,程式碼也隨之泉湧。每次當我不知如何是好時,我就會去CSDN,部落格園這些論壇搜尋相關資訊,向身邊的人尋求幫助。也正是因為他們,我的課程學習才能圓滿結束。

       最後,我希望在之後的路上,就算忘記了學過的知識,但我希望自己不要忘記,在python課程上學習的寶貴經歷。