如何用pygame编写一个简单小游戏(升级后的2048小游戏)
如何用pygame编写一个简单小游戏(升级后的2048小游戏)那当然是大大的不同那,今天教大家写的这款是有界面的小程序,单单是有界面的这一点就可以超前面那款了,更加富有趣味性的撒~来,我们来看看!慢慢来,木木子一直在等你们崛起~哈哈哈哈 ,呐~ 现在这篇文章的话是上次承诺的一个升级版本的2048小游戏。比之之前那款呢?有什么不同?
导语“嗨嗨嗨!别睡了,醒醒醒醒!该干活儿了~” by——顾木子吖!
“刚睡醒,大佬你有什么事儿吖?” by——全体成员!
上期给大家分享的超详细——简易版本的2048都吃透了没?咳咳咳......没吃透也没关系!
慢慢来,木木子一直在等你们崛起~哈哈哈哈 ,呐~ 现在这篇文章的话是上次承诺的一个升级版本的2048小游戏。
比之之前那款呢?有什么不同?
那当然是大大的不同那,今天教大家写的这款是有界面的小程序,单单是有界面的这一点就可以超前面那款了,更加富有趣味性的撒~来,我们来看看!
正文环境安装:Python3、pycharm、Pygame模块等。
pip install -i https://pypi.douban.com/simple/ pygame
配置文件:
音乐、背景、字体等。
import os
'''FPS'''
FPS = 60
'''背景颜色'''
BG_COLOR = '#D3D3D3'
'''屏幕大小'''
SCREENSIZE = (650 370)
'''保存当前最高分的文件'''
MAX_SCORE_FILEPATH = 'score'
'''字体路径'''
FONTPATH = os.path.join(os.getcwd() 'resources/font/Gabriola.ttf')
'''背景音乐路径'''
BGMPATH = os.path.join(os.getcwd() 'resources/audio/bgm.mp3')
'''其他一些必要的常量'''
MARGIN_SIZE = 10
BLOCK_SIZE = 80
GAME_MATRIX_SIZE = (4 4)
定义2048游戏:
class Game2048(object):
def __init__(self matrix_size=(4 4) max_score_filepath=None **kwargs):
# matrix_size: (num_rows num_cols)
self.matrix_size = matrix_size
# 游戏最高分保存路径
self.max_score_filepath = max_score_filepath
# 初始化
self.initialize()
'''更新游戏状态'''
def update(self):
game_matrix_before = copy.deepcopy(self.game_matrix)
self.move()
if game_matrix_before != self.game_matrix: self.randomGenerateNumber()
if self.score > self.max_score: self.max_score = self.score
'''根据指定的方向 移动所有数字块'''
def move(self):
# 提取非空数字
def extract(array):
array_new = []
for item in array:
if item != 'null': array_new.append(item)
return array_new
# 合并非空数字
def merge(array):
score = 0
if len(array) < 2: return array score
for i in range(len(array)-1):
if array[i] == 'null':
break
if array[i] == array[i 1]:
array[i] *= 2
array.pop(i 1)
array.append('null')
score = array[i]
return extract(array) score
# 不需要移动的话直接return
if self.move_direction is None: return
# 向上
if self.move_direction == 'up':
for j in range(self.matrix_size[1]):
col = []
for i in range(self.matrix_size[0]):
col.append(self.game_matrix[i][j])
col = extract(col)
col.reverse()
col score = merge(col)
self.score = score
col.reverse()
col = col ['null' ] * (self.matrix_size[0] - len(col))
for i in range(self.matrix_size[0]):
self.game_matrix[i][j] = col[i]
# 向下
elif self.move_direction == 'down':
for j in range(self.matrix_size[1]):
col = []
for i in range(self.matrix_size[0]):
col.append(self.game_matrix[i][j])
col = extract(col)
col score = merge(col)
self.score = score
col = ['null' ] * (self.matrix_size[0] - len(col)) col
for i in range(self.matrix_size[0]):
self.game_matrix[i][j] = col[i]
# 向左
elif self.move_direction == 'left':
for idx row in enumerate(copy.deepcopy(self.game_matrix)):
row = extract(row)
row.reverse()
row score = merge(row)
self.score = score
row.reverse()
row = row ['null' ] * (self.matrix_size[1] - len(row))
self.game_matrix[idx] = row
# 向右
elif self.move_direction == 'right':
for idx row in enumerate(copy.deepcopy(self.game_matrix)):
row = extract(row)
row score = merge(row)
self.score = score
row = ['null' ] * (self.matrix_size[1] - len(row)) row
self.game_matrix[idx] = row
self.move_direction = None
'''在新的位置随机生成数字'''
def randomGeneratenumber(self):
empty_pos = []
for i in range(self.matrix_size[0]):
for j in range(self.matrix_size[1]):
if self.game_matrix[i][j] == 'null': empty_pos.append([i j])
i j = random.choice(empty_pos)
self.game_matrix[i][j] = 2 if random.random() > 0.1 else 4
'''初始化'''
def initialize(self):
self.game_matrix = [['null' for _ in range(self.matrix_size[1])] for _ in range(self.matrix_size[0])]
self.score = 0
self.max_score = self.readMaxScore()
self.move_direction = None
self.randomGenerateNumber()
self.randomGenerateNumber()
'''设置移动方向'''
def setDirection(self direction):
assert direction in ['up' 'down' 'left' 'right']
self.move_direction = direction
'''保存最高分'''
def saveMaxScore(self):
f = open(self.max_score_filepath 'w' encoding='utf-8')
f.write(str(self.max_score))
f.close()
'''读取游戏最高分'''
def readMaxScore(self):
try:
f = open(self.max_score_filepath 'r' encoding='utf-8')
score = int(f.read().strip())
f.close()
return score
except:
return 0
'''游戏是否结束'''
@property
def isgameover(self):
for i in range(self.matrix_size[0]):
for j in range(self.matrix_size[1]):
if self.game_matrix[i][j] == 'null': return False
if (i == self.matrix_size[0] - 1) and (j == self.matrix_size[1] - 1):
continue
elif (i == self.matrix_size[0] - 1):
if (self.game_matrix[i][j] == self.game_matrix[i][j 1]):
return False
elif (j == self.matrix_size[1] - 1):
if (self.game_matrix[i][j] == self.game_matrix[i 1][j]):
return False
else:
if (self.game_matrix[i][j] == self.game_matrix[i 1][j]) or (self.game_matrix[i][j] == self.game_matrix[i][j 1]):
return False
return True
然后设置不同的颜色。
不同的数字2-4-8等等组合成不同的数字颜色相应的变化。
颜色展示:
def getColorByNumber(number):
number2color_dict = {
2: ['#eee4da' '#776e65'] 4: ['#ede0c8' '#776e65'] 8: ['#f2b179' '#f9f6f2']
16: ['#f59563' '#f9f6f2'] 32: ['#f67c5f' '#f9f6f2'] 64: ['#f65e3b' '#f9f6f2']
128: ['#edcf72' '#f9f6f2'] 256: ['#edcc61' '#f9f6f2'] 512: ['#edc850' '#f9f6f2']
1024: ['#edc53f' '#f9f6f2'] 2048: ['#edc22e' '#f9f6f2'] 4096: ['#eee4da' '#776e65']
8192: ['#edc22e' '#f9f6f2'] 16384: ['#f2b179' '#776e65'] 32768: ['#f59563' '#776e65']
65536: ['#f67c5f' '#f9f6f2'] 'null': ['#9e948a' None]
}
return number2color_dict[number]
'''将2048游戏的当前数字排列画到屏幕上'''
def drawGameMatrix(screen game_matrix cfg):
for i in range(len(game_matrix)):
for j in range(len(game_matrix[i])):
number = game_matrix[i][j]
x = cfg.MARGIN_SIZE * (j 1) cfg.BLOCK_SIZE * j
y = cfg.MARGIN_SIZE * (i 1) cfg.BLOCK_SIZE * i
pygame.draw.rect(screen pygame.Color(getColorByNumber(number)[0]) (x y cfg.BLOCK_SIZE cfg.BLOCK_SIZE))
if number != 'null':
font_color = pygame.Color(getColorByNumber(number)[1])
font_size = cfg.BLOCK_SIZE - 10 * len(str(number))
font = pygame.font.Font(cfg.FONTPATH font_size)
text = font.render(str(number) True font_color)
text_rect = text.get_rect()
text_rect.centerx text_rect.centery = x cfg.BLOCK_SIZE / 2 y cfg.BLOCK_SIZE / 2
screen.blit(text text_rect)
游戏界面添加额外的元素。
如下图:玩法介绍、分数显示。
'''将游戏的最高分和当前分数画到屏幕上'''
def drawScore(screen score max_score cfg):
font_color = (255 255 255)
font_size = 30
font = pygame.font.Font(cfg.FONTPATH font_size)
text_max_score = font.render('Best: %s' % max_score True font_color)
text_score = font.render('Score: %s' % score True font_color)
start_x = cfg.BLOCK_SIZE * cfg.GAME_MATRIX_SIZE[1] cfg.MARGIN_SIZE * (cfg.GAME_MATRIX_SIZE[1] 1)
screen.blit(text_max_score (start_x 10 10))
screen.blit(text_score (start_x 10 20 text_score.get_rect().height))
start_y = 30 text_score.get_rect().height text_max_score.get_rect().height
return (start_x start_y)
'''游戏介绍'''
def drawGameIntro(screen start_x start_y cfg):
start_y = 40
font_color = (0 0 0)
font_size_big = 30
font_size_small = 20
font_big = pygame.font.Font(cfg.FONTPATH font_size_big)
font_small = pygame.font.Font(cfg.FONTPATH font_size_small)
intros = ['Game play:' ' Slide the keyboard up down left and right.' 'Combine two identical numbers' 'For example: 2 2 = 4 4 4 = 8... Until 1024 1024 = 2048!' 'You win!']
for idx intro in enumerate(intros):
font = font_big if idx == 0 else font_small
text = font.render(intro True font_color)
screen.blit(text (start_x 10 start_y))
start_y = text.get_rect().height 10
游戏结束界面:
附源码:
def endInterface(screen cfg):
font_size_big = 60
font_size_small = 30
font_color = (255 255 255)
font_big = pygame.font.Font(cfg.FONTPATH font_size_big)
font_small = pygame.font.Font(cfg.FONTPATH font_size_small)
surface = screen.convert_alpha()
surface.fill((127 255 212 2))
text = font_big.render('Game Over!' True font_color)
text_rect = text.get_rect()
text_rect.centerx text_rect.centery = cfg.SCREENSIZE[0]/2 cfg.SCREENSIZE[1]/2-50
surface.blit(text text_rect)
button_width button_height = 100 40
button_start_x_left = cfg.SCREENSIZE[0] / 2 - button_width - 20
button_start_x_right = cfg.SCREENSIZE[0] / 2 20
button_start_y = cfg.SCREENSIZE[1] / 2 - button_height / 2 20
pygame.draw.rect(surface (0 255 255) (button_start_x_left button_start_y button_width button_height))
text_restart = font_small.render('Restart' True font_color)
text_restart_rect = text_restart.get_rect()
text_restart_rect.centerx text_restart_rect.centery = button_start_x_left button_width / 2 button_start_y button_height / 2
surface.blit(text_restart text_restart_rect)
pygame.draw.rect(surface (0 255 255) (button_start_x_right button_start_y button_width button_height))
text_quit = font_small.render('Quit' True font_color)
text_quit_rect = text_quit.get_rect()
text_quit_rect.centerx text_quit_rect.centery = button_start_x_right button_width / 2 button_start_y button_height / 2
surface.blit(text_quit text_quit_rect)
while True:
screen.blit(surface (0 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN and event.button:
if text_quit_rect.collidepoint(pygame.mouse.get_pos()):
return False
if text_restart_rect.collidepoint(pygame.mouse.get_pos()):
return True
pygame.display.update()
主程序:
def main(cfg):
# 游戏初始化
pygame.init()
screen = pygame.display.set_mode(cfg.SCREENSIZE)
pygame.display.set_caption('2048小游戏升级版')
# 播放背景音乐
pygame.mixer.music.load(cfg.BGMPATH)
pygame.mixer.music.play(-1)
# 实例化2048游戏
game_2048 = Game2048(matrix_size=cfg.GAME_MATRIX_SIZE max_score_filepath=cfg.MAX_SCORE_FILEPATH)
# 游戏主循环
clock = pygame.time.Clock()
is_running = True
while is_running:
screen.fill(pygame.Color(cfg.BG_COLOR))
# --按键检测
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key in [pygame.K_UP pygame.K_DOWN pygame.K_LEFT pygame.K_RIGHT]:
game_2048.setDirection({pygame.K_UP: 'up' pygame.K_DOWN: 'down' pygame.K_LEFT: 'left' pygame.K_RIGHT: 'right'}[event.key])
# --更新游戏状态
game_2048.update()
if game_2048.isgameover:
game_2048.saveMaxScore()
is_running = False
# --将必要的游戏元素画到屏幕上
drawGameMatrix(screen game_2048.game_matrix cfg)
start_x start_y = drawScore(screen game_2048.score game_2048.max_score cfg)
drawGameIntro(screen start_x start_y cfg)
# --屏幕更新
pygame.display.update()
clock.tick(cfg.FPS)
return endInterface(screen cfg)
'''run'''
if __name__ == '__main__':
while True:
if not main(cfg):
break
2048游戏效果如下图所示:
本来是想给大家截一张2048的图的,但是玩了好几遍都卡死了,这图你们就将就着看叭~我尽力了!
总结好啦!这篇升级版的2048小游戏就到这里结束啦,快来试试你能通关嘛?
免费源码领取处:如需完整的项目源码 素材源码基地见:#私信小编06#即可获取免费的福利!
你们的支持是我最大的动力!!记得三连哦~mua 欢迎大家阅读往期的文章哦~