pythonで小さなゲームを作成する方法、いくつかの非常にエキサイティングな記事を確認してください
タンクバトルをパイソンで実装しました
パイソンメイクタンクバトル
宇宙船戦争をPythonで実装しました
pythonは宇宙船戦争をします
pythonで2つの異なるスネークゲームを実装しました
200 スネークゲームを実現するためのラインパイソンコード
150 スネークゲームを実現するためのラインコード
pythonでminesweeperゲームを実装しました
Pythonはminesweeperゲームを実装しています
Gobangゲームをpythonで実装しました
Pythonはgomokuゲームを実装します
今日、私たちはpythonを使用して、若い頃にプレイしたTetrisゲームを実装しています。
特定のコードとファイルは私のGitHubアドレスから入手できます
最初のステップ-さまざまなブロックを構築する
import random
from collections import namedtuple
Point =namedtuple('Point','X Y')
Shape =namedtuple('Shape','X Y Width Height')
Block =namedtuple('Block','template start_pos end_pos name next')
# 正方形のデザインは、もともと4×4にしました。最長の長さと幅が4なので、回転させるときは、どのように回転させるかを考えずに、ある形状を別の形状に置き換えるだけです。
# 実際、この機能を実現するには、左上隅の座標を修正するだけで済みます。
# S字型の正方形
S_BLOCK =[Block(['.OO','OO.','...'],Point(0,0),Point(2,1),'S',1),Block(['O..','OO.','.O.'],Point(0,0),Point(1,2),'S',0)]
# Z字型の正方形
Z_BLOCK =[Block(['OO.','.OO','...'],Point(0,0),Point(2,1),'Z',1),Block(['.O.','OO.','O..'],Point(0,0),Point(1,2),'Z',0)]
# ブロックします
I_BLOCK =[Block(['.O..','.O..','.O..','.O..'],Point(1,0),Point(1,3),'I',1),Block(['....','....','OOOO','....'],Point(0,2),Point(3,2),'I',0)]
# O字型ボックス
O_BLOCK =[Block(['OO','OO'],Point(0,0),Point(1,1),'O',0)]
# Jスクエア
J_BLOCK =[Block(['O..','OOO','...'],Point(0,0),Point(2,1),'J',1),Block(['.OO','.O.','.O.'],Point(1,0),Point(2,2),'J',2),Block(['...','OOO','..O'],Point(0,1),Point(2,2),'J',3),Block(['.O.','.O.','OO.'],Point(0,0),Point(1,2),'J',0)]
# L字型ブロック
L_BLOCK =[Block(['..O','OOO','...'],Point(0,0),Point(2,1),'L',1),Block(['.O.','.O.','.OO'],Point(1,0),Point(2,2),'L',2),Block(['...','OOO','O..'],Point(0,1),Point(2,2),'L',3),Block(['OO.','.O.','.O.'],Point(0,0),Point(1,2),'L',0)]
# Tブロック
T_BLOCK =[Block(['.O.','OOO','...'],Point(0,0),Point(2,1),'T',1),Block(['.O.','.OO','.O.'],Point(1,0),Point(2,2),'T',2),Block(['...','OOO','.O.'],Point(0,1),Point(2,2),'T',3),Block(['.O.','OO.','.O.'],Point(0,0),Point(1,2),'T',0)]
BLOCKS ={'O': O_BLOCK,'I': I_BLOCK,'Z': Z_BLOCK,'T': T_BLOCK,'L': L_BLOCK,'S': S_BLOCK,'J': J_BLOCK}
def get_block():
block_name = random.choice('OIZTLSJ')
b = BLOCKS[block_name]
idx = random.randint(0,len(b)-1)return b[idx]
def get_next_block(block):
b = BLOCKS[block.name]return b[block.next]
2番目の部分-メイン関数を構築する
import sys
import time
import pygame
from pygame.locals import*import blocks
SIZE =30 #各小さな正方形のサイズ
BLOCK_HEIGHT =25 #ゲームエリアの高さ
BLOCK_WIDTH =10 #ゲームエリア幅
BORDER_WIDTH =4 #ゲームエリアの境界線の幅
BORDER_COLOR =(40,40,200) #ゲームエリアの境界線の色
SCREEN_WIDTH = SIZE *(BLOCK_WIDTH +5) #ゲーム画面の幅
SCREEN_HEIGHT = SIZE * BLOCK_HEIGHT #ゲーム画面の高さ
BG_COLOR =(40,40,60) #背景色
BLOCK_COLOR =(20,128,200) #
BLACK =(0,0,0)
RED =(200,30,30) #GAMEOVERフォントの色
def print_text(screen, font, x, y, text, fcolor=(255,255,255)):
imgText = font.render(text, True, fcolor)
screen.blit(imgText,(x, y))
def main():
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('テトリス')
font1 = pygame.font.SysFont('SimHei',24) #ブラックボディ24
font2 = pygame.font.Font(None,72) #GAMEOVERフォント
font_pos_x = BLOCK_WIDTH * SIZE + BORDER_WIDTH +10 #右側の情報表示領域のフォント位置のX座標
gameover_size = font2.size('GAME OVER')
font1_height =int(font1.size('スコア')[1])
cur_block = None #現在の落下ブロック
next_block = None #次の広場
cur_pos_x, cur_pos_y =0,0
game_area = None #ゲームエリア全体
game_over = True
start = False #開始するかどうか、いつ開始するか= True,game_over =Trueの場合、GAMEOVERが表示されます
score =0 #スコア
orispeed =0.5 #元の速度
speed = orispeed #現在の速度
pause = False #タイムアウト
last_drop_time = None #去年の秋の時間
last_press_time = None #最後のキー押下時間
def _dock():
nonlocal cur_block, next_block, game_area, cur_pos_x, cur_pos_y, game_over, score, speed
for _i inrange(cur_block.start_pos.Y, cur_block.end_pos.Y +1):for _j inrange(cur_block.start_pos.X, cur_block.end_pos.X +1):if cur_block.template[_i][_j]!='.':
game_area[cur_pos_y + _i][cur_pos_x + _j]='0'if cur_pos_y + cur_block.start_pos.Y <=0:
game_over = True
else:
# 計算の排除
remove_idxs =[]for _i inrange(cur_block.start_pos.Y, cur_block.end_pos.Y +1):ifall(_x =='0'for _x in game_area[cur_pos_y + _i]):
remove_idxs.append(cur_pos_y + _i)if remove_idxs:
# スコアを計算する
remove_count =len(remove_idxs)if remove_count ==1:
score +=100
elif remove_count ==2:
score +=300
elif remove_count ==3:
score +=700
elif remove_count ==4:
score +=1500
speed = orispeed -0.03*(score // 10000)
# 排除する
_ i = _j = remove_idxs[-1]while _i =0:while _j in remove_idxs:
_ j -=1if _j <0:
game_area[_i]=['.']* BLOCK_WIDTH
else:
game_area[_i]= game_area[_j]
_ i -=1
_ j -=1
cur_block = next_block
next_block = blocks.get_block()
cur_pos_x, cur_pos_y =(BLOCK_WIDTH - cur_block.end_pos.X -1)// 2, -1 - cur_block.end_pos.Y
def _judge(pos_x, pos_y, block):
nonlocal game_area
for _i inrange(block.start_pos.Y, block.end_pos.Y +1):if pos_y + block.end_pos.Y = BLOCK_HEIGHT:return False
for _j inrange(block.start_pos.X, block.end_pos.X +1):if pos_y + _i =0 and block.template[_i][_j]!='.' and game_area[pos_y + _i][pos_x + _j]!='.':return False
return True
while True:for event in pygame.event.get():if event.type == QUIT:
sys.exit()
elif event.type == KEYDOWN:if event.key == K_RETURN:if game_over:
start = True
game_over = False
score =0
last_drop_time = time.time()
last_press_time = time.time()
game_area =[['.']* BLOCK_WIDTH for _ inrange(BLOCK_HEIGHT)]
cur_block = blocks.get_block()
next_block = blocks.get_block()
cur_pos_x, cur_pos_y =(BLOCK_WIDTH - cur_block.end_pos.X -1)// 2, -1 - cur_block.end_pos.Y
elif event.key == K_SPACE:if not game_over:
pause = not pause
elif event.key in(K_w, K_UP):
# スピン
# 実際、私はあまりはっきりと覚えていません。
# .0.
# .00
# ..0
# 右端にあるときに回転できますか?インターネットでテトリスを試しましたが、回転できません。ここでは「回転できません」と表示します。
# シェイプをデザインするときに多くのブランクを作成したので、ブランク部分を含むシェイプ全体がゲーム領域にあることを指定するだけで、回転できます。
if0<= cur_pos_x <= BLOCK_WIDTH -len(cur_block.template[0]):
_ next_block = blocks.get_next_block(cur_block)if_judge(cur_pos_x, cur_pos_y, _next_block):
cur_block = _next_block
if event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:if not game_over and not pause:if time.time()- last_press_time 0.1:
last_press_time = time.time()if cur_pos_x - cur_block.start_pos.X:if_judge(cur_pos_x -1, cur_pos_y, cur_block):
cur_pos_x -=1if event.key == pygame.K_RIGHT:if not game_over and not pause:if time.time()- last_press_time 0.1:
last_press_time = time.time()
# 右の境界線を削除できません
if cur_pos_x + cur_block.end_pos.X +1< BLOCK_WIDTH:if_judge(cur_pos_x +1, cur_pos_y, cur_block):
cur_pos_x +=1if event.key == pygame.K_DOWN:if not game_over and not pause:if time.time()- last_press_time 0.1:
last_press_time = time.time()if not _judge(cur_pos_x, cur_pos_y +1, cur_block):_dock()else:
last_drop_time = time.time()
cur_pos_y +=1_draw_background(screen)_draw_game_area(screen, game_area)_draw_gridlines(screen)_draw_info(screen, font1, font_pos_x, font1_height, score)
# 表示情報に次のボックスを描画します
_ draw_block(screen, next_block, font_pos_x,30+(font1_height +6)*5,0,0)if not game_over:
cur_drop_time = time.time()if cur_drop_time - last_drop_time speed:if not pause:
# テトリスをプレイするときは、キューブが下に落ちると左右に動くことができます。
if not _judge(cur_pos_x, cur_pos_y +1, cur_block):_dock()else:
last_drop_time = cur_drop_time
cur_pos_y +=1else:if start:print_text(screen, font2,(SCREEN_WIDTH - gameover_size[0])// 2, (SCREEN_HEIGHT - gameover_size[1]) // 2,'GAME OVER', RED)
# 現在の下降する正方形を描く
_ draw_block(screen, cur_block,0,0, cur_pos_x, cur_pos_y)
pygame.display.flip()
# 背景を描く
def _draw_background(screen):
# 背景色を塗りつぶす
screen.fill(BG_COLOR)
# ゲームエリアの仕切りを描く
pygame.draw.line(screen, BORDER_COLOR,(SIZE * BLOCK_WIDTH + BORDER_WIDTH // 2, 0),(SIZE * BLOCK_WIDTH + BORDER_WIDTH // 2, SCREEN_HEIGHT), BORDER_WIDTH)
# グリッド線を引く
def _draw_gridlines(screen):
# グリッド線と垂直線を描く
for x inrange(BLOCK_WIDTH):
pygame.draw.line(screen, BLACK,(x * SIZE,0),(x * SIZE, SCREEN_HEIGHT),1)
# グリッド線を引く
for y inrange(BLOCK_HEIGHT):
pygame.draw.line(screen, BLACK,(0, y * SIZE),(BLOCK_WIDTH * SIZE, y * SIZE),1)
# 倒れた正方形を描く
def _draw_game_area(screen, game_area):if game_area:for i, row inenumerate(game_area):for j, cell inenumerate(row):if cell !='.':
pygame.draw.rect(screen, BLOCK_COLOR,(j * SIZE, i * SIZE, SIZE, SIZE),0)
# 単一の正方形を描く
def _draw_block(screen, block, offset_x, offset_y, pos_x, pos_y):if block:for i inrange(block.start_pos.Y, block.end_pos.Y +1):for j inrange(block.start_pos.X, block.end_pos.X +1):if block.template[i][j]!='.':
pygame.draw.rect(screen, BLOCK_COLOR,(offset_x +(pos_x + j)* SIZE, offset_y +(pos_y + i)* SIZE, SIZE, SIZE),0)
# スコアやその他の情報を描く
def _draw_info(screen, font, pos_x, font_height, score):print_text(screen, font, pos_x,10, f'スコア: ')print_text(screen, font, pos_x,10+ font_height +6, f'{score}')print_text(screen, font, pos_x,20+(font_height +6)*2, f'速度: ')print_text(screen, font, pos_x,20+(font_height +6)*3, f'{score // 10000}')print_text(screen, font, pos_x,30+(font_height +6)*4, f'次:')if __name__ =='__main__':main()
ゲームのスクリーンショット
実行結果
Tetrisに関するさらにエキサイティングな記事については、トピック「TetrisGameCollection」をクリックして学習してください。
より興味深い古典的なミニゲームの実装トピックもあなたと共有します:
C ++クラシックゲームの概要
Pythonクラシックゲームの概要
pythontetrisゲームコレクション
JavaScriptクラシックゲームは常にプレイされています
古典的なJavaゲームの概要
JavaScriptクラシックゲームの概要
以上が本稿の内容ですので、皆様のご勉強に役立てていただければ幸いです。
Recommended Posts