用Pygame写俄罗斯方块

这篇具有很好参考价值的文章主要介绍了用Pygame写俄罗斯方块。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

此文章参考的是吃饭超人的文章

首先我们先打开cmd输入如下令命

pip install pygame

然后打开python或者pycharm

输入如下代码文章来源地址https://www.toymoban.com/news/detail-529735.html

import os
import pygame
import sys
import random
import pygame.font
import time
pygame.init()

clos = 10                        #游戏网格列数,可以调整,>=8
rows = 20                        #游戏网格行数,可以调整
cell_size = 40                    #一个网格的大小
block_size = cell_size - 1        #一个方块的大小,小于等于cell_size
block_edge = int(block_size /2)    #方块的立体感,数字>=1,数字越小立体感越强
fps = 40                        #每秒帧数,建议范围20-60,越大难度递进越越缓

win_width = clos * 2 * cell_size + 6 * cell_size
win_hight = (rows + 1) * cell_size    
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (400,40)
screen = pygame.display.set_mode((win_width, win_hight))
pygame.display.set_caption("Crystal方块")

#在4*4的小网格内,以左上角坐标为(0,0),7种方块及其各形态4个方块在小网格的相对坐标
#移动时记录小网络(0,0)点在游戏网格的(x,y),就知道4个方块在游戏网格中的位置
blocks = {
    1: [[(0,1),(1,1),(2,1),(3,1)],
        [(2,0),(2,1),(2,2),(2,3)]],        #I型
    2: [[(1,1),(2,1),(1,2),(2,2)]],        #O型
    3: [[(0,1),(1,1),(2,1),(1,2)],
        [(1,0),(0,1),(1,1),(1,2)],
        [(1,1),(0,2),(1,2),(2,2)],
        [(1,0),(1,1),(2,1),(1,2)]],        #T型
    4: [[(0,1),(1,1),(2,1),(0,2)],
        [(0,0),(1,0),(1,1),(1,2)],
        [(2,1),(0,2),(1,2),(2,2)],
        [(1,0),(1,1),(1,2),(2,2)]],        #L型
    5: [[(0,1),(1,1),(2,1),(2,2)],
        [(1,0),(1,1),(0,2),(1,2)],
        [(0,1),(0,2),(1,2),(2,2)],
        [(1,0),(2,0),(1,1),(1,2)]],        #J型
    6: [[(1,1),(2,1),(0,2),(1,2)],
        [(0,0),(0,1),(1,1),(1,2)]],        #s型
    7: [[(0,1),(1,1),(1,2),(2,2)],
        [(2,0),(1,1),(2,1),(1,2)]],}    #Z型
        
#第1个为网格底色,后7个为对应方块的颜色,因为要加和原色相近的明暗边,自定义色RGB值最小得不低于50,最高不超过205,否则出错。    
#最后一个颜色(灰)用来画NEXT方块,也可以用NEXT方块的next_key值来指向本色    
block_color = [(199,238,206),(200,50,50),(50,200,200),(50,50,200),(200,200,50),(200,50,200),(50,200,50),(125,50,125),(180,180,180)]

