REPORT ztest_xk08.
*Author:Zhou xk 20190404 IN ShangHai
CLASS zcl_snake DEFINITION.
PUBLIC SECTION.
TYPES:c2 TYPE char2,
c4 TYPE char4.
TYPES:BEGIN OF ty_bg,
c101 TYPE c2,c102 TYPE c2,c103 TYPE c2,c104 TYPE c2,c105 TYPE c2,
c106 TYPE c2,c107 TYPE c2,c108 TYPE c2,c109 TYPE c2,c110 TYPE c2,
c111 TYPE c2,c112 TYPE c2,c113 TYPE c2,c114 TYPE c2,c115 TYPE c2,
c116 TYPE c2,c117 TYPE c2,c118 TYPE c2,c119 TYPE c2,c120 TYPE c2,
c121 TYPE c2,
m101 TYPE c4,m102 TYPE c4,m103 TYPE c4,m104 TYPE c4,m105 TYPE c4,
color TYPE lvc_t_scol,
type TYPE salv_t_int4_column,
END OF ty_bg.
TYPES:BEGIN OF ty_body,
xcol TYPE c2,
krow TYPE c2,
ztop TYPE c2, "蛇头标记
END OF ty_body.
* 背景框
DATA:gs_bg TYPE ty_bg,
gt_bg LIKE STANDARD TABLE OF gs_bg.
* 蛇身体
DATA:gs_body TYPE ty_body,
gt_body TYPE STANDARD TABLE OF ty_body.
DATA:gc_st TYPE REF TO cl_salv_table.
DATA:gc_timer TYPE REF TO cl_gui_timer.
* 行列确定地图上随机的一个点
DATA:gv_random_col TYPE qf00-ran_int,
gv_random_row TYPE qf00-ran_int.
* 常量
CONSTANTS:cons_up TYPE c VALUE '↑',
cons_down TYPE c VALUE '↓',
cons_left TYPE c VALUE '←',
cons_right TYPE c VALUE '→',
cons_border TYPE c VALUE '✰',
cons_food TYPE c VALUE '❀',
cons_body TYPE c VALUE 'O'.
* 初始化 背景地图
METHODS:init_bg.
* 定时器
METHODS:handle_finished FOR EVENT finished OF cl_gui_timer.
* 热点hotspot事件
METHODS:handle_link_click FOR EVENT link_click OF cl_salv_events_table IMPORTING row column.
* 刷新背景地图
METHODS:refresh_bg.
* 运行游戏
METHODS:run.
* 地图上随机产生一个点,贪吃蛇需要吃的果实
METHODS:target_random.
* 构造蛇的主体
METHODS:init_snake.
* 移动蛇体
METHODS:move_snake IMPORTING direction TYPE c OPTIONAL RETURNING VALUE(r_flag) TYPE char1.
* 新的蛇体
METHODS:new_snake IMPORTING i_flag TYPE char1.
ENDCLASS.
CLASS zcl_snake IMPLEMENTATION.
METHOD:init_bg.
CLEAR:gt_bg.
* 21*21的地图,1列 21列 1行 21行为边界
DO 21 TIMES.
APPEND INITIAL LINE TO gt_bg.
ENDDO.
LOOP AT gt_bg INTO gs_bg.
IF sy-tabix = 1 OR sy-tabix = 21.
* 第1行 第21行 改变颜色作为边界
gs_bg-color = VALUE #( FOR i = 1 UNTIL i > 21
( fname = |C{ i + 100 }| color = VALUE #( col = '1' int = '1' inv = '0' ) ) ) .
DO 21 TIMES.
ASSIGN COMPONENT |C{ sy-index + 100 }| OF STRUCTURE gs_bg TO FIELD-SYMBOL(<fs_bg_border>).
<fs_bg_border> = cons_border.
ENDDO.
ELSE.
* 第1列 第21列 改变颜色作为边界
gs_bg-color = VALUE #( ( fname = 'C101' color = VALUE #( col = '1' int = '1' inv = '0' ) )
( fname = 'C121' color = VALUE #( col = '1' int = '1' inv = '0' ) ) ).
gs_bg-c101 = cons_border.
gs_bg-c121 = cons_border.
ENDIF.
MODIFY gt_bg FROM gs_bg.
ENDLOOP.
cl_salv_table=>factory( IMPORTING r_salv_table = gc_st CHANGING t_table = gt_bg ).
* hotspot event
DATA(lc_events) = gc_st->get_event( ).
SET HANDLER handle_link_click FOR lc_events.
* 开始按钮
* READ TABLE gt_bg ASSIGNING FIELD-SYMBOL(<fs_bg>) INDEX 13.
* IF sy-subrc = 0.
* <fs_bg>-m102 = 'GO'.
* <fs_bg>-type = VALUE salv_t_int4_column( "( columnname = 'M102' value = if_salv_c_cell_type=>button )
* ( columnname = 'M102' value = if_salv_c_cell_type=>hotspot ) ).
* ENDIF.
* 方向按钮
READ TABLE gt_bg ASSIGNING FIELD-SYMBOL(<fs_bg>) INDEX 17.
IF sy-subrc = 0.
<fs_bg>-m103 = icon_next_value.
<fs_bg>-type = VALUE salv_t_int4_column( ( columnname = 'M103' value = if_salv_c_cell_type=>hotspot ) ).
ENDIF.
READ TABLE gt_bg ASSIGNING <fs_bg> INDEX 18.
IF sy-subrc = 0.
<fs_bg>-m102 = icon_column_left.
<fs_bg>-m104 = icon_column_right.
<fs_bg>-type = VALUE salv_t_int4_column( ( columnname = 'M102' value = if_salv_c_cell_type=>hotspot )
( columnname = 'M104' value = if_salv_c_cell_type=>hotspot ) ).
ENDIF.
READ TABLE gt_bg ASSIGNING <fs_bg> INDEX 19.
IF sy-subrc = 0.
<fs_bg>-m103 = icon_previous_value.
<fs_bg>-type = VALUE salv_t_int4_column( ( columnname = 'M103' value = if_salv_c_cell_type=>hotspot ) ).
ENDIF.
* 颜色样式和单元格样式
DATA(lc_columns) = gc_st->get_columns( ).
lc_columns->set_color_column( 'COLOR' ).
lc_columns->set_cell_type_column( 'TYPE' ).
* 选择模式
DATA(lc_selections) = gc_st->get_selections( ).
lc_selections->set_selection_mode( if_salv_c_selection_mode=>cell ).
DATA:lc_column TYPE REF TO cl_salv_column.
DO 21 TIMES.
lc_column = lc_columns->get_column( CONV lvc_fname( |C{ sy-index + 100 }| ) ).
* 居中显示
lc_column->set_alignment( if_salv_c_alignment=>centered ).
ENDDO.
DATA:lc_column_table TYPE REF TO cl_salv_column_table.
DO 5 TIMES.
lc_column_table ?= lc_columns->get_column( CONV lvc_fname( |M{ sy-index + 100 }| ) ).
* 将列设置为显示ICON
lc_column_table->set_icon( if_salv_c_bool_sap=>true ).
lc_column_table->set_alignment( if_salv_c_alignment=>centered ).
lc_column_table->set_output_length( 2 ).
ENDDO.
ENDMETHOD.
METHOD handle_finished.
DATA(zflag) = move_snake( ).
new_snake( zflag ).
gc_st->refresh( ).
CALL METHOD gc_timer->run.
ENDMETHOD.
METHOD handle_link_click.
DATA(lv_direction) = COND string( WHEN row = 17 AND column = 'M103' THEN 'UP'
WHEN row = 18 AND column = 'M102' THEN 'LEFT'
WHEN row = 18 AND column = 'M104' THEN 'RIGHT'
WHEN row = 19 AND column = 'M103' THEN 'DOWN').
CASE lv_direction.
WHEN 'UP'.
DATA(zflag) = move_snake( direction = cons_up ).
new_snake( zflag ).
WHEN 'LEFT'.
zflag = move_snake( direction = cons_left ).
new_snake( zflag ).
WHEN 'RIGHT'.
zflag = move_snake( direction = cons_right ).
new_snake( zflag ).
WHEN 'DOWN'.
zflag = move_snake( direction = cons_down ).
new_snake( zflag ).
WHEN OTHERS.
ENDCASE.
ENDMETHOD.
METHOD:refresh_bg.
CREATE OBJECT gc_timer.
SET HANDLER handle_finished FOR gc_timer.
gc_timer->interval = 1.
CALL METHOD gc_timer->run.
ENDMETHOD.
METHOD:run.
init_snake( ).
target_random( ).
refresh_bg( ).
gc_st->display( ).
ENDMETHOD.
METHOD:target_random.
DATA:lv_flag TYPE c.
CLEAR:lv_flag.
WHILE lv_flag IS INITIAL.
* 随机一列
CALL FUNCTION 'QF05_RANDOM_INTEGER'
EXPORTING
ran_int_max = 20
ran_int_min = 2
IMPORTING
ran_int = gv_random_col.
* 随机一行
CALL FUNCTION 'QF05_RANDOM_INTEGER'
EXPORTING
ran_int_max = 20
ran_int_min = 2
IMPORTING
ran_int = gv_random_row.
* 新的果实不能占用蛇的身体
IF line_exists( gt_body[ xcol = gv_random_col krow = gv_random_row ] ).
ELSE.
lv_flag = 'X'.
ENDIF.
ENDWHILE.
READ TABLE gt_bg ASSIGNING FIELD-SYMBOL(<fs_bg>) INDEX gv_random_row.
IF sy-subrc = 0.
<fs_bg>-color = VALUE #( ( fname = |C{ gv_random_col + 100 }| color = VALUE #( col = '7' int = '1' inv = '0' ) )
( fname = 'C101' color = VALUE #( col = '1' int = '1' inv = '0' ) )
( fname = 'C121' color = VALUE #( col = '1' int = '1' inv = '0' ) ) ).
ASSIGN COMPONENT |C{ gv_random_col + 100 }| OF STRUCTURE <fs_bg> TO FIELD-SYMBOL(<fs_target>).
<fs_target> = cons_food.
ENDIF.
ENDMETHOD.
METHOD:init_snake.
CLEAR:gt_body.
gt_body = VALUE #( ( xcol = 11 krow = 11 ztop = cons_up )
( xcol = 11 krow = 12 )
( xcol = 11 krow = 13 ) ).
LOOP AT gt_body INTO gs_body.
ASSIGN COMPONENT |C{ gs_body-xcol + 100 }| OF STRUCTURE gt_bg[ gs_body-krow ] TO FIELD-SYMBOL(<fs_bg>).
IF gs_body-ztop = cons_up.
<fs_bg> = cons_up.
ELSE.
<fs_bg> = cons_body.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD:move_snake.
CLEAR:r_flag.
LOOP AT gt_bg INTO DATA(ls_bg).
* 查询到蛇头得位置,并判断方向
DO 21 TIMES.
ASSIGN COMPONENT |C{ sy-index + 100 }| OF STRUCTURE ls_bg TO FIELD-SYMBOL(<fs_arrow>).
* 判断是否反方向运行 反方向则退出
IF ( <fs_arrow> = cons_up AND direction = cons_down ) OR
( <fs_arrow> = cons_down AND direction = cons_up ) OR
( <fs_arrow> = cons_left AND direction = cons_right ) OR
( <fs_arrow> = cons_right AND direction = cons_left ).
r_flag = 'X'.
RETURN.
ENDIF.
* 判断是否相同方向运行 同方向则不进行操作
IF <fs_arrow> = direction.
* 判断蛇头是否变更了方向
ELSEIF ( <fs_arrow> = cons_up OR <fs_arrow> = cons_down OR <fs_arrow> = cons_left OR <fs_arrow> = cons_right ) AND direction IS NOT INITIAL.
<fs_arrow> = direction.
ENDIF.
* 移动蛇之后的蛇头坐标
CASE <fs_arrow>.
WHEN cons_up.
gs_body-xcol = sy-index.
gs_body-krow = sy-tabix - 1.
gs_body-ztop = cons_up.
WHEN cons_down.
gs_body-xcol = sy-index.
gs_body-krow = sy-tabix + 1.
gs_body-ztop = cons_down.
WHEN cons_left.
gs_body-xcol = sy-index - 1.
gs_body-krow = sy-tabix.
gs_body-ztop = cons_left.
WHEN cons_right.
gs_body-xcol = sy-index + 1.
gs_body-krow = sy-tabix.
gs_body-ztop = cons_right.
WHEN OTHERS.
ENDCASE.
* 删除移动前蛇在地图上的轨迹
<fs_arrow> = ''.
* 将新坐标添加到内表
IF gs_body-ztop IS NOT INITIAL.
INSERT gs_body INTO gt_body INDEX 1.
CLEAR:gs_body.
READ TABLE gt_body ASSIGNING FIELD-SYMBOL(<fs_body>) INDEX 2.
IF sy-subrc = 0.
<fs_body>-ztop = ''.
ENDIF.
RETURN.
ENDIF.
ENDDO.
ENDLOOP.
ENDMETHOD.
METHOD:new_snake.
LOOP AT gt_body INTO gs_body WHERE ztop IS NOT INITIAL.
ASSIGN COMPONENT |C{ gs_body-xcol + 100 }| OF STRUCTURE gt_bg[ gs_body-krow ] TO FIELD-SYMBOL(<fs_bg>).
* 检查是否撞墙 或者撞上自己
IF <fs_bg> = cons_border OR <fs_bg> = cons_body.
MESSAGE 'YOU LOST!' TYPE 'I'.
LEAVE TO SCREEN 0.
ENDIF.
* 检查是否吃到果实
IF <fs_bg> = cons_food.
ASSIGN COMPONENT 'COLOR' OF STRUCTURE gt_bg[ gs_body-krow ] TO FIELD-SYMBOL(<fs_bg_color>).
<fs_bg_color> = VALUE lvc_t_scol( ( fname = 'C101' color = VALUE #( col = '1' int = '1' inv = '0' ) )
( fname = 'C121' color = VALUE #( col = '1' int = '1' inv = '0' ) ) ).
* 生成新的果实
target_random( ).
* 增加尾巴长度
DATA(lv_tail) = 'X'.
ENDIF.
ENDLOOP.
* 吃到果实蛇尾长度+1 ,没吃到 -1
IF lv_tail = 'X'.
ELSE.
IF i_flag IS INITIAL.
DATA(lv_tabix) = lines( gt_body ).
DELETE gt_body INDEX lv_tabix.
ENDIF.
ENDIF.
* 删除旧蛇
LOOP AT gt_bg INTO gs_bg.
DO 21 TIMES.
ASSIGN COMPONENT |C{ sy-index + 100 }| OF STRUCTURE gs_bg TO <fs_bg>.
IF <fs_bg> <> cons_food AND <fs_bg> <> cons_border.
<fs_bg> = ''.
ENDIF.
ENDDO.
MODIFY gt_bg FROM gs_bg.
ENDLOOP.
* 构造移动后的蛇的身体
LOOP AT gt_body INTO gs_body.
ASSIGN COMPONENT |C{ gs_body-xcol + 100 }| OF STRUCTURE gt_bg[ gs_body-krow ] TO <fs_bg>.
IF gs_body-ztop <> ''.
<fs_bg> = gs_body-ztop.
ELSE.
<fs_bg> = cons_body.
ENDIF.
ENDLOOP.
* 刷新后强制双击表格,就可以看到修改的内表了
CALL FUNCTION 'SAPGUI_SET_FUNCTIONCODE'
EXPORTING
functioncode = '=ENT'
EXCEPTIONS
function_not_supported = 1
OTHERS = 2.
gc_st->refresh( ).
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(gc_snake) = NEW zcl_snake( ).
gc_snake->init_bg( ).
gc_snake->run( ).
贪吃蛇 BY ABAP
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 过程 搭建环境 绘制游戏背景 创建Snake函数 创建Food函数 绘制Snake和Food 最终代码 搭建环境 ...
- Mac上没有装Alfred的人,一定是Mac小白用户Mac上装了Alfred却没有破解的人,一定是Mac初级选手M...