吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1696|回复: 6
收起左侧

[讨论] 新手用python写了一个俄罗斯方块目前个人只能做到这样,而且流畅性不佳求大佬指点

[复制链接]
suneryzgg123 发表于 2023-5-22 15:36
[Python] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import random
import pygame
 
# 定义方块类
class Block:
    def __init__(self, shape, color, x, y):
        self.shape = shape
        self.color = color
        self.x = x
        self.y = y
 
    def draw(self, surface):
        pygame.draw.rect(surface, self.color, (self.x*25+1, self.y*25+1, 24, 24))
 
# 定义游戏类
class Game:
    def __init__(self, width=10, height=20):
        self.width = width
        self.height = height
        self.board = [[0 for x in range(self.width)] for y in range(self.height)]
        self.score = 0
        self.level = 1
        self.falling_block = None
        self.next_block = None
        self.game_over = False
 
    def new_block(self):
        # 随机生成新的方块
        shapes = [
            [[[1, 1, 1, 1]], (255, 0, 0)],
            [[[1, 1], [1, 1]], (0, 255, 0)],
            [[[1, 1, 0], [0, 1, 1]], (0, 0, 255)],
            [[[0, 1, 1], [1, 1, 0]], (255, 255, 0)],
            [[[1, 1, 1], [0, 1, 0]], (0, 255, 255)],
            [[[1, 1, 0], [0, 1, 1]], (255, 0, 255)],
            [[[0, 1, 0], [1, 1, 1]], (128, 0, 128)]
        ]
        shape, color = random.choice(shapes)
        self.falling_block = Block(shape, color, self.width//2-2, 0)
        shape, color = random.choice(shapes)
        self.next_block = Block(shape, color, 0, 0)
 
    def draw_board(self, surface):
        # 绘制游戏区域
        for y in range(self.height):
            for x in range(self.width):
                pygame.draw.rect(surface, (255, 255, 255), (x*25, y*25, 25, 25), 1)
                if self.board[y][x]:
                    pygame.draw.rect(surface, self.board[y][x], (x*25+1, y*25+1, 24, 24))
 
    def draw_falling_block(self, surface):
        # 绘制当前下落的方块
        if self.falling_block:
            for y, row in enumerate(self.falling_block.shape):
                for x, val in enumerate(row):
                    if val:
                        b = Block(self.falling_block.shape, self.falling_block.color, self.falling_block.x+x, self.falling_block.y+y)
                        b.draw(surface)
 
    def draw_next_block(self, surface):
        # 绘制下一个方块
        if self.next_block:
            for y, row in enumerate(self.next_block.shape):
                for x, val in enumerate(row):
                    if val:
                        b = Block(self.next_block.shape, self.next_block.color, self.width+x, y)
                        b.draw(surface)
 
    def move_left(self):
        # 向左移动方块
        if self.falling_block:
            if self.falling_block.x > 0 and not self.collides(self.falling_block, -1):
                self.falling_block.x -= 1
 
    def move_right(self):
        # 向右移动方块
        if self.falling_block:
            if self.falling_block.x < self.width-len(self.falling_block.shape[0]) and not self.collides(self.falling_block, 1):
                self.falling_block.x += 1
 
    def rotate(self):
        # 旋转方块
        if self.falling_block:
            tmp = list(zip(*self.falling_block.shape[::-1]))
            if self.falling_block.x + len(tmp[0]) <= self.width and not self.collides(Block(tmp, self.falling_block.color, self.falling_block.x, self.falling_block.y), 0):
                self.falling_block.shape = tmp
 
    def fall(self):
        # 下落方块
        if self.falling_block:
            if self.falling_block.y < self.height-len(self.falling_block.shape) and not self.collides(self.falling_block, 0, 1):
                self.falling_block.y += 1
                return False
            else:
                self.merge_falling_block()
                self.new_block()
                return True
 
    def merge_falling_block(self):
        # 将当前方块合并到游戏区域
        for y, row in enumerate(self.falling_block.shape):
            for x, val in enumerate(row):
                if val:
                    self.board[self.falling_block.y+y][self.falling_block.x+x] = self.falling_block.color
        # 消除填满一行的方块
        for y in range(self.height):
            if all(self.board[y]):
                self.board.pop(y)
                self.board.insert(0, [0 for x in range(self.width)])
                self.score += 10
                if self.score % 100 == 0:
                    self.level += 1
 
    def collides(self, block, dx=0, dy=0):
        # 判断方块是否与游戏区域或已有方块重叠
        for y, row in enumerate(block.shape):
            for x, val in enumerate(row):
                if val:
                    try:
                        if self.board[block.y+y+dy][block.x+x+dx]:
                            return True
                    except IndexError:
                        return True
        return False
 
# 游戏主循环
def main():
    pygame.init()
    screen = pygame.display.set_mode((320, 480))
    clock = pygame.time.Clock()
    game = Game()
    game.new_block()
    paused = False
    font = pygame.font.SysFont('Arial', 20)
    while not game.game_over:
        clock.tick(game.level * 5)
        screen.fill((0, 0, 0))
        game.draw_board(screen)
        game.draw_falling_block(screen)
        game.draw_next_block(screen)
 
        # 显示分数
        text = font.render('Score: ' + str(game.score), True, (255, 255, 255))
        screen.blit(text, (10, 10))
 
        # 监听键盘事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game.game_over = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    game.move_left()
                elif event.key == pygame.K_RIGHT:
                    game.move_right()
                elif event.key == pygame.K_UP:
                    game.rotate()
                elif event.key == pygame.K_DOWN:
                    if not paused:
                        game.fall()
                elif event.key == pygame.K_p:
                    paused = not paused
                elif event.key == pygame.K_SPACE:
                    if paused:
                        game = Game()
                        game.new_block()
                        paused = False
        # 游戏暂停时不更新屏幕
        if not paused:
            if game.fall():
                if game.collides(game.falling_block, 0, 0):
                    # 游戏结束
                    text = font.render('Game Over', True, (255, 255, 255))
                    screen.blit(text, (100, 200))
                    paused = True
 
        pygame.display.update()
    pygame.quit()
 
if __name__ == '__main__':
    main()

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
blindcat + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

仲舒 发表于 2023-5-22 16:06
可以尝试以下几种优化方法:

1. 减少绘制次数:在每一帧中,你的代码会多次调用`draw()`方法来绘制方块和游戏区域。如果绘制操作过于频繁,会导致性能下降。你可以考虑减少绘制次数,只在方块状态发生变化或需要更新时进行绘制。

2. 使用双缓冲技术:双缓冲技术可以提高绘制效率。你可以创建一个后台缓冲区,在其中进行绘制操作,然后将缓冲区的内容一次性绘制到屏幕上,减少屏幕刷新次数,从而提高性能。

3. 优化碰撞检测:在`collides()`方法中,你通过逐个检查方块位置来判断碰撞。这种方法可能会随着方块数量的增加而变得低效。你可以考虑使用更高效的碰撞检测算法,例如使用边界框或分割区域来加速碰撞检测过程。

4. 使用图像缓存:在每一帧中,方块的形状和颜色都是不变的。你可以将方块的绘制结果缓存为图像,而不是每次都重新绘制。这样可以减少绘制操作的数量,提高性能。

5. 优化事件处理:在事件处理的部分,你使用了`pygame.event.get()`来获取所有的事件。这会一次性获取所有的事件,可能会导致输入响应的延迟。你可以考虑使用`pygame.event.poll()`或者`pygame.event.wait()`来获取单个事件,以提高输入的实时性。

6. 使用适当的图像格式:在绘制和加载图像时,使用适当的图像格式可以提高性能。例如,使用压缩格式(如PNG)而不是无损格式(如BMP)可以减少图像的内存占用和加载时间。

7. 调整游戏速度参数:通过调整游戏速度参数,可以在流畅性和游戏难度之间取得平衡。可以尝试逐渐增加或减少帧率限制,找到最佳的游戏速度。

这些是一些常见的优化方法,但具体的优化策略可能因游戏的复杂性和硬件平台而有所不同。建议你逐步实施这些优化措施,并进行性能测试和调整,以找到最适合你的游戏的优化方案。

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
jjjzw + 1 + 1 热心回复!

查看全部评分

仲舒 发表于 2023-5-22 16:59
[Python] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import pygame
import random
 
# 游戏区域的宽度和高度
grid_width = 10
grid_height = 20
 
# 方块大小和窗口尺寸
block_size = 30
window_width = grid_width * block_size
window_height = grid_height * block_size
 
# 初始化Pygame
pygame.init()
window = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("Tetris Game")
 
# 颜色定义
BLACK = (0, 0, 0)
CYAN = (0, 255, 255)
YELLOW = (255, 255, 0)
PURPLE = (255, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
ORANGE = (255, 165, 0)
 
# 方块的形状和颜色
tetriminos = [
    [[1, 1, 1, 1]],  # I
    [[1, 1], [1, 1]],  # O
    [[1, 1, 0], [0, 1, 1]],  # Z
    [[0, 1, 1], [1, 1, 0]],  # S
    [[1, 1, 1], [0, 1, 0]],  # T
    [[1, 1, 1], [0, 0, 1]],  # L
    [[1, 1, 1], [1, 0, 0]]  # J
]
 
# 方块颜色对应关系
tetrimino_colors = [CYAN, YELLOW, PURPLE, GREEN, RED, BLUE, ORANGE]
 
# 初始化游戏区域
grid = [[0] * grid_width for _ in range(grid_height)]
 
# 当前方块的形状、颜色和位置
current_tetrimino = random.choice(tetriminos)
current_tetrimino_color = random.choice(tetrimino_colors)
current_tetrimino_x = grid_width // 2 - len(current_tetrimino[0]) // 2
current_tetrimino_y = 0
 
# 绘制游戏区域
def draw_grid():
    for row in range(grid_height):
        for col in range(grid_width):
            if grid[row][col] != 0:
                pygame.draw.rect(window, tetrimino_colors[grid[row][col] - 1],
                                 (col * block_size, row * block_size, block_size, block_size))
            pygame.draw.rect(window, BLACK, (col * block_size, row * block_size, block_size, block_size), 1)
 
# 绘制方块
def draw_tetrimino(tetrimino, x, y, color):
    for row in range(len(tetrimino)):
        for col in range(len(tetrimino[row])):
            if tetrimino[row][col] == 1:
                pygame.draw.rect(window, color,
                                 ((x + col) * block_size, (y + row) * block_size, block_size, block_size))
                pygame.draw.rect(window, BLACK,
                                 ((x + col) * block_size, (y + row) * block_size, block_size, block_size), 1)
 
# 检查方块是否可以放置到游戏区域中
def can_place_tetrimino(tetrimino, x, y):
    for row in range(len(tetrimino)):
        for col in range(len(tetrimino[row])):
            if tetrimino[row][col] == 1:
                if x + col < 0 or x + col >= grid_width or y + row >= grid_height or grid[y + row][x + col] != 0:
                    return False
    return True
 
# 将方块放置到游戏区域中
def place_tetrimino(tetrimino, x, y, color):
    for row in range(len(tetrimino)):
        for col in range(len(tetrimino[row])):
            if tetrimino[row][col] == 1:
                grid[y + row][x + col] = color
 
# 旋转方块形状
def rotate_tetrimino(tetrimino):
    return list(zip(*reversed(tetrimino)))
 
# 消除满行的方块
def clear_lines():
    full_rows = []
    for row in range(grid_height):
        if all(grid[row]):
            full_rows.append(row)
 
    for row in full_rows:
        del grid[row]
        grid.insert(0, [0] * grid_width)
 
# 判断游戏是否结束
def is_game_over():
    return any(grid[0])
 
# 游戏主循环
clock = pygame.time.Clock()
game_over = False
 
while not game_over:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            game_over = True
 
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                if can_place_tetrimino(current_tetrimino, current_tetrimino_x - 1, current_tetrimino_y):
                    current_tetrimino_x -= 1
            elif event.key == pygame.K_RIGHT:
                if can_place_tetrimino(current_tetrimino, current_tetrimino_x + 1, current_tetrimino_y):
                    current_tetrimino_x += 1
            elif event.key == pygame.K_DOWN:
                if can_place_tetrimino(current_tetrimino, current_tetrimino_x, current_tetrimino_y + 1):
                    current_tetrimino_y += 1
            elif event.key == pygame.K_UP:
                rotated_tetrimino = rotate_tetrimino(current_tetrimino)
                if can_place_tetrimino(rotated_tetrimino, current_tetrimino_x, current_tetrimino_y):
                    current_tetrimino = rotated_tetrimino
 
    # 移动方块下落
    if can_place_tetrimino(current_tetrimino, current_tetrimino_x, current_tetrimino_y + 1):
        current_tetrimino_y += 1
 
    # 检查是否需要固定方块并生成新的方块
    if not can_place_tetrimino(current_tetrimino, current_tetrimino_x, current_tetrimino_y + 1):
        place_tetrimino(current_tetrimino, current_tetrimino_x, current_tetrimino_y, tetrimino_colors.index(current_tetrimino_color) + 1)
        clear_lines()
 
        current_tetrimino = random.choice(tetriminos)
        current_tetrimino_color = random.choice(tetrimino_colors)
        current_tetrimino_x = grid_width // 2 - len(current_tetrimino[0]) // 2
        current_tetrimino_y = 0
 
        if not can_place_tetrimino(current_tetrimino, current_tetrimino_x, current_tetrimino_y):
            game_over = True
 
    # 渲染游戏界面
    window.fill(BLACK)
    draw_grid()
    draw_tetrimino(current_tetrimino, current_tetrimino_x, current_tetrimino_y, current_tetrimino_color)
    pygame.display.update()
 
    # 控制游戏帧率
    clock.tick(5)
 
# 游戏结束后退出
pygame.quit()
friendnabs 发表于 2023-5-22 16:59
仲舒 发表于 2023-5-22 16:06
可以尝试以下几种优化方法:

1. 减少绘制次数:在每一帧中,你的代码会多次调用`draw()`方法来绘制方块 ...

这明显就是chatgpt的答案
仲舒 发表于 2023-5-22 17:00
仲舒 发表于 2023-5-22 16:59
[mw_shl_code=python,true]import pygame
import random

找了以前写的一个例子,希望对你有帮助
wasd71 发表于 2023-5-22 17:26
引入pygame库和random库吗
TR小米哥 发表于 2023-5-22 18:04
有一说一,看着很不错
我试着改了下下,这么运行下去的话要好些,你可以看看。
[Python] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
import randomimport pygame
 
# 定义方块类
class Block:
    def __init__(self, shape, color, x, y):
        self._shape = shape
        self._color = color
        self.x = x
        self.y = y
 
    @property
    def shape(self):
        return self._shape
 
    @property
    def color(self):
        return self._color
 
    def draw(self, surface):
        rect = (self.x*25+1, self.y*25+1, 24, 24)
        pygame.draw.rect(surface, self.color, rect)
 
# 定义游戏类
class Game:
    def __init__(self, width=10, height=20):
        self.width = width
        self.height = height
        self._board = [[0 for x in range(self.width)] for y in range(self.height)]
        self.score = 0
        self.level = 1
        self.falling_block = None
        self.next_block = None
        self.game_over = False
 
    @property
    def board(self):
        return self._board
 
    def new_block(self):
        # 随机生成新的方块
        shapes = [
            [[[1, 1, 1, 1]], (255, 0, 0)],
            [[[1, 1], [1, 1]], (0, 255, 0)],
            [[[1, 1, 0], [0, 1, 1]], (0, 0, 255)],
            [[[0, 1, 1], [1, 1, 0]], (255, 255, 0)],
            [[[1, 1, 1], [0, 1, 0]], (0, 255, 255)],
            [[[1, 1, 0], [0, 1, 1]], (255, 0, 255)],
            [[[0, 1, 0], [1, 1, 1]], (128, 0, 128)]
        ]
        shape, color = random.choice(shapes)
        self.falling_block = Block(shape, color, self.width//2-2, 0)
        shape, color = random.choice(shapes)
        self.next_block = Block(shape, color, 0, 0)
 
    def draw_board(self, surface):
        # 绘制游戏区域
        rect = pygame.Rect(0, 0, 25, 25)
        for y in range(self.height):
            for x in range(self.width):
                rect.topleft = (x*25, y*25)
                pygame.draw.rect(surface, (255, 255, 255), rect, 1)
                if self.board[y][x]:
                    rect.topleft = (x*25+1, y*25+1)
                    pygame.draw.rect(surface, self.board[y][x], rect)
 
    def draw_falling_block(self, surface):
        # 绘制当前下落的方块
        if self.falling_block:
            for y, row in enumerate(self.falling_block.shape):
                for x, val in enumerate(row):
                    if val:
                        b = Block(self.falling_block.shape, self.falling_block.color, self.falling_block.x+x, self.falling_block.y+y)
                        b.draw(surface)
 
    def draw_next_block(self, surface):
        # 绘制下一个方块
        if self.next_block:
            for y, row in enumerate(self.next_block.shape):
                for x, val in enumerate(row):
                    if val:
                        b = Block(self.next_block.shape, self.next_block.color, self.width+x, y)
                        b.draw(surface)
 
    def move_left(self):
        # 向左移动方块
        if self.falling_block:
            if self.falling_block.x > 0 and not self.collides(self.falling_block, -1):
                self.falling_block.x -= 1
 
    def move_right(self):
        # 向右移动方块
        if self.falling_block:
            if self.falling_block.x < self.width-len(self.falling_block.shape[0]) and not self.collides(self.falling_block, 1):
                self.falling_block.x += 1
 
    def rotate(self):
        # 旋转方块
        if self.falling_block:
            tmp = list(zip(*self.falling_block.shape[::-1]))
            if self.falling_block.x + len(tmp[0]) <= self.width and not self.collides(Block(tmp, self.falling_block.color, self.falling_block.x, self.falling_block.y), 0):
                self.falling_block.shape = tmp
 
    def fall(self):
        # 下落方块
        if self.falling_block:
            if self.falling_block.y < self.height-len(self.falling_block.shape) and not self.collides(self.falling_block, 0, 1):
                self.falling_block.y += 1
                return False
            else:
                self.merge_falling_block()
                self.new_block()
                return True
 
    def merge_falling_block(self):
        # 将当前方块合并到游戏区域
        for y, row in enumerate(self.falling_block.shape):
            for x, val in enumerate(row):
                if val:
                    self.board[self.falling_block.y+y][self.falling_block.x+x] = self.falling_block.color
        # 消除填满一行的方块
        for y in range(self.height):
            if all(self.board[y]):
                self.board.pop(y)
                self.board.insert(0, [0 for x in range(self.width)])
                self.score += 10
                if self.score % 100 == 0:
                    self.level += 1
 
    @staticmethod
    def collides(block, dx=0, dy=0, board=None):
        # 判断方块是否与游戏区域或已有方块重叠
        board = board or []
        for y, row in enumerate(block.shape):
            for x, val in enumerate(row):
                if val:
                    try:
                        if board[block.y+y+dy][block.x+x+dx]:
                            return True
                    except IndexError:
                        return True
        return False
 
# 游戏主循环
def main():
    pygame.init()
    screen = pygame.display.set_mode((320, 480))
    clock = pygame.time.Clock()
    game = Game()
    game.new_block()
    paused = False
    font = pygame.font.SysFont('Arial', 20)
    while not game.game_over:
        clock.tick(game.level * 5)
        screen.fill((0, 0, 0))
        game.draw_board(screen)
        game.draw_falling_block(screen)
        game.draw_next_block(screen)
 
        # 显示分数
        text = font.render('Score: ' + str(game.score), True, (255, 255, 255))
        screen.blit(text, (10, 10))
 
        # 监听键盘事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game.game_over = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    game.move_left()
                elif event.key == pygame.K_RIGHT:
                    game.move_right()
                elif event.key == pygame.K_UP:
                    game.rotate()
                elif event.key == pygame.K_DOWN:
                    if not paused:
                        game.fall()
                elif event.key == pygame.K_p:
                    paused = not paused
                elif event.key == pygame.K_SPACE:
                    if paused:
                        game = Game()
                        game.new_block()
                        paused = False
        # 游戏暂停时不更新屏幕
        if not paused:
            if game.fall():
                if game.collides(game.falling_block, 0, 0, game.board):
                    # 游戏结束
                    text = font.render('Game Over', True, (255, 255, 255))
                    screen.blit(text, (100, 200))
                    paused = True
 
        pygame.display.update()
    pygame.quit()
 
if __name__ == '__main__':
    main()

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
suneryzgg123 + 1 + 1 谢谢@Thanks!

查看全部评分

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-5-29 06:11

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表