python+pygame实现推箱子小游戏之三

在前面的讲解

python+pygame实现推箱子小游戏之一

python+pygame实现推箱子小游戏之二

已经实现了游戏的组成元素的类,从这种类的构造可以看到类的构造的基本原则尽量小,只关注这一个类,类是有边界的。当然也可以看到:两个类其实还可以再优化一下,产生一个基类,然后从这个基类派生出这两个类会更合理一些。

有了基本游戏元素,那么就可以构造一个地图了。

游戏地图的构造及相关判断动作class gameMap,主要是加载地图上对应的元素,判断是否通关,判断1和2中计算出的位置是否可以到达。这里不涉及到pygame的应用,和前端页面没有太大关系,可以理解为就是个后端的服务,是在内存中的一个模拟,后续再一并画到游戏界面即可。在分层结构中,类似于中间层。

3.1

from workerSprite import *
from gameElementSprite import *
from params import Params
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 addGameElement(self, gameelementtype, col, row):
		if gameelementtype == 'wall':
			self.walls.append(gameElementSprite('wall.png', col, row))
		elif gameelementtype == 'box':
			self.boxes.append(gameElementSprite('box.png', col, row))
		elif gameelementtype == 'target':
			self.targets.append(gameElementSprite('target.png', col, row))

注解:

1、界面上所有的箱子box,外墙wall,终点target分别组成一个列表(数组)

2、addGameElement函数中可以看到将游戏各元素实例化,包括其坐标信息,不清楚的可以查阅

python+pygame实现推箱子小游戏之二的代码,串起来还是比较好理解的。

为了将这些元素都 “画” 在游戏界面上,就添加

3.2

from workerSprite import *
from gameElementSprite import *
from params import Params
from itertools import chain

'''
构造游戏地图
'''
class gameMap():
	...
	'''
	创建游戏元素迭代器
	'''
	def elemsIter(self):
		for elemyield in chain(self.targets, self.walls, self.boxes):
			yield elemyield

	'''
	逐一画出游戏上的元素,最终完成游戏地图
	'''
	def draw(self, screen):
		for elemyield in self.elemsIter():
			elemyield.draw(screen)

注解:

1、为了画这些元素,所以首先将它们放在一起实现迭代器平时可能接触的不多,或者使用起来很少,但这个可以作为一个容器的使用场景来学习一下。这样画的时候就不需要从各个元素列表中一并读取来实现了(想象一下,如果这个列表非常大,岂不麻烦),每当 yield 被调用时,函数会生成一个新的值,然后暂停执行。当下一个值被请求时(例如,在 for 循环中的下一次迭代),函数会从上次离开的地方恢复执行,再次运行到 yield 语句,然后再次暂停。这种方法对内存的利用更高效因为我们并不需要在内存中一次性存储所有的数字。无论列表数组多大,这个生成器在任何时候都只会产生一个数字。

3.3

通过遍历该关卡中所有的箱子box是否都在指定位置target, 是的话就是通关了:

from workerSprite import *
from gameElementSprite import *
from params import Params
from itertools import chain

'''
构造游戏地图
'''
class gameMap():
	...
	'''
	通过遍历该关卡中所有的箱子box是否都在指定位置target, 是的话就是通关了
	'''
	def curLevelCompleted(self):
		for box in self.boxes:
			is_completed = False
			for target in self.targets:
				if box.col == target.col and box.row == target.row:
					is_completed = True
					break
			if not is_completed:
				return False
		return True

注解:

1、因为都是方块,所以只需要比较行,列坐标是否对应即可。

3.4

因为都是方块,所以利用python中的rect的碰撞测试函数“预判”箱子能不能移动的逻辑。

from workerSprite import *
from gameElementSprite import *
from params import Params
from itertools import chain

'''
构造游戏地图
'''
class gameMap():
	...
	'''
	判断某位置是否可到达,推到了边界或有障碍物就不能通过
	'''
	def isCanPushPos(self, col, row):
		if col >= 0 and row >= 0 and col < self.num_cols and row < self.num_rows:
			block_size = Params.get('blockSize')
			test1 = self.walls + self.boxes
			test2 = pygame.Rect(col * block_size, row * block_size, block_size, block_size)
			return test2.collidelist(test1) == -1   #pygame中rect的碰撞检测函数,本游戏都是规则的方块,所以用这最方便。
		else:
			return False

注解:

1、只有墙和箱子是障碍物,故首先test1 = self.walls + self.boxes,再测试。

