Mình đang thực hiện làm game Brickbreaker trên DE1.Viết được kha khá code rồi nhưng bị vướng mắc xử lý trường hợp bóng đập vào tường và nảy lại.mình post cả code của mình lên cho mọi người tham khảo.Help me!!!
library ieee ;
library ieee ;
HTML Code:
use ieee.std_logic_1164.all ; use ieee.numeric_std.all ; entity ball is port( clk,rst : in std_logic ; video_on : in std_logic ; pixel_x,pixel_y : in std_logic_vector( 9 downto 0 ) ; graph_rgb : out std_logic_vector( 2 downto 0 ) ) ; end ball ; architecture behav of ball is constant max_x :integer:= 640 ; constant max_y :integer := 480 ; signal pix_x,pix_y: unsigned( 9 downto 0 ) ; constant ball_size : integer := 13 ; signal ball_x_l,ball_x_r : unsigned( 9 downto 0 ) ; signal ball_x_reg,ball_x_next: unsigned( 9 downto 0 ) ; signal ball_y_t,ball_y_b : unsigned( 9 downto 0 ) ; signal ball_y_reg,ball_y_next: unsigned( 9 downto 0 ) ; signal ball_on: std_logic ; signal ball_rgb: std_logic_vector( 2 downto 0 ) ; --reg to track ball speed signal x_delta_reg,x_delta_next: unsigned( 9 downto 0 ) ; signal y_delta_reg,y_delta_next: unsigned( 9 downto 0 ) ; constant ball_v_p : unsigned(9 downto 0 ) := to_unsigned(1,10); constant ball_v_n : unsigned(9 downto 0 ) :=to_unsigned(-1,10) ; type rom_type is array( 12 downto 0 ) of std_logic_vector( 12 downto 0 ) ; constant ball_rom:rom_type := (-- 0123456789012 "0000111110000",--0 "0001111111000",--1 "0011111111100",--2 "0111111111110",--3 "1111111111111",--4 "1111111111111",--5 "1111111111111",--6 "1111111111111",--7 "1111111111111",--8 "0111111111110",--9 "0011111111100",--10 "0001111111000",--11 "0000111110000"--12 ) ; signal rom_addr,rom_col : unsigned( 3 downto 0 ) ; signal rom_data: std_logic_vector( 12 downto 0 ) ; signal rom_bit : std_logic ; signal sq_ball_on,rd_ball_on : std_logic ; signal led:std_logic_vector( 3 downto 0 ):=(others =>'0') ; -------------screen and ball--------------------- type screen_arr is array( 9 downto 0 , 29 downto 0 ) of unsigned( 2 downto 0 ) ; signal screen,screen_reg,screen_next: screen_arr; signal x_reg,y_reg:integer range 0 to 30 ; signal screen_x,screen_y:integer range 0 to 30 ; signal pong_y_t,pong_y_b,pong_x_l,pong_x_r:std_logic ;--bien luu trang thai dap vao tuong signal wall_red,wall_blue,back_ground:std_logic ; signal screen_rgb: std_logic_vector( 2 downto 0 ) ; signal refr_tick:std_logic ; begin process( clk,rst,screen) begin if( rst = '1' ) then ball_x_reg <= (others=> '0') ; ball_y_reg <= (others => '0') ; x_delta_reg <="0000000001" ; y_delta_reg <="0000000001"; screen_reg <= screen ; elsif( clk'event and clk = '1' ) then ball_x_reg <= ball_x_next ; ball_y_reg <= ball_y_next ; x_delta_reg<=x_delta_next ; y_delta_reg<=y_delta_next ; screen_reg <= screen_next ; end if ; end process ; pix_x <= unsigned(pixel_x) ; pix_y <= unsigned(pixel_y) ; refr_tick <= '1' when (pix_y = 481) and (pix_x = 0 ) else '0' ; 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 ; 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) else '0'; rom_addr <= pix_y( 3 downto 0 ) - ball_y_t( 3 downto 0 ) ; rom_col <= pix_x( 3 downto 0 ) - ball_x_l ( 3 downto 0 ) ; rom_data <= ball_rom( to_integer(rom_addr)) ; rom_bit <= rom_data(to_integer(rom_col)) ; rd_ball_on <= '1' when sq_ball_on = '1' and rom_bit = '1' else '0' ; ball_rgb <= "110" ; process( x_delta_reg , y_delta_reg ,ball_x_l,ball_x_r , ball_y_t,ball_y_b,pong_y_t,pong_y_b,pong_x_r,pong_x_l ) begin x_delta_next <= x_delta_reg ; y_delta_next <= y_delta_reg ; if( ball_x_l <1 and ball_y_b >max_y-1) then--neu bong dap vao goc man hinh thi nay lai x_delta_next <= ball_v_p ; y_delta_next <= ball_v_n ; elsif( ball_y_t < 1 or pong_y_b= '1') then--neu bong dap vao mep tren man hinh y_delta_next <= ball_v_p ; --hoac bong dap vao canh duoi cua tuong elsif ( ball_y_b > max_y -1 or pong_y_t = '1') then--bong dap vao mep duoi man hinh y_delta_next <= ball_v_n ; --hoac bong dap vao canh tren cua tuong elsif ( ball_x_l < 1 or pong_x_r= '1' ) then--bong dap vao mep trai man hinh va mep phai gach x_delta_next <= ball_v_p ; elsif ( ball_x_r > max_x -1 or pong_x_l = '1') then--dap vao mep phai man hinh va mep trai gach x_delta_next <= ball_v_n ; end if ; end process ; ball_x_next <= ball_x_reg + x_delta_reg when refr_tick = '1' else--tin hieu nay the hien bong dang chuyen dong ball_x_reg ; ball_y_next <= ball_y_reg + y_delta_reg when refr_tick = '1' else--tin hieu nay the hien bong dang chuyen dong ball_y_reg ; ball_on <= rd_ball_on ; --------------------------------------------------------- --------------screen and ball---------------------------- G2: for j in 0 to 29 generate--doan nay la chia man hinh ra thanh G1: for i in 0 to 9 generate-- cac o vuong voi kich thuoc 64x16pixels screen(i,j) <= "001" when (i=0 and j=20) or ( i=1 and j= 20) or ( i = 2 and j = 20) or ( i= 3 and j = 20) or (i=4 and j = 20 ) or (i=5 and j = 20 ) or (i=6 and j = 20 ) or (i=7 and j = 20 ) or (i=8 and j = 20 ) or (i=9 and j = 20 ) else "000" ; end generate ; end generate ; x_reg <= to_integer(pix_x)/64 ; --dia chi o theo hang ngang y_reg <= to_integer(pix_y)/16 ; --dia chia o theo hang doc screen_x <= to_integer(ball_x_reg)/64 ;-- screen_y <= to_integer(ball_y_reg)/16 ; --2 bien nay luu dia chi cua bong nam trong o nao process(clk,screen_reg,ball_x_r,ball_x_l,ball_y_b,ball_y_t,screen_x,screen_y) begin screen_next <= screen_reg ; pong_y_t <= '0' ; pong_y_b <= '0' ; pong_x_l <= '0' ; pong_x_r <= '0' ; if( screen_reg(screen_x,screen_y) /= 0 ) then --khi bong dap vao tuong screen_next(screen_x,screen_y) <= screen_reg(screen_x,screen_y) - 1;--gia tri nam o o tuong day giam di 1 dvi if( ball_y_b >= screen_y* 16 and ball_y_t <= screen_y*16 + 15 ) then if(ball_x_r >= screen_x *64 and ball_x_l < screen_x*64 ) then pong_x_l <= '1' ;--tin hieu chi trang thai bong dap vao ben trai tuong elsif( ball_x_l <= screen_x*64 + 63 and ball_x_r > screen_x*64 + 63 ) then pong_x_r <= '1' ;--bong dap ben phai tuong end if ; elsif( ball_x_r >= screen_x*64 and ball_x_l < screen_x*64+ 63 ) then if( ball_y_b >= screen_y *16 and ball_y_t <= screen_y*16) then pong_y_t <= '1' ;--bong dap phia tren tuong elsif( ball_y_t <= screen_y*16 + 15 and ball_y_b > screen_y*16+15 ) then pong_y_b <= '1' ;--bong dap phia duoi tuong end if ; end if ; end if ; end process ; wall_red <= '1' when screen_reg(x_reg,y_reg ) = "001" else '0'; wall_blue <= '1' when screen_reg(x_reg,y_reg) = "010" else '0' ; back_ground <= '1' when screen_reg(x_reg,y_reg) = "000" else '0' ; screen_rgb <= "100" when wall_red = '1' else "010" when wall_blue= '1' else "000" when back_ground = '1' else UNAFFECTED ; process( video_on ,ball_on, ball_rgb, screen_rgb ) begin if( video_on = '0' ) then graph_rgb <= "000" ; elsif( ball_on = '1' ) then graph_rgb <= ball_rgb ; else graph_rgb <= screen_rgb ; end if ; end process ; end behav ;
Comment