From 6849da209f0fc8c8b0c5b438d4ee067479368b48 Mon Sep 17 00:00:00 2001 From: zengxh Date: Sat, 12 Jul 2025 14:07:04 +0000 Subject: [PATCH] =?UTF-8?q?update=20main.py.=20=E4=B8=BB=E8=A6=81=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E4=BA=86=E9=A3=9F=E7=89=A9=E7=94=9F=E6=88=90=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=81=E5=88=86=E6=95=B0?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E4=BC=98=E5=8C=96=E4=BA=86=E6=B8=B8=E6=88=8F=E4=BD=93?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zengxh --- main.py | 216 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 122 insertions(+), 94 deletions(-) diff --git a/main.py b/main.py index 724fc84..0e73489 100644 --- a/main.py +++ b/main.py @@ -5,157 +5,185 @@ import random # 全局定义 SCREEN_X = 600 SCREEN_Y = 600 +GRID_SIZE = 25 # 网格大小,用于控制蛇和食物的位置精度 # 蛇类 -# 点以25为单位 +# 点以GRID_SIZE为单位 class Snake(object): # 初始化各种需要的属性 [开始时默认向右/身体块x5] def __init__(self): - self.dirction = pygame.K_RIGHT + self.direction = pygame.K_RIGHT self.body = [] for x in range(5): - self.addnode() - + self.add_node() + # 无论何时 都在前端增加蛇块 - def addnode(self): - left,top = (0,0) + def add_node(self): + left, top = (0, 0) if self.body: - left,top = (self.body[0].left,self.body[0].top) - node = pygame.Rect(left,top,25,25) - if self.dirction == pygame.K_LEFT: - node.left -= 25 - elif self.dirction == pygame.K_RIGHT: - node.left += 25 - elif self.dirction == pygame.K_UP: - node.top -= 25 - elif self.dirction == pygame.K_DOWN: - node.top += 25 - self.body.insert(0,node) - + left, top = (self.body[0].left, self.body[0].top) + node = pygame.Rect(left, top, GRID_SIZE, GRID_SIZE) + if self.direction == pygame.K_LEFT: + node.left -= GRID_SIZE + elif self.direction == pygame.K_RIGHT: + node.left += GRID_SIZE + elif self.direction == pygame.K_UP: + node.top -= GRID_SIZE + elif self.direction == pygame.K_DOWN: + node.top += GRID_SIZE + self.body.insert(0, node) + # 删除最后一个块 - def delnode(self): + def del_node(self): self.body.pop() - + # 死亡判断 - def isdead(self): + def is_dead(self): # 撞墙 - if self.body[0].x not in range(SCREEN_X): + if self.body[0].x not in range(0, SCREEN_X, GRID_SIZE): return True - if self.body[0].y not in range(SCREEN_Y): + if self.body[0].y not in range(0, SCREEN_Y, GRID_SIZE): return True # 撞自己 if self.body[0] in self.body[1:]: return True return False - + # 移动! def move(self): - self.addnode() - self.delnode() - + self.add_node() + self.del_node() + # 改变方向 但是左右、上下不能被逆向改变 - def changedirection(self,curkey): - LR = [pygame.K_LEFT,pygame.K_RIGHT] - UD = [pygame.K_UP,pygame.K_DOWN] - if curkey in LR+UD: - if (curkey in LR) and (self.dirction in LR): + def change_direction(self, cur_key): + LR = [pygame.K_LEFT, pygame.K_RIGHT] + UD = [pygame.K_UP, pygame.K_DOWN] + if cur_key in LR + UD: + if (cur_key in LR) and (self.direction in LR): return - if (curkey in UD) and (self.dirction in UD): + if (cur_key in UD) and (self.direction in UD): return - self.dirction = curkey - - + self.direction = cur_key + + # 食物类 # 方法: 放置/移除 -# 点以25为单位 class Food: - def __init__(self): - self.rect = pygame.Rect(-25,0,25,25) - + def __init__(self, grid_size=GRID_SIZE): + self.grid_size = grid_size + self.rect = pygame.Rect(-grid_size, 0, grid_size, grid_size) + def remove(self): - self.rect.x=-25 - - def set(self): - if self.rect.x == -25: - allpos = [] - # 不靠墙太近 25 ~ SCREEN_X-25 之间 - for pos in range(25,SCREEN_X-25,25): - allpos.append(pos) - self.rect.left = random.choice(allpos) - self.rect.top = random.choice(allpos) - print(self.rect) + self.rect.x = -self.grid_size + + def set(self, snake_body, screen_width=SCREEN_X, screen_height=SCREEN_Y): + if self.rect.x == -self.grid_size: + # 生成食物时考虑更灵活的位置,仍然使用网格,但允许更靠近边缘 + # 生成所有可能的位置 + all_positions = [] + for x in range(0, screen_width, self.grid_size): + for y in range(0, screen_height, self.grid_size): + pos = pygame.Rect(x, y, self.grid_size, self.grid_size) + # 确保食物不会生成在蛇身上 + if pos not in snake_body: + all_positions.append(pos) + if all_positions: + self.rect = random.choice(all_positions) + else: + # 如果没有可用位置(理论上不会发生),重置食物 + self.rect = pygame.Rect(-self.grid_size, 0, self.grid_size, self.grid_size) + -def show_text(screen, pos, text, color, font_bold = False, font_size = 60, font_italic = False): - #获取系统字体,并设置文字大小 - cur_font = pygame.font.SysFont("宋体", font_size) - #设置是否加粗属性 - cur_font.set_bold(font_bold) - #设置是否斜体属性 - cur_font.set_italic(font_italic) - #设置文字内容 - text_fmt = cur_font.render(text, 1, color) - #绘制文字 +def show_text(screen, pos, text, color, font_bold=False, font_size=60, font_italic=False): + # 获取系统字体,并设置文字大小 + cur_font = pygame.font.SysFont("宋体", font_size) + # 设置是否加粗属性 + cur_font.set_bold(font_bold) + # 设置是否斜体属性 + cur_font.set_italic(font_italic) + # 设置文字内容 + text_fmt = cur_font.render(text, 1, color) + # 绘制文字 screen.blit(text_fmt, pos) - + def main(): pygame.init() - screen_size = (SCREEN_X,SCREEN_Y) + screen_size = (SCREEN_X, SCREEN_Y) screen = pygame.display.set_mode(screen_size) pygame.display.set_caption('Snake') clock = pygame.time.Clock() scores = 0 - isdead = False + is_dead = False # 蛇/食物 snake = Snake() food = Food() + # 生成第一个食物 + food.set(snake.body) + + # 游戏状态:0-准备开始,1-游戏进行中,2-游戏结束 + game_state = 0 + while True: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if event.type == pygame.KEYDOWN: - snake.changedirection(event.key) - # 死后按space重新 - if event.key == pygame.K_SPACE and isdead: - return main() + if game_state == 0 and event.key == pygame.K_SPACE: + game_state = 1 # 开始游戏 + elif game_state == 1: + snake.change_direction(event.key) + elif game_state == 2 and event.key == pygame.K_SPACE: + return main() # 重新开始游戏 - - screen.fill((255,255,255)) + screen.fill((255, 255, 255)) - # 画蛇身 / 每一步+1分 - if not isdead: - scores+=1 + if game_state == 0: + # 显示开始游戏提示 + show_text(screen, (100, 200), 'SNAKE GAME', (20, 220, 39), True, 80) + show_text(screen, (150, 300), 'Press SPACE to start', (0, 0, 22), False, 30) + + elif game_state == 1: + # 游戏进行中 + # 移动蛇 snake.move() - for rect in snake.body: - pygame.draw.rect(screen,(20,220,39),rect,0) - # 显示死亡文字 - isdead = snake.isdead() - if isdead: - show_text(screen,(100,200),'YOU DEAD!',(227,29,18),False,100) - show_text(screen,(150,260),'press space to try again...',(0,0,22),False,30) + # 检查是否吃到食物 + if food.rect == snake.body[0]: + scores += 50 + food.remove() + snake.add_node() + # 生成新食物 + food.set(snake.body) - # 食物处理 / 吃到+50分 - # 当食物rect与蛇头重合,吃掉 -> Snake增加一个Node - if food.rect == snake.body[0]: - scores+=50 - food.remove() - snake.addnode() - - # 食物投递 - food.set() - pygame.draw.rect(screen,(136,0,21),food.rect,0) + # 检查是否死亡 + is_dead = snake.is_dead() + if is_dead: + game_state = 2 + + # 画蛇身 + for rect in snake.body: + pygame.draw.rect(screen, (20, 220, 39), rect, 0) + + # 画食物 + pygame.draw.rect(screen, (136, 0, 21), food.rect, 0) + + # 显示分数文字 + show_text(screen, (50, 500), 'Scores: ' + str(scores), (0, 0, 0)) - # 显示分数文字 - show_text(screen,(50,500),'Scores: '+str(scores),(223,223,223)) + elif game_state == 2: + # 显示死亡文字 + show_text(screen, (100, 200), 'YOU DIED!', (227, 29, 18), False, 100) + show_text(screen, (150, 260), f'Final Score: {scores}', (0, 0, 22), False, 40) + show_text(screen, (150, 320), 'Press SPACE to try again...', (0, 0, 22), False, 30) pygame.display.update() clock.tick(10) - - + + if __name__ == '__main__': main() \ No newline at end of file -- Gitee