2、注意测试函数collidelist,pygame中有几个类似的(spritrcollide,collide_mask,groupcollide,collide_rect...)使用的时候注意其使用场景

3.5

界面上的箱子可能有多个,所以要有获取“这个箱子”的对象的方法

from workerSprite import *
from gameElementSprite import *
from params import Params
from itertools import chain

'''
构造游戏地图
'''
class gameMap():
    ...
	'''
	获得某位置的box
	'''
	def getTheBoxByPos(self, col, row):
		for box in self.boxes:
			if box.col == col and box.row == row:
				return box
		return None

待续...

python+pygame实现推箱子小游戏之四 

  • 25
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个用Python实现推箱子小游戏的示例代码(仅供参考): ``` # 导入必要的模块 import tkinter as tk # 定义游戏界面的类 class Game(tk.Frame): # 初始化游戏界面 def __init__(self, master): super().__init__(master) self.master = master self.pack() # 定义游戏地图和游戏元素 self.map = [ "#### ", "#@### ", "# $ ", "# $ ", "# . ", "######" ] self.player_x, self.player_y = 1, 1 self.box_x, self.box_y = 2, 2 self.target_x, self.target_y = 4, 5 # 创建游戏界面的组件 self.create_widgets() # 创建游戏界面的组件 def create_widgets(self): # 创建游戏地图的画布 self.canvas = tk.Canvas(self, width=300, height=300) self.canvas.pack() # 加载游戏元素的图片 self.wall_img = tk.PhotoImage(file="wall.gif") self.box_img = tk.PhotoImage(file="box.gif") self.target_img = tk.PhotoImage(file="target.gif") self.player_img = tk.PhotoImage(file="player.gif") # 在画布上绘制游戏地图和游戏元素 for y in range(len(self.map)): for x in range(len(self.map[y])): if self.map[y][x] == "#": self.canvas.create_image(x*50+25, y*50+25, image=self.wall_img) elif self.map[y][x] == "$": self.canvas.create_image(x*50+25, y*50+25, image=self.box_img) elif self.map[y][x] == ".": self.canvas.create_image(x*50+25, y*50+25, image=self.target_img) elif self.map[y][x] == "@": self.canvas.create_image(x*50+25, y*50+25, image=self.player_img) # 绑定键盘事件 self.master.bind("<Up>", self.move_up) self.master.bind("<Down>", self.move_down) self.master.bind("<Left>", self.move_left) self.master.bind("<Right>", self.move_right) # 判断游戏是否胜利 def check_win(self): return self.box_x == self.target_x and self.box_y == self.target_y # 移动玩家和箱子 def move(self, dx, dy): new_player_x, new_player_y = self.player_x + dx, self.player_y + dy new_box_x, new_box_y = self.box_x, self.box_y if new_player_x == self.box_x and new_player_y == self.box_y: new_box_x, new_box_y = self.box_x + dx, self.box_y + dy if self.map[new_player_y][new_player_x] != "#": self.player_x, self.player_y = new_player_x, new_player_y self.box_x, self.box_y = new_box_x, new_box_y self.update_game() # 上移 def move_up(self, event): self.move(0, -1) # 下移 def move_down(self, event): self.move(0, 1) # 左移 def move_left(self, event): self.move(-1, 0) # 右移 def move_right(self, event): self.move(1, 0) # 更新游戏界面 def update_game(self): self.canvas.delete("all") for y in range(len(self.map)): for x in range(len(self.map[y])): if self.map[y][x] == "#": self.canvas.create_image(x*50+25, y*50+25, image=self.wall_img) elif self.map[y][x] == "$": self.canvas.create_image(x*50+25, y*50+25, image=self.box_img) elif self.map[y][x] == ".": self.canvas.create_image(x*50+25, y*50+25, image=self.target_img) elif self.map[y][x] == "@": self.canvas.create_image(x*50+25, y*50+25, image=self.player_img) if self.check_win(): self.canvas.create_text(150, 150, text="You Win!", font=("Arial", 20)) # 创建主窗口并运行游戏 if __name__ == "__main__": root = tk.Tk() root.title("Push Box Game") game = Game(root) game.mainloop() ``` 需要注意的是,由于没有使用pygame库,所以在实现游戏界面和游戏元素时,使用了Tkinter库的Canvas组件来绘制游戏界面。同时,由于没有使用外部资源加载函数,所以在代码中需要手动加载游戏元素的图片,并使用Canvas组件的create_image方法来绘制游戏元素。另外,由于没有使用pygame库的事件循环机制,所以在实现玩家移动和箱子移动时,使用了Tkinter库的键盘事件绑定功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值