class Game_machine():
    def __init__(self,x0,y0):
        self.x0, self.y0 = x0, y0                #记录player游戏区(0,0)点在屏幕的坐标
        self.rect = pygame.Rect(0,0,block_size, block_size)    #方块矩形大小            
        self.display_array = [[0 for i in range(clos)] for j in range(rows)]    #游戏区每格初始值设为0,为1时不能通过
        self.color_array = [[0 for i in range(clos)] for j in range(rows)]        #游戏区每格的颜色block_color的索引值
        self.x, self.y = 0, 0                    #记录移动方块(0,0)点在游戏网格的(clo,row)位置
        self.key = 0                            #记录移动方块在blocks的键,是哪种方块
        self.index_ = 0                            #记录移动方块形态的索引
        self.next_key = self.rand_key()            #记录NEXT方块在blocks的键        
        self.speed = fps                        #速度,和帧率一致
        self.fall_buffer = self.speed            #自动下落的缓冲时间,屏幕每刷一次自动减1
        self.fall_speed_up = False                #是否加速下落
        self.score = 0
        self.lines = 0
        self.level = 0
        self.creat_new_block()
                        
    def creat_new_block(self):
        #产生新的移动方块和NEXT方块,以第一形态作为初始形态
        self.key = self.next_key
        self.next_key = self.rand_key()
        self.index = 0
        self.x = 4                    #初始列设在第4列
        self.y = -1                    #初始高度设为-1,保证方块在最顶部位置出现,研究每种方块第一形态坐标可以找到答案

    def rand_key(self):
        keys = [1,1,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,7,7]        #决定每种方块出现概率
        return keys[random.randint(0,len(keys)-1)]
        
    def move(self, dx, dy):
        #方块左、右、下移动:左:dx=-1,dy=0  右:dx=1,dy=0  下:dx=0,dy=1
        if self.can_move(self.index, dx, dy):
            self.x += dx
            self.y += dy
        elif dy:
            #不能下落:在顶部位置不能下落,游戏结束,以下位置则停止移动
            if self.y <= 0:
                self.game_over()
            else:
                self.stop_move()
            
    def rotate(self):
        #方块旋转至下一形态,使用的顺时针旋转,被注释的是逆时针旋转
        next_index = (self.index + 1) % len(blocks[self.key])
        #next_index = (self.index - 1 + len(blocks[self.key])) % len(blocks[self.key])
        if self.can_move(next_index, 0, 0):
            self.index = next_index
    
    def can_move(self, index, dx, dy):
        #方块能否移动:出界或碰到其他方块
        for (x,y) in blocks[self.key][index]:
            clo, row = self.x + x + dx , self.y + y + dy
            if clo >= clos  or clo < 0 or row >= rows or row < 0:    #出界
                return False
            if self.display_array[row][clo]:            #值等于1时不能移动
                return False
        return True

    def stop_move(self):
        #方块停止移动,停落区域赋值1和相应的颜色
        self.score += 4    
        for (x,y) in  blocks[self.key][self.index]:
            self.display_array[y+self.y][x+self.x] = 1
            self.color_array[y+self.y][x+self.x] = self.key
        self.del_full_row()    
        self.creat_new_block()    
    
    def del_full_row(self):
        #删除填满的行,记录成绩
        lines = 0        
        for row in range(rows):
            if sum(self.display_array[row]) == clos:            #填满行判断
                lines += 1                #记录一次连续删除的行数,实现多消多奖
                self.lines += 1
                if self.lines % 5 == 0:                #每消5行等级升1,速度加快
                    self.level = self.lines / 5
                    self.speed = int(self.speed * 0.9)            #越小越快
                self.score += (self.level + clos * lines) * 5
                
                del self.display_array[row]
                self.display_array.insert(0,[0 for i in range(clos)])
                
    def display(self):
        self.display_stop_blocks()
        self.display_next_blocks()
        self.display_move_blocks()
        self.display_score()
        
        #每刷一次缓冲计数减1,缓冲计数=0,或按住了向下键则下落一格
        self.fall_buffer -= 1
        if self.fall_buffer == 0 or self.fall_speed_up:
            self.fall_buffer = self.speed
            self.move(0,1)
                
    def display_stop_blocks(self):
        #显示不移动的方块,值为1画彩色立体方块,值为0画底色块
        for y in range(rows):
            for x in range(clos):
                self.rect.topleft = x * cell_size, y * cell_size
                if  self.display_array[y][x]:
                    self.draw_block(self.color_array[y][x], 1)
                else:
                    self.draw_block(0, 0)
                    
    def display_next_blocks(self):
        #显示下一个方块
        for (x,y) in  blocks[self.next_key][0]:
            self.rect.topleft = x * cell_size , (y - 1) * cell_size
            self.draw_block(8, 1)        

    def display_move_blocks(self):
        #显示移动的方块
        for (x,y) in  blocks[self.key][self.index]:
            self.rect.topleft = (self.x + x) * cell_size, (self.y + y) * cell_size
            self.draw_block(self.key, 1)    

    def display_score(self):
        #显示得分记录
        text = "得分:%d  行数:%d  等级:%d" %(self.score,self.lines,self.level)
        self.img = pygame.font.SysFont("kaiti",25).render(text, True, (0,0,255))
        self.img_rect = self.img.get_rect()
        self.img_rect.topleft = (self.x0, rows* cell_size)
        screen.blit(self.img, self.img_rect)
                
    def game_over(self):
        #只是简单的数据重新初始化后立即重新开始
        self.__init__(self.x0, self.y0)
                        
    def draw_block(self, color_index, draw_edge):
        #在指定位置画方块
        (r,g,b) = block_color[color_index]
        self.rect.centerx = self.rect.left + self.x0 + int(cell_size / 2)
        self.rect.centery = self.rect.top + self.y0 + int(cell_size / 2)
        if draw_edge:
            #画方块明暗过度边,增加立体感,x0~x4是方块四角和中心的坐标。
            x0 = self.rect.center                    
            x1 = self.rect.topleft
            x2 = self.rect.topright
            x3 = self.rect.bottomright
            x4 = self.rect.bottomleft
            pygame.draw.polygon(screen, (r+50, g+50, b+50), (x0,x1,x2), 0)
            pygame.draw.polygon(screen, (r+20, g+20, b+20), (x0,x2,x3), 0)
            pygame.draw.polygon(screen, (r-50, g-50, b-50), (x0,x3,x4), 0)
            pygame.draw.polygon(screen, (r-20, g-20, b-20), (x0,x4,x1), 0)
            pygame.draw.rect(screen, (r,g,b), self.rect.inflate(-block_edge, -block_edge), 0)
        else:
            pygame.draw.rect(screen, (r,g,b), self.rect, 0)

time = pygame.time.Clock()    
player1 = Game_machine(0, 0)
player2 = Game_machine((clos + 6) * cell_size, 0)

