pong

PONG

Pong (o Tele-Pong) fue un videojuego de la primera generación de videoconsolas publicado por Atari es de origen japonés, creado por Nolan Bushnell y lanzado el 29 de noviembre de 1972. Pong está basado en el deporte de tenis de mesa (o ping pong). La palabra Pong es una marca registrada por Atari Interactive, mientras que la palabra genérica "pong" es usada para describir el género de videojuegos "bate y bola". La popularidad de Pong dio lugar a una demanda de infracción de patentes y ganada por parte de los fabricantes de Magnavox Odyssey, que poseía un juego similar.

Este es un juego de deportes en dos dimensiones que simula un tenis de mesa. El jugador controla en el juego una paleta moviéndola verticalmente en la parte izquierda de la pantalla, y puede competir tanto contra un oponente controlado por computadora, como con otro jugador humano que controla una segunda paleta en morongas la parte opuesta. Los jugadores pueden usar las paletas para pegarle a la pelota hacia un lado u otro. El objetivo consiste en que uno de los jugadores consiga más puntos que el oponente al finalizar el juego. Estos puntos se obtienen cuando el jugador adversario falla al devolver la pelota

pong.screenshot.png
Imagen 1: juego pong

CARACTERÍSTICAS

Las características requeridas para este sistema
son:

  • El movimiento de las barras debe ser controlado por medio de los pulsadores de la tarjeta Nexys 2, uno para cada usuario
  • El desplazamiento de las barras está restringido, sólo de un lado al otro
  • Entre las barras se mostrará la pelota de colores con la cual los usuarios jugarán.
  • La pelota se moverá de manera independiente, en línea recta y partiendo de un inicio semi-aleatorio
  • Una vez que la pelota se muestra en la pantalla, los jugadores deben comenzar a mover su barra correspondiente
  • Las teclas se configurarán por default y no será posible seleccionar otras.
  • Una vez comenzado el juego, los jugadores deben evitar que la pelota cruce su lado de la pantalla.
  • La velocidad con la que se mueve la pelota es fija.

DISEÑO DEL JUEGO

para la realización de este juego es necesario contar con:

TARJETA NEXSYS 2

El Nexys 2 es una plataforma de diseño de sistemas digitales de gran alcance en torno a un Xilinx Spartan 3E FPGA. Con 16Mbytes de SDRAM rápido y 16Mbytes de flash ROM, el Nexys 2 es ideal para procesadores embebidos como de Xilinx 32-bit RISC Microblaze ™. El puerto USB2 de alta velocidad a bordo en, junto con una colección de dispositivos de E / S, puertos de datos y los conectores de expansión, permite una amplia gama de diseños para ser completado sin la necesidad de ningún componente adicional.

NEXYS2_400.jpg

DISEÑO LOGICO

el juego se controla con dos pulsadores para poder mover cada una de las paletas, la pelota debe rebotar al tocar las paletas al igual que cuando toca los bordes de los laterales de la pantalla, si la pelota toca la linea inferior o la linea superior de la pantalla la pelota debe volver a su posición inicial para que el juego pueda volver a empezar.

TOP VGA

En el top VGA se muestran todas las conexiones realizadas

11291834_10152756031751650_1038517374_n.jpg?oh=c6c4d17ceecee381cc9973cd6d33e154&oe=55672F31&__gda__=1432831505_16bdfc532ed4605f676e96664212d73c

Top VGA


11291789_10152756031761650_463206001_n.jpg?oh=87d19ac26d533fd4d475ae080e712b93&oe=556738AD&__gda__=1432824684_a7874141855b561459755c40836361d0

Top VGA expandido


