2048小游戏
本次学习视频:https://www.bilibili.com/video/BV1iC4y1W7Ck
相关素材:点击这里啦啦啦啦啦
import turtle
import random
sinlery = turtle.Screen()
sinlery.setup(430, 630, 500, 10) # 设置 图形框 的大小及位置,(宽、高、以及位置)
sinlery.bgcolor('grey') # 背景颜色,grey:灰色
sinlery.title('2048小游戏') # 标题
sinlery.register_shape('bg.gif') # 注册一下这个图片。
sinlery.register_shape('title.gif') # 注册一下这个图片。
sinlery.register_shape('score.gif') # 注册一下这个图片。
sinlery.register_shape('top_score.gif') # 注册一下这个图片。
sinlery.register_shape('2.gif')
sinlery.register_shape('4.gif')
sinlery.register_shape('8.gif')
sinlery.register_shape('16.gif')
sinlery.register_shape('32.gif')
sinlery.register_shape('64.gif')
sinlery.register_shape('64.gif')
sinlery.register_shape('128.gif')
sinlery.register_shape('256.gif')
sinlery.register_shape('512.gif')
sinlery.register_shape('1024.gif')
sinlery.register_shape('2048.gif')
sinlery.register_shape('2048.gif')
sinlery.tracer(0) # 直接显示结果,没有划线,填充的过程
class Block(turtle.Turtle):
def __init__(self):
super().__init__()
self.penup() # 从开始的时候断线
def grow(self):
number = random.choice([2, 2, 2, 4, 4]) # 选择出现的数字
self.shape(f'{number}.gif')
a = random.choice(position)
self.goto(a)
# self.stamp() # ????
position.remove(a)
block_list.append(self)
def go_down(self):
return self.go(-150, -50, 50, 0, -100, True)
def go_up(self):
return self.go(-50, -150, -250, 0, 100, True)
def go_left(self):
return self.go(-50, 50, 150, -100, 0, False)
def go_right(self):
return self.go(50, -50, -150, 100, 0, False)
def go(self, a, b, c, px, py, bool):
global move_time, z_bool # 定义一个移动次数
move_time = 0
block1, block2, block3 = [], [], []
for i in block_list:
if bool is True:
if i.ycor() == a:
block1.append(i)
if i.ycor() == b:
block2.append(i)
if i.ycor() == c:
block3.append(i)
else:
if i.xcor() == a:
block1.append(i)
if i.xcor() == b:
block2.append(i)
if i.xcor() == c:
block3.append(i)
for j in block1:
j.move(j.xcor() + px, j.ycor() + py)
for j in block2:
for k in range(2):
j.move(j.xcor() + px, j.ycor() + py)
for j in block3:
for k in range(3):
j.move(j.xcor() + px, j.ycor() + py)
if move_time != 0: # 如果没有移动,则不会新创建一个数字方块儿
new_block = Block()
new_block.grow()
bc_score.show_score(score)
bc_top_score.show_top_score(top_score)
for k in block_list:
if k.shape() == '2048.gif' and z_bool: # 达成xx成功
win_lose.show_text(' 达成2048\n按回车键继续!')
z_bool = False
if judge() is False:
win_lose.show_text(' 游戏失败\n空格键重来!')
# 上下左右 移动一次
def move(self, gox, goy):
global move_time, num, score, top_score # 全局变量
if (gox, goy) in position:
position.append(self.pos()) # pos() 是个函数,得到的是一个数组(坐标)
self.goto(gox, goy)
position.remove(self.pos()) # 把新的坐标拿掉
move_time += 1 # 移动一次,move_time +1, 用来判断是否要新创建一个数字方块儿
# 数字相同时相加
else:
for i in block_list:
if i.pos() == (gox, goy) and i.shape() == self.shape():
position.append(self.pos())
self.goto(gox, goy)
self.ht() # 隐藏
block_list.remove(self)
num = int(i.shape()[0:-4])
i.shape(f'{num * 2}.gif')
move_time += 1 # 移动一次,move_time +1, 用来判断是否要新创建一个数字方块儿
score += num
# else:
# continue
if score > top_score:
top_score = score
# 达成目标 或者 失败显示的字
class WinLose(turtle.Turtle):
def __init__(self):
super().__init__()
self.penup()
self.ht() # 隐藏
self.color('red')
def show_text(self, text):
self.write(f'{text}', align='center', font=('黑体', 20, 'bold'))
# 判断是否失败
def judge():
judge_a = 0
if position == []:
for i in block_list:
for j in block_list:
if i.shape() == j.shape() and i.distance(j) == 100:
judge_a += 1
if judge_a == 0:
return False
else:
return True
else:
return True
# 初始化
def init():
global num, z_bool, block_list, position, score
num = 0
z_bool = True
score = 0
position = [
(-150, 50), (-50, 50), (50, 50), (150, 50),
(-150, -50), (-50, -50), (50, -50), (150, -50),
(-150, -150), (-50, -150), (50, -150), (150, -150),
(-150, -250), (-50, -250), (50, -250), (150, -250)
]
for i in block_list:
i.clear()
i.ht()
win_lose.clear()
block_list = []
block = Block()
block.grow()
bc_score.show_score(score) # 初始化显示当前得分为0
# 背景
class BackGround(turtle.Turtle):
def __init__(self):
super().__init__()
self.penup() # 开始的时候,断线
self.ht()
def show_back(self):
for i in position: # 循环画图片
self.shape('bg.gif') # 使用注册好了的pg.gif图片
self.goto(i)
self.stamp() # 填充图片
def show_test(self): # 描绘出中间的分割线
self.color('white', 'white') # 划线颜色、填充颜色
self.goto(-215, 120) # 起点
self.begin_fill() # 开始填充
self.pendown()
self.goto(215, 120) # 经过的路线
self.goto(215, 110)
self.goto(-215, 110)
self.end_fill() # 结束填充
self.penup() # 断线
self.shape('title.gif') # 每使用一张图片是记得注册图片
self.goto(-125, 210)
self.stamp()
self.shape('score.gif') # 每使用一张图片是记得注册图片
self.goto(125, 255)
self.stamp()
self.shape('top_score.gif') # 每使用一张图片是记得注册图片
self.goto(125, 170)
self.stamp()
# 显示当前分数
def show_score(self, score):
self.color('white')
self.goto(125, 225)
self.clear() # 每次调用它之前都清除掉原先的数字,在显示现在的
self.write(f'{score}', align='center', font=("Arial", 20, 'bold'))
# 显示最高分数
def show_top_score(self, top_score):
self.color('white')
self.goto(125, 140)
self.clear()
self.write(f'{top_score}', align='center', font=("Arial", 20, 'bold'))
if __name__ == '__main__':
position = [
(-150, 50), (-50, 50), (50, 50), (150, 50),
(-150, -50), (-50, -50), (50, -50), (150, -50),
(-150, -150), (-50, -150), (50, -150), (150, -150),
(-150, -250), (-50, -250), (50, -250), (150, -250)
]
num = 0
z_bool = True
move_time = 0
score = 0 # 当前分数
top_score = 0 # 最高分数
back = BackGround()
back.show_test()
back.show_back()
block_list = []
block = Block()
block.grow()
win_lose = WinLose()
bc_score = BackGround()
bc_top_score = BackGround()
bc_score.show_score(score)
bc_top_score.show_top_score(top_score)
sinlery.listen()
sinlery.onkey(block.go_down, 'Down')
sinlery.onkey(block.go_up, 'Up')
sinlery.onkey(block.go_left, 'Left')
sinlery.onkey(block.go_right, 'Right')
sinlery.onkey(win_lose.clear, 'Return')
sinlery.onkey(init, 'space')
while True:
sinlery.update()
# sinlery.mainloop()