while True:
    time.tick(fps)
    screen.fill((166,124,64))
    player1.display()
    player2.display()
    pygame.display.update()
        
    #移动旋转控制            
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_g:            #player1 :g键右移动一格
                player1.move(1,0)
            elif event.key == pygame.K_d:        #player1 :d键左移动一格
                player1.move(-1,0)
            elif event.key == pygame.K_r:        #player1 :r键旋转一次
                player1.rotate()
            elif event.key == pygame.K_f:        #player1 :f键加速下移
                player1.fall_speed_up = True
                
            if event.key == pygame.K_RIGHT:        #player2 :→键右移动一格
                player2.move(1,0)
            elif event.key == pygame.K_LEFT:    #player2 :←键左移动一格
                player2.move(-1,0)
            elif event.key == pygame.K_UP:        #player2 :↑键旋转一次
                player2.rotate()
            elif event.key == pygame.K_DOWN:    #player2 :↓键加速下移
                player2.fall_speed_up = True
                
            elif event.key == pygame.K_q:
                sys.exit()
                
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_f:
                player1.fall_speed_up = False
            if event.key == pygame.K_DOWN:
                player2.fall_speed_up = False    
        elif event.type == pygame.QUIT:
            sys.exit()

到了这里,关于用Pygame写俄罗斯方块的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Javascript 俄罗斯方块 游戏代码

    本俄罗斯方块代码采用 JavaScript 脚本代码写成,简单易懂; 全代码采用静态类及静态变量成员组成; 全脚本通过实现代码全局配置 OLSFK.Options = {...} 定义方块起始坐标及定义各自的旋转点; 从初始化俄罗斯方块界面开始,再监听键盘事件;以及左右,向下及旋转动作判断,

    2024年02月07日
    浏览(48)
  • 经典俄罗斯方块代码(转javascript代码)

    在网上发现一篇60行javascript超经典俄罗斯方块代码,值得学习,转为Delphi如下,有详细注释,不再另讲解:

    2024年01月20日
    浏览(40)
  • python实现俄罗斯方块【含代码和讲解】

    Python实现俄罗斯方块:打造经典游戏的代码实现教程 俄罗斯方块是世界上最受欢迎的电子游戏之一,源自俄罗斯。这是一个简单却富有挑战和乐趣的游戏,让玩家必须思考如何将各种形状的积木放入底部的平面上,以便完整地填满一行或多行,每填满一行就会消失并获得分数

    2024年02月11日
    浏览(53)
  • Java实现俄罗斯方块小游戏。(附完整源代码)

    大家好,我是百思不得小赵。 创作时间:2022 年 5 月 12 日 博客主页: 🔍点此进入博客主页 —— 新时代的农民工 🙊 —— 换一种思维逻辑去看待这个世界 👀 今天是加入CSDN的第1167天。觉得有帮助麻烦👏点赞、🍀评论、❤️收藏 目录 一、游戏背景 二、功能实现 三、效果

    2024年02月03日
    浏览(72)
  • 免费分享一套Python俄罗斯方块源码 PyQt5俄罗斯方块源码,太好玩了~

    大家好,我是java1234_小锋老师,看到一个不错的Python俄罗斯方块源码 PyQt5俄罗斯方块源码,分享下哈。 【免费】Python俄罗斯方块源码 PyQt5俄罗斯方块源码 Python小游戏源码_哔哩哔哩_bilibili 【免费】Python俄罗斯方块源码 PyQt5俄罗斯方块源码 Python小游戏源码项目来自互联网,免

    2024年01月25日
    浏览(47)
  • 编写一个俄罗斯方块

    编写俄罗斯方块 思路。 1、创建容器数组,方块, 2、下落,左右移动,旋转,判断结束,消除。  定义一个20行10列的数组表示游戏区。初始这个数组里用0填充,1表示有一个方块,2表示该方块固定了, 然后随机出一个方块,操作左右转,触底变2后,再随机下一个方块,循

    2024年02月12日
    浏览(53)
  • c语言——俄罗斯方块

    俄罗斯方块是久负盛名的游戏,它也和贪吃蛇,扫雷等游戏位列经典游戏的⾏列。 《俄罗斯方块》(Tetris,俄文:Тетрис)是一款由俄罗斯人阿列克谢·帕基特诺夫于1984年6月发明的休闲游戏。 该游戏曾经被多家公司代理过。经过多轮诉讼后,该游戏的代理权最终被任天堂

    2024年02月05日
    浏览(46)
  • python制作俄罗斯方块

    作者简介 :一名后端开发人员,每天分享后端开发以及人工智能相关技术,行业前沿信息,面试宝典。 座右铭 :未来是不可确定的,慢慢来是最快的。 个人主页 :极客李华-CSDN博客 合作方式 :私聊+ 这个专栏内容 :BAT等大厂常见后端java开发面试题详细讲解,更新数目10

    2024年02月12日
    浏览(51)
  • 俄罗斯方块小游戏开发

    代码图: 结果图:

    2024年02月04日
    浏览(56)
  • 用python制作俄罗斯方块

    代码如下,可以直接运行:

    2024年02月11日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包