codigo

 module top_vga(
    module top_vga(
    input clk, reset,
    input [2:0]sw,
    input izquierda,derecha,izquierda2,derecha2,
    output hsync, vsync,
    output [2:0] rgb
    );
    wire [2:0] w_sw2;    
    wire [9:0] w_posx;
    wire [9:0] w_posy;
    wire [9:0] w_posbarrax;
    wire [9:0] w_posbarray;
    wire  w_clk2;

    position posicion(.clk(clk),.posx(w_posx), .posy(w_posy),.posbarrax(w_posbarrax),.posbarray(w_posbarray));
    color colores(.clk(clk),.sw2(w_sw2));
    barra_de_despazamiento barra(.izquierda(izquierda) ,.derecha(derecha),.clk(clk),.posbarrax(w_posbarrax));
    barra_de_despazamiento2 barra2(.izquierda2(izquierda2) ,.derecha2(derecha2),.clk(clk),.posbarray(w_posbarray));
    Imagen image(.clk(clk), .reset(reset),.sw(sw),.sw2(w_sw2), .hsync(hsync), .vsync(vsync),.rgb(rgb), .posx(w_posx), .posy(w_posy),.posbarrax(w_posbarrax), .posbarray(w_posbarray));//,.poscaja4x(w_poscaja4x),.poscaja4y(w_poscaja4y),.poscaja5x(w_poscaja5x),.poscaja5y(w_poscaja5y),.poscaja6x(w_poscaja6x),.poscaja6y(w_poscaja6y),.poscaja7x(w_poscaja7x),.poscaja7y(w_poscaja7y),.poscaja8x(w_poscaja8x),.poscaja8y(w_poscaja8y),.poscaja9x(w_poscaja9x),.poscaja9y(w_poscaja9y));
endmodule

IMAGEN

11358644_10152756149136650_1252046283_n.jpg?oh=5ab09b71721ead7ed025750ca450768a&oe=556834FA&__gda__=1432894154_25cb1ef9d4375df1065b0c5986e24dc9
Diagrama de bloques de imagen

codigo imagen

tambien conocido como VGA, es el encargado de recibir las señales de color y posición para dibujar las barras y la bola

module Imagen( 
    input clk, reset, 
    input [9:0]posx, 
    input [9:0]posy,
    input [2:0]sw,
    input [2:0]sw2, 
    output hsync, vsync,
    output [2:0] rgb
    );
    //signal declaration
    reg [2:0] rgb_reg;
    wire video_on;
     wire [9:0] x,y;
    //instantiate vga sync circuit
    vga_sync vsync_unit (.clk(clk), .reset(reset), .hsync(hsync), . vsync(vsync), .video_on(video_on), . p_tick(), .pixel_x(x), .pixel_y(y));
    //rgb buffer
     always @(posedge clk, posedge reset) begin
        if (reset) rgb_reg <= 0;
        else begin
            if (x>posx & x<(20+posx) & y>posy & y<(20+posy)) rgb_reg<=sw2;
            else if (x>=0 & x<=10 & y>=0 & y<=480) rgb_reg<=3'b111;
            else if (x>=630 & x<=640 & y>=0 & y<=480) rgb_reg<=3'b111;
            else if (x>=0 & x<=640 & y>=0 & y<=10) rgb_reg<=3'b111;
            else if (x>=0 & x<=640 & y>=470 & y<=480) rgb_reg<=3'b111;
            else rgb_reg <= sw;
        end
    end
    // output
    assign rgb = (video_on) ? rgb_reg : 3'b000;
endmodule

POCISION

11349911_10152756305501650_78228182_n.jpg?oh=9cc313bbddff3e57b500313207087005&oe=55670BD4&__gda__=1432887364_2bf1205b9e0391ce5e778aa772961bdf

Diagrama de bloques de posicion

Codigo

module position(clk, clk2,posx, posy, posbarrax, posbarray);
    input clk;
    output reg [9:0] posx=590;
    output reg [9:0] posy=450;
    output reg clk2;
   input [9:0] posbarrax;
    input [9:0] posbarray;
    reg [17:0] temp=0;
    reg dirx=0;
    reg diry=0;
    always @(posedge clk) begin
        temp=temp+1;
        clk2=temp[17];
    end

    always @(posedge clk2) begin

    //iniciadores.
            if (dirx==0 & diry==0) begin
         if (posx>=610) dirx=1;
            else dirx=0;
            if (posy>=460) diry=1;    //desactivar mas no borrar
            else diry=0;              //desactivar mas no borrar
            end
            else if (dirx==0 & diry==1) begin
            if (posx>=610) dirx=1;
            else dirx=0;
            if (posy<=10) diry=0;
            else diry=1;
            end
          if (dirx==1 & diry==1) begin
            if (posx<=10) dirx=0;
            else dirx=1;
            if (posy<=10) diry=0;
            else diry=1;
            end
            else if (dirx==1 & diry==0) begin
            if (posx<=10) dirx=0;
            else dirx=1;
            if (posy>=460) diry=1;     //desactivar mas no borrar
            else diry=0;               //desactivar mas no borrar
          end
    //choque con los bordes.        

            //diagonal derecha decendente/////////////////////////////////////////////////////7
           if (dirx==0 & diry==0) begin
            posx=posx+1;
            posy=posy+1;
         if (posx>=610) dirx=1;
            else dirx=0;
            if (posy>=460) diry=1;    //desactivar mas no borrar
            else diry=0;              //desactivar mas no borrar
            //choque con el borde de la barra
            if(posx+20==posbarrax)
            if(posy>=430 & posy<=440) dirx=1; 
            else dirx=0; 
            // barra de desplazamiento
            if ((posy==410)&(posx>=posbarrax-20)& (posx<=posbarrax+100) | (posy>=450) ) diry=1;
            else diry=0;
            // choque con el borde de la barra
            if ((posy+20>=410 & posy<=430)&(posx==posbarrax-20)) dirx=1;
            else dirx=0;
            end

            //diagonal izquierda decendente//////////////////////////////////////////
           else if (dirx==1 & diry==0) begin
            posx=posx-1;
            posy=posy+1;
            if (posx<=10) dirx=0;
            else dirx=1;
            if (posy>=460) diry=1;     //desactivar mas no borrar
            else diry=0;               //desactivar mas no borrar
            //choque con el borde de la barra
            if(posx==posbarrax+100)
            if(posy>=430 & posy<=440)dirx=0; 
            else dirx=1;
            // barra de desplazamiento
            if ((posy==410)&(posx>=posbarrax-20)& (posx<=posbarrax+100) | (posy>=450)) diry=1;
            else diry=0;
            // choque con el borde de la barra
            if ((posy+20>=410 & posy<=430)&(posx==posbarrax+100)) dirx=0;
            else dirx=1;

            end 

           //diagonal derecha ascendente
           else if (dirx==0 & diry==1) begin
            posx=posx+1;
            posy=posy-1;    
            if (posx>=610) dirx=1;
            else dirx=0;
            if (posy<=10) diry=0;
            else diry=1;
            //choque con el borde de la barra
            if(posx+20==posbarray)
            if(posy>=430 & posy<=440) dirx=1; 
            else dirx=0; 
            // barra de desplazamiento
            if ((posy==410)&(posx>=posbarray-20)& (posx<=posbarray+100) | (posy>=450) ) diry=1;
            else diry=0;
            // choque con el borde de la barra
            if ((posy+20>=410 & posy<=430)&(posx==posbarray-20)) dirx=1;
            else dirx=0;
            end

            //diagonal izquierda ascendente
          if (dirx==1 & diry==1) begin
            posx=posx-1;
            posy=posy-1;
            if (posx<=10) dirx=0;
            else dirx=1;
            if (posy<=10) diry=0;
            else diry=1;                                        
            //choque con el borde de la barra
            if(posx==posbarray+100)
            if(posy>=430 & posy<=440)dirx=0; 
            else dirx=1;
            // barra de desplazamiento
            if ((posy==410)&(posx>=posbarray-20)& (posx<=posbarray+100) | (posy>=450)) diry=1;
            else diry=0;
            // choque con el borde de la barra
            if ((posy+20>=410 & posy<=430)&(posx==posbarray+100)) dirx=0;
            else dirx=1;

        end        

        end

endmodule

BARRAS DE DESPLAZAMIENTO

11287268_10152756194996650_569366327_n.jpg?oh=b0424fb60f6b046e01a91a3c633c966f&oe=5567FF95&__gda__=1432895124_92f1357473c69aa8ec0f4ff1173295a311349062_10152760806541650_1919395870_n.jpg?oh=e77d04aa2a5fa7b8e6b5ed9692d20d71&oe=5568CEF6&__gda__=1432869486_33b1a164db0cf17b2741e2417e14adde

Diagrama de bloques barra de desplazamiento

codigo de barra 1

este codigo le permite al jugador mover la barra de izquierda a derecha y tambien hace
tambien establece los limites de movilidad de la barra de manera que no se pueda
salir de la pantalla.

----------------------------barra de juego-----------------------------
module barra_de_despazamiento(izquierda , derecha,clk,posbarrax);

    input clk;
    input izquierda;
    input derecha;
    output reg [9:0] posbarrax=190;

    reg clk3;
    reg [16:0] temp1=0;
    always @(posedge clk) begin
        temp1=temp1+1;
        clk3=temp1[16];
    end

    always@(posedge clk3)begin

        if(izquierda)begin
            posbarrax=posbarrax-1;
            if (posbarrax==11) posbarrax=11;
            else posbarrax=posbarrax;          
            end
        else if(derecha)begin
            posbarrax=posbarrax+1;
            if (posbarrax==530) posbarrax=530;
            else posbarrax=posbarrax;
            end
        else posbarrax=posbarrax;
    end

endmodule

BOLA

Codigo

este codigo lo que hace es que cuando la pelota toque alguna de las esquinas del juego o alguna de las barras la pelota
reconfigura su direccion haciendo que rebote.

codigo de la bola

module position(clk, clk2,posx, posy, posbarrax, posbarray);
    input clk;
    output reg [9:0] posx=590;
    output reg [9:0] posy=450;
    output reg clk2;
   input [9:0] posbarrax;
    input [9:0] posbarray;
    reg [17:0] temp=0;
    reg dirx=0;
    reg diry=0;
    always @(posedge clk) begin
        temp=temp+1;
        clk2=temp[17];
    end

    always @(posedge clk2) begin

    //iniciadores.
            if (dirx==0 & diry==0) begin
         if (posx>=610) dirx=1;
            else dirx=0;
            if (posy>=460) diry=1;    //desactivar mas no borrar
            else diry=0;              //desactivar mas no borrar
            end
            else if (dirx==0 & diry==1) begin
            if (posx>=610) dirx=1;
            else dirx=0;
            if (posy<=10) diry=0;
            else diry=1;
            end
          if (dirx==1 & diry==1) begin
            if (posx<=10) dirx=0;
            else dirx=1;
            if (posy<=10) diry=0;
            else diry=1;
            end
            else if (dirx==1 & diry==0) begin
            if (posx<=10) dirx=0;
            else dirx=1;
            if (posy>=460) diry=1;     //desactivar mas no borrar
            else diry=0;               //desactivar mas no borrar
          end
    //choque con los bordes.        

            //diagonal derecha decendente/////////////////////////////////////////////////////7
           if (dirx==0 & diry==0) begin
            posx=posx+1;
            posy=posy+1;
         if (posx>=610) dirx=1;
            else dirx=0;
            if (posy>=460) diry=1;    //desactivar mas no borrar
            else diry=0;              //desactivar mas no borrar
            //choque con el borde de la barra
            if(posx+20==posbarrax)
            if(posy>=430 & posy<=440) dirx=1; 
            else dirx=0; 
            // barra de desplazamiento
            if ((posy==410)&(posx>=posbarrax-20)& (posx<=posbarrax+100) | (posy>=450) ) diry=1;
            else diry=0;
            // choque con el borde de la barra
            if ((posy+20>=410 & posy<=430)&(posx==posbarrax-20)) dirx=1;
            else dirx=0;
            end

            //diagonal izquierda decendente//////////////////////////////////////////
           else if (dirx==1 & diry==0) begin
            posx=posx-1;
            posy=posy+1;
            if (posx<=10) dirx=0;
            else dirx=1;
            if (posy>=460) diry=1;     //desactivar mas no borrar
            else diry=0;               //desactivar mas no borrar
            //choque con el borde de la barra
            if(posx==posbarrax+100)
            if(posy>=430 & posy<=440)dirx=0; 
            else dirx=1;
            // barra de desplazamiento
            if ((posy==410)&(posx>=posbarrax-20)& (posx<=posbarrax+100) | (posy>=450)) diry=1;
            else diry=0;
            // choque con el borde de la barra
            if ((posy+20>=410 & posy<=430)&(posx==posbarrax+100)) dirx=0;
            else dirx=1;

            end 

           //diagonal derecha ascendente
           else if (dirx==0 & diry==1) begin
            posx=posx+1;
            posy=posy-1;    
            if (posx>=610) dirx=1;
            else dirx=0;
            if (posy<=10) diry=0;
            else diry=1;
            //choque con el borde de la barra
            if(posx+20==posbarray)
            if(posy>=430 & posy<=440) dirx=1; 
            else dirx=0; 
            // barra de desplazamiento
            if ((posy==410)&(posx>=posbarray-20)& (posx<=posbarray+100) | (posy>=450) ) diry=1;
            else diry=0;
            // choque con el borde de la barra
            if ((posy+20>=410 & posy<=430)&(posx==posbarray-20)) dirx=1;
            else dirx=0;
            end

            //diagonal izquierda ascendente
          if (dirx==1 & diry==1) begin
            posx=posx-1;
            posy=posy-1;
            if (posx<=10) dirx=0;
            else dirx=1;
            if (posy<=10) diry=0;
            else diry=1;                                        
            //choque con el borde de la barra
            if(posx==posbarray+100)
            if(posy>=430 & posy<=440)dirx=0; 
            else dirx=1;
            // barra de desplazamiento
            if ((posy==410)&(posx>=posbarray-20)& (posx<=posbarray+100) | (posy>=450)) diry=1;
            else diry=0;
            // choque con el borde de la barra
            if ((posy+20>=410 & posy<=430)&(posx==posbarray+100)) dirx=0;
            else dirx=1;

        end        

        end

endmodule

COLOR

11303446_10152756415276650_1733880052_n.jpg?oh=073970d58b330e2acafd0a3b677523fa&oe=5567F179&__gda__=1432897945_78a6b02e5c41661cce5547db99ca7db7

Diagrama de bloques de color

Codigo Color

este codigo tiene la funcion de cambiar la pelota de color por uno de los 7 posibles
colores de modo que la pelota nunca tendra un solo color

module color(clk,sw2);
    input clk;
    output reg [2:0] sw2;
    reg clk3;
    reg [21:0]temp=0;

    always @(posedge clk) begin
        temp=temp+1;
        clk3=temp[21];
    end

    always @(posedge clk3) begin
        if (sw2==7) sw2=1;
        else sw2=sw2+1;
    end

endmodule

MODULE VGA_SYNC

module vga_sync(
    input clk, reset,
    output hsync , vsync , video_on, p_tick,
    output [9:0] pixel_x, pixel_y
    );

    //constant declaration
    //VGA 640-by-480 sync parameters

    localparam HD = 640;     // horizontal display area
    localparam HF = 48 ;     // h.front(left)border
    localparam HB = 16 ;     // h.back(right)border
    localparam HR = 96 ;     // h.retrace
    localparam VD = 480;     // vertical display area
    localparam VF = 10;     // v.front(top)border
    localparam VB = 33;     // v.back(bottom)border
    localparam VR = 2;        // v.retrace

    // mod-2 counter

    reg mod2_reg;
    wire mod2_next ;
    // sync counters
    reg [9:0] h_count_reg, h_count_next;
    reg [9:0] v_count_reg , v_count_next;
    // output buffer
    reg v_sync_reg , h_sync_reg;
    wire v_sync_next , h_sync_next ;

    // status signal
    wire h_end, v_end, pixel_tick;

    // body
    // registers

    always @(posedge clk, posedge reset)
        if (reset)begin 
            mod2_reg <= 1'b0;
            v_count_reg <= 0;
            h_count_reg <= 0;
            v_sync_reg <= 1'b0;
            h_sync_reg <= 1'b0;
        end
        else begin
            mod2_reg <= mod2_next;
            v_count_reg <= v_count_next;
            h_count_reg <= h_count_next;
            v_sync_reg <= v_sync_next;
            h_sync_reg <= h_sync_next;
        end

    // mod-2 circuit to generate 25 MHz enable tick
    assign mod2_next = ~mod2_reg;
    assign pixel_tick = mod2_reg;

    // status signals
    // end of horizontal counter (799)
    assign h_end = (h_count_reg==(HD+HF+HB+HR-1));
    // end of vertical counter (524)
    assign v_end = (v_count_reg==(VD+VF+VB+VR-1));

    // next-state logic of mod-800 horizontal sync counter
    always @*
        if (pixel_tick)
        // 25 MHz p u l s e
            if (h_end)
                h_count_next = 0;
            else
                h_count_next = h_count_reg+1;
        else
            h_count_next = h_count_reg;

    // next-state logico fmod-525 vertical sync counter
    always @*
        if (pixel_tick & h_end)
            if (v_end)
                v_count_next = 0 ;
            else
                v_count_next = v_count_reg + 1;
        else
            v_count_next = v_count_reg;

    // horizontal and vertical sync, buffered to avoid glitch
    // h-sync-next asserted between 656 and 751
    assign h_sync_next = (h_count_reg>=(HD+HB) && h_count_reg<=(HD+HB+HR-1));
    // vh-sync-next asserted between 490 and 491
    assign v_sync_next = (v_count_reg>=(VD+VB) && v_count_reg<=(VD+VB+VR-1));
    // video on/off
    assign video_on = (h_count_reg<HD) && (v_count_reg<VD);
    // output
    assign hsync = h_sync_reg;
    assign vsync = v_sync_reg;
    assign pixel_x = h_count_reg;
    assign pixel_y = v_count_reg;
    assign p_tick = pixel_tick;
endmodule

INTEGRANTES

  • Jessica Montero
  • Ivan cortes
  • Jessica Cardenas
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License