当前位置: 首页 > news >正文

上班无聊用python写一个摸鱼小游戏:数字碰撞

上班摸鱼小游戏

游戏名字叫:《数字碰撞》
你推过推箱子,你也玩过消消乐,并且你也是一个数学天才,所以这个小小游戏你完全可以拿捏。
1、效果图
2、游戏规则
3、游戏画面
4、源码

1、游戏主要有两种模式:经典模式和闯关模式

主界面

经典模式就是只要你得到2048这个数即可。而闯关模式,第一关从8开始,我设置了100关[哈哈哈哈哈]。
在这里插入图片描述
不用我说,第100关的数字,你们口算都能算出来,我也来口算一下
在这里插入图片描述
这个数:5070602400912917605986812821504
笑死[哈哈哈哈哈哈]

2、游戏规则

游戏规则

3、游戏画面

经典模式
闯关模式

4、代码

这里有一个智能家居项目可以看看(开源)

# -*- coding: utf-8 -*-
import pygame
import random
import sys
import os
from pygame.locals import *# 初始化配置
pygame.init()
CELL_SIZE = 100
GRID_PADDING = 10
GRID_SIZE = 4
WIDTH = CELL_SIZE * GRID_SIZE + GRID_PADDING * (GRID_SIZE + 1)
HEIGHT = WIDTH + 240  # 增加高度以适应更多按钮和信息
FPS = 60
MAX_LEVEL = 100  # 最大关卡数
START_TARGET = 8  # 第一关目标# 颜色配置 - 更新到更大的数字
COLORS = {0: (204, 192, 179),2: (238, 228, 218),4: (237, 224, 200),8: (242, 177, 121),16: (245, 149, 99),32: (246, 124, 95),64: (246, 94, 59),128: (237, 207, 114),256: (237, 204, 97),512: (237, 200, 80),1024: (237, 197, 63),2048: (237, 194, 46),4096: (237, 190, 30),8192: (237, 187, 15),16384: (237, 183, 0),32768: (60, 58, 50),65536: (45, 60, 50),131072: (30, 60, 50),"bg": (187, 173, 160),"text": (119, 110, 101),"button": (143, 122, 102),"button_hover": (165, 142, 122),"text_light": (249, 246, 242),"level": (237, 194, 46),"level_text": (255, 215, 0),"selected": (100, 200, 100)
}# 创建游戏窗口
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("2048 游戏 - 经典与闯关模式")
clock = pygame.time.Clock()def load_font(size):"""加载字体,确保中文显示正常"""font = Nonefont_file = "simhei.ttf"if os.path.exists(font_file):try:font = pygame.font.Font(font_file, size)test_surface = font.render(" 测试", True, (0, 0, 0))if test_surface.get_width() > 0:return fontexcept:passsystem_fonts = ["Microsoft YaHei","SimHei","STHeiti","WenQuanYi Zen Hei"]for font_name in system_fonts:try:font = pygame.font.SysFont(font_name, size)test_surface = font.render(" 测试", True, (0, 0, 0))if test_surface.get_width() > 0:return fontexcept:continuereturn pygame.font.Font(None, size)# 加载字体
try:font_large = load_font(48)font_medium = load_font(36)font_small = load_font(18)test_text = font_small.render(" 测试", True, (0, 0, 0))if test_text.get_width() == 0:raise Exception("字体加载失败")
except Exception as e:print(f"字体加载错误: {e}")font_large = pygame.font.Font(None, 48)font_medium = pygame.font.Font(None, 36)font_small = pygame.font.Font(None, 24)class Game2048:def __init__(self):self.reset_game()self.game_mode = "classic"  # classic/levelself.level = 1self.level_target = START_TARGETself.level_completed = Falsedef reset_game(self):self.grid = [[0] * GRID_SIZE for _ in range(GRID_SIZE)]self.score = 0self.high_score = self.load_high_score()self.add_random_tile()self.add_random_tile()self.game_over = Falseself.win = Falseself.level_completed = Falsedef reset_level_mode(self, level=1):self.level = levelself.level_target = START_TARGET * (2 ** (level - 1))self.reset_game()def load_high_score(self):try:with open("highscore.txt", "r", encoding='utf-8') as f:return int(f.read())except:return 0def save_high_score(self):if self.score > self.high_score:self.high_score = self.scorewith open("highscore.txt", "w", encoding='utf-8') as f:f.write(str(self.score))def save_level_progress(self):"""保存关卡进度"""if self.game_mode == "level":with open("level_progress.txt", "w", encoding='utf-8') as f:f.write(f"{self.level},{self.level_target}")def load_level_progress(self):"""加载关卡进度"""try:with open("level_progress.txt", "r", encoding='utf-8') as f:level, target = f.read().split(',')self.level = int(level)self.level_target = int(target)except:self.level = 1self.level_target = START_TARGETdef add_random_tile(self):empty_cells = [(i, j) for i in range(GRID_SIZE)for j in range(GRID_SIZE) if self.grid[i][j] == 0]if empty_cells:i, j = random.choice(empty_cells)self.grid[i][j] = 2 if random.random() < 0.9 else 4def move(self, direction):if self.game_over or self.level_completed:return Falsemoved = Falseold_grid = [row[:] for row in self.grid]if direction == 0:  # 上self.grid = [list(row) for row in zip(*self.grid)]elif direction == 1:  # 右self.grid = [row[::-1] for row in self.grid]elif direction == 2:  # 下self.grid = [list(row)[::-1] for row in zip(*self.grid)]for i in range(GRID_SIZE):new_row = [num for num in self.grid[i] if num != 0]merged_row = []skip = Falsefor j in range(len(new_row)):if skip:skip = Falsecontinueif j < len(new_row) - 1 and new_row[j] == new_row[j + 1]:merged_num = new_row[j] * 2merged_row.append(merged_num)self.score += merged_num# 闯关模式胜利条件判断if self.game_mode == "level" and merged_num >= self.level_target:self.win = Trueself.level_completed = Trueelif self.game_mode == "classic" and merged_num == 2048:self.win = Trueskip = Trueelse:merged_row.append(new_row[j])merged_row += [0] * (GRID_SIZE - len(merged_row))if self.grid[i] != merged_row:moved = Trueself.grid[i] = merged_rowif direction == 0:  # 还原上self.grid = [list(row) for row in zip(*self.grid)]elif direction == 1:  # 还原右self.grid = [row[::-1] for row in self.grid]elif direction == 2:  # 还原下self.grid = [list(row) for row in zip(*self.grid)][::-1]if moved and self.grid != old_grid:self.add_random_tile()self.check_game_over()return moveddef next_level(self):"""进入下一关"""if self.game_mode == "level" and self.level < MAX_LEVEL:self.level += 1self.level_target *= 2  # 目标翻倍self.save_level_progress()self.reset_game()def check_game_over(self):if any(0 in row for row in self.grid):returnfor i in range(GRID_SIZE):for j in range(GRID_SIZE - 1):if self.grid[i][j] == self.grid[i][j + 1]:returnfor j in range(GRID_SIZE):for i in range(GRID_SIZE - 1):if self.grid[i][j] == self.grid[i + 1][j]:returnself.game_over = Trueself.save_high_score()if self.game_mode == "level":self.save_level_progress()def draw(self):screen.fill(COLORS["bg"])# 绘制游戏模式信息mode_text = font_small.render(f"模式: {'闯关模式' if self.game_mode == 'level' else '经典模式'}",True, COLORS["text_light"])screen.blit(mode_text, (20, HEIGHT - 210))# 闯关模式显示关卡信息if self.game_mode == "level":level_text = font_small.render(f"第{self.level} 关: 目标 {self.level_target}",True, COLORS["level_text"])screen.blit(level_text, (20, HEIGHT - 180))# 绘制分数score_text = font_small.render(f" 分数: {self.score}", True, (255, 255, 255))high_score_text = font_small.render(f" 最高分: {self.high_score}", True, (255, 255, 255))screen.blit(score_text, (20, HEIGHT - 150))screen.blit(high_score_text, (20, HEIGHT - 120))# 绘制网格for i in range(GRID_SIZE):for j in range(GRID_SIZE):value = self.grid[i][j]# 为更大的数字提供颜色if value > 131072:color = (15, 60, 50)  # 更大的数字颜色else:color = COLORS.get(value, COLORS[0])pygame.draw.rect(screen, color,(GRID_PADDING + j * (CELL_SIZE + GRID_PADDING),GRID_PADDING + i * (CELL_SIZE + GRID_PADDING),CELL_SIZE, CELL_SIZE),border_radius=5)if value > 0:text_color = COLORS["text"] if value < 8 else (249, 246, 242)text = font_medium.render(str(value), True, text_color)text_rect = text.get_rect(center=(GRID_PADDING + j * (CELL_SIZE + GRID_PADDING) + CELL_SIZE // 2,GRID_PADDING + i * (CELL_SIZE + GRID_PADDING) + CELL_SIZE // 2))screen.blit(text, text_rect)# 绘制按钮 - 根据游戏模式决定按钮数量button_rects = []# 始终显示的按钮if self.game_mode == "classic":buttons = [("重新开始", WIDTH * 1 / 5, HEIGHT - 50),("游戏规则", WIDTH * 2 / 4, HEIGHT - 50),("返回", WIDTH * 4 / 5, HEIGHT - 50)]else:buttons = [("重新开始", WIDTH * 1 / 7, HEIGHT - 50),("规则", WIDTH * 3 / 8, HEIGHT - 50),("关卡选择", WIDTH * 5 / 8, HEIGHT - 50),("返回", WIDTH * 6 / 7, HEIGHT - 50)]mouse_pos = pygame.mouse.get_pos()for text, x, y in buttons:# 根据文本长度动态调整按钮宽度text_width = font_small.size(text)[0]button_width = max(text_width + 30, 100)  # 最小宽度100rect = pygame.Rect(0, 0, button_width, 40)rect.center = (x, y)hover = rect.collidepoint(mouse_pos)color = COLORS["button_hover"] if hover else COLORS["button"]pygame.draw.rect(screen, color, rect, border_radius=5)pygame.draw.rect(screen, (255, 255, 255), rect, 2, border_radius=5)text_surf = font_small.render(text, True, (255, 255, 255))text_rect = text_surf.get_rect(center=rect.center)screen.blit(text_surf, text_rect)button_rects.append((text, rect))# 游戏状态提示if self.game_over:self.draw_overlay(" 游戏结束!", (255, 100, 100))elif self.win:if self.game_mode == "level" and self.level_completed:return self.draw_level_win(), button_rectselse:self.draw_overlay(" 恭喜获胜!", (237, 194, 46))return button_rectsdef draw_level_win(self):"""闯关模式胜利界面"""overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)overlay.fill((*COLORS["level"], 180))screen.blit(overlay, (0, 0))win_text = font_large.render(f" 第{self.level} 关完成!", True, (255, 255, 255))win_rect = win_text.get_rect(center=(WIDTH // 2, HEIGHT // 2 - 50))screen.blit(win_text, win_rect)# 下一关按钮next_button_rect = pygame.Rect(0, 0, 200, 50)next_button_rect.center = (WIDTH // 2, HEIGHT // 2 + 30)mouse_pos = pygame.mouse.get_pos()hover = next_button_rect.collidepoint(mouse_pos)color = COLORS["button_hover"] if hover else COLORS["button"]pygame.draw.rect(screen, color, next_button_rect, border_radius=10)pygame.draw.rect(screen, (255, 255, 255), next_button_rect, 2, border_radius=10)next_text = font_medium.render(" 进入下一关", True, (255, 255, 255))next_rect = next_text.get_rect(center=next_button_rect.center)screen.blit(next_text, next_rect)return next_button_rectdef draw_overlay(self, text, color):overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)overlay.fill((*color, 180))screen.blit(overlay, (0, 0))text_surf = font_large.render(text, True, (255, 255, 255))text_rect = text_surf.get_rect(center=(WIDTH // 2, HEIGHT // 2 - 50))screen.blit(text_surf, text_rect)restart_text = font_small.render(" 按R键重新开始", True, (255, 255, 255))restart_rect = restart_text.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 20))screen.blit(restart_text, restart_rect)def draw_rules(self):screen.fill(COLORS["bg"])title = font_large.render("2048 游戏规则", True, COLORS["text"])screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 30))rules = ["1. 使用方向键 ↑ ↓ ← → 移动方块","2. 相同数字的方块会合并相加","3. 每次移动后在空白处生成2或4","4. 经典模式: 合并出2048获胜",f"5. 闯关模式: 共{MAX_LEVEL}关,目标为{START_TARGET}开始","6. 无法移动时游戏结束"]for i, rule in enumerate(rules):text = font_small.render(rule, True, COLORS["text"])screen.blit(text, (50, 100 + i * 40))# 返回按钮back_rect = pygame.Rect(WIDTH // 2 - 70, HEIGHT - 80, 140, 40)hover = back_rect.collidepoint(pygame.mouse.get_pos())color = COLORS["button_hover"] if hover else COLORS["button"]pygame.draw.rect(screen, color, back_rect, border_radius=5)pygame.draw.rect(screen, (255, 255, 255), back_rect, 2, border_radius=5)text = font_small.render(" 返回游戏", True, (255, 255, 255))text_rect = text.get_rect(center=back_rect.center)screen.blit(text, text_rect)return back_rectdef show_menu():screen.fill(COLORS["bg"])title = font_large.render("2048 游戏", True, COLORS["text"])screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 100))buttons = []options = [("经典模式", WIDTH // 2, 250),("闯关模式", WIDTH // 2, 330),("退出游戏", WIDTH // 2, 410)]for text, x, y in options:rect = pygame.Rect(0, 0, 200, 50)rect.center = (x, y)hover = rect.collidepoint(pygame.mouse.get_pos())color = COLORS["button_hover"] if hover else COLORS["button"]pygame.draw.rect(screen, color, rect, border_radius=10)pygame.draw.rect(screen, (255, 255, 255), rect, 2, border_radius=10)text_surf = font_medium.render(text, True, (255, 255, 255))text_rect = text_surf.get_rect(center=rect.center)screen.blit(text_surf, text_rect)buttons.append((text, rect))pygame.display.flip()return buttonsdef show_level_select(current_level=1):screen.fill(COLORS["bg"])title = font_large.render(" 选择关卡", True, COLORS["text"])screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 30))# 分页设计,每页显示20个关卡levels_per_page = 20total_pages = (MAX_LEVEL + levels_per_page - 1) // levels_per_page# 当前页码page = (current_level - 1) // levels_per_pagestart_level = page * levels_per_page + 1end_level = min((page + 1) * levels_per_page, MAX_LEVEL)# 显示当前页码page_text = font_small.render(f" 第 {page + 1}/{total_pages} 页", True, COLORS["text"])screen.blit(page_text, (WIDTH // 2 - page_text.get_width() // 2, 80))# 绘制关卡按钮level_buttons = []rows = 4cols = 5button_size = 60padding = 10start_x = WIDTH // 2 - (cols * button_size + (cols - 1) * padding) // 2start_y = 120for i in range(rows):for j in range(cols):level_num = start_level + i * cols + jif level_num > end_level:breakx = start_x + j * (button_size + padding)y = start_y + i * (button_size + padding)rect = pygame.Rect(x, y, button_size, button_size)hover = rect.collidepoint(pygame.mouse.get_pos())# 当前选择的关卡特殊显示if level_num == current_level:color = COLORS["selected"]else:color = COLORS["button_hover"] if hover else COLORS["button"]pygame.draw.rect(screen, color, rect, border_radius=5)pygame.draw.rect(screen, (255, 255, 255), rect, 2, border_radius=5)level_text = font_small.render(str(level_num), True, (255, 255, 255))level_rect = level_text.get_rect(center=rect.center)screen.blit(level_text, level_rect)level_buttons.append((level_num, rect))# 绘制翻页按钮nav_buttons = []if page > 0:prev_rect = pygame.Rect(20, HEIGHT - 60, 100, 40)pygame.draw.rect(screen, COLORS["button"], prev_rect, border_radius=5)pygame.draw.rect(screen, (255, 255, 255), prev_rect, 2, border_radius=5)prev_text = font_small.render(" 上一页", True, (255, 255, 255))prev_rect_text = prev_text.get_rect(center=prev_rect.center)screen.blit(prev_text, prev_rect_text)nav_buttons.append(("prev", prev_rect))if page < total_pages - 1:next_rect = pygame.Rect(WIDTH - 120, HEIGHT - 60, 100, 40)pygame.draw.rect(screen, COLORS["button"], next_rect, border_radius=5)pygame.draw.rect(screen, (255, 255, 255), next_rect, 2, border_radius=5)next_text = font_small.render(" 下一页", True, (255, 255, 255))next_rect_text = next_text.get_rect(center=next_rect.center)screen.blit(next_text, next_rect_text)nav_buttons.append(("next", next_rect))# 返回按钮back_rect = pygame.Rect(WIDTH // 2 - 50, HEIGHT - 60, 100, 40)pygame.draw.rect(screen, COLORS["button"], back_rect, border_radius=5)pygame.draw.rect(screen, (255, 255, 255), back_rect, 2, border_radius=5)back_text = font_small.render(" 返回", True, (255, 255, 255))back_rect_text = back_text.get_rect(center=back_rect.center)screen.blit(back_text, back_rect_text)nav_buttons.append(("back", back_rect))pygame.display.flip()return level_buttons, nav_buttonsdef main():game = Game2048()current_screen = "menu"running = Trueselected_level = 1  # 当前选中的关卡while running:button_rects = []level_buttons = []nav_buttons = []if current_screen == "menu":button_rects = show_menu()elif current_screen == "game":buttons = game.draw()if isinstance(buttons, tuple):  # 处理关卡胜利界面next_button_rect, regular_buttons = buttonsbutton_rects = regular_buttonsbutton_rects.append(("next_level", next_button_rect))else:button_rects = buttonselif current_screen == "rules":back_rect = game.draw_rules()button_rects = [("返回", back_rect)]elif current_screen == "level_select":level_buttons, nav_buttons = show_level_select(selected_level)pygame.display.flip()clock.tick(FPS)for event in pygame.event.get():if event.type == QUIT:running = Falseelif event.type == KEYDOWN:if current_screen == "game":if event.key in (K_UP, K_w):game.move(0)elif event.key in (K_RIGHT, K_d):game.move(1)elif event.key in (K_DOWN, K_s):game.move(2)elif event.key in (K_LEFT, K_a):game.move(3)elif event.key == K_r:if game.game_mode == "level":game.reset_level_mode(selected_level if current_screen == "level_select" else game.level)else:game.reset_game()if event.key == K_ESCAPE:if current_screen in ["rules", "level_select"]:current_screen = "menu"elif current_screen == "game":current_screen = "menu"elif event.type == MOUSEBUTTONDOWN and event.button == 1:mouse_pos = pygame.mouse.get_pos()# 处理主菜单按钮if current_screen == "menu":for btn_text, btn_rect in button_rects:if btn_rect.collidepoint(mouse_pos):if btn_text == "经典模式":game.game_mode = "classic"game.reset_game()current_screen = "game"elif btn_text == "闯关模式":game.game_mode = "level"game.load_level_progress()selected_level = game.levelcurrent_screen = "level_select"elif btn_text == "退出游戏":running = False# 处理游戏内按钮elif current_screen == "game":for btn_text, btn_rect in button_rects:if btn_rect.collidepoint(mouse_pos):if btn_text == "重新开始":if game.game_mode == "level":game.reset_level_mode(selected_level if current_screen == "level_select" else game.level)else:game.reset_game()elif btn_text == "规则":current_screen = "rules"elif btn_text == "关卡选择" and game.game_mode == "level":current_screen = "level_select"elif btn_text == "返回":current_screen = "menu"elif btn_text == "next_level":game.next_level()# 处理规则界面按钮elif current_screen == "rules":for btn_text, btn_rect in button_rects:if btn_rect.collidepoint(mouse_pos):if btn_text == "返回":current_screen = "game"# 处理关卡选择界面elif current_screen == "level_select":# 检查关卡按钮for level_num, btn_rect in level_buttons:if btn_rect.collidepoint(mouse_pos):selected_level = level_numgame.reset_level_mode(level_num)current_screen = "game"# 检查翻页按钮for btn_type, btn_rect in nav_buttons:if btn_rect.collidepoint(mouse_pos):if btn_type == "prev":selected_level = max(1, selected_level - 20)elif btn_type == "next":selected_level = min(MAX_LEVEL, selected_level + 20)elif btn_type == "back":current_screen = "menu"pygame.quit()sys.exit()if __name__ == "__main__":main()
http://www.xdnf.cn/news/230743.html

