diff --git a/GameCollection/1.png b/GameCollection/1.png new file mode 100644 index 0000000..71ccde0 Binary files /dev/null and b/GameCollection/1.png differ diff --git a/GameCollection/2.png b/GameCollection/2.png new file mode 100644 index 0000000..1feb54b Binary files /dev/null and b/GameCollection/2.png differ diff --git a/GameCollection/2048.png b/GameCollection/2048.png new file mode 100644 index 0000000..3f9ef35 Binary files /dev/null and b/GameCollection/2048.png differ diff --git a/GameCollection/3.png b/GameCollection/3.png new file mode 100644 index 0000000..55e4545 Binary files /dev/null and b/GameCollection/3.png differ diff --git a/GameCollection/4.png b/GameCollection/4.png new file mode 100644 index 0000000..a161d55 Binary files /dev/null and b/GameCollection/4.png differ diff --git a/GameCollection/5.png b/GameCollection/5.png new file mode 100644 index 0000000..635a984 Binary files /dev/null and b/GameCollection/5.png differ diff --git a/GameCollection/6.png b/GameCollection/6.png new file mode 100644 index 0000000..5928583 Binary files /dev/null and b/GameCollection/6.png differ diff --git a/GameCollection/__pycache__/game_2048.cpython-314.pyc b/GameCollection/__pycache__/game_2048.cpython-314.pyc new file mode 100644 index 0000000..ec909e3 Binary files /dev/null and b/GameCollection/__pycache__/game_2048.cpython-314.pyc differ diff --git a/GameCollection/__pycache__/snack_pygame.cpython-314.pyc b/GameCollection/__pycache__/snack_pygame.cpython-314.pyc new file mode 100644 index 0000000..fc24cee Binary files /dev/null and b/GameCollection/__pycache__/snack_pygame.cpython-314.pyc differ diff --git a/GameCollection/game2048_score.npy b/GameCollection/game2048_score.npy new file mode 100644 index 0000000..13550ac Binary files /dev/null and b/GameCollection/game2048_score.npy differ diff --git a/GameCollection/game_2048.py b/GameCollection/game_2048.py new file mode 100644 index 0000000..126129f --- /dev/null +++ b/GameCollection/game_2048.py @@ -0,0 +1,259 @@ +import pygame +import numpy as np +import copy +import os +from pygame.locals import * + +BOARD_SIZE = 4 +TILE_SIZE = 100 +GRID_SIZE = 10 +WINDOW_WIDTH = BOARD_SIZE * TILE_SIZE + (BOARD_SIZE + 1) * GRID_SIZE +WINDOW_HEIGHT = WINDOW_WIDTH + 100 + +WHITE = (255, 255, 255) +BLACK = (0, 0, 0) +GRAY = (187, 173, 160) +LIGHT_GRAY = (205, 193, 180) + +COLORS = { + 0: (205, 193, 180), + 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), +} + +score = 0 +win = 0 +FILENAME = 'game2048_score.npy' + +def init(): + if FILENAME not in os.listdir(): + np.save(FILENAME, 0) + init_board = choice(np.zeros((BOARD_SIZE, BOARD_SIZE), dtype=np.int64)) + return init_board + +def choice(board): + udict = {} + count = 0 + for i in range(BOARD_SIZE): + for j in range(BOARD_SIZE): + if not board[i, j]: + udict[count] = (i, j) + count += 1 + if count == 0: + return board + random_number = np.random.randint(0, count) + two_or_four = np.random.choice([2, 2, 2, 4]) + board[udict[random_number]] = two_or_four + return board + +def basic(board): + global score + global win + for i in range(BOARD_SIZE): + flag = 1 + while flag: + flag = 0 + j = BOARD_SIZE - 2 + while j >= 0: + if board[i, j] != 0: + if board[i, j + 1] == board[i, j]: + board[i, j + 1] = 2 * board[i, j] + if board[i, j + 1] == 2048: + win = 1 + board[i, j] = 0 + score += board[i, j + 1] + flag = 1 + elif board[i, j + 1] == 0: + temp = board[i, j] + board[i, j] = board[i, j + 1] + board[i, j + 1] = temp + flag = 1 + j -= 1 + return board + +def move_right(board): + return basic(board) + +def move_up(board): + board = board[::-1, ::-1].T + board = basic(board) + board = board[::-1, ::-1].T + return board + +def move_left(board): + board = board[::-1, ::-1] + board = basic(board) + board = board[::-1, ::-1] + return board + +def move_down(board): + board = board.T + board = basic(board) + board = board.T + return board + +def fail(board): + diff1 = board[:, 1:] - board[:, :-1] + diff2 = board[1:, :] - board[:-1, :] + inter = (diff1 != 0).all() and (diff2 != 0).all() + return inter + +def load_score(): + rank_score = np.load(FILENAME) + return rank_score + +def save_score(score): + rscore = load_score() + if score > rscore: + np.save(FILENAME, score) + +def draw_board(screen, board, rscore): + global score + screen.fill(GRAY) + font = pygame.font.SysFont('Arial', 36) + small_font = pygame.font.SysFont('Arial', 24) + + score_text = small_font.render(f"Score: {score}", True, BLACK) + screen.blit(score_text, (20, 20)) + + high_text = small_font.render(f"Best: {max(score, rscore)}", True, BLACK) + screen.blit(high_text, (WINDOW_WIDTH - 120, 20)) + + for i in range(BOARD_SIZE): + for j in range(BOARD_SIZE): + x = GRID_SIZE + j * (TILE_SIZE + GRID_SIZE) + y = 80 + GRID_SIZE + i * (TILE_SIZE + GRID_SIZE) + + value = board[i, j] + color = COLORS.get(value, (60, 58, 50)) + pygame.draw.rect(screen, color, (x, y, TILE_SIZE, TILE_SIZE)) + + if value != 0: + text_color = (119, 110, 101) if value <= 4 else (255, 255, 255) + text = font.render(str(value), True, text_color) + text_rect = text.get_rect(center=(x + TILE_SIZE // 2, y + TILE_SIZE // 2)) + screen.blit(text, text_rect) + +def main(return_to_menu=False): + global score, win + pygame.init() + os.chdir(os.path.dirname(os.path.abspath(__file__))) + screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT)) + pygame.display.set_caption('2048') + + board = init() + rscore = load_score() + score = 0 + win = 0 + + running = True + is_fail = False + font2 = pygame.font.SysFont('Arial', 48) + + while running: + draw_board(screen, board, rscore) + + if win: + text = font2.render("You Win!", True, (255, 0, 0)) + text_rect = text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2)) + screen.blit(text, text_rect) + pygame.display.update() + + if is_fail: + text = font2.render("Game Over!", True, (255, 0, 0)) + text_rect = text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2)) + screen.blit(text, text_rect) + pygame.display.update() + + for event in pygame.event.get(): + if event.type == QUIT: + save_score(score) + running = False + if return_to_menu: + return 'menu' + else: + pygame.quit() + return + elif event.type == KEYDOWN: + if win or is_fail: + if event.key == K_r: + save_score(score) + board = init() + score = 0 + win = 0 + is_fail = False + continue + elif event.key == K_q or event.key == K_ESCAPE: + save_score(score) + running = False + if return_to_menu: + return 'menu' + else: + pygame.quit() + return + elif event.key == K_TAB: + save_score(score) + if return_to_menu: + return 'snake' + continue + + change = False + tempboard = copy.deepcopy(board) + + if event.key == K_UP or event.key == K_w: + board = move_up(board) + elif event.key == K_DOWN or event.key == K_s: + board = move_down(board) + elif event.key == K_LEFT or event.key == K_a: + board = move_left(board) + elif event.key == K_RIGHT or event.key == K_d: + board = move_right(board) + elif event.key == K_r: + save_score(score) + board = init() + score = 0 + win = 0 + is_fail = False + continue + elif event.key == K_q or event.key == K_ESCAPE: + save_score(score) + running = False + if return_to_menu: + return 'menu' + else: + pygame.quit() + return + elif event.key == K_TAB: + save_score(score) + if return_to_menu: + return 'snake' + continue + + if not (board == tempboard).all(): + change = True + + if change: + board = choice(board) + + if (board != 0).all(): + is_fail = fail(board) + + pygame.display.update() + + save_score(score) + if return_to_menu: + return 'menu' + else: + pygame.quit() + +if __name__ == '__main__': + main() diff --git a/GameCollection/game_launcher.py b/GameCollection/game_launcher.py new file mode 100644 index 0000000..d600cc3 --- /dev/null +++ b/GameCollection/game_launcher.py @@ -0,0 +1,120 @@ +import pygame +import sys +import os +from pygame.locals import * + +os.chdir(os.path.dirname(os.path.abspath(__file__))) + +from game_2048 import main as game_2048_main +from snack_pygame import main as snake_main + +WINDOW_WIDTH = 800 +WINDOW_HEIGHT = 600 + +WHITE = (255, 255, 255) +BLACK = (0, 0, 0) +GRAY = (100, 100, 100) +LIGHT_GRAY = (150, 150, 150) +BLUE = (0, 100, 200) +LIGHT_BLUE = (0, 150, 255) + +pygame.init() + +screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT)) +pygame.display.set_caption('Game Collection') + +def draw_text(text, font, color, x, y, center=True): + img = font.render(text, True, color) + rect = img.get_rect() + if center: + rect.center = (x, y) + else: + rect.topleft = (x, y) + screen.blit(img, rect) + return rect + +def draw_button(text, x, y, width, height, color, hover_color, font, mouse_pos, mouse_click): + rect = pygame.Rect(x, y, width, height) + if rect.collidepoint(mouse_pos): + pygame.draw.rect(screen, hover_color, rect, border_radius=10) + if mouse_click: + return True + else: + pygame.draw.rect(screen, color, rect, border_radius=10) + draw_text(text, font, WHITE, x + width // 2, y + height // 2) + return False + +def main_menu(): + title_font = pygame.font.SysFont('Arial', 60, bold=True) + button_font = pygame.font.SysFont('Arial', 30) + small_font = pygame.font.SysFont('Arial', 20) + + clock = pygame.time.Clock() + + while True: + screen.fill((20, 20, 40)) + + mouse_pos = pygame.mouse.get_pos() + mouse_click = False + + for event in pygame.event.get(): + if event.type == QUIT: + pygame.quit() + sys.exit() + elif event.type == MOUSEBUTTONDOWN: + if event.button == 1: + mouse_click = True + + draw_text('Game Collection', title_font, WHITE, WINDOW_WIDTH // 2, 100) + + if draw_button('2048', 300, 200, 200, 60, BLUE, LIGHT_BLUE, button_font, mouse_pos, mouse_click): + return '2048' + + if draw_button('Snake', 300, 300, 200, 60, BLUE, LIGHT_BLUE, button_font, mouse_pos, mouse_click): + return 'snake' + + if draw_button('Exit', 300, 400, 200, 60, GRAY, LIGHT_GRAY, button_font, mouse_pos, mouse_click): + pygame.quit() + sys.exit() + + draw_text('Press TAB to switch games while playing', small_font, LIGHT_GRAY, WINDOW_WIDTH // 2, 550) + + pygame.display.update() + clock.tick(30) + +def run_game(game_name): + pygame.display.quit() + pygame.quit() + pygame.init() + + while True: + if game_name == '2048': + result = game_2048_main(return_to_menu=True) + elif game_name == 'snake': + result = snake_main(return_menu=True) + + if result == 'menu': + break + elif result == 'snake': + game_name = 'snake' + elif result == '2048': + game_name = '2048' + + pygame.display.quit() + pygame.quit() + pygame.init() + + pygame.display.quit() + pygame.quit() + pygame.init() + global screen + screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT)) + pygame.display.set_caption('Game Collection') + +def main(): + while True: + game = main_menu() + run_game(game) + +if __name__ == '__main__': + main() diff --git a/GameCollection/snack_pygame.py b/GameCollection/snack_pygame.py new file mode 100644 index 0000000..91e1a21 --- /dev/null +++ b/GameCollection/snack_pygame.py @@ -0,0 +1,267 @@ +import pygame +import time +import numpy as np +# 此模块包含游戏所需的常量 +from pygame.locals import * + +# 设置棋盘的长宽 +BOARDWIDTH = 48 +BOARDHEIGHT = 28 +# 分数 +score = 0 + + +# 更多精彩关注微信公众号:python高效编程 +# 食物 +class Food(object): + def __init__(self): + self.item = (4, 5) + + # 画出食物 + def _draw(self, screen, i, j): + color = 255, 0, 255 + radius = 10 + width = 10 + # i:1---34 j:1---25 + position = 10 + 20 * i, 10 + 20 * j + # 画出半径为 10 的粉色实心圆 + pygame.draw.circle(screen, color, position, radius, width) + + # 随机产生食物 + def update(self, screen, enlarge, snack): + if enlarge: + self.item = np.random.randint(1, BOARDWIDTH - 2), np.random.randint(1, BOARDHEIGHT - 2) + while self.item in snack.item: + self.item = np.random.randint(1, BOARDWIDTH - 2), np.random.randint(1, BOARDHEIGHT - 2) + self._draw(screen, self.item[0], self.item[1]) + + +# 贪吃蛇 +class Snack(object): + def __init__(self): + # self.item = [(3, 25), (2, 25), (1, 25), (1,24), (1,23), + # (1,22), (1,21), (1,20), (1,19), (1,18), (1,17), (1,16)] + # x 水平方向 y 竖直方向 + # 初始方向竖直向上 + self.item = [(3, 25), (2, 25), (1, 25), (1, 24), ] + self.x = 0 + self.y = -1 + + def move(self, enlarge): + # enlarge 标记贪吃蛇有没有吃到食物 + if not enlarge: + # 吃到食物删除尾部元素 + self.item.pop() + # 新蛇头的坐标为旧蛇头坐标加上移动方向的位移 + head = (self.item[0][0] + self.x, self.item[0][1] + self.y) + # 将新的蛇头坐标插入在 list 最前面 + self.item.insert(0, head) + + def eat_food(self, food): + global score + # snack_x,snack_y 蛇头坐标 + # food_x, food_y 食物坐标 + snack_x, snack_y = self.item[0] + food_x, food_y = food.item + # 比较蛇头坐标与食物坐标 + if (food_x == snack_x) and (food_y == snack_y): + score += 100 + return 1 + else: + return 0 + + def toward(self, x, y): + # 改变蛇头朝向 + if self.x * x >= 0 and self.y * y >= 0: + self.x = x + self.y = y + + def get_head(self): + # 获取蛇头坐标 + return self.item[0] + + def draw(self, screen): + # 画出贪吃蛇 + # 蛇头为半径为 15 的红色实心圆 + radius = 15 + width = 15 + # i:1---34 j:1---25 + color = 255, 0, 0 + # position 为图形的坐标 + position = 10 + 20 * self.item[0][0], 10 + 20 * self.item[0][1] + pygame.draw.circle(screen, color, position, radius, width) + # 蛇身为半径为 10 的黄色实心圆 + radius = 10 + width = 10 + color = 255, 255, 0 + for i, j in self.item[1:]: + position = 10 + 20 * i, 10 + 20 * j + pygame.draw.circle(screen, color, position, radius, width) + + +# 初始界面 +def init_board(screen): + board_width = BOARDWIDTH + board_height = BOARDHEIGHT + color = 10, 255, 255 + width = 0 + # width:x, height:y + # 左右边框占用了 X: 0 35*20 + for i in range(board_width): + pos = i * 20, 0, 20, 20 + pygame.draw.rect(screen, color, pos, width) + pos = i * 20, (board_height - 1) * 20, 20, 20 + pygame.draw.rect(screen, color, pos, width) + # 上下边框占用了 Y: 0 26*20 + for i in range(board_height - 1): + pos = 0, 20 + i * 20, 20, 20 + pygame.draw.rect(screen, color, pos, width) + pos = (board_width - 1) * 20, 20 + i * 20, 20, 20 + pygame.draw.rect(screen, color, pos, width) + + +# 游戏失败 +def game_over(snack): + broad_x, broad_y = snack.get_head() + flag = 0 + old = len(snack.item) + new = len(set(snack.item)) + # 游戏失败的两种可能 + # 咬到自身 + if new < old: + flag = 1 + # 撞到边框 + if broad_x == 0 or broad_x == BOARDWIDTH - 1: + flag = 1 + if broad_y == 0 or broad_y == BOARDHEIGHT - 1: + flag = 1 + + if flag: + return True + else: + return False + + +# 打印字符 +def print_text(screen, font, x, y, text, color=(255, 0, 0)): + # 在屏幕上打印字符 + # text是需要打印的文本,color为字体颜色 + # (x,y)是文本在屏幕上的位置 + imgText = font.render(text, True, color) + screen.blit(imgText, (x, y)) + + +# 按键 +def press(keys, snack): + global score + # K_w 为 pygame.locals 中的常量 + # keys[K_w] 返回 True or False + # 上移 + if keys[K_w] or keys[K_UP]: + snack.toward(0, -1) + # 下移 + elif keys[K_s] or keys[K_DOWN]: + snack.toward(0, 1) + # 左移 + elif keys[K_a] or keys[K_LEFT]: + snack.toward(-1, 0) + # 右移 + elif keys[K_d] or keys[K_RIGHT]: + snack.toward(1, 0) + # 重置游戏 + elif keys[K_r]: + global return_to_menu + score = 0 + return 'reset' + # 退出游戏 + elif keys[K_ESCAPE]: + return 'quit' + # 切换游戏 + elif keys[K_TAB]: + return 'switch' + return None + + +return_to_menu = False + +def game_init(return_menu=False): + global return_to_menu + return_to_menu = return_menu + pygame.init() + screen = pygame.display.set_mode((BOARDWIDTH * 20, BOARDHEIGHT * 20)) + pygame.display.set_caption('Snake Game') + return screen + + +def game(screen): + global score, return_to_menu + snack = Snack() + food = Food() + font = pygame.font.SysFont('Arial', 20) + is_fail = False + while True: + for event in pygame.event.get(): + if event.type == QUIT: + if return_to_menu: + return 'menu' + else: + pygame.quit() + exit() + elif event.type == KEYDOWN: + if event.key == K_TAB: + if return_to_menu: + return '2048' + screen.fill((0, 0, 100)) + init_board(screen=screen) + keys = pygame.key.get_pressed() + result = press(keys, snack) + if result == 'reset': + return 'reset' + elif result == 'quit': + if return_to_menu: + return 'menu' + else: + pygame.quit() + exit() + elif result == 'switch': + if return_to_menu: + return '2048' + if is_fail: + font2 = pygame.font.Font(None, 40) + print_text(screen, font2, 400, 200, "GAME OVER", (255, 255, 255)) + if keys[K_r]: + return 'reset' + elif keys[K_ESCAPE]: + if return_to_menu: + return 'menu' + else: + pygame.quit() + exit() + if not is_fail: + enlarge = snack.eat_food(food) + text = "score: {}".format(score) + print_text(screen, font, 0, 0, text, (255, 255, 255)) + food.update(screen, enlarge, snack) + snack.move(enlarge) + is_fail = game_over(snack=snack) + snack.draw(screen) + pygame.display.update() + time.sleep(0.1) + + +def main(return_menu=False): + global score + while True: + score = 0 + screen = game_init(return_menu) + result = game(screen) + if result == 'menu': + return 'menu' + elif result == '2048': + return '2048' + elif result != 'reset': + break + + +if __name__ == '__main__': + main() diff --git "a/GameCollection/\345\212\237\350\203\275\346\250\241\345\235\227.png" "b/GameCollection/\345\212\237\350\203\275\346\250\241\345\235\227.png" new file mode 100644 index 0000000..7de6639 Binary files /dev/null and "b/GameCollection/\345\212\237\350\203\275\346\250\241\345\235\227.png" differ diff --git "a/GameCollection/\346\215\225\350\216\267.PNG" "b/GameCollection/\346\215\225\350\216\267.PNG" new file mode 100644 index 0000000..e2e3e50 Binary files /dev/null and "b/GameCollection/\346\215\225\350\216\267.PNG" differ diff --git "a/GameCollection/\346\265\201\347\250\213\344\270\200.png" "b/GameCollection/\346\265\201\347\250\213\344\270\200.png" new file mode 100644 index 0000000..d1343a8 Binary files /dev/null and "b/GameCollection/\346\265\201\347\250\213\344\270\200.png" differ