需了解的知识

Pygame中的各个模块及其功能:

Pygame.init():初始化所有导入的模块

pygame.display:

pygame.display.init()  —  初始化 display 模块

pygame.display.set_mode()  —  初始化一个准备显示的窗口或屏幕

pygame.display.set_caption()  — 设置当前窗口标题

pygame.mixer.music:

pygame.mixer.music.load()  —  加载音乐进行播放

pygame.mixer.music.play()  —  开始播放音乐(参数:int播放次数,-1为无限重复。。)

pygame.time,Clock(创建一个对象帮助跟踪时间):

pygame.time.Clock.tick():  —  更新时钟

pygame.event(用户事件和队列进行交互):

pygame.event.get():  —  在队列中获取事件

pygame.key(与键盘使用的关系):

常用列表:

pygame

Constant      ASCII   Description

---------------------------------

K_BACKSPACE   \b      backspace

K_TAB         \t      tab

K_CLEAR               clear

K_RETURN      \r      return

K_PAUSE               pause

K_ESCAPE      ^[      escape

K_SPACE               space

K_EXCLAIM     !       exclaim

K_QUOTEDBL    "       quotedbl

K_HASH        #       hash

K_DOLLAR      $       dollar

K_AMPERSAND   &       ampersand

K_QUOTE               quote

K_LEFTPAREN   (       left parenthesis

K_RIGHTPAREN  )       right parenthesis

K_ASTERISK    *       asterisk

K_PLUS        +       plus sign

K_COMMA       ,       comma

K_MINUS       -       minus sign

K_PERIOD      .       period

K_SLASH       /       forward slash

K_0           0       0

。。。

K_COLON       :       colon

K_SEMICOLON   ;       semicolon

K_LESS        <       less-than sign

K_EQUALS      =       equals sign

K_GREATER     >       greater-than sign

K_QUESTION    ?       question mark

K_AT          @       at

K_LEFTBRACKET [       left bracket

K_BACKSLASH   \       backslash

K_RIGHTBRACKET ]      right bracket

K_CARET       ^       caret

K_UNDERSCORE  _       underscore

K_BACKQUOTE   `       grave

K_a           a       a

。。。

K_DELETE              delete

K_KP0                 keypad 0

。。。

K_KP_PERIOD   .       keypad period

K_KP_DIVIDE   /       keypad divide

K_KP_MULTIPLY *       keypad multiply

K_KP_MINUS    -       keypad minus

K_KP_PLUS     +       keypad plus

K_KP_ENTER    \r      keypad enter

K_KP_EQUALS   =       keypad equals

K_UP                  up arrow

K_DOWN                down arrow

K_RIGHT               right arrow

K_LEFT                left arrow

K_INSERT              insert

K_HOME                home

K_END                 end

K_PAGEUP              page up

K_PAGEDOWN            page down

K_F1                  F1

。。。

K_NUMLOCK             numlock

K_CAPSLOCK            capslock

K_SCROLLOCK           scrollock

K_RSHIFT              right shift

K_LSHIFT              left shift

K_RCTRL               right control

K_LCTRL               left control

K_RALT                right alt

K_LALT                left alt

K_RMETA               right meta

K_LMETA               left meta

K_LSUPER              left Windows key

K_RSUPER              right Windows key

K_MODE                mode shift

K_HELP                help

K_PRINT               print screen

K_SYSREQ              sysrq

K_BREAK               break

K_MENU                menu

K_POWER               power

K_EURO                Euro

 

系统结构

Modules存放实现的模块

Resources存放游戏资源文件

cfg.py存放配置文件

实现代码

cfg.py配置文件:

 

import os

'''FPS'''
FPS = 60
'''背景颜色'''
BG_COLOR = '#92877d'
'''屏幕大小'''
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)

执行文件2048Game.py

# 游戏初始化

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)

在modules中定义一个Game2048的类(里面主要负责实现2048的各种游戏规则):

class Game2048(object):

   def __init__(self, matrix_size=(4, 4), max_score_filepath=None):

      # matrix_size: (num_rows, num_cols)

      self.matrix_size = matrix_size

      # 游戏最高分保存路径

      self.max_score_filepath = max_score_filepath

      # 初始化

      self.initialize()

游戏开始时需要随机的在二维列表里随机选择两个位置生成2或者4:

在新的位置随机生成数字
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 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

判断游戏是否结束:

游戏是否结束

 

@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

在游戏主循环里根据用户操作来更新当前的游戏状态并将游戏里所有必要的元素显示在屏幕:

# 游戏主循环

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)

实验

使用python ./Game2048来执行:

总结和展望

通过此次学习,我了解了python的灵活性以及代码的可阅读性比一般的语言要强,并且如今python社区有许多活跃的用户可以在网络上找到许多相关的资料资源。通过此次学习深刻理解了python中的面向对象思想,也了解了一些游戏的设计想法和可供实现的模块。现如今正在学习其他东西,如果未来有更多充裕的时间可以加深python的理解,学习更多的内容,自己做出更好的项目。

参考:https://mp.weixin.qq.com/s/WJhg4J0MuuEcmDasRzuE9Q

python作业-2048小游戏的更多相关文章

  1. python写2048小游戏

    #!/usr/bin/env python # coding=utf-8 #******************************************************** # > ...

  2. jQuery实践-网页版2048小游戏

    ▓▓▓▓▓▓ 大致介绍 看了一个实现网页版2048小游戏的视频,觉得能做出自己以前喜欢玩的小游戏很有意思便自己动手试了试,真正的验证了这句话-不要以为你以为的就是你以为的,看视频时觉得看懂了,会写了, ...

  3. C# 开发2048小游戏

    这应该是几个月前,闲的手痒,敲了一上午代码搞出来的,随之就把它丢弃了,当时让别人玩过,提过几条更改建议,但是时至今日,我也没有进行过优化和更改(本人只会作案,不会收场,嘎嘎),下面的建议要给代码爱好的 ...

  4. Swift实战之2048小游戏

    上周在图书馆借了一本Swift语言实战入门,入个门玩一玩^_^正好这本书的后面有一个2048小游戏的实例,笔者跟着实战了一把. 差不多一周的时间,到今天,游戏的基本功能已基本实现,细节我已不打算继续完 ...

  5. 如何在CentOS上安装一个2048小游戏

    如何在centos上安装一个2048小游戏 最近在学习CentOS系统,就琢磨着玩点什么,然后我看到有人在玩2048小游戏,所有我就在想,为啥不装一个2048小游戏搞一下嘞,于是乎,我就开始工作啦 由 ...

  6. js、jQuery实现2048小游戏

    2048小游戏 一.游戏简介:  2048是一款休闲益智类的数字叠加小游戏 二. 游戏玩法: 在4*4的16宫格中,您可以选择上.下.左.右四个方向进行操作,数字会按方向移动,相邻的两个数字相同就会合 ...

  7. 用js实现2048小游戏

    用js实现2048小游戏 笔记仓库:https://github.com/nnngu/LearningNotes 1.游戏简介 2048是一款休闲益智类的数字叠加小游戏.(文末给出源代码和演示地址) ...

  8. 2048小游戏代码解析 C语言版

    2048小游戏,也算是风靡一时的益智游戏.其背后实现的逻辑比较简单,代码量不算多,而且趣味性强,适合作为有语言基础的童鞋来加强编程训练.本篇分析2048小游戏的C语言实现代码. 前言 游戏截图:  游 ...

  9. Docker从0开始之部署一套2048小游戏

    本文记录一下在docker部署一套2048小游戏的过程,在娱乐中熟悉docker的应用部署.docker 安装不在本文讲述之中,参考我的其它博客. 1.获取image镜像. 方法一:daocloud. ...

随机推荐

  1. 最多约数问题(Java)

    Description 正整数x 的约数是能整除x 的正整数.正整数x的约数个数记为div(x).例如,1,2,5,10 都是正整数10的约数,且div(10)=4.设a 和b是2 个正整数,a≤b, ...

  2. iMindMap不同视图的应用技巧介绍

    在刚开始使用iMindMap思维导图软件时,很多用户会习惯性地使用默认的Mind Map视图.因该视图布局自由,用户可以发挥自我创造力,进行多种形式的思维图表创建. 其实,除此之外,iMindMap还 ...

  3. 给PDF批量添加文本链接

    为了进一步补充说明文件中的一些重要内容,PDF文件的创建者会为一些文本创建链接,方便阅读者访问相关的网站,获取更多的信息. 我们可以通过使用pdfFactory文本链接功能来实现以上需求,另外,我们还 ...

  4. 怎么用MindManager自带的模板和设计画思维导图

    小编知道大家平时工作学习都很忙,思维导图能完成的效率越高越好.所以今天,小编就为大家介绍两个能高效使用思维导图软件完成制作思维导图的小技巧.保证内容充实美观,还不费时间. 一.使用模板 打开MindM ...

  5. JS 数组对象

    定义数组: 数组对象用来在单独的变量名中存储一系列的值. 创建一个数组有三种方法. 1: 常规方式: var myCars=new Array(); myCars[0]="Saab" ...

  6. IntelliJ IDEA 行注释的缩进设置(不自动添加注释到行首)

    目录 现状 修改对比 最后 现状 想注释一行或一个方法,//注释总是生成在行首: 修改对比 要修改的配置在这: 我们可以在注释后添加一个空格,就变成了: 最后 设置完了看下注释效果: 这看起来才舒服.

  7. leetcode 33和 leetcode81

    //感想: 1.对于这两题,我真的是做到吐,这篇博客本来是昨晚准备写的,但是对于这个第二题,我真的做到头痛,实在是太尼玛的吐血了,主要是我也是头铁,非要找到那个分界点. 2.其实之前在牛客网上做过非常 ...

  8. 自学linux——8.firewall-cmd的命令使用

    firewall-cmd使用方法 1.firewall-cmd的含义 firewall-cmd 是 firewalld的字符界面管理工具,firewalld是centos7之后版本的一大特性, 最大的 ...

  9. 如何获取公网IP的mac地址

    如何获取远程IP的mac地址 思路分析 由于java本身没有相关的jar包进行获取,所以这里介绍从其他的方面进行入手和实践 使用的工具对比: tcpdump tshark pcap4j 都可以达到抓包 ...

  10. VM15 Ubuntu18.04下固定IP

    输入su 进入root用户 为下面修改文件内容提供权限 1.查看自己网卡名称:输入命令: ifconfig -a 或者 ip link 或者 ip addr 所以我的网卡名称是:ens33 2. 然后 ...