Bootstrap

python俄罗斯方块代码34行_python,基于tkinter模块编写的完整俄罗斯方块游戏代码...

使用python编写小游戏挺容易的,常用的模块是pygame, 本文用tkinter,实现了俄罗斯方块小游戏,感觉还是比较容易的。

import tkinter as tk

import time

import random

from tkinter import messagebox

import pygame

pygame.mixer.pre_init(44100, -16, 2, 512)

pygame.mixer.init() # 初始化混音器

# 读取最高纪录

with open('record.txt', 'r') as f:

record = int(f.read())

# 定义游戏中的常量

R = 20 # 20行

C = 12 # 30列

cell_size = 30 #方块边长

with open('speed.txt', 'r') as f:

FPS = int(f.readline()) # 读取刷新时间

height = R * cell_size #画布高度

width = C * cell_size #画布宽度

#定义形状的座标矩阵

SHAPES = {

'O': [(-1, -1), (0, -1), (-1, 0), (0, 0)],

'S': [(-1, 0), (0, 0), (0, -1), (1, -1)],

'T': [(-1, 0), (0, 0), (0, -1), (1, 0)],

'I': [(0, 1), (0, 0), (0, -1), (0, -2)],

'L': [(-1, 0), (0, 0), (-1, -1), (-1, -2)],

'J': [(-1, 0), (0, 0), (0, -1), (0, -2)],

'Z': [(-1, -1), (0, -1), (0, 0), (1, 0)]

}

# 定义每个形状的颜色

SHAPECOLOR = {

'O': 'blue',

'S': 'red',

'T': 'yellow',

'I': 'green',

'L': 'purple',

'J': 'orange',

'Z': 'Cyan'

}

# 定义函数,在画板指定的行列上画指定颜色的方格

def draw_cell_by_cr(canvas, c, r, color = '#CCCCCC'):

#定义左上角和右下角座标

x0 = c * cell_size

y0 = r * cell_size

x1 = c * cell_size + cell_size

y1 = r * cell_size + cell_size

canvas.create_rectangle(x0, y0, x1, y1, fill = color, outline = 'white', width = 2)

# 定义函数,画背景画布

def draw_board(canvas, block_list):

for ri in range(R):

for ci in range(C):

cell_type = block_list[ri][ci]

if cell_type:

draw_cell_by_cr(canvas, ci, ri, SHAPECOLOR[cell_type])

else:

draw_cell_by_cr(canvas, ci, ri)

# 定义在指定的行列,绘制指定颜色的图形

def draw_cell(canvas, c, r, cell_list, color = '#cccccc'):

for cell in cell_list:

cell_c, cell_r = cell

ci = cell_c + c # 实际列座标

ri = cell_r + r # 实际行座标

if 0 <= c < C and 0 <= r < R:

draw_cell_by_cr(canvas, ci, ri, color) # 画出一个方格

win = tk.Tk()

canvas = tk.Canvas(win, width = width, height = height) #定义画布控件

win.geometry('+800+10')

canvas.pack()

# draw_blank_board(canvas)

# draw_cell(canvas, 3, 3, SHAPES['O'], SHAPECOLOR['O'])

# draw_cell(canvas, 3, 8, SHAPES['S'], SHAPECOLOR['S'])

# draw_cell(canvas, 3, 13, SHAPES['T'], SHAPECOLOR['T'])

# draw_cell(canvas, 8, 3, SHAPES['I'], SHAPECOLOR['I'])

# draw_cell(canvas, 8, 8, SHAPES['L'], SHAPECOLOR['L'])

# draw_cell(canvas, 8, 13, SHAPES['J'], SHAPECOLOR['J'])

# draw_cell(canvas, 5, 18, SHAPES['Z'], SHAPECOLOR['Z'])

block_list = [] # 定义记录已经生成的方块的列表

for i in range(R):

i_row = ['' for i in range(C)]

block_list.append(i_row) # 生成由空字符串组成的R行C列的列表

draw_board(canvas, block_list)

# 定义移动方块函数

def draw_block_move(canvas, block, direction = [0, 0]):

'''

:param:

:param canvas: 画布

:param block: 方块对象

:param direction: 移动方向

:return:

'''

shape_type = block['kind']

c, r = block['cr']

cell_list = block['cell_list']

draw_cell(canvas, c, r, cell_list) # 擦除旧位置的形状

dc, dr = direction

new_c, new_r = c + dc, r + dr

block['cr'] = [new_c, new_r]

draw_cell(canvas, new_c, new_r, cell_list, SHAPECOLOR[shape_type]) # 绘制新位置的形状

# draw_block_move(canvas, a_block)

# 定义一个随机生成形状的函数

def generate_new_block():

kind = random.choice(list(SHAPES.keys()))

