基于树莓派RP2040实现拼图游戏的移植报告
基于树莓派RP2040实现拼图游戏的移植,打乱读入图片的顺序,经由摇杆操控复原,复原时原图显现
标签
嵌入式系统
测试
显示
2022寒假在家练
Johnzax
更新2022-03-03
中央民族大学
1403

基于树莓派RP2040实现拼图游戏的移植报告

项目介绍:该项目采用树莓派Pico核心芯片RP2040,有上位机中用Thony进行代码编译,经USB串口输入芯片内,实现游戏--拼图的移植。代码采用MicroPython语言进行编写,借用了在电脑上实现拼图游戏的部分代码结构,以及编写思维,将其转成适合与板卡手柄相连接操作的代码。最终实现在板卡机上简易的9*9拼图游戏。

设计思路FtFAHMTQXvDQjdDGbdDO3thD0PH0

硬件介绍

(1)采用树莓派Pico核心芯片RP2040,双核Arm Cortex M0+内核,可以运行到133MHz;264KB内存;性能强大、高度灵活的可编程IO可用于高速数字接口;片内温度传感器、并支持外部4路模拟信号输入,内部ADC采样率高达500Ksps、12位精度;支持MicroPython、C、C++编程

(2)

板上功能:240*240分辨率的彩色IPS LCD,SPI接口,控制器为ST7789;四向摇杆 + 2个轻触按键 + 一个三轴姿态传感器MMA7660用做输入控制;板上外扩2MB Flash,预刷MicroPython的UF2固件;一个红外接收管 + 一个红外发射管;一个三轴姿态传感器MMA7660;一个蜂鸣器;双排16Pin连接器,有SPI、I2C以及2路模拟信号输入;可以使用MicroPython、C、C++编程;USB Type C连接器用于供电、程序下载

实现功能:用摇杆遥控黑块进行左右移动,最后完成拼图。

图片展示FhO6AhdjuSUmTqKUsiXn7ziFku3vFsZJ3nXraHV2F55srZ1XSc2uhAuTFhMJXcuXZnURsXxKOlOMTmBTiS81FnOLzhZ-6tpYSCHEuzaj2iLMNcR2FidIm0v_cbp7DLsRZhn4Kqo-dnk_

主要代码:

#头文件
import uos
import machine
from machine import Pin, SPI, ADC
import st7789 as st7789
#from fonts import vga2_8x8 as font1
#from fonts import vga1_16x32 as font2
import random
import framebuf
import time
# 设置画布尺寸
w = 240
h = 240
buf=[[None]*3]*240

st7789_res = 0
st7789_dc  = 1


spi_sck=machine.Pin(2)
spi_tx=machine.Pin(3)
spi0=machine.SPI(0,baudrate=4000000, phase=1, polarity=1, sck=spi_sck, mosi=spi_tx)
#
display = st7789.ST7789(spi0, w, w,
                          reset=machine.Pin(st7789_res, machine.Pin.OUT),
                          dc=machine.Pin(st7789_dc, machine.Pin.OUT),
                          xstart=0, ystart=0, rotation=0)

image_file0 = "logo.bin" #图片文件地址

#
xAxis = ADC(Pin(29))
yAxis = ADC(Pin(28))


# 定义图像块的边长
image_size = w / 3

# 定义图像块坐标列表
all_coordinates = [[image_size * 0.5, image_size * 0.5], [image_size * 1.5, image_size * 0.5],
                   [image_size * 2.5, image_size * 0.5], [image_size * 0.5, image_size * 1.5],
                   [image_size * 1.5, image_size * 1.5], [image_size * 2.5, image_size * 1.5],
                   [image_size * 0.5, image_size * 2.5], [image_size * 1.5, image_size * 2.5],
                   [image_size * 2.5, image_size * 2.5]
                   ]

# 棋盘的行列
row = 3
col = 3
# 保存所有图像块的列表
board = [[None, None, None], [None, None, None], [None, None, None]]
# 定义一个图像块的类
class Square:
    # 定义一个构造函数,用于初始化
    def __init__(self, coordinate):
        self.center = coordinate
        self.isblack = False