相关文章:

  • conda管理python环境
  • 2025年渗透测试面试题总结-拷打题库28(题目+回答)
  • 前端跨域问题详解:原因、解决方案与最佳实践
  • Doris索引机制全解析,如何用高效索引加速数据分析
  • PCB设计工艺规范(一)概述
  • 树莓派智能摄像头实战指南:基于TensorFlow Lite的端到端AI部署
  • Docker进入MySQL之后如何用sql文件初始化数据
  • 阿里云服务迁移实战: 07-其他服务迁移
  • Learning vtkjs之ImageStreamline
  • 【Fifty Project - D21】
  • w314基于java无人超市管理系统设计与实现
  • 【数据库原理及安全实验】实验五 数据库备份与恢复
  • 短视频矩阵系统贴牌开发实战:批量剪辑文件夹功能设计与实现
  • mybatis-plus 枚举实现模版,导入,导出
  • JVM——Java的基本类型的实现
  • 【ArcGISPro学习笔记】布局输出时图例总是有省略号怎么办?
  • 大连理工大学选修课——机器学习笔记(1):概述
  • 【c++】【STL】list详解
  • Laravel + Vue 3 (Vite、TypeScript) SPA 设置全攻略
  • 在Windows系统上如何用Manifest管理嵌入式项目
  • SVTAV1 编码函数 svt_aom_is_pic_skipped
  • 逻辑回归在信用卡欺诈检测中的实战应用
  • 解决GoLand无法Debug的问题
  • GCC-C语言“自定义段”
  • 2025东三省B题深圳杯B题数学建模挑战赛数模思路代码文章教学
  • AI Agent新范式:FastGPT+MCP协议实现工具增强型智能体构建
  • 2024睿抗CAIP-编程技能赛-本科组(省赛)题解
  • 软考:硬件中的CPU架构、存储系统(Cache、虚拟内存)、I/O设备与接口
  • iview内存泄漏
  • Copilot重磅更新:引用文件夹创建Word文档