Announcement

Collapse
No announcement yet.

Radar Pong demo - range of player determines pong paddle position in y

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Radar Pong demo - range of player determines pong paddle position in y

    So my group and I made a Radar Pong game. It uses the µVGA-II GFX2.

    It looks good and works most times, but what can be done about the flickering of the paddles and the slowing way down when a sound plays? Other than those quirks it still works and is playable with the radar equipment. You can comment out the ard_input variable and use a random position for the paddles if you'd like to run the code as a demo. You might have to disable the media files such as pictures and sound too.

    1.) How to fix paddle flickering?
    2.) How to stop slow downs/lagging when a sound is playing? (Maybe a "2nd thread"?)

    Code:

    #platform "uVGA-II_GFX2"
    /* 4DGL Simple Pong Demo
    */
    #inherit "4DGL_16bitColours.fnc"

    #CONST
    TRIANGLE 3
    RECTANGLE 4
    PENTAGON 5
    HEXAGON 6
    LEFTCOLOR 0xF800
    RIGHTCOLOR 0xF800
    TOPCOLOR DARKGREEN
    BOTTOMCOLOR DARKGREEN
    #END

    #constant WALL 20 // outer wall thickness

    #CONST
    LEFTHIT WALL
    RIGHTHIT 640-WALL
    TOPHIT WALL
    BOTTOMHIT 480-WALL
    #END

    // constants for the viewport
    #CONST
    windowXpos WALL
    windowYpos WALL
    windowWidth 640-WALL
    windowHeight 480-WALL
    #END

    // constant object definitions
    #constant ERASEBALL $ball_x, ball_y, 3, BLACK
    #constant DRAWBALL $ball_x, ball_y, 3, ball_color
    #constant LEFTWALL $0, 0, WALL , 480, LEFTCOLOR
    #constant RIGHTWALL $640-WALL , 0, 640, 480, RIGHTCOLOR
    #constant TOPWALL $0, 0, 640-WALL, WALL , TOPCOLOR
    #constant BOTTOMWALL $gfx_Rectangle(0, 480-WALL, 640, 480, BOTTOMCOLOR)

    //----------------------------------------------------------------------------------------//
    var ball_x, ball_y, ball_r, ball_color, ball_type;
    var ard_input := 0;
    var XSPEED, YSPEED;

    // Set the color, width, height and min and max speed of paddles
    var lpaddle_color := WHITE;
    var rpaddle_color := DARKGREEN;
    var lpaddle_width := 27;
    var lpaddle_height := 110;
    var rpaddle_width := 30;
    var rpaddle_height := 120;
    var minSpeed := 5;
    var maxSpeed := 12;

    // Set starting positions of paddles
    var lpaddle_x1 := 30;
    var lpaddle_y1 := 180;
    var rpaddle_x1 := 570;
    var rpaddle_y1 := 430;

    // initialize the other coordinates for starting positions
    var lpaddle_x2 := lpaddle_x1 + lpaddle_width;
    var lpaddle_y2 := lpaddle_y1 + lpaddle_height;
    var rpaddle_x2 := rpaddle_x1 + rpaddle_width;
    var rpaddle_y2 := rpaddle_y1 + rpaddle_height;

    var xdir, ydir, angle, lscore, rscore, games;
    var targetX, targetY;
    var Xcoords[6], Ycoords[6];
    //----------------------------------------------------------------------------------------//

    func resetGame()
    ball_type := 0;
    angle := 0;
    lscore := 0;
    rscore := 0;
    games++;
    SEED(sys_T());
    ball_type := ABS(RAND()%8);
    minSpeed := 5;
    maxSpeed := 12;
    loseScreen();
    splash();
    resetBall();
    drawWalls();
    endfunc

    func loseScreen()
    gfx_Set(CLIPPING, OFF);
    gfx_Set(PEN_SIZE, SOLID); // clear the window
    gfx_Rectangle(0, 0, 640, 480, BLACK);

    var i := 0;

    repeat // display scoreboard
    while(!media_Init());
    media_SetSector(0x003B,0x9D61);
    media_Image(0,0);
    while(!file_Mount())
    wend
    if(file_Exists("sadtrom.wav"))
    snd_Volume(100);
    file_PlayWAV("sadtrom.wav");
    while(snd_Playing());
    endif
    i++;
    until(i>1);
    endfunc

    func resetBall()
    angle := 0;
    ball_color := WHITE; // initial ball colour
    xdir := 1; ydir := 1; // initial ball direction
    ball_x := 320; ball_y := 240; // initial ball position

    XSPEED := ABS(RAND()%100)/10;
    YSPEED := ABS(RAND()%100)/10;

    increaseSpeed();
    checkSpeed();

    gfx_Set(CLIPPING, OFF); // clear the window
    gfx_Set(PEN_SIZE, SOLID);
    gfx_Rectangle(0, 0, 640, 480, BLACK);

    drawWalls();
    endfunc

    func checkSpeed()
    if(XSPEED < minSpeed)
    XSPEED := minSpeed;
    endif
    if(YSPEED < minSpeed)
    YSPEED := minSpeed;
    endif

    if(XSPEED > maxSpeed)
    XSPEED := maxSpeed;
    endif
    if(YSPEED > maxSpeed)
    YSPEED := maxSpeed;
    endif
    endfunc

    func increaseSpeed()
    if(lscore >= 3)
    minSpeed := minSpeed + lscore;
    maxSpeed := maxSpeed + lscore;
    endif
    endfunc

    func drawPicPaddle()
    gfx_Set(CLIPPING, ON);
    while(!media_Init());
    media_SetSector(0x003B,0x98A4);
    media_Image(lpaddle_x1, lpaddle_y1);
    while(!media_Init());
    media_SetSector(0x003B,0x9895);
    media_Image(rpaddle_x1, rpaddle_y1);
    //gfx_Set(CLIPPING, OFF);
    endfunc

    func erasePicPaddle()
    gfx_Set(CLIPPING, ON);
    drawPaddle(lpaddle_x1, lpaddle_y1, lpaddle_x2, lpaddle_y2, BLACK);
    drawPaddle(rpaddle_x1, rpaddle_y1, rpaddle_x2, rpaddle_y2, BLACK);
    //gfx_Set(CLIPPING, OFF);
    endfunc

    func Score()
    var n, x, y, r;
    gfx_ClipWindow(ball_x-20, ball_y-20, ball_x+20, ball_y+20);
    gfx_Set(CLIPPING, ON);
    r := sys_T();

    // a really cheap looking explosion of dots
    n := -1000;
    SEED(r);
    while (n++20);
    endif
    gfx_Set(PEN_SIZE, SOLID); // clear the window
    gfx_Rectangle(0, 0, 640, 480, BLACK);

    repeat // display pong rules
    while(!media_Init());
    media_SetSector(0x003B,0x98B0);
    media_Image(0,0);
    i++;
    until(i>30);

    gfx_Set(PEN_SIZE, SOLID); // clear the window
    gfx_Rectangle(0, 0, 640, 480, BLACK);
    endfunc

    func collision()
    if(ball_x = RIGHTHIT)
    ball_x := RIGHTHIT;
    xdir := -xdir;
    lscore++;
    Score();
    resetBall();
    endif

    if (ball_y = BOTTOMHIT)
    ball_y := BOTTOMHIT;
    ydir := -ydir;

    SEED(sys_T());
    YSPEED := YSPEED + (RAND()%4);
    increaseSpeed();
    checkSpeed();
    endif
    endfunc

    func padCollision()
    // left paddle collision detection
    if(ball_y >= lpaddle_y1)
    if(ball_y = 10)
    resetGame();
    endif
    if(rscore >= 10)
    resetGame();
    endif

    ard_input := bus_Read();

    UpdateCounter();

    // undraw ball and paddles
    erasePicPaddle();

    switch
    case(ball_type == 0)
    gfx_MoveTo(ball_x, ball_y); // using the balls origin
    MakePolygon(angle, TRIANGLE, 10, BLACK); // undraw old triangle

    case(ball_type == 1)
    gfx_MoveTo(ball_x, ball_y); // using the balls origin
    MakePolygon(angle, RECTANGLE, 10, BLACK); // undraw old rectangle

    case(ball_type == 2)
    gfx_MoveTo(ball_x, ball_y); // using the balls origin
    MakePolygon(angle, PENTAGON, 10, BLACK); // undraw old rectangle

    case(ball_type == 3)
    gfx_MoveTo(ball_x, ball_y); // using the balls origin
    MakePolygon(angle, HEXAGON, 10, BLACK); // undraw old rectangle

    default:
    if(ball_type >= 4)
    gfx_Set(PEN_SIZE, SOLID);
    gfx_Circle(ERASEBALL); // erase the ball
    endif
    endswitch

    // move ball to new position
    ball_x := ball_x + xdir * XSPEED; // move to new X pos
    ball_y := ball_y + ydir * YSPEED; // move to new Y pos
    collision();
    padCollision();

    angle := angle + 10; // step to new angle

    // move paddles to new positions
    /*
    // left paddle AI is random
    lpaddle_y1 := lpaddle_y1 - (RAND()%40);
    lpaddle_x2 := lpaddle_x1 + lpaddle_width;
    lpaddle_y2 := lpaddle_y1 + lpaddle_height;
    */
    // get new position from arduino
    //lpaddle_y1 := 10*ard_input;

    switch
    case((ard_input >= 14) && (ard_input < 22))
    lpaddle_y1 := 20;
    case((ard_input >= 22) && (ard_input < 30))
    lpaddle_y1 := 130;
    case((ard_input >= 30) && (ard_input < 37))
    lpaddle_y1 := 240;
    case(ard_input >= 37)
    lpaddle_y1 := 350;
    default:
    endswitch

    lpaddle_x2 := lpaddle_x1 + lpaddle_width;
    lpaddle_y2 := lpaddle_y1 + lpaddle_height;
    /*
    if(lpaddle_y1 = BOTTOMHIT)
    lpaddle_y2 := BOTTOMHIT;
    lpaddle_y1 := BOTTOMHIT - lpaddle_height;
    endif
    */
    // right paddle AI ALWAYS WINS!!!
    rpaddle_y1 := ball_y - rpaddle_height/2;
    rpaddle_x2 := rpaddle_x1 + rpaddle_width;
    rpaddle_y2 := rpaddle_y1 + rpaddle_height;

    if(rpaddle_y1 = BOTTOMHIT)
    rpaddle_y2 := BOTTOMHIT;
    rpaddle_y1 := BOTTOMHIT - rpaddle_height;
    endif

    // redraw ball and paddles
    switch
    case(ball_type == 0)
    gfx_MoveTo(ball_x, ball_y); // using the balls origin
    MakePolygon(angle, TRIANGLE, 10, ball_color); // draw triangle

    case(ball_type == 1)
    gfx_MoveTo(ball_x, ball_y);
    MakePolygon(angle, RECTANGLE, 10, ball_color); // draw rectangle

    case(ball_type == 2)
    gfx_MoveTo(ball_x, ball_y);
    MakePolygon(angle, PENTAGON, 10, ball_color); // draw rectangle

    case(ball_type == 3)
    gfx_MoveTo(ball_x, ball_y);
    MakePolygon(angle, HEXAGON, 10, ball_color); // draw rectangle

    default:
    if(ball_type >= 4)
    gfx_Set(PEN_SIZE, SOLID);
    gfx_Circle(DRAWBALL); // draw the ball
    endif
    endswitch

    //drawPaddle(lpaddle_x1, lpaddle_y1, lpaddle_x2, lpaddle_y2, lpaddle_color);
    //drawPaddle(rpaddle_x1, rpaddle_y1, rpaddle_x2, rpaddle_y2, rpaddle_color);

    drawPicPaddle();
    forever
    endfunc
    //----------------------------------------------------------------------------------------//

  • #2


    Unfortnately, since I don't have your images, or sound files I can't work out exactly what is causing your problems, but I think I can hazzard a couple of good guesses.



    1. You are erasing the old paddles, doing heaps of calculations, drawing new paddles and then pausing for a bit. Reorder that to doing heaps of calculations, erasing the old paddles, drawing new paddles and then pausing for a bit. The idea is to keep the image static for the longest possible period of time.



    2. There is only one Picaso Processor, so a second thread wont help, actually there is effectively already a sound thread, which is why you can do anything at all whilst sound is playing. The old pong games would lock up whilst they played a sound, this always seemd the ugliest part of the game to me.



    The amount of 'slowdown' will be affected by the complexity of your wav file. If it is 44khz stereo 16bit, it will take 22x more effort to play than a 8khz mono 8 bit wav file. Have a look at what you are using and see if it can be simplified easily and still sound good.



    The other possiblity is to build it into your program. A complex thing to do would be to try and manage a continuing sound effect, that changes when needed.



    A simpler method would be to change the delay loop, eg

    if (snd_Playing())

    pause(2); // sound playing, short pause

    else

    pause(12) ; // no sound, long pause
    endif

    I have no idea about the values, it will depend on the compexity of your wav files.



    Also note, there is a disp_Sync() command that might be of use to you in this, although I'd only use it if it was definitely needed.



    This looks really good, maybe could use an ADC0804 to replace the Arduino for use in another project Even better, if you could wait a little while Diablo16 wouldn't even need the extra chip http://4d.websitetoolbox.com/post?id=5817069
    Mark

    Comment


    • #3


      Still a bit of a rookie with 4d programming so I may be off in my assumptions.
      You use erase ~6 places, this seems to repeat as you move the ball and paddles. A quicker way to do it: Let's say you are moving an object like a paddle vertically. Instead of erasing the previous paddle you just define the top and bottom of the paddle as the same color as the back ground and the distance moved. Let's say you only move 1 vertical pixel, you would have your paddle defined asbbbcccccccccccccccbbbwhere c is the color you want your paddle and b is the background color. Now as you move your paddle up or down it becomes self erasing. Of course you need to have the background part as wide as your biggest move or it will leave streaks.Likewise for the ball you would use something likebbbbbccbbccbbccbbbbbThere will be a slight glitch/indentation when the ball and paddle over lap but speed will improve and program should be shorter. If you are already doing this, my apologies. Kind of hard to tell w/o seeing the actual graphics.
      Rick

      Comment

      Working...
      X