150行python代码制作一个简单的俄罗斯方块小游戏
程序员文章站
2024-03-18 19:50:58
...
只是实现了最简单功能。。。
这个主要是转动数据麻烦,虽说全部手动写上去也行,实际也比代码要短,只是不太好意思,强行转动(共7个图形,最后一个转动时中心会发生偏移,耍赖了一把)
实际流程(三个状态):
-
新生成图形块,如果从下往上已经堆到这里了(图形块出现位置出现不为空白的背景)游戏结束
-
下落(途中可以键盘操作块的移动,转动)
-
到底,图形数据记录到map,检查是否消去一行
所有的检查,就用check_action(位置x,位置y,图形块号,图形转动角度):检查是否出界或遇到原先的块,
-
游戏是否结束判断:新生成图形块位置是否check_action == False
-
下落是否到底:y+1位置是否check_action == False
-
操作动作(x-1,x+1,y+1,角度+1):是否check_action == False
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
import sys
import pygame
from pygame.locals import *
import random
class Block:
blk_color = [(255, 255, 255),(255, 255, 0),(255, 0, 255),(0, 255, 255),(255, 0, 0),(0, 255, 0),(0, 0, 255),(32,32,32)]
BLANK = 7
type_coord=[[[-1,0],[0,0],[1,0],[2,0]]\
,[[-1,0],[0,0],[1,0],[0,1]]\
,[[-1,0],[0,0],[-1,1],[0,1]]\
,[[-1,0],[0,0],[0,1],[1,1]]\
,[[0,0],[1,0],[-1,1],[0,1]]\
,[[-1,0],[0,0],[1,0],[1,1]]\
,[[-1,0],[0,0],[1,0],[-1,1]]]
type_rotate = []
def __init__(self,x,y,blk,angle):
self.x = x
self.y = y
self.blk = blk
self.angle = angle
@staticmethod
def rotate(no):
rt_all = []
rt = Block.type_coord[no][:]
cx,cy=0,0
for b in range(4):
rt[b][0],rt[b][1] = rt[b][0]*4,rt[b][1]*4
cx += rt[b][0]
cy += rt[b][1]
cx = (cx)//8*2 if no !=6 else (cx+4)//8*2
cy = (cy)//8*2 if no !=6 else (cy-4)//8*2
rt_all.append(rt)
for r in range(3):
rt_new = []
for b in range(4):
rt_new.append([cx + (cy-rt[b][1]),cy-(cx-rt[b][0])])
rt_all.append(rt_new)
rt = rt_new
for r in range(4):
for b in range(4):
rt_all[r][b][0] //= 4
rt_all[r][b][1] //= 4
return rt_all
@staticmethod
def init_rotate():
for r in range(7):
Block.type_rotate.append(Block.rotate(r))
class TRS:
screen = None
map = [[Block.BLANK]*10 for i in range(20)]
STATUS = 0
cbk = None
def __init__(self,screen):
TRS.screen = screen
@staticmethod
def action(key_pressed):
if(key_pressed[K_LEFT] and TRS.check_action(TRS.cbk.x-1,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle)):
TRS.cbk.x -= 1
elif (key_pressed[K_RIGHT] and TRS.check_action(TRS.cbk.x+1,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle)):
TRS.cbk.x += 1
elif (key_pressed[K_UP] and TRS.check_action(TRS.cbk.x,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle+1)):
TRS.cbk.angle += 1
elif (key_pressed[K_DOWN] and TRS.check_action(TRS.cbk.x,TRS.cbk.y+1,TRS.cbk.blk,TRS.cbk.angle)):
TRS.cbk.y += 1
@staticmethod
def new_blk():
TRS.cbk = Block(5,0,random.randint(0,6),0)
@staticmethod
def check_action(x,y,blk,angle):
tr = Block.type_rotate[blk][angle%4]
for b in range(4):
bx,by = x + tr[b][0],y + tr[b][1]
if(bx<0 or bx>9 or by <0 or by>19 or TRS.map[by][bx]!=Block.BLANK):
return False
return True
@staticmethod
def check_drop():
if TRS.check_action(TRS.cbk.x,TRS.cbk.y+1,TRS.cbk.blk,TRS.cbk.angle):
TRS.cbk.y += 1
else:
TRS.STATUS = 2
@staticmethod
def check_clear():
blk = Block.type_rotate[TRS.cbk.blk][TRS.cbk.angle%4]
row = list({TRS.cbk.y + blk[i][1] for i in range(4)})
row.sort()
row.reverse()
for b in range(4):
TRS.map[TRS.cbk.y + blk[b][1]][TRS.cbk.x + blk[b][0]] = TRS.cbk.blk
del_rows = 0
for r in row:
if not (Block.BLANK in TRS.map[r]):
TRS.map.pop(r)
del_rows += 1
for d in range(del_rows):
TRS.map.insert(0,[Block.BLANK for i in range(10)])
@staticmethod
def print_game():
TRS.screen.fill((0, 0, 0))
for row in range(20):
for col in range(10):
pygame.draw.rect(TRS.screen, Block.blk_color[TRS.map[row][col]], ((col*21,row*21), (20, 20)), 0)
blk = Block.type_rotate[TRS.cbk.blk][TRS.cbk.angle%4]
for b in range(4):
pygame.draw.rect(TRS.screen, Block.blk_color[TRS.cbk.blk], (((TRS.cbk.x+blk[b][0])*21,(TRS.cbk.y+blk[b][1])*21), (20, 20)), 0)
class App:
def __init__(self):
pygame.init()
screen = pygame.display.set_mode((300,430))
Block.init_rotate()
TRS(screen)
def main(self):
clock = pygame.time.Clock() # 创建游戏时钟
count = 1
# 进入游戏循环
while True:
# 设置刷新帧率
clock.tick(15)
# 事件检测
for event in pygame.event.get():
if event.type == pygame.QUIT: # 退出事件
sys.exit()
if TRS.STATUS == 0:
TRS.new_blk()
if TRS.check_action(TRS.cbk.x,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle):
TRS.STATUS = 1
else:
TRS.STATUS = 3
print("GAME OVER")
elif TRS.STATUS == 1:
TRS.action(pygame.key.get_pressed())
if count % 10 == 0:
TRS.check_drop()
elif TRS.STATUS == 2:
TRS.check_clear()
TRS.STATUS = 0
TRS.print_game()
pygame.display.update() #刷新屏幕
count += 1
App().main()
下一篇: 俄罗斯方块小游戏