cr = [C // 2, 0]

new_block = {

'kind': kind,

'cell_list': SHAPES[kind],

'cr': cr

}

return(new_block)

# 定义检测方块是否移动到最底部的函数

def check_move(block, direction = [0, 0]):

cc, cr = block['cr'] # 定义当前的行列座标

cell_list = block['cell_list']

for cell in cell_list:

cell_c, cell_r = cell

c = cell_c + cc + direction[0]

r = cell_r + cr + direction[1]

if c < 0 or c >= C or r >= R:

return False

if r >= 0 and block_list[r][c]:

return False

return True

# 定义一个存储已生成方块列表的函数

def save_to_block_list(block):

shape_type = block['kind']

cc, cr = block['cr']

cell_list = block['cell_list']

for cell in cell_list:

cell_c, cell_r = cell

c = cell_c + cc

r = cell_r + cr

block_list[r][c] = shape_type

def horizontal_move_block(event):

'''

:左右移动方块

:param event: 键鼠标事件

:return:

'''

direction = [0, 0] #默认方向为不动

if event.keysym == 'Left':

direction = [-1, 0]

elif event.keysym == 'Right':

direction = [1, 0]

else:

return

global current_block

if current_block is not None and check_move(current_block, direction):

draw_block_move(canvas, current_block, direction)

# 定义旋转方块函数

def rotate_block(event):

global current_block

if current_block is None:

return

cell_list = current_block['cell_list']

rotate_list = []

for cell in cell_list:

cell_c, cell_r = cell

rotate_cell = [cell_r, -cell_c]

rotate_list.append(rotate_cell)

block_after_rotate = {

'kind': current_block['kind'],

'cell_list': rotate_list,

'cr': current_block['cr']

}

if check_move(block_after_rotate):

cc, cr = current_block['cr']

draw_cell(canvas, cc, cr, current_block['cell_list'])

draw_cell(canvas, cc, cr, rotate_list, SHAPECOLOR[current_block['kind']])

current_block = block_after_rotate

# 定义一个按向下键直接着陆的函数

def land(event):

global current_block

if current_block is None:

return

cell_list = current_block['cell_list']

cc, cr = current_block['cr']

min_height = R

for cell in cell_list:

cell_c, cell_r = cell

c, r = cell_c + cc, cell_r + cr

if block_list[r][c]:

return

h = 0

for ri in range(r + 1, R):

if block_list[ri][c]:

break

else:

h += 1

if h < min_height:

min_height = h

down = [0, min_height]

if check_move(current_block, down):

draw_block_move(canvas, current_block, down)

# wave_down.play()

# 定义保存得分的变量

score = 0

win.title('To lotus! Scores:%s The record is %s' % (score, record))

# 定义函数判断指定行是否已经满了

def check_row_complete(row):

for cell in row:

if cell == '':

return False

return True

# 定义函数检查是否满了,同时清除满行方块

def check_and_clear():

has_complete_row = False

for ri in range(len(block_list)):

if check_row_complete(block_list[ri]):

has_complete_row = True

if ri > 0:

for cur_ri in range(ri, 0, -1):

block_list[cur_ri] = block_list[cur_ri -1][:]

block_list[0] = ['' for i in range(C)]

else:

block_list[ri] = ['' for i in range(C)]

global score

score += 10

if has_complete_row:

remove.play()

draw_board(canvas, block_list)

win.title('To lotus! Scores:%s The record is %s' % (score, record))

# 定义定时刷新函数

def game_loop():

win.update()

global current_block

if current_block == None:

new_block = generate_new_block()

draw_block_move(canvas, new_block) # 绘制形状(未输入direction,在new_block点绘制,不移动)

current_block = new_block

if not check_move(current_block):

game_over.play()

if score >= record:

messagebox.showinfo('Game Over!', '宝贝,我爱你!Your score is %s! Congratulations on setting a new record!' % score)

with open('record.txt', 'w') as f:

f.write(str(score))

else:

messagebox.showinfo('Game Over!', 'Your score is %s!' % score)

win.destroy()

return

else:

if check_move(current_block, [0, 1]):

draw_block_move(canvas, current_block, [0, 1])

else:

save_to_block_list(current_block)

current_block = None

wave_down.play()

check_and_clear()

win.after(FPS, game_loop)

current_block = None

canvas.focus_set() # 聚焦到画板对象

canvas.bind('', horizontal_move_block)

canvas.bind('', horizontal_move_block)

canvas.bind('', rotate_block)

canvas.bind('', land)

game_loop()

pygame.mixer.pre_init(44100, -16, 2, 512)

pygame.mixer.init() # 初始化混音器

#加载音乐文件

# mp3_backGround = pygame.mixer.music.load("background.mp3")

background = pygame.mixer.Sound('background.wav')

#加载wave文件

wave_down = pygame.mixer.Sound("down.wav")

remove = pygame.mixer.Sound("remove.wav")

game_over = pygame.mixer.Sound("gameover.wav")

#设置背景音乐的音量

# pygame.mixer.music.set_volume(Config.bgMusicVolume)

#播放背景音乐,参数-1表示循环播放

background.play(-1)

win.mainloop()

1865240-20200611170611850-1428981342.png

;