Pygame actual combat: upgraded 2048 games - unlocking new patterns can't stop at all

Introduction

"Hey! Don't sleep, wake up! It's time to work ~" by - Mengya!

"Just woke up, boss, what can I do for you?" by - all members!

Have you had a thorough understanding of the super detailed - simple version of 2048 shared with you in the last issue? Cough... It doesn't matter if you don't eat it thoroughly!

Take your time, mumuzi has been waiting for you to rise ~ ha ha, ha ha, Na ~ now this article is an upgraded version of 2048 game promised last time.

What about the previous one? Any difference?

Of course, it's very different. Today, I teach you to write this small program with interface. This point with interface alone can surpass the previous one. It's more interesting. Let's have a look!

text

Environmental installation:

Python 3, pycharm, Pygame modules, etc.

 pip install -i https://pypi.douban.com/simple/ pygame

Profile:

Music, background, font, etc.

import os'''FPS'''FPS = 60'''background color ''
'BG_COLOR = '#D3 '' '' screen size '' '
SCREENSIZE = (650, 370)'''Save the current highest score file'''MAX_SCORE_FILEPATH = 'score''''
Font path'''FONTPATH = os.path.join(os.getcwd(), 'resources/font/Gabriola.ttf')'''
Background music path'''BGMPATH = os.path.join(os.getcwd(), 'resources/audio/bgm.mp3')'''
Other necessary constants'''
MARGIN_SIZE = 10BLOCK_SIZE = 80GAME_MATRIX_SIZE = (4, 4)

Define 2048 Games:

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        
# Save path of the highest score of the game        
self.max_score_filepath = max_score_filepath        
# initialization        
self.initialize()    
'''Update game status'''    
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   
 '''According to the specified direction, Move all blocks'''    
def move(self):        
# Extract non empty number        
def extract(array):            
array_new = []            
for item in array:                
if item != 'null': array_new.append(item)           
 return array_new        
# Merge non empty numbers        
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 you don't need to move        
if self.move_direction is None: return        
# Up        
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]        
# down        
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]        
# towards the left        
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        
# towards the right        
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    '''Randomly generate numbers in new locations'''    
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    '''initialization'''    
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()    '''Set direction of movement'''    
def setDirection(self, direction):        
assert direction in ['up', 'down', 'left', 'right']        
self.move_direction = direction    '''Save highest score'''    
def saveMaxScore(self):        
f = open(self.max_score_filepath, 'w', encoding='utf-8')        f.write(str(self.max_score))        
f.close()    '''Read the highest score of the game'''    
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    '''Is the game over'''    @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

Then set different colors.

Different numbers 2-4-8 and so on are combined into different numbers, and the color changes accordingly.

Color display:

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]'''Draw the current number arrangement of 2048 games to the screen'''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)

Add additional elements to the game interface.

The following figure: introduction to playing methods and score display.

'''Draw the highest score and current score of the game to the screen'''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)'''Game introduction'''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

Game end interface:

Attached source code:

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()

Main program:

def main(cfg):    
# Game initialization    
pygame.init()    
screen = pygame.display.set_mode(cfg.SCREENSIZE)    pygame.display.set_caption('2048 Small game upgrade')    
# Play background music pygame.mixer.music.load (CFG. Bgmpath) pygame.mixer.music.play (- 1)    
# Instantiate 2048 games    
game_2048 = Game2048(matrix_size=cfg.GAME_MATRIX_SIZE, max_score_filepath=cfg.MAX_SCORE_FILEPATH)    
# Game main loop    
clock = pygame.time.Clock()    
is_running = True    
while is_running:        
screen.fill(pygame.Color(cfg.BG_COLOR))        
# --Key detection        
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])        
# --Update game status        
game_2048.update()        
if game_2048.isgameover:            
game_2048.saveMaxScore()            
is_running = False        
# --Draw the necessary game elements to the screen        
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)        
# --Screen update        
pygame.display.update()        
clock.tick(cfg.FPS)    
return endInterface(screen, cfg)'''run'''if __name__ == '__main__':    
while True:        
if not main(cfg):            
break

2048 game effect is shown in the figure below:

I wanted to cut a picture of 2048 for you, but it got stuck after playing for several times. You'll make do with it. BAM ~ I tried my best!

Summary

All right! This upgraded 2048 game is over here. Come and try. Can you pass the customs?

Free source code collection office:

For a complete project source code + material source code base, see: # private letter Xiaobian 06# you can get free benefits!

Your support is my biggest motivation!! Remember three times in a row, oh ~mua welcome to read previous articles~

Tags: Python Pycharm Programmer crawler

Posted on Fri, 26 Nov 2021 05:57:12 -0500 by kranthi117