저는 Spartan3e 용 vhdl에서 현재 스네이크 게임을 구현했습니다.Vhdl 스네이크 - 꼬리 구현을 자동화하는 방법
VGA 화면에서 셀 사각형을 그리는 부분을 이미 작성했으며 사각형 주위로 이동할 수 있습니다.
문제는 꼬리 구현입니다. 지금까지 수동으로 다른 셀 세그먼트를 내뱀에 추가했지만 자동화하고 싶습니다 (예 : 자바에서 대기열과 셀을 간단히 만들고 다음 위치의 positiong를 설정하는 경우) 셀을 셀로 사용). 나는 vhdl 같은 복잡한 함수를 작성하는 방법을 모르겠습니다.
begin
process (clk, reset, endOfGame)
begin
if reset='1' or endOfGame=true then
ball_y_reg <= to_unsigned(231,10);
ball_x_reg <= to_unsigned(311,10);
ball_x_reg_cell<=to_unsigned(231,10);
ball_y_reg_cell<=to_unsigned(311,10);
-- velocity after reset schould be none
x_delta_reg <= ("0000000000");
y_delta_reg <= ("0000000000");
elsif (clk'event and clk='1') then
ball_x_reg_cell<=ball_x_next_cell;
ball_y_reg_cell<=ball_y_next_cell;
ball_x_reg <= ball_x_next;
ball_y_reg <= ball_y_next;
x_delta_reg <= x_delta_next;
y_delta_reg <= y_delta_next;
end if;
end process;
pix_x <= unsigned(pixel_x);
pix_y <= unsigned(pixel_y);
-- refr_tick: 1-clock tick asserted at start of v-sync
-- i.e., when the screen is refreshed (60 Hz)
refr_tick <= '1' when (pix_y=481) and (pix_x=0) else
'0';
----------------------------------------------
-- pixel within wall
wall_on <=
'1' when ((WALL_X_LEFTSIDE_L<=pix_x) and (pix_x<=WALL_X_LEFTSIDE_R)) or ((WALL_X_RIGHTSIDE_L<=pix_x) and (pix_x<=WALL_X_RIGHTSIDE_R)) or ((WALL_Y_UPSIDE_U<=pix_y) and (pix_y<=WALL_Y_UPSIDE_D)) or ((WALL_Y_DOWNSIDE_U<=pix_y) and (pix_y<=WALL_Y_DOWNSIDE_D)) else
'0';
-- wall rgb output
wall_rgb <= "001"; -- blue
----------------------------------------------
-- square ball
ball_x_l <= ball_x_reg;
ball_y_t <= ball_y_reg;
ball_x_r <= ball_x_l + BALL_SIZE - 1;
ball_y_b <= ball_y_t + BALL_SIZE - 1;
ball_x_l_cell <= ball_x_reg_cell;
ball_y_t_cell <= ball_y_reg_cell;
ball_x_r_cell <= ball_x_l_cell + BALL_SIZE - 1;
ball_y_b_cell <= ball_y_t_cell + BALL_SIZE - 1;
--tail
-- pixel within squared ball
sq_ball_on <=
'1' when ((ball_x_l<=pix_x) and (pix_x<=ball_x_r) and
(ball_y_t<=pix_y) and (pix_y<=ball_y_b))
or
((ball_x_l_cell<=pix_x) and (pix_x<=ball_x_r_cell) and
(ball_y_t_cell<=pix_y) and (pix_y<=ball_y_b_cell))
else
'0';
ball_x_next <= ball_x_reg + x_delta_reg
when refr_tick='1' else
ball_x_reg ;
ball_y_next <= ball_y_reg + y_delta_reg
when refr_tick='1' else
ball_y_reg ;
ball_x_next_cell <= ball_x_reg - BALL_SIZE when refr_tick='1' and CURRENT_DIRECTION = DIR_RIGHT
else ball_x_reg + BALL_SIZE when refr_tick='1' and CURRENT_DIRECTION = DIR_LEFT
else ball_x_reg when refr_tick='1'
else ball_x_reg_cell;
ball_y_next_cell <= ball_y_reg - BALL_SIZE when refr_tick='1' and CURRENT_DIRECTION = DIR_UP
else ball_y_reg + BALL_SIZE when refr_tick='1' and CURRENT_DIRECTION = DIR_DOWN
else ball_y_reg when refr_tick='1'
else ball_y_reg_cell;
-- new bar y-position
process(ball_y_reg, ball_y_b, ball_y_t, refr_tick, btn, ball_x_reg ,ball_x_r, ball_x_l, x_delta_reg, y_delta_reg)
begin
x_delta_next <= x_delta_reg;
y_delta_next <= y_delta_reg;
if refr_tick='1' then
if btn(1)='1' and ball_y_b<(MAX_Y-1-BALL_SIZE) then
if CURRENT_DIRECTION /= DIR_UP then
CURRENT_DIRECTION <= DIR_DOWN;
y_delta_next <= BALL_V_P; -- move down
x_delta_next <= (others=>'0');
end if;
elsif btn(0)='1' and ball_y_t > BALL_SIZE then
if CURRENT_DIRECTION /= DIR_DOWN then
CURRENT_DIRECTION <= DIR_UP;
y_delta_next <= BALL_V_N; -- move up
x_delta_next <= (others=>'0');
end if;
elsif btn(2)='1' and ball_x_r<(MAX_X-1-BALL_SIZE) then
if CURRENT_DIRECTION /= DIR_LEFT then
CURRENT_DIRECTION <= DIR_RIGHT;
x_delta_next <= BALL_V_P;
y_delta_next <= (others=>'0');
end if;
elsif btn(3)='1' and ball_x_l > BALL_SIZE then
if CURRENT_DIRECTION /= DIR_RIGHT then
CURRENT_DIRECTION <= DIR_LEFT;
x_delta_next <= BALL_V_N;
y_delta_next <= (others=>'0');
end if;
end if;
if ball_x_l < WALL_X_LEFTSIDE_R or ball_y_t < WALL_Y_UPSIDE_D or ball_y_b > WALL_Y_DOWNSIDE_U or ball_x_r > WALL_X_RIGHTSIDE_L then
endOfGame <= true;
CURRENT_DIRECTION <= IDLE;
else
endOfGame <= false;
end if;
end if;
end process;
"볼 X 다음 셀"부분을 수동으로 추가 된 두 번째 셀 :
여기 내 코드입니다.
비슷한 문제가 포함 된 주제를 검색했지만 vhdl에서 다루지 않습니다.
도움 주셔서 감사합니다.
빠른 답변 감사합니다!vhdl 언어의 한계를 알고 있지만 구현 팁을 묻습니다. 내가 currect 및 다음 위치, 방향, 가시성을 포함하는 레코드 배열을 사용해야한다는 것을 알고 있습니다. 문제는 어떻게하면 현재 하나의 셀 (세그먼트)을 사용하여 동시 레코드로 레코드 배열을 반복 할 수 있는가입니다. 나는 내가 직면해야하는 애니메이션으로 그런 조작을 할 필요가있다. –
성능 요구에 따라 다릅니다. 간단한 루프는 단일 클럭 사이클에서 배열의 범위를 반복 할 수 있지만 BlockRam으로 구현되지 않도록하며 거대한 하드웨어를 생성 할 수 있습니다. 아마도 상태 머신을보고 클럭 사이클 당 하나의 셀을 반복합니다. 그것은 당신의 정확한 요구 사항에 달려 있습니다. –