连连看是一个小游戏,主要是打发时间的,闲来无事,记录一下编写的过程。
设想步骤:1、在图片中
截取几个小的图片作为连连看的小图标
2、随机实现小图片的排列(注意一定是成对出现,不然咋连),为方便测试,先弄6*6的
3、连连看逻辑实现
4、通关后的界面
以下是过程:
一、界面初始化等基本动作
没有啥好讲的,直接上代码:
import pygame
import sys
from pygame.locals import *
import time
import traceback
import os,random
def main():
pygame.init()
game_size = width,height = 700,500
bg_color = (255,255,255) #白色底
game_cols = 6
game_rows = 6
imgs_repeat = game_cols * game_rows / 4
cell_size = 40
pygame.display.set_caption('Hi,连连看!')
'''
让游戏界面居中显示
'''
os.environ['SDL_VIDEO_CENTERED'] = '1'
game_screen = pygame.display.set_mode(game_size)
# 获取屏幕的宽度和高度
game_screen_width = game_screen.get_width()
game_screen_height = game_screen.get_height()
# 计算图片应该被放置的位置,使其居中
x_position = (game_screen_width // 2) - (game_cols * cell_size // 2)
y_position = (game_screen_height // 2) - (game_rows * cell_size // 2)
game_screen.fill(bg_color) #1、填充背景颜色,这样也把上一次的图像刷掉了。
pygame.display.flip() #3、双缓冲机制,一次性将缓冲好的内容显示在屏幕上
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# 检查鼠标事件
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1 :
print("鼠标点击:", event.pos[0])
if __name__ == "__main__":
try:
main()
except SystemExit:
pass
except:
traceback.print_exc()
pygame.quit()
input()
简单起见,目前只搞6*6,每个小图标是40*40,imgs_repeat表示的是一个图片可以出现4次。上述代码将其设置为居中:游戏居中,未来的图片显示在游戏中也是居中。
框架已有了,下面就慢慢添砖加瓦。
二、切出小图片
利用pygame中对象Surface的subsurface方法即可实现,它返回一个子 Surface 对象,它将与父对象共享所有的像素。有4个参数,依次为左上角坐标(x,y)及截取的宽度,高度。依赖左上角坐标x的值可以循环截取了。
实现的方法就是这样的:
def main():
...
cell_size = 40
small_imgs = [] #新增
...
'''
分割小图标
'''
def splitImg():
llk_base = pygame.image.load("imgs\\llk.png") #图片加载成功后,pygame将图片转换为一个Surface对象
for i in range(0, int(imgs_repeat)):
i_left = i * cell_size
small_imgs.append(llk_base.subsurface(i_left,0,cell_size,cell_size))
三、随机将小图片放在屏幕上
选图片有三步
1、将需要的图放在一个列表tmp_game中
2、随机选中放到列表mid_game,并从tmp_game删除
3、将mid_game转为一个二维的,这样对应了屏幕的2D空间
def main():
...
cur_game = [] #游戏 ,新增
tmp_game = [] #临时游戏内容 ,新增
mid_game = [] #中间游戏 ,新增
'''
初始化游戏
'''
def iniGame():
for i in range(0, int(imgs_repeat)):
for j in range(0, 4):
tmp_game.append(i)
total = game_cols * game_rows
for x in range(0, total):
index = random.randint(0, total - x - 1)
mid_game.append(tmp_game[index])
del tmp_game[index]
# 一维转为二维,y为高
for y in range(0, game_rows):
for x in range(0, game_cols):
if x == 0:
cur_game.append([])
cur_game[y].append(mid_game[x + y * game_rows])
最后的cur_game就是对应的屏幕上的二维数组了。数组的内容就是小图标small_imgs的下标。
选完后将小图片按规定的二维顺序显示到页面上即可。显示时还是利用循环按行列顺序blit组成一个大的Surface,然后再flip刷到屏幕上就可以了。注意,在后面消掉后也要调用该方法,所以设置一个EMPTYCELL常量,对应-1,这样就表示当前的格子上的小图标已经消掉了。
def main():
...
EMPTYCELL = -1 #新增
'''
显示 game_screen.blit(small_imgs[0],(x_position,y_position))
'''
def drawGame():
game_screen.fill(bg_color)
for y in range(0, game_rows):
for x in range(0, game_cols):
if cur_game[y][x] != EMPTYCELL:
game_screen.blit(small_imgs[cur_game[y][x]],(x_position + x * cell_size,y_position + y * cell_size))
pygame.display.flip()
修改main代码,把程序完善一下。
def main():
...
# 计算图片应该被放置的位置,使其居中
x_position = (game_screen_width // 2) - (game_cols * cell_size // 2)
y_position = (game_screen_height // 2) - (game_rows * cell_size // 2)
splitImg() #新增
game_screen.fill(bg_color) #1、填充背景颜色,这样也把上一次的图像刷掉了。
'''
初始化,并显示
'''
iniGame() #新增
drawGame() #新增
pygame.display.flip() #3、双缓冲机制,一次性将缓冲好的内容显示在屏幕上
调试程序:
对应的例如cur_game[0][5]的值是2,对应的图片就是
待续。。。