用halcon写一个俄罗斯方块

记得两个月前闲得没事用halcon写了一个俄罗斯方块玩玩,现在突然翻到了它那就直接贡献出来。

关键在于基于仿射变换的区域变换。

也就是如下两个算子:

vector_angle_to_rigid
affine_trans_region 

放代码:

ps:首先必须得说清楚一件事,在两个月之前为了完成它重构了几次代码也是抱着玩玩的心态没有将最终的代码分拣出来,既然这样我就将最后一次重构的代码发出来,难免怕是存在bug的那个项目。总之就是基于上述那两个算子,仿照我的代码思路重写一份来提高自己也是最好不过的。

*加载俄罗斯方块元素
dev_close_window ()
*方块大小
PieceSize:=10
Width:=PieceSize*2*25
Height:=PieceSize*2*25
dev_open_window (0, 0, Width, Height, 'black', WindowHandle1)
*田
gen_rectangle2 (rec1, 30, 30, 0, PieceSize, PieceSize)
gen_rectangle2 (rec2, 30, 50, 0, PieceSize, PieceSize)
gen_rectangle2 (rec3, 50, 30, 0, PieceSize, PieceSize)
gen_rectangle2 (rec4, 50, 50, 0, PieceSize, PieceSize)
union2 (rec1, rec2, Obj1)
union2 (Obj1, rec3, Obj1)
union2 (Obj1, rec4, Obj1)
*T
gen_rectangle2 (rec1, 30, 130, 0, PieceSize, PieceSize)
gen_rectangle2 (rec2, 30, 150, 0, PieceSize, PieceSize)
gen_rectangle2 (rec3, 30, 170, 0, PieceSize, PieceSize)
gen_rectangle2 (rec4, 50, 150, 0, PieceSize, PieceSize)
union2 (rec1, rec2, Obj2)
union2 (Obj2, rec3, Obj2)
union2 (Obj2, rec4, Obj2)
*L
gen_rectangle2 (rec1, 30, 260, 0, PieceSize, PieceSize)
gen_rectangle2 (rec2, 50, 260, 0, PieceSize, PieceSize)
gen_rectangle2 (rec3, 70, 260, 0, PieceSize, PieceSize)
gen_rectangle2 (rec4, 70, 280, 0, PieceSize, PieceSize)
union2 (rec1, rec2, Obj3)
union2 (Obj3, rec3, Obj3)
union2 (Obj3, rec4, Obj3)
*Z
gen_rectangle2 (rec1, 30, 350, 0, PieceSize, PieceSize)
gen_rectangle2 (rec2, 30, 370, 0, PieceSize, PieceSize)
gen_rectangle2 (rec3, 50, 370, 0, PieceSize, PieceSize)
gen_rectangle2 (rec4, 50, 390, 0, PieceSize, PieceSize)
union2 (rec1, rec2, Obj4)
union2 (Obj4, rec3, Obj4)
union2 (Obj4, rec4, Obj4)
*I
gen_rectangle2 (rec1, 30, 450, 0, PieceSize, PieceSize)
gen_rectangle2 (rec2, 50, 450, 0, PieceSize, PieceSize)
gen_rectangle2 (rec3, 70, 450, 0, PieceSize, PieceSize)
gen_rectangle2 (rec4, 90, 450, 0, PieceSize, PieceSize)
union2 (rec1, rec2, Obj5)
union2 (Obj5, rec3, Obj5)
union2 (Obj5, rec4, Obj5)
*将元素添入图元数组
gen_empty_obj (EmptyObject)
concat_obj (EmptyObject, Obj1, EmptyObject)
concat_obj (EmptyObject, Obj2, EmptyObject)
concat_obj (EmptyObject, Obj3, EmptyObject)
concat_obj (EmptyObject, Obj4, EmptyObject)
concat_obj (EmptyObject, Obj5, EmptyObject)
*设置游戏窗口
WindowW:=Height
WindowR:=Width
*底座
gen_rectangle2 (Rectangle, Height, Width/2, 0, Width, PieceSize*2)
*开始游戏
*方块元素:EmptyObject
while (1)
    *判断是否游戏结束
    smallest_rectangle1 (Rectangle, Row11, Column11, Row22, Column22)
    if (Row11<=PieceSize*4)
        set_display_font (WindowHandle1, 30, 'mono', 'true', 'false')
        disp_message (WindowHandle1, '游戏结束!!', 'window', Row11, Column11, 'green', 'false')
        stop ()
    endif
    *产生随机数
    Num:=int(rand(1)*4)+1
    select_obj (EmptyObject, ObjectSelected, Num)
    *方块初始位置
    smallest_rectangle1 (ObjectSelected, Row1, Column1, Row2, Column2)
    vector_angle_to_rigid (Row1, Column1, 0, PieceSize*4, WindowR/2-10, 0, HomMat2D)
    affine_trans_region (ObjectSelected, RegionAffineTran, HomMat2D, 'nearest_neighbor')
    dev_clear_window ()
    dev_display (Rectangle)
    dev_display (RegionAffineTran)
    stop ()
     *方块坠落间隔
    DeclineTime:=0.1
    *方块坠落增量
    Decline:=PieceSize*2
    *方块左右移动增量
    Direction:=PieceSize*2
    *方块旋转弧度
    Phi:=rad(90)
    *方块循环坠落,操作对象RegionAffineTran
   while (1)
       *真实左右移动增量增量
       DirectionD:=0
       *真实旋转增量
       PhiP:=rad(0)
       *当前方块位置
       smallest_rectangle1 (RegionAffineTran, Row1, Column1, Row2, Column2)
       *鼠标事件
       try
            get_mposition (3600, mouseR, mouseC, Button)
            *方块向右移动
            if (mouseC>=Column2 and Column2<=Width-Direction)
                DirectionD:=Decline
            elseif(mouseC<=Column1 and Column1>=Direction)
                *方块向左移动 
                DirectionD:=-Decline
            endif
            *方块的旋转,这里定义为鼠标在方块当前上方位置即为需要旋转
            if (mouseR<Row1)
                PhiP:=Phi
            endif
            vector_angle_to_rigid (Row1, Column1, 0, Row1, Column1+DirectionD, PhiP, HomMat2D)
            affine_trans_region (RegionAffineTran, RegionAffineTran, HomMat2D, 'nearest_neighbor')
       catch (Exception)
       endtry
       dev_clear_window ()
       dev_display (Rectangle)
       dev_display (RegionAffineTran)
       *线程等待
       wait_seconds (DeclineTime)
       *下降
       smallest_rectangle1 (RegionAffineTran, Row1, Column1, Row2, Column2)
       vector_angle_to_rigid (Row1, Column1, 0, Row1+Decline, Column1, 0, HomMat2D)
       affine_trans_region (RegionAffineTran, RegionAffineTran, HomMat2D, 'nearest_neighbor')
       *判断方块是否被某物接住
        *元素碰撞检测
        intersection (Rectangle, RegionAffineTran, RegionIntersection)
        area_center (RegionIntersection, Area1, Row1, Column1)
        dev_clear_window ()
        dev_display (Rectangle)
        dev_display (RegionAffineTran)
        *即便被某物接住,仍继续下坠,当碰撞面积达到一定程度被确定被某物接住
        if (Area1>=400)
            *方块回撤
            vector_angle_to_rigid (Row1, Column1, 0, Row1-Decline, Column1, 0, HomMat2D)
            affine_trans_region (RegionAffineTran, RegionAffineTran, HomMat2D, 'nearest_neighbor')
            *将被接住的物体融为一体
            union2 (Rectangle, RegionAffineTran, Rectangle)
        
        *扫描法扫描是否得分
            *确定首次扫描矩形区域的中心点
            RR:=Height-PieceSize*3
            CC:=Width/2
            *确定扫描矩形区域的宽度
            scanSize:=PieceSize*2
            *计算扫描次数,取整
            scanCount:=int(Height/scanSize)
            *开始扫描
            gen_empty_obj (Empty)
            p:=false
            for Index := 1 to scanCount by 1
                *创建扫描矩形
                gen_rectangle2 (Rectangle1, RR, CC, 0, Width/2, PieceSize)
                *计算两区域的交集
                intersection (Rectangle, Rectangle1, RegionDifference)
                area_center (RegionDifference, Area, Row, Column)
                *扫描矩形区域内若存在2个以上对象视为感兴趣区域
                if (Area>9500)
                    stop ()
                    union2 (Empty, RegionDifference, Empty)
                    p:=true
                endif
                
                *扫描矩形区域平移增量
                RR:=RR-scanSize
                *显示结果
                dev_clear_window ()
                dev_display (Rectangle)
                dev_display (RegionAffineTran)
            endfor
         *以下代码为补全以消除的区域
            if (p)
                *取差集
                difference (Rectangle, Empty, RegionDifference)
                dev_clear_window ()
                dev_display (RegionDifference)
                connection (RegionDifference, ConnectedRegions)
                stop ()
                count_obj (ConnectedRegions, Number)
                if (Number>=2)
                    gen_empty_obj (Empty2)
                    sort_region (ConnectedRegions, SortedRegions, 'upper_left', 'true', 'row')
                    if (Number>2)
                        select_obj (SortedRegions, ObjectSelected2, Number)
                        for Index1 := 1 to Number-1 by 1
                            select_obj (SortedRegions, ObjectSelected, Index1)
                            union2 (Empty2, ObjectSelected, Empty2)
                        endfor
                    else
                        select_obj (SortedRegions, ObjectSelected1, 1)
                        Empty2:=ObjectSelected1
                        select_obj (SortedRegions, ObjectSelected2, 2)
                    endif
                    area_center (Empty2, Area, Row, Column)
                    
                    distance_rr_min (Empty2, ObjectSelected2, MinDistance1, Row12, Column12, Row21, Column21)
                    vector_angle_to_rigid (Row, Column, 0, Row+MinDistance1, Column, 0, HomMat2D)
                    affine_trans_region (Empty2, Empty2, HomMat2D, 'nearest_neighbor')
                    union2 (ObjectSelected2, Empty2, Rectangle)               
                else
                   Rectangle:=ConnectedRegions
                endif
            endif
            break
        endif    
   endwhile
    
    *stop ()
endwhile

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值