python小游戏——推箱子代码开源_python因为游戏界面面积>游戏窗口界面, 所以需要根据人物位置滚动,

♥️每天分享云计算网络运维课堂笔记,努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生!

♥️夕阳下,是最美的,绽放,愿所有的美好,再疫情结束后如约而至。

目录

一.效果呈现

二.主代码

三.cfg

四.README


一.效果呈现

二.主代码

'''
Function:
    推箱子小游戏
 
'''
import os
import sys
import cfg
import pygame
from modules import *
from itertools import chain


'''游戏地图'''
class gameMap():
    def __init__(self, num_cols, num_rows):
        self.walls = []
        self.boxes = []
        self.targets = []
        self.num_cols = num_cols
        self.num_rows = num_rows
    '''增加游戏元素'''
    def addElement(self, elem_type, col, row):
        if elem_type == 'wall':
            self.walls.append(elementSprite('wall.png', col, row, cfg))
        elif elem_type == 'box':
            self.boxes.append(elementSprite('box.png', col, row, cfg))
        elif elem_type == 'target':
            self.targets.append(elementSprite('target.png', col, row, cfg))
    '''画游戏地图'''
    def draw(self, screen):
        for elem in self.elemsIter():
            elem.draw(screen)
    '''游戏元素迭代器'''
    def elemsIter(self):
        for elem in chain(self.targets, self.walls, self.boxes):
            yield elem
    '''该关卡中所有的箱子是否都在指定位置, 在的话就是通关了'''
    def levelCompleted(self):
        for box in self.boxes:
            is_match = False
            for target in self.targets:
                if box.col == target.col and box.row == target.row:
                    is_match = True
                    break
            if not is_match:
                return False
        return True
    '''某位置是否可到达'''
    def isValidPos(self, col, row):
        if col >= 0 and row >= 0 and col < self.num_cols and row < self.num_rows:
            block_size = cfg.BLOCKSIZE
            temp1 = self.walls + self.boxes
            temp2 = pygame.Rect(col * block_size, row * block_size, block_size, block_size)
            return temp2.collidelist(temp1) == -1
        else:
            return False
    '''获得某位置的box'''
    def getBox(self, col, row):
        for box in self.boxes:
            if box.col == col and box.row == row:
                return box
        return None


'''游戏界面'''
class gameInterface():
    def __init__(self, screen):
        self.screen = screen
        self.levels_path = cfg.LEVELDIR
        self.initGame()
    '''导入关卡地图'''
    def loadLevel(self, game_level):
        with open(os.path.join(self.levels_path, game_level), 'r') as f:
            lines = f.readlines()
        # 游戏地图
        self.game_map = gameMap(max([len(line) for line in lines]) - 1, len(lines))
        # 游戏surface
        height = cfg.BLOCKSIZE * self.game_map.num_rows
        width = cfg.BLOCKSIZE * self.game_map.num_cols
        self.game_surface = pygame.Surface((width, height))
        self.game_surface.fill(cfg.BACKGROUNDCOLOR)
        self.game_surface_blank = self.game_surface.copy()
        for row, elems in enumerate(lines):
            for col, elem in enumerate(elems):
                if elem == 'p':
                    self.player = pusherSprite(col, row, cfg)
                elif elem == '*':
                    self.game_map.addElement('wall', col, row)
                elif elem == '#':
                    self.game_map.addElement('box', col, row)
                elif elem == 'o':
                    self.game_map.addElement('target', col, row)
    '''游戏初始化'''
    def initGame(self):
        self.scroll_x = 0
        self.scroll_y = 0
    '''将游戏界面画出来'''
    def draw(self, *elems):
        self.scroll()
        self.game_surface.blit(self.game_surface_blank, dest=(0, 0))
        for elem in elems:
            elem.draw(self.game_surface)
        self.screen.blit(self.game_surface, dest=(self.scroll_x, self.scroll_y))
    '''因为游戏界面面积>游戏窗口界面, 所以需要根据人物位置滚动'''
    def scroll(self):
        x, y = self.player.rect.center
        width = self.game_surface.get_rect().w
        height = self.game_surface.get_rect().h
        if (x + cfg.SCREENSIZE[0] // 2) > cfg.SCREENSIZE[0]:
            if -1 * self.scroll_x + cfg.SCREENSIZE[0] < width:
                self.scroll_x -= 2
        elif (x + cfg.SCREENSIZE[0] // 2) > 0:
            if self.scroll_x < 0:
                self.scroll_x += 2
        if (y + cfg.SCREENSIZE[1] // 2) > cfg.SCREENSIZE[1]:
            if -1 * self.scroll_y + cfg.SCREENSIZE[1] < height:
                self.scroll_y -= 2
        elif (y + 250) > 0:
            if self.scroll_y < 0:
                self.scroll_y += 2


'''某一关卡的游戏主循环'''
def runGame(screen, game_level):
    clock = pygame.time.Clock()
    game_interface = gameInterface(screen)
    game_interface.loadLevel(game_level)
    font_path = os.path.join(cfg.FONTDIR, 'simkai.ttf')
    text = '按R键重新开始本关'
    font = pygame.font.Font(font_path, 15)
    text_render = font.render(text, 1, (255, 255, 255))
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit(0)
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    next_pos = game_interface.player.move('left', is_test=True)
                    if game_interface.game_map.isValidPos(*next_pos):
                        game_interface.player.move('left')
                    else:
                        box = game_interface.game_map.getBox(*next_pos)
                        if box:
                            next_pos = box.move('left', is_test=True)
                            if game_interface.game_map.isValidPos(*next_pos):
                                game_interface.player.move('left')
                                box.move('left')
                    break
                if event.key == pygame.K_RIGHT:
                    next_pos = game_interface.player.move('right', is_test=True)


![img](https://img-blog.csdnimg.cn/img_convert/db834deebb019c9b44cc4206f90d25b2.png)
![img](https://img-blog.csdnimg.cn/img_convert/b58909f24826de344c580f651d70799d.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,箱子游戏是一个很好的练手项目,可以帮助您熟悉 Python 的 GUI 编程和游戏逻辑设计。以下是一个简单的箱子游戏代码示例,希望对您有所帮助: ```python import tkinter as tk # 定义常量 CELL_SIZE = 50 MAP_WIDTH = 8 MAP_HEIGHT = 8 BOX_IMG = tk.PhotoImage(file="box.gif") TARGET_IMG = tk.PhotoImage(file="target.gif") PLAYER_IMG = tk.PhotoImage(file="player.gif") WALL_IMG = tk.PhotoImage(file="wall.gif") # 定义游戏地图 game_map = [ ["#", "#", "#", "#", "#", "#", "#", "#"], ["#", " ", " ", " ", " ", " ", " ", "#"], ["#", " ", " ", " ", " ", " ", " ", "#"], ["#", " ", " ", " ", " ", " ", " ", "#"], ["#", " ", " ", " ", " ", " ", " ", "#"], ["#", " ", " ", " ", " ", " ", " ", "#"], ["#", " ", " ", " ", " ", " ", " ", "#"], ["#", "#", "#", "#", "#", "#", "#", "#"], ] # 定义游戏状态 player_pos = (1, 1) boxes_pos = [(3, 3), (4, 3), (5, 3)] targets_pos = [(3, 4), (4, 4), (5, 4)] # 定义游戏界面 root = tk.Tk() root.title("箱子游戏") canvas = tk.Canvas(root, width=MAP_WIDTH * CELL_SIZE, height=MAP_HEIGHT * CELL_SIZE) canvas.pack() # 加载游戏元素图片 wall_images = {} for i in range(0, 4): wall_images[i] = canvas.create_image(0, 0, image=WALL_IMG) target_images = {} for i in range(len(targets_pos)): target_images[i] = canvas.create_image(0, 0, image=TARGET_IMG) box_images = {} for i in range(len(boxes_pos)): box_images[i] = canvas.create_image(0, 0, image=BOX_IMG) player_image = canvas.create_image(0, 0, image=PLAYER_IMG) # 绘制游戏地图 def draw_map(): for i in range(MAP_HEIGHT): for j in range(MAP_WIDTH): x = j * CELL_SIZE y = i * CELL_SIZE if game_map[i][j] == "#": canvas.create_image(x, y, image=WALL_IMG) else: canvas.create_rectangle(x, y, x+CELL_SIZE, y+CELL_SIZE, fill="#F5DEB3") for i, (x, y) in enumerate(targets_pos): canvas.coords(target_images[i], x * CELL_SIZE, y * CELL_SIZE) for i, (x, y) in enumerate(boxes_pos): canvas.coords(box_images[i], x * CELL_SIZE, y * CELL_SIZE) canvas.coords(player_image, player_pos[0] * CELL_SIZE, player_pos[1] * CELL_SIZE) # 处理键盘事件 def handle_key(event): global player_pos, boxes_pos dx, dy = 0, 0 if event.keysym == "Up": dy = -1 elif event.keysym == "Down": dy = 1 elif event.keysym == "Left": dx = -1 elif event.keysym == "Right": dx = 1 new_player_pos = (player_pos[0] + dx, player_pos[1] + dy) if game_map[new_player_pos[1]][new_player_pos[0]] != "#": for i, (x, y) in enumerate(boxes_pos): if (x, y) == new_player_pos: new_box_pos = (x + dx, y + dy) if game_map[new_box_pos[1]][new_box_pos[0]] != "#" and new_box_pos not in boxes_pos: boxes_pos[i] = new_box_pos break else: return player_pos = new_player_pos draw_map() # 绑定键盘事件处理函数 root.bind("<Key&gt;", handle_key) # 绘制初始游戏地图 draw_map() # 进入主循环 root.mainloop() ``` 您需要在同一目录下准备 box.gif、target.gif、player.gif 和 wall.gif 这四张图片供代码使用。这份示例代码还有很多可以改进和优化的地方,希望可以激发您的灵感,继续完善这个小游戏。 ### 回答2: 箱子是一种经典的益智小游戏,玩家需要通过移动箱子将它们到指定位置,从而完成关卡。 在Python中,我们可以使用Tkinter库来进行界面设计。首先,我们需要创建一个窗口对象,然后在窗口中添加游戏所需的各种组件。 在箱子游戏中,我们需要一个地图来展示箱子和角色的位置。可以使用Tkinter的Canvas组件来创建一个类似于网格的图像,来表示箱子游戏的地图。然后,我们可以使用矩形和颜色来表示箱子、墙壁和目标位置游戏的核心是玩家通过键盘按键控制角色的移动。我们可以使用Tkinter的bind方法来监测键盘按键事件,并根据键盘按键的类型来改变角色的位置。 此外,我们还可以添加一些游戏操作提示和计分板等组件,以提升用户体验。 最后,我们需要编写游戏逻辑,包括判断箱子是否到目标位置、是否遇到墙壁等等。这需要使用条件判断语句和循环语句来实现。 总之,通过使用Tkinter库来进行界面设计,结合游戏逻辑的编写,我们可以用Python开发一个简单的箱子游戏。这样的小游戏既有娱乐性,又可以培养玩家的逻辑思维和问题解决能力。 ### 回答3: 箱子是一种经典的益智游戏,我们可以使用Python进行界面设计来实现箱子游戏。在界面设计中,我们可以使用Python的图形库,如Pygame或Tkinter。 首先,我们需要设计游戏的地图。地图是由一系列方块组成的矩阵,代表游戏场景。每个方块可以是墙壁、箱子、目标或玩家。我们可以使用二维数组来表示整个地图。 接着,我们需要设计玩家的移动逻辑。玩家可以通过键盘输入控制上、下、左、右移动,同时需要检测移动的合法性。如果玩家移动到目标位置,判断是否完成游戏。 然后,我们需要设计箱子的移动逻辑。箱子可以动或被动,但不能穿过墙壁或其他箱子。如果箱子动到目标位置,判断是否完成游戏。 最后,我们需要设计界面显示的逻辑。可以显示当前地图的状态,如墙壁、箱子、目标和玩家的位置。同时也需要显示游戏的操作提示和游戏完成的提示。 为了提升游戏体验和趣味性,我们可以添加一些额外功能。如显示计时器、记录最佳成绩、增加关卡难度等。 通过Python界面设计,我们可以实现箱子游戏,并提供一个友好的界面供用户进行操作和享受游戏乐趣。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值