mp = [[None, None, None], [None, None, None], [None, None, None]]    
def drawall():
    for i in range(3):
        for j in range(3):
            if board[i][j].isblack:
                mp[i][j]=2,2
                continue
            for k in range(3):
                for h in range(3):
                    
                    
                    if board[i][j].center== [h*80+40, k*80+40]:
                        mp[i][j]=k,h
            #

        #print(board[i][j].center,i,j)
                        
                        
            
    
    f_image = open(image_file0, 'rb')
    display.fill(st7789.BLACK)
    #print(mp[0][1],i,j)
    for i in range(240):
        for j in range(3):
            if board[i//80][j].isblack:
                buf[i][j]=f_image.read(240//3*2)
                #display.blit_buffer(buf[i][j], b*80+1, i-i//80*80+a*80+1, 80, 1)
                #print(buf[i][j])
                continue 
            
            [a,b]=mp[i//80][j]
            #print(a,b,i//80,j,i)
            buf[i][j]=f_image.read(240//3*2)
            #if i//80==2 and j==2:
                #break
            display.blit_buffer(buf[i][j], b*80+1, i-i//80*80+a*80+1, 80, 1)
            
# 定义一个方法进行拼接
def init_board():
    
       
        # 打乱图像
    # 填充并且拼接图版
    for i in range(row):
        for j in range(col):
            idx = i * row + j
            squar_center = all_coordinates[idx]
            if idx==8:
                board[i][j] = Square(squar_center)
                board[i][j].isblack = True
            else:
                board[i][j] = Square(squar_center)
                board[i][j].isblack = False
    for t in range(99):
        i=random.randrange(3)
        j=random.randrange(3)
        k=random.randrange(3)
        h=random.randrange(3)
        #i,j,k,h=2,2,2,1
        
        board[i][j].center,board[k][h].center= board[k][h].center, board[i][j].center
                

#判断对错
def is_right():
    for i in range(row):
        for j in range(col):
            print(board[i][j].center,[i*80+40,j*80+40])
            if board[i][j].center != [j*80+40,i*80+40]:
                return False
    return  True
    

#摇杆控制左右
def dir_select():
    xValue = xAxis.read_u16()
    yValue = yAxis.read_u16()
    for i in range(3):
        for j in range(3):
            if board[i][j].isblack:
                
                
                x,y=board[i][j].center
                for k in range(3):
                    for h in range(3):
                        if k ==i and h==j:
                            continue
                        if [x-80,y]==board[k][h].center and xValue<15000:
                            
                            
                            board[i][j].center,board[k][h].center= board[k][h].center, board[i][j].center
                            print(1,x,y,k,h,board[k][h].center, board[i][j].isblack)
                        elif [x+80,y]==board[k][h].center and xValue>45000:
                            print(2,x,y,k,h,board[k][h].center, board[i][j].isblack)
                            board[i][j].center,board[k][h].center= board[k][h].center, board[i][j].center
                        elif [x,y-80]==board[k][h].center and yValue<15000:
                            print(3,x,y,k,h,board[k][h].center, board[i][j].isblack)
                            board[i][j].center,board[k][h].center= board[k][h].center, board[i][j].center
                        elif [x,y+80]==board[k][h].center and yValue>45000:
                            print(4,x,y,k,h,board[k][h].center, board[i][j].isblack)
                            board[i][j].center,board[k][h].center= board[k][h].center, board[i][j].center  
               
    
               
                   
                    #director = snake.DOWN
def main():
    init_board()
    drawall()
    
    
    
    while True:
        if is_right():
            for i in range(3):
                for j in range(3):
                    if board[i][j].isblack:
                        mp[i][j]=2,2
                        continue
                    for k in range(3):
                        for h in range(3):
                            if board[i][j].center== [h*80+40, k*80+40]:
                                mp[i][j]=k,h
            f_image = open(image_file0, 'rb')
            for i in range(240):
                for j in range(3):
                    
                    
                    [a,b]=mp[i//80][j]
                    buf[i][j]=f_image.read(240//3*2)
                    display.blit_buffer(buf[i][j], b*80+1, i-i//80*80+a*80+1, 80, 1)
            
            break
        dir_select()
        
        
        drawall()
        time.sleep(2)

main()
            
            

           

 

遇到的主要难题:主要是图片的读入和画出以及黑色块左右移动问题。图片读入和画出最后通过计算坐标的方式解决,黑块的移动通过刷黑全屏然后通过交换两个位置的坐标再刷黑得到解决。

未来的建设还有两个按键没被用上,就是A,B键,以及游戏没有好看的载入页面和音乐,希望后期能不断完善吧

 

软硬件
元器件
RP2040
树莓派基金会推出的双核Arm Cortex M0+微控制器,133MHz时钟速率,264KB SRAM,支持C/C++、MicroPython编程
MMA7660
重力感应传感器 - 3-Axis Orientation/Motion Detection Sensor
XT3406AFMR
XT3406 是一款由基准电压源、振荡电路、比较器、PWM/PFM 控制电路等构成的 CMOS 降压 DC/DC 调整器。利用 PWM/PFM 自动切换控制电路达到可调占空比,具有全输入电压范围(1.8-5.5V)内的低纹波、高效率和大输出电流等特点。
FJ08K-N
游戏摇杆电位计
Buzzer -蜂鸣器
一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。
VSMB10940
高速红外发射二极管, 940 nm, GaAlAs, MQW
IRM-H638T
台湾亿光/EVERLIGHT公司的红外线接收头,贴片小尺寸压膜圆头封装,主要应用于遥控器的光检测部分
电路图
附件下载
pintugame.zip
团队介绍
中央民族大学信息工程学院18电子周桉旭
团队成员
Johnzax
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号