Virtual Debouncing

edited February 2014 in How To...

Using this code to toggle modes between on and off:

if (keyPressed && key == 'm')
{
  if (menu)
  {
    menu = false;
  }
  else
  {
    menu = true;
  }
}

is fine in theory. However the result flickers and the out come isn't always the desired one. I compare this to like debouncing physical buttons in arduino, however I'm a little lost this being processing and not using buttons, or having delay.

Thank you in advances! :)

Answers

  • edited February 2014 Answer ✓

    when this is part of draw() it gets checked 60x per sec - therefore flickers

    better:

    void keyPressed() {
     if (menu)
      {
        menu = false;
      }
      else
      {
        menu = true;
      }
    }
    

    own func, gets only to run once every key press

    it's an in-build func, see reference

  • short

    menu = !menu;

  • _vk_vk
    edited February 2014 Answer ✓

    edit: ops, late...

    That's probably because you are checking for keyPressed in draw 60 times each second. So It keeps changing between both states. I would use keyPressed the function, or keyReleased() so it won't meter how long user hold the key pressed. Also there is the notation menu = !menu that will toggle the state of the boolean.

    untested

    void keyReleased(){
    if (key == 'm'){
    menu = !menu;
    }
    }
    

    that should do it ; )

  • edited February 2014 Answer ✓

    edit: it seems I was even later, at least everyone was thinking of similar solutions

    The problem is that this code is probably in your draw() loop and is thus run 60 times per second. The outcome is unpredictable as it will just go back and forth many times.

    The solution is to move this code to the keyPressed() method external to draw(). Also there is a shorter way to code 'invert the boolean variable'. Adapted code:

    void keyPressed() {
      if (key == 'm') { menu = !menu; }
    }
    
  • Answer ✓

    just for once I was the fastest...

  • but I still feel this is not well documented and hard to find

  • Wow thank you all for these answers! It will certainly help me from now on and I really appreciate it! Hopefully this will help other people with this issue. And again thanks!! :)

  • Oh wait... I can only do it once! NONONONONONONO!!!!!

    It says: dublicate method keyPressed() in

    WHAT DO I DO!!! I ALREADY ACCEPTED ANSWERS!!!!! NNOOOOOOO

    Ahhh this kinda sucks. I should go check the function refference.

  • edited February 2014 Answer ✓

    We can't have methods sharing the same name within the same class.
    If you need keyPressed() callback method to check more things out, just use more if () & else if () blocks there! ;;)

  • Answer ✓

    Crazy compact: menu=key=='m'?menu:!menu;

  • _vk_vk
    edited February 2014

    The code should look like:

    void setup(){//blah//
    }
    
    void draw(){ //blah//
    }
    
    void keyPressed() {
     if (key == 'm') { menu = !menu; }
    }
    

    If you can get it working, consider posting a sample code that produces the error

  • Ohhhhhhhhhh... I see. So somehow for some reason when the true is returned from keypressed that activates the function? And then from there I can put more into it. AWESOME :)

  • I got it working, thanks everybody, however other parts of my program are failing. Such as for whatever reason to get into fantom mode I must be in another mode first... I don't know why that is, and I can't get the light black part to cycle nicely. I'll work on that later but that if else needing another one activating first is stumping me. And some weird bugs are happening where the ball just goes through the wall and you have to watch it in action but if you's guys have any suggestions or notices or tips 'n' tricks it would appreciated, and help me learn tremendously. This is after all only my second 'real' program (asides from a couple number guessing console games in C++ and what have you with arduino).

    Here is my program:

    //   ______A______
    //   |                  |
    //  B|                 |D
    //   |___________|
    //         C
    
    
    /* TO DO LIST */
    
    // MAIN
    
    // Implement the menu!
    // Finish Game Modes (Add different controls and player options)
    
    
    // Secondary 
    
    // Add fasing effect like in psychedelic mode to fantom mode
    
    
    // Bugs
    
    // Fix it when it moves too fast and goes into the paddles then bugs out a bit
    // Enter protocol so that when the pixel speed makes it go way too far out of bounds it fixes it
    // Fix the number problems going to like 1.885999 and constrain to 1.885
    
    
    // Eventually
    
    // Turn the directions into Angles. y=mx+b perpendicular angles.
    // Add momentum / velocity to the ball
    // Highscore system (write to file)
    // Difficulty level (initial PPF speed, paddle sizes)
    // Add AI opponent
    
    
    
    int ballX = 0;
    int ballY = 0;
    
    int scoreB = 0;
    int scoreD = 0;
    
    int boundry = 50;
    int direct = 0; // Direction of ball, standard cartesian plane counter clockwise I II III IV
    
    float PPF = 0; // Pixels Per Frame
    float PPFmod = 0;
    float initialPPF = 2;
    
    int PBTX = 50; // Paddles: Paddle, Paddle Side, Top/Bottom, X/Y
    int PBBX = 50;
    int PBTY = 195;
    int PBBY = 405;
    
    int PDTX = 1000;
    int PDBX = 1000;
    int PDTY = 195;
    int PDBY = 405;
    
    int time = 0;
    int lastSecond = 0;
    
    float Hue = 0;
    int Sat = 0;
    int Bright = 0;
    float Hue2 = 0;
    int Sat2 = 0;
    float Bright2 = 0;
    
    int colourMode = 5;
    boolean gMode = false;
    boolean pMode = false;
    boolean secondPaddle = true;
    
    boolean menu = true;
    
    int lastFrameCount = 0;
    int pmodframecount = 0;
    
    boolean fantom = false;
    
    
    
    void setup()
    {
      size(1050, 600);
      background(0);
      frameRate(60);
      ballX = width/2;
      ballY = height/2;  
    }
    
    void draw()
    {
      // Reset
      if (keyPressed && key == 'r')
      {   
        ballX = width/2;
        ballY = height/2;
    
        scoreB = 0;
        scoreD = 0;
    
        PPF = 0;
        PPFmod = 0;
        initialPPF = 2;
    
        PBTX = 50;
        PBBX = 50;
        PBTY = 195;
        PBBY = 405;
    
        PDTX = 1000;
        PDBX = 1000;
        PDTY = 195;
        PDBY = 405;
    
        colourMode = 5;
    
        lastFrameCount = 0;
        pmodframecount = 0;
    
    
        gMode = false;
        pMode = false;
        menu = true;
        secondPaddle = true;  
      }
      // End
    
    
    
    
    
      // Colour Mode Select
      if (keyPressed && key == 'x')
      {
        colourMode = 1;
      }
      else if (keyPressed && key == 'i')
      {
        colourMode = 2;
      }
      else if (keyPressed && key == 'f')
      {
        colourMode = 3;
      }
      else if (keyPressed && key == '8')
      {
        colourMode = 4; 
      }
      else if (keyPressed && key == 'n')
      {
        colourMode = 5; 
      }
      else if (keyPressed && key == 'c')
      {
        colourMode = 6; 
      }
      //End
    
    
    
    
    
      // Colour Mode Hues
      //println("Hue: " + Hue + "  Sat: " + Sat + "  Bright: " + Bright);
      //println("Hue2: " + Hue2 + "  Sat2: " + Sat2 + "  Bright2: " + Bright2);
    
        if (colourMode == 1) //Psychedelic
        {
          if (Hue >= 255)
          {
            Hue = 0;
          }
          else
          {
            Hue += .75; 
          }
    
          Sat = 255;
          Bright = 255;
    
          Hue2 = abs(Hue - 255);
          Sat2 = 255;
          Bright2 = 255;
        }  
        else if (colourMode == 2) //Inverted    
        {
    
          Hue = 0;
          Sat = 0;
          Bright = 255;
    
          Hue2 = 0;
          Sat2 = 0;
          Bright2 = 0;
        }
        else if (colourMode == 3) //Fantom
        {
          Hue = 0;
          Sat = 0;
          Bright = 0;
    
          Hue2 = 0;
          Sat2 = 0;
          Bright2 = 10;
    
        }
        else if (colourMode == 4) //80's Computer
        {
          Hue = 0;
          Sat = 0;
          Bright = 0;
    
          Hue2 = 100;
          Sat2 = 255;
          Bright2 = 120;
        }
        else if (colourMode == 5) //Normal
        {
          Hue = 0;
          Sat = 0;
          Bright = 0;
    
          Hue2 = 0;
          Sat2 = 0;
          Bright2 = 255;
        }
        else if (colourMode == 6) // Cool Blue
        {
          Hue = 0;
          Sat = 0;
          Bright = 0;
    
          Hue2 = 160;
          Sat2 = 255;
          Bright2 = 255;
        }
      //End
    
    
    
    
    
      // Board, FrameRate, Scores, Name, Mouse Co-ords, assorted other  
      colorMode(HSB);
      rectMode(CORNER);
      fill(Hue, Sat, Bright);
      noStroke();
      rect(0, 0, width, height);
    
      //println("Mouse X: " + mouseX + "  Mouse Y: " + mouseY);
    
      fill(Hue2, Sat2, Bright2);
      textSize(10);
      textAlign(LEFT, TOP);
      text("    FPS: " + int(frameRate)+ "/60", 0, 0);
      text("F: " + frameCount, 75, 0);
    
      if (second() != lastSecond)
      {
        time++;
      }
      lastSecond = second();
    
      text("~T: " + time, 125, 0);
      text("PPF: " + PPF, 165, 0);
    
      if (pMode)
      {
        text("Players: 2", 225, 0);
      }
      else
      {
        text("Players: 1", 225, 0);
      }
    
      if (gMode)
      {
         text("Game Mode: 2", 285, 0);
      }
      else
      {
         text("Game Mode: 1", 285, 0);
      }
    
    
    
      textAlign(RIGHT, TOP);
      text("BASIC PONG PLUS - BETA    ", width, 0);
    
      textSize(100);
      textAlign(RIGHT, CENTER);
      text(scoreB, width/2 - 15, 60);
      textAlign(LEFT, CENTER);
      text(scoreD, width/2 + 15, 60);
    
      rectMode(CENTER);
      noFill();
      stroke(Hue2, Sat2, Bright2);
      strokeWeight(10);
      rect(width/2, height/2, width - 40, height - 40);
    
      for (int dotted = 45; dotted < 19*30; dotted += 30)
      {
      rect(width/2, dotted, 5, 5);
      }
      // End
    
    
    
    
    
      // The Ball
      fill(Hue2, Sat2, Bright2);
      stroke(Hue, Sat, Bright);
      strokeWeight(1);
      ellipseMode(CENTER);
      ellipse(ballX, ballY, 50, 50);
      // End
    
    
    
    
      /*
      // Menu
       while(menu)
      {
    
        fill(0);
        stroke(255);
        rectMode(CENTER);
        strokeWeight(20);
        rect(width/2, height/2, 800, 400); 
      }
      // End
      */
    
    
    
    
      // Random Starting Direction
      if (frameCount == 1)
      {
        direct = int(random(1, 4));
      }
      // End
    
    
    
    
    
      // Direction Being set for rest of loop
      if (direct == 1)
      {
        directI();
      }
      else if (direct == 2)
      {
        directII();
      }
      else if (direct == 3)
      {
        directIII();
      }
      else if (direct == 4)
      {
        directIV();
      }
      else
      {
    
      }
      // End
    
    
    
    
    
      // Boundries
      if (ballX <= boundry) // Hits B
      {   
        if (direct == 2)
        {
          direct = 1;
          scoreD++;
        }
        else if (direct == 3)
        {
          direct = 4;
          scoreD++;
        }
      }
    
      if (ballX >= width - boundry) // Hits D
      {   
        if (direct == 1)
        {
          direct = 2; 
          scoreB++;
        }
        else if (direct == 4)
        {
          direct = 3; 
          scoreB++;
        }
      }
    
      if (ballY <= boundry) // Hits A
      {
         if (direct == 2)
        {
          direct = 3; 
        }
        else if (direct == 1)
        {
          direct = 4; 
        }
      }
    
      if (ballY >= height - boundry) // Hits C
      {
         if (direct == 3)
        {
          direct = 2; 
        }
        else if (direct == 4)
        {
          direct = 1; 
        }
      } 
     // End
    
    
    
    
    
      // Direction Testing
      if (keyPressed && key == 'h')
      {
        direct = 3;
      }
      if (keyPressed && key == 'u')
      {
        direct = 2;
      }
      if (keyPressed && key == 'i')
      {
        direct = 1;
      }
      if (keyPressed && key == 'l')
      {
        direct = 4;
      }
      // End
    
    
    
    
    
      // Paddle Coords & Draw
    
      if (pMode == false) // 1 Player
      {
    
        if (gMode == false) // 1 Player, Game Mode 1 - Mouse
        {
          if (mouseY > 145 && mouseY < height - 145)
          {
          PDTY = mouseY + 105;
          PDBY = mouseY - 105;
          }
    
    
          PBTY = PDTY;
          PBBY = PDBY;
        }
        else if (gMode == true) // 1 Player, Game Mode 2 - Keys
        {
          if (keyPressed && key == CODED)
      {
         if (keyCode == UP)
         {
          if ((PDBY - PDTY)/2 + PDTY >= 145)
          {
            PDTY -= 8;
            PDBY -= 8;
    
          PBTY = PDTY;
          PBBY = PDBY;
          }
         }
    
        if (keyCode == DOWN)
        {
          if ((PDBY - PDTY)/2 + PDTY <= height - 145)
          {
            PDTY += 8;
            PDBY += 8;
    
          PBTY = PDTY;
          PBBY = PDBY;
          }
        } 
      }
        }
      }
      else if (pMode == true) // 2 Players
      {
        if (gMode == false) // 2 Players, Game Mode 1 keys-mouse
        {
    
        }
        else if (gMode == true) // 2 Players, Game Mode 2 keys-keys
        {
    
        }
      }
    
      strokeWeight(20);
      stroke(Hue2, Sat2, Bright2);
      if (secondPaddle)
      {
      line(PBTX, PBTY, PBBX, PBBY); //Paddle B
      }
      line(PDTX, PDTY, PDBX, PDBY);//Paddle D
      //End
    
    
    
    
    
      // paddle  Hit
      if (secondPaddle)
      {
        if (ballX <= PBTX + 35 && ballY <= PBTY && ballY >= PBBY) // Hits paddle B
        { 
          // Comes from front 
    
          if (direct == 2)
          {
            direct = 1;
          }
          else if (direct == 3)
          {
            direct = 4;
          }
    
         // Comes from the back
    
          else if (direct == 1)
          {
            direct = 2;
          }
          else if (direct == 4)
          {
            direct = 3;
          }
    
        }
      }
    
      if (ballX >= PDTX - 35 && ballY <= PDTY && ballY >= PDBY) // Hits paddle D
      {    
    
        {
        // Comes from front 
        if (direct == 2)
        {
          direct = 1;
        }
        else if (direct == 3)
        {
          direct = 4;
        }
    
        // Comes from the back
    
        else if (direct == 1)
        {
          direct = 2;
        }
        else if (direct == 4)
        {
          direct = 3;
        }
    
      } 
      }
      // End 
    
    
    
    
    
      // Increase in PPF
      if (lastFrameCount != frameCount)
      {
        pmodframecount++; 
      }
       lastFrameCount = frameCount;
    
      PPFmod = float(pmodframecount)/1000;
      PPF = PPF - PPF + PPFmod + initialPPF; 
      //End
    
    
    
    
    
    } // End of Draw
    
    void directI()
    {
      ballX += PPF;
      ballY -= PPF;
    }
    
    void directII()
    {
      ballX -= PPF;
      ballY -= PPF;
    }
    
    void directIII()
    {
      ballX -= PPF;
      ballY += PPF;
    }
    
    void directIV()
    {
      ballX += PPF;
      ballY += PPF;
    }
    
    
    void keyPressed() 
    {
      if (key == 'm') 
      {
        menu = !menu;
      }
    
      if (key == 'p')
      {
        pMode = !pMode;
      }
    
      if (key == 'g')
      {
        gMode = !gMode;
      }
    
      if (key == '/')
      {
        secondPaddle = !secondPaddle;
      }
    
    }
    
  • edited February 2014

    Hello,

    you wrote

    for whatever reason to get into fantom mode I must be in another mode first...

    I don't see - I can press f at start and be in fantom mode (dark gray) immediately.

    What do you mean?

    Anyway

    sometimes it's worth to re-write your code a little

    it gives you practice

    first I'd suggest to put all key related stuff into your new function

    you can start there by saying

    if (key == CODED) {
     // check all special keys like UP
     if................
    }
     // -------------------------------------
    else {
    // check all normal keys like n
    if...................
    }
    

    It's best to have all key-stuff in one place

    Next

    ok, then I suggest you make more functions like:

    • managaPaddle
    • drawBall

    etc.

    that gives you practice

    So take a bunch of lines and put them out of draw() in an own function and give it a good name (and write the name of the func into draw() where the bunch of lines was before of course)

    please do a lot of testing after a change to make sure it still works

    draw() could contain then only managaPaddle, drawBall etc., so it is very readable then

    Also

    At the moment, you add the same value to ball x and y.

    void directIII()
    {
      ballX -= PPF;
      ballY += PPF;
    }
    

    so it can only at 45° - which is boring

    instead you can have float ballAddX and ballAddY and add them

    Also I noticed a stuttering when ball is close at paddle. Bad. You can avoid that when you say

    // for left side   
    if (ballX >= PDTX - 35 && ballY <= PDTY && ballY >= PDBY) // Hits paddle D
    {
      ballAddX = abs (ballAddX);
    }
    

    Greetings, Chrisir

  • I just tried out my sketch again and Fantom (Yes Google, I know it's spelled 'phantom', put I need p for psychedelic, phantom and players so I changed it. No squiggly red line needed) mode worked immediately. Odd considering it wasn't the other day.

    Anywho

    ballAddX & ballAddY, do mean like make those a function and then call them when needed? Or they are like PPF (Pixels Per Second) but for X and Y both, not just a direction? I am a little unsure of what you mean.

    Also I will never use somebody else's code unless I understand it (just how I am, I feel it to be cheaty and has the possibility to cause problems later on - because I don't know how it works, I can't fix it) and I don't quite understand what abs()ing it will achieve? I'm guessing that ballAddX is what is making it go sideways and turning it positive will immediately make it head the other direction? Or something of the sort. But also what will happen when when it reaches 32 PPF (what I will cap it to). If it's right at the edge, the moves 32 pixels, it will completely bypass it. Currently I'm pretty sure this already happens with the edges, but the change in direction quickly puts it back. I'd love to know how these type of this get fixed, not so much for my program to work, but because I'm curious and excited to know how that protocol will work =D

    And thank you for your tips. if (key == CODED) ect. I will definitively be using that from now on, it is genius! For the draw(), I will add them as functions, and luckily the "chunks" of code to go in them are mostly already laid out for me ;)

    I do have a question though about functions, I was going to make a thread but perhaps here will do. How exactly do the functions, draw, and other functions (void keypressed) all work? I understand draw is the infinite loop that runs so long as the program is open, and that for example "int fucntionName(X, Y, Z) { }" is placed outside the loop and is then called for when your using it multiple times or to conserve space in (tidy up) draw(). But what about the void keyPressed type ones. Do they run like a separate draw? How are they activated exactly? They don't run at 60x per second, but only when keyPressed is true, but does it check for that every 60x per second too? What am I missing here? I couldn't find anything (exept for string functions) in the reference.

    Thank-you all very much!

  • edited February 2014

    ... if (key == CODED) ect. I will definitively be using that from now on,...

    Actually, testing for CODED is completely unnecessary within callbacks! L-)
    Here's an online example which uses keyCode only and got no need to test for lower case at all:

    http://studio.processingtogether.com/sp/pad/export/ro.9bY07S95k2C2a/latest

  • edited February 2014

    How exactly do the functions, draw, and other functions void keyPressed() all work?

    • When the compiled Java starts, it instantiates the whole Processing's framework by invoking PApplet.main()
    • Once that initialization is done, that program finally calls our own customized setup().
    • Then the Processing's canvas is finally displayed.
    • Now, Processing keeps calling back our custom draw() @ 60 FPS by default.
    • Any triggered event is enqueued by another Thread.
    • At the end of draw(), the contents of the PGraphics object referenced by variable g is rendered to the canvas.
    • Finally events are dequeued and executed synchronously.
    • If the elapsed time from draw() until all event callbacks are done is less than frameRate(), sleeps the remaining time.

    Well, that's a short description of what I investigated till now! :-B

  • Answer ✓

    @ GoToLoop : I still think if (key == CODED) is useful in keyPressed() because you structure it in two parts and can find your entries (F1 oder f...) more easily

    @ MadScience2728 : ballAddX & ballAddY are both global vars.

    instead of

    void directIII()
    {
      ballX -= PPF;
      ballY += PPF;
    }
    

    say

    void move()
    {
      ballX += ballAddX ;
      ballY += ballAddY ;
    }
    

    instead of having directI(), directII() etc. you only have move()

    but ballAddX & ballAddY can both have neg values.

    Look a the examples

    http://processing.org/examples/bounce.html

    (here the bouncing is different than I'd do it)

    for stuff like abs looks at the reference

    http://processing.org/reference/

    • to avoid that it goes into the paddle you can check before move if the ball would be inside the paddle when you would add it (so test it before moving it)
  • edited February 2014

    I still think if (key == CODED) is useful in keyPressed() because you structure it in 2 parts...

    It seems 1 more slow layer to check against! That would be useful only if we had 2 big if CODED & !CODED blocks.
    Or even better, if we're not interested in 1 group, just abort keyPressed() right way:

    if (key != CODED)  return;
    

    Most of the time we're not interested in discriminating between lower & upper letter cases!
    Therefore, variable key is completely unnecessary!

    By using keyCode alone, we can check all available keys, no matter if they're CODED or not!
    With the added bonus of not worrying about letter cases either! \m/

    void keyPressed() {
      final int k = keyCode;
    
      if (k == ' ' | k == ENTER | k == RETURN)
        ballOrBox = !ballOrBox;
    
      if      (k == UP    | k == 'W')   north = true;
      else if (k == DOWN  | k == 'S')   south = true;
      else if (k == LEFT  | k == 'A')   west  = true;
      else if (k == RIGHT | k == 'D')   east  = true;
    }
    

    My issue about if (key == CODED) is that it is taught as if it was an obligatory step! ~X(
    As if the code would be somewhat flawed or bugged otherwise! Spreading like superstition to every1! :^o

  • Looks to me as if Chrisirs way would be for more noobies, and then when they get a little more comfortable go with Loops way. Both good in my opinion, I guess it'll just depend on your situation and what not.

    Anyway thank you's guys tremendously! I will change the directIs to a move function and base it off of the reference sketch linked. This will make implementing angles more than 45d much easier!

  • edited February 2014

    @ MadScience

    in the example it says when you hit left / right wall: just ballAddX = -1 * ballAddX /// meaning make a pos number neg or a neg number pos

    same for upper and lower wall

    but this can lead to stutter and that's what we see in your sketch

    so I keep saying:

    • check left and right wall seprately

    • on left side say ballAddX = abs (ballAddX); /// means it gets always pos

    • on right side say ballAddX = -1 * abs (ballAddX); /// means it gets always neg

    @ gotoloop

    I agree it's not mandatory but when you have long keyPressed with mixed checks for 'a' 'b' F1 F1 UP DOWN etc.... two big if CODED & !CODED blocks structure it better

    like this:

    // =============================
    // Inputs 
    
    void keyPressed() {
      if (key == CODED) {
        // CODED ------------------------------------------------
        EvluateCodedKeys();
      } 
      else {
        // not Coded --------------------------------------
        EvluateNotCodedKeys();
      } // else
    } // func 
    
    // ==============================================================
    
    void EvluateCodedKeys () {
      if (keyCode == RIGHT) {
        // move month up
        intCurrentMonth++;
        // boundary
        if (intCurrentMonth>12) {
          intCurrentMonth=1;
        } // if 
        Output();
      } //  
      else if (keyCode == LEFT) {
        // move month down
        intCurrentMonth--;
        // boundary
        if (intCurrentMonth<1) {
          intCurrentMonth=12;
        } // if 
        Output();
      } // 
      else 
      {
        // do nothing
      } // else
    } // func 
    
    // ------------------------------------------------
    
    void EvluateNotCodedKeys () {
      if (key == '+') {
        // 
        // do nothing
      } 
      else if (key == '-') {
        // 
        // do nothing
      }
      else {
        // do nothing
      } // else
    } // func 
    
    // ==================================================================
    
  • edited February 2014

    ... but when you have long keyPressed with mixed checks...

    I thought my example showed that I've cached keyCode as local variable k? 8-}
    I hate typing long names. I'm lazy! :!! Also, local variables are faster than field 1s! \m/

    final int k = keyCode;
    

    And as shown, I mix both CODED & !CODED together: :ar!

    if (k == UP | k == 'W') {}
    

    2 big if () CODED & !CODED block structures are better.

    I've mentioned that as a valid case for splitting them:
    "That would be useful only if we had 2 big if CODED & !CODED blocks."

  • _vk_vk
    edited February 2014

    @goToLoop indeed I liked learning that the check to see if "key is coded" is not mandatory, thanks ;)

  • Well I made the conversion from direct to ballAdd. I'm still unsure what will influence the change in rise/run (ballAddY, ballAddX) yet but I'll get there.

    So here is the sketch so far but I'm having troubles making the ball increase speed like before. I tried adding PPF to ballAddX/Y but that failed. Then I added it right in the ballX/Y = ballAddX/Y ; and that didn't work either. Then I multiplied ballAddX/Y by PPF to see if it would keep the negative aspect and it just freaked out.

    Well ok then

    Here is the code: Any thoughts?

    //   ______A______
    //   |           |
    //  B|           |D
    //   |___________|
    //         C
    
    
    /* TO DO LIST */
    
    // MAIN
    
    // Implement the menu! (remember to mention I know fantom mode is with an f: Press 'f' for Phantom mode)
    // Finish Game Modes (Add different controls and player options)
    
    
    // Secondary 
    
    // No secondary Task to show!
    
    
    // Bugs
    
    // Fix it when it moves too fast and goes into the paddles then bugs out a bit
    // Enter protocol so that when the pixel speed makes it go way too far out of bounds it fixes it
    
    
    // Eventually
    
    // Turn the directions into Angles. y=mx+b perpendicular angles.
    // Add momentum / velocity to the ball
    // Highscore system (write to file)
    // Difficulty level (initial PPF speed, paddle sizes)
    // Add AI opponent
    
    
    // ballAdd
    
    // if hits baddles or sides: 
    
    /*
    check left and right wall seprately
    
    on left side say ballAddX = abs (ballAddX); // means it gets always pos
    
    on right side say ballAddX = -1 * abs (ballAddX); // means it gets always neg
    
    same for top and bottom
    */
    
    
    int ballX = 0;
    int ballY = 0;
    
    int scoreB = 0;
    int scoreD = 0;
    
    int boundry = 50;
    int direct = 0; // Direction of ball, standard cartesian plane counter clockwise I II III IV
    
    float PPF = 0; // Pixels Per Frame
    float PPFmod = 0;
    float initialPPF = 2;
    
    int PBTX = 50; // Paddles: Paddle, Paddle Side, Top/Bottom, X/Y
    int PBBX = 50;
    int PBTY = 195;
    int PBBY = 405;
    
    int PDTX = 1000;
    int PDBX = 1000;
    int PDTY = 195;
    int PDBY = 405;
    
    int timer = 0;
    int lastSecond = 0;
    
    char pModeChar = '1';
    char gModeChar = '2';
    
    String PPFstring = "0";
    
    float Hue = 0;
    int Sat = 0;
    int Bright = 0;
    float Hue2 = 0;
    int Sat2 = 0;
    float Bright2 = 0;
    
    float time = 0;
    
    int colourMode = 5;
    boolean gMode = false;
    boolean pMode = false;
    boolean secondPaddle = true;
    
    boolean menu = true;
    
    int lastFrameCount = 0;
    int pmodframecount = 0;
    
    boolean fantom = false;
    
    float ballAddX = 2;
    float ballAddY = 2;
    
    
    void setup()
    {
      size(1050, 600);
      background(0);
      frameRate(60);
      ballX = width/2;
      ballY = height/2;  
      smooth();
    }
    
    void draw()
    {
    
      drawBoard(); // Draw the board and texts
    
      menu(); // Check for menu, draw it if true
    
      reset(); // Check for reset, reset if true
    
      colourModeSelect(); // Check if different colour mode is selected, change the mode to it
    
      colourMode(); // Sets the colours for different colour mode
    
      randomStart(); // Sets a random starting direction for the ball
    
      directTesting(); // Manually Overides the direction for the ball
    
      PPF(); // Pixels Per Frame of the ball
    
      move(); // 
    
      boundries(); // Boundry Box for the ball
    
      drawBall(); // Draws the ball
    
      paddles(); // Sets paddles co-ords then draws them
    
      paddlesHit(); // Changes Ball direction upon hitting the paddles
    
    } 
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void drawBall()
    {
      fill(Hue2, Sat2, Bright2);
      stroke(Hue, Sat, Bright);
      strokeWeight(1);
      ellipseMode(CENTER);
      ellipse(ballX, ballY, 50, 50); 
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void drawBoard()
    {
      // Setting Up
      colorMode(HSB);
      rectMode(CORNER);
      fill(Hue, Sat, Bright);
      noStroke();
      rect(0, 0, width, height);
      //println("Mouse X: " + mouseX + "  Mouse Y: " + mouseY);
      // End
    
      // Time Calc & P&G Modes
      if (second() != lastSecond) {timer++;  }
      lastSecond = second();
    
      if (pMode) {pModeChar = '2';}
      else {pModeChar = '1';}
    
      if (gMode) {gModeChar = '2';}
      else {gModeChar = '1';}
      // End
    
      // PPF constrain
      PPFstring = nfc(PPF, 2);
      // End
    
      // Top Left
      fill(Hue2, Sat2, Bright2);
      textSize(10);
      textAlign(LEFT, TOP);
      text("    FPS: " + int(frameRate)+ "/60   F: " + frameCount + "   ~T: " + timer + "   PPF: " + PPFstring + "   Players: " + pModeChar + "   GameMode: " + gModeChar, 0, 0);
      // End
    
      // Name of the Game
      textAlign(RIGHT, TOP);
      text("BASIC PONG PLUS - BETA V1.2.0    ", width, 0);
      // End
    
      // Score
      textSize(100);
      textAlign(RIGHT, CENTER);
      text(scoreB, width/2 - 15, 60);
      textAlign(LEFT, CENTER);
      text(scoreD, width/2 + 15, 60);
      // End
    
      // Boundry Box
      rectMode(CENTER);
      noFill();
      stroke(Hue2, Sat2, Bright2);
      strokeWeight(10);
      rect(width/2, height/2, width - 40, height - 40);
      // End
    
      // Midpoint dotted line
      for (int dotted = 45; dotted < 19*30; dotted += 30)
      {
      rect(width/2, dotted, 5, 5);
      // End
      } 
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void menu()
    {
        /*
      // Menu
       while(menu)
      {
    
        fill(0);
        stroke(255);
        rectMode(CENTER);
        strokeWeight(20);
        rect(width/2, height/2, 800, 400); 
      }
      // End
      */ 
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void PPF()
    {
        if (lastFrameCount != frameCount)
      {
        pmodframecount++; 
      }
       lastFrameCount = frameCount;
    
      PPF = float(pmodframecount)/1000 + initialPPF; 
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void paddles()
    {
    
      if (pMode == false) // 1 Player
      {
    
        if (gMode == false) // 1 Player, Game Mode 1 - Mouse
        {
          if (mouseY > 145 && mouseY < height - 145)
          {
          PDTY = mouseY + 105;
          PDBY = mouseY - 105;
          }
    
    
          PBTY = PDTY;
          PBBY = PDBY;
        }
        else if (gMode == true) // 1 Player, Game Mode 2 - Keys
        {
          if (keyPressed && key == CODED)
      {
         if (keyCode == UP)
         {
          if ((PDBY - PDTY)/2 + PDTY >= 145)
          {
            PDTY -= 8;
            PDBY -= 8;
    
          PBTY = PDTY;
          PBBY = PDBY;
          }
         }
    
        if (keyCode == DOWN)
        {
          if ((PDBY - PDTY)/2 + PDTY <= height - 145)
          {
            PDTY += 8;
            PDBY += 8;
    
          PBTY = PDTY;
          PBBY = PDBY;
          }
        } 
      }
        }
      }
      else if (pMode == true) // 2 Players
      {
        if (gMode == false) // 2 Players, Game Mode 1 keys-mouse
        {
    
        }
        else if (gMode == true) // 2 Players, Game Mode 2 keys-keys
        {
    
        }
      }
    
      strokeWeight(20);
      stroke(Hue2, Sat2, Bright2);
      if (secondPaddle)
      {
      line(PBTX, PBTY, PBBX, PBBY); //Paddle B
      }
      line(PDTX, PDTY, PDBX, PDBY);//Paddle D
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void directTesting()
    {
      if (keyPressed && key == 'h')
      {
        direct = 3;
      }
      if (keyPressed && key == 'u')
      {
        direct = 2;
      }
      if (keyPressed && key == 'i')
      {
        direct = 1;
      }
      if (keyPressed && key == 'l')
      {
        direct = 4;
      }
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void reset()
    {
      if (keyPressed && key == 'r')
      {   
        ballX = width/2;
        ballY = height/2;
    
        scoreB = 0;
        scoreD = 0;
    
        PPF = 0;
        PPFmod = 0;
        initialPPF = 2;
        lastFrameCount = 0;
        pmodframecount = 0;
    
        PBTX = 50;
        PBBX = 50;
        PBTY = 195;
        PBBY = 405;
    
        PDTX = 1000;
        PDBX = 1000;
        PDTY = 195;
        PDBY = 405;
    
        colourMode = 5;
    
        gMode = false;
        pMode = false;
        menu = true;
        secondPaddle = true;  
      }
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void colourModeSelect()
    {
      if (keyPressed && key == 'x')
      {
        colourMode = 1;
      }
      else if (keyPressed && key == 'i')
      {
        colourMode = 2;
      }
      else if (keyPressed && key == 'f')
      {
        colourMode = 3;
      }
      else if (keyPressed && key == '8')
      {
        colourMode = 4; 
      }
      else if (keyPressed && key == 'n')
      {
        colourMode = 5; 
      }
      else if (keyPressed && key == 'c')
      {
        colourMode = 6; 
      }
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void colourMode()
    {
      //println("Hue: " + Hue + "  Sat: " + Sat + "  Bright: " + Bright);
      //println("Hue2: " + Hue2 + "  Sat2: " + Sat2 + "  Bright2: " + Bright2);
    
        if (colourMode == 1) //Psychedelic
        {
          if (Hue >= 255)
          {
            Hue = 0;
          }
          else
          {
            Hue += .75; 
          }
    
          Sat = 255;
          Bright = 255;
    
          Hue2 = abs(Hue - 255);
          Sat2 = 255;
          Bright2 = 255;
        }  
        else if (colourMode == 2) //Inverted    
        {
    
          Hue = 0;
          Sat = 0;
          Bright = 255;
    
          Hue2 = 0;
          Sat2 = 0;
          Bright2 = 0;
        }
        else if (colourMode == 3) //Fantom
        {
          Hue = 0;
          Sat = 0;
          Bright = 0;
    
          time += .025;
    
          Hue2 = 0;
          Sat2 = 0;
          Bright2 = 25 + cos(time)*20;
    
        }
        else if (colourMode == 4) //80's Computer
        {
          Hue = 0;
          Sat = 0;
          Bright = 0;
    
          Hue2 = 100;
          Sat2 = 255;
          Bright2 = 120;
        }
        else if (colourMode == 5) //Normal
        {
          Hue = 0;
          Sat = 0;
          Bright = 0;
    
          Hue2 = 0;
          Sat2 = 0;
          Bright2 = 255;
        }
        else if (colourMode == 6) // Cool Blue
        {
          Hue = 0;
          Sat = 0;
          Bright = 0;
    
          Hue2 = 160;
          Sat2 = 255;
          Bright2 = 255;
        }
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void randomStart()
    {
      if (frameCount == 1 || keyPressed && key == 'r')
      {
        direct = constrain(int(random(1, 5)), 1, 4);
      }
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void boundries()
    {
        if (ballX <= boundry) // Hits B
      {   
        ballAddX = abs (ballAddX);
        scoreD++;
      }
    
      if (ballX >= width - boundry) // Hits D
      {   
        ballAddX = -1 * abs (ballAddX);
        scoreB++;
      }
    
      if (ballY <= boundry) // Hits A
      {
        ballAddY = abs (ballAddY);
      }
    
      if (ballY >= height - boundry) // Hits C
      {
        ballAddY = -1 * abs (ballAddY);
      } 
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void paddlesHit()
    {
        if (secondPaddle)
      {
        if (ballX <= PBTX + 35 && ballY <= PBTY && ballY >= PBBY) // Hits paddle B
        { 
          ballAddX = abs(ballAddX);
        }
      }
    
      if (ballX >= PDTX - 35 && ballY <= PDTY && ballY >= PDBY) // Hits paddle D
      {    
        ballAddX = -1 * abs (ballAddX);
      }
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void keyPressed() 
    {
      if (key == 'm') 
      {
        menu = !menu;
      }
    
      if (key == 'p')
      {
        pMode = !pMode;
      }
    
      if (key == 'g')
      {
        gMode = !gMode;
      }
    
      if (key == '/')
      {
        secondPaddle = !secondPaddle;
      }
    
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void move()
    {
      //ballAddX += PPF;
      //ballAddY += PPF;
    
      println("ballAddX: " + ballAddX + "   ballAddY: " + ballAddY);
    
      ballX += ballAddX + PPF;
      ballY += ballAddY + PPF;
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
  • Well this seemed to fix it but now it does not turn the value negative. I'm gonna go test to see if it's still detecting that it passed or not.

    void PPF()
    {
        if (lastFrameCount != frameCount)
      {
        pmodframecount++; 
      }
       lastFrameCount = frameCount;
    
      //PPF = float(pmodframecount)/1000 + initialPPF; 
    
      ballAddX = float(pmodframecount)/1000 + initialPPF;
      ballAddY = float(pmodframecount)/1000 + initialPPF;
    

    I think it's about time I move this into the 'My Projects' section.

  • Figured it out!

    Set ballAdds to 1 so they only change direction, then we multiply PPF by them so that were using PPF again for ballX & ballY but now their polarity is based off of ballAdd. So really ball add is now ball direct, and PPF will be need to have of each for X and Y and it really will ballAddX/Y soo.... Not too confusing I guess.

    int ballAddX = 1;
    int ballAddY = 1;
    
    void move()
    { 
      println("ballAddX: " + ballAddX + "   ballAddY: " + ballAddY);
    
      ballX += ballAddX * PPF;
      ballY += ballAddY * PPF;
    }
    
  • edited February 2014

    Congratulations!

    I feel your program is better now...

    draw() looks very clean

    It's "boundaries" btw with a

    Does the menu work?

    additional cleaning up

    Maybe you can additional cleaning up:

    e.g.

    void randomStart()
    {
      if (frameCount == 1 || keyPressed && key == 'r')
      {
        direct = constrain(int(random(1, 5)), 1, 4);
      }
    }
    

    I suggest getting rid of "direct" altogether (can you? I dunno)

    But I think direct is replaced by ballAddX and ballAddY, isn't it?

    in the function randomStart() we want to give ballAddX and ballAddY random values!

    ballAddX = random (-5,5);
    ballAddY = random (-5,5);`
    

    or so - only then you achieve different angles in which the ball flies...

    Good work!

    Greetings, Chrisir

    ;-)

  • I have more ideas in store for you but step by step....

    :D

  • I thought I had gotten rid of all the directs? Oh well I'll go back and make sure, because yes it has ;) I haven't yet re-wrote the random start so that's why it's like that, I'll add it to the to-do list, as well as changing boundries.

    Ok control F'd and replaced all boundries with boundaries =D And rewrite the random is added to to-do.

    Also menu isn't operational yet (And from my brief testing it out it didn't work) so I should be heading off to bed but I mean come on, coding or sleep, what would you choose lol :P.

    Ok I'm off to test menu, but first I want to say thanks so much ppls! Especially you chrisir, your getting a thanks on the bottom of the menu or something ;) So I'll (try) to get menu up, but meanwhile by all means chrisir suggest your ideas, I'm all ears. 2 ears. Actually 2 eyes. Cuz you know, text and all. I have a to-do list with Main Task, Secondary Task, Eventually Task, and Bugs Task, and I can add them there.

    Ok the code is here: https://www.dropbox.com/s/ptanuzei3v9bjct/Pong_BETA_V1_2_3.pde

    ///////////////

    Also why I was here in the first place. Do you's guys know exactly why the ball was studering so much around the paddles and occasional wall. I know PPF would have been a problem making it skip right over the line in one frame, but then it would change direct and then problem solved. But if I recall that wasn't always the case, and it would stray way out then come back in. And when it would get stuck "inside" the paddles, that just confused me since the paddle was in essentially 1d relative to how the ball could hit it so there was no "inside". My guess is that when it would be near, the speed of it (PPF) would jump it right through, then the direction would change, it would go out of it, and for some reason it would change back and repeat, hitting the paddles again.

    Sorry if this is all worded a little funny I'm tired.

  • Yeha menu isn't really going well and I'm stumped for now..

    void menu()
    {
    
        while(menu)
        {
    
          fill(0);
          stroke(255);
          rectMode(CENTER);
          strokeWeight(20);
          rect(width/2, height/2, 800, 400); 
          println(menu);
        }
    
    }
    

    It's getting stuck in menu, and unresponsize to the menu commands when in the while loop. And the screen is white.

    See I need it to be in an infinite loop right there so long as menu i

  • I'm going to bed now.

  • edited February 2014

    you wrote:

    Do you's guys know exactly why the ball was studering so much around the paddles and occasional wall.

    That's easy.

    you check whether the ball is in a zone at the paddle / near wall

    if so, you changed direct and substracted PPF

    good.

    but now in the next loop of draw() the ball is still in the zone: you again change the direct (although it's correct already), so we add PPF again so it goes deeper into the zone, stays in the zone...

    and therefore it stutters...

  • edited February 2014

    My additional ideas

    • have a advanced paddle: at the edges a little round. When the ball hits it there the angle changes differently
    • have a wall in the middle. The ball gets reflected. Only top and bottom is space for the ball to go through. When a brick gets hit three times, it dies.
    • some bricks can also be moving
    • have levels of that game with different walls and different colors
    • do you know good old arkanoid - lots of ideas there

    the menu problem:

    • you need to use states of program: one state is you are in menu, one state is start splash screen, one is the game, one is a help screen etc.

    in draw() have a switch(state) { } and have for each state one paragraph

    in keyPressed also have

    switch(state) { 
    case 0:
    break;
    }  
    

    when user hits the correct key in state menu say

    state = stateGame;
    

    yes, you can give the states names, e.g. stateGame

    final int stateGame=0;
    final int stateMenu = 1; 
    final int stateSplashScreen = 2;
    final int stateHelp = 3;  // when he hits F1 
    
  • to demonstrate states with a menu...

    // consts 
    final int stateGame=0;
    final int stateMenu = 1;
    final int stateSplashScreen = 2;
    final int stateHelp = 3;  // when he hits F1 
    // current state 
    int state = stateSplashScreen;
    //
    int playerNumber = 0; 
    // ---------------------------------------------------------------
    //
    void setup()
    {
      // runs once
      // init
      size(800, 600);
    } // func 
    //
    //
    void draw() 
    { 
      // runs on and on in a loop
      background(255);
      fill(0);
      stroke(0);
      textSize(22);
    
      // states: 
      switch(state) {
      case stateGame:
        text("Game...", 200, 200);
        text(playerNumber 
          + " Players. Hit F1 for help. Hit r to restart.", 
        200, height-20);
        for (int i = 1; i < 10 * playerNumber; i++) 
          signHome(0 + i*20, 100);
        break;
      case stateSplashScreen:
        // show splash screen
        // 
        // the big rect for the splashscreen
        noStroke();
        fill(111);  // gray 
        rect (100, 100, width-200, height-200);
        // the texts 
        fill(255, 0, 0); // red 
        textSize(32);
        text ("Cool Game!", width/2-100, height /2);
        fill(0);
        textSize(22);
        text ("Loading...", width/2, height /2+60);
        // the small game scene 
        fill(233, 2, 2);
        ellipse (200, 150, 10, 10);  // big ball
        // little trace  
        fill(0, 255, 0); // green 
        noStroke();  
        int step=6;
        for (int i = 1; i < 8 ; i++) 
          ellipse (200-i*step, 150-i*step, 3, 3);
        rect  (250, 110, 6, 60);  // the paddle 
        // 
        break; 
      case stateHelp:
        text("the help...", 200, 100);
        break;  
      case stateMenu:
        text("the menu", 200, 100);
        text("   1. Play with 2 players ", 200, 150);
        text("   2. Play with 4 players ", 200, 200);
        text("hit 1 or 2  ", 200, 250);
        break; 
      default:
        // error 
        break;
      } // switch
      //
    } // func 
    //
    
    void keyPressed() {
      // states: 
      switch(state) {
      case stateGame:
        //     
        if (keyCode==java.awt.event.KeyEvent.VK_F1) {
          // F1
          state =  stateHelp;
        } // if 
        else if (key == 'r') {
          state = stateSplashScreen;
        }
        else {
          //
        }
        break;
      case stateSplashScreen:
        // next state 
        state = stateMenu;
        break; 
      case stateHelp:
        // back to game 
        state = stateGame;
        break;  
      case stateMenu:
        // read key in menu
        switch (key) {
        case '1' :
          playerNumber = 2;
          state = stateGame;
          break;
        case '2' :
          playerNumber = 4;
          state = stateGame;
          break;
        case 'x':
          exit();
          break;
        default :
          println ("unknown input");
          break;
        } // inner switch  
        break; 
      default:
        // error 
        break;
      } // switch
      //
    }
    
    // =====================================================================
    
    void signHome(int x, int y) {
      // gives a sign for a house / home sign
    
      final int width1=6;
      final int height1=8;
    
      fill( 2, 255, 0 );
      strokeWeight(1);
      stroke ( 2, 255, 0 );
      noFill();
      x+=21;
      y+=14;
      triangle ( x-width1, y, 
      x, y-height1, 
      x+width1, y );
      rect(x-width1/2, y, width1, width1);
      rect(x-width1/4+1, y+height1/4+1, width1/4, width1/3);
      strokeWeight(1);
    }
    
    
    // =====================================================================
    
  • also in mousePressed you want to use state

    as you can see, draw() has gotten long again -

    you could again kick out splash screen as an extra function....

  • Ok that's just a wee bit complicated... I'm working my way through it. It seems pretty straight forward if you ignore the visual stuff. In the draw() put a switch state. Based on the switch state it will run different screens. And as for the void keyPressed I finally got that. Realizing that oh yeah, this is keyPressed helped. Cool. I will certainly implement this. And basically it will have one state for play game, and that's where my game play functions will be right.

    have a advanced paddle

    Good idea for how I can implement angles changing. But then if someone hits it on the end, then it could go all very narrow zig-zag or some other weird angle. Do you have any suggestions on ways to implement angles? After reading this it did spawn the idea to have the end thirds of the paddles at 22.5 degrees. Then change angle based on that. But that would mean figuring out when the ball hit it and sigh. I'm post boning different angles to the eventually section for now. PLEASE HELP WITH ANGLES!!!! I'm gonna go play pong games to see what they did for angles :D

    have a wall in the middle

    Ahh great idea for a like a I can't remember what they're called. But yeah, I could use switch case to bring it into that 'Mode' and then I could call the regular functions but add the ones for the walls. I think programming it will be funner than the mode itself. And then the moving walls thing! But what are they called. It's not gonna be game modes because that's already taken. But you know theres classic, walls, super speed, hard mode etc... Wow this is givng me the idea to but the colour modes in the menu and man! This is gonna be awesome! My menu will have settings! I'm exited!

    some bricks can also be moving

    Um bricks? Like moving obstacles? Thought about, forgot about it. I will be adding that to the list. I could use sin/cos so that it's not just linear movement up and down, and yeah I like it.

    have levels of that game with different walls and different colors

    Levels? I kinda have that, I have PPF ball speed. It goes up to 25 Pixels Per Frame and slowly increases. And then with the colour modes I think this is it?

    do you know good old arkanoid - lots of ideas there

    Sorry no. Were can I find him. Is he youtube or forums or other?

    Well cool thanks for the suggestions, I will implement menu then using the switch case I can put in different options like an options menu and coulour modes that you turn on. It'll be great!

  • Damn angles... My other option asides from 45Degrees is to invert the angles.

    Like if the ball its the wall C at 10 degrees heading for D, it leaves at 170 degrees. Or hits heading for D at 100 degrees, hits A, then leaves it at 80 degrees. If you know what I mean.

    What do you think?

  • The angle is just a result of balladdx and balladdy

    The angle is just where the ball goes because of the two

    Angle is not a var in your sketch!!

    Sorry.

    Anyway at upper edge of right paddle just say

    Balladdy -= 1;

    So it goes a little more sideways than in the middle of the paddle

  • When both are same angle is 45

    When its 1 and 2 angle is e.g. 22.5

  • Just remember that ballAddX and ballAddY are changed to ballDirectX/Y. They are also set to 1, and 1 to remain. As we multiply PPFX and PPFY by them it changes the direction. So now ballAddX/Y are PPFX/Y (Pixels Per Second X/Y) and by changing these it changes the angle (rise/run (PPFY/PPFX)).

  • And no I know :P But my question is how will I determine angle change based off of when it hits. For example right now it hits at 45d then leaves at 45d (1/1). Should I make it so that if it hits at 2/1 should I change it -1/2 (perpendicular angle)? Or should I make it -2/1 (Inverted angle, other example: 2/4 → -2/4). Or some other suggestion?

  • Also, but then what factors will change the angle? What will make it go from 1/1 to 2/1 which then I can hit against a wall and then -1/2 or -2/1 it. Because other wise if it's at default 1/2 it will always only be some variation of that. The thing I see most pong games do is something I don't know how to do. They make it so when the ball hits the paddle, if the paddle is moving then alter the angle based of that.

    Like if the ball is on trajectory -1/2, hits the paddle, and instead of going back at 2/1 (perpendicular), if the paddle is moving up then come back at 1/4.

    I don't know exactly how that would work. Like I'd have to check the difference in position of the paddle, then apply that to the angle. So I'll do that after the menu :/

  • Idea!

    I should set a level thing and call it Super Random! Basically almost every int/float in the game gets a random value between 0, and twice it's default! And booleans too.

  • the idea

    Zwischenablage02

    red normal reflect

    yellow - stronger reflect, that would appear on the edge of the paddle at the lower side

    think of it has the edge of the paddle a little rounded

    so when he hits on the broad side, normal reflect

    when he's near edge, have a formula the closer to the edge, the bigger balladdy gets (+0.1, then +0.2....)

    it's only a gimmick

    also when the paddle has a speed you can also change the direction of the ball when he hits it

  • An good idea and I could just make it invisible so the user doesn't notice and then maybe even do it with the sides.

    As for the paddle speed thing I've been wanting to do that all along as I always see that in these type of games, however I'm not sure how to do it.

    Chrisir, what do you know about xbee wireless, and serial data via processing? I just got a rover in the mail and will be really getting into serial communication soon so I can command the rover via a emotiv mind reading headset, into processing (like a wasd type thing) then sending that to an arduino, then wirelessly to the robot. A.k.a wirelessly controlling a robot to move around with my thoughts alone.

    The graph post I made, that's actually because in the live data feed window, I want to have graphs reporting back on board accelerometer data. And the pong game never meant to go so huge as it is. It was honestly just supposed to be a nice small pong game just to be like wow, I was able to make a pong game! Because asides from like testing things it was my second real program.

    Anyway I want to say thanks to all you's guys whom for without I would not be where I am =D

  • hi!

    sure the pong s only for training - forget about it.

    Your new project sounds absolutely cool and I know nothing about it

    so it's worth starting a new thread...

    Greetings, Chrisir

  • I won't be yet unless I need some help getting xbee and arduino and processing communicating, and I don't have the headset yet. It's 300 bucks and I don't have a job, so I'm practicing getting really good at coding the other parts first :P

    As for pong I figure I'll finish the menu, then leave it for when I'm older and an expert programmer and be like (in 30 some year old me's voice): "Oh yeah, I remember these old projects I never finished, I think I should finish them finally". Only to rewrite the entire codes thinking how crappy I was back then lol.

    Pong was a great start and it taught me alot. My next big project (solo processing i.e. no mind reading) I'm hoping to be a evolution simulator of sorts. Basically have a box, with 3 legs, and 3 fore legs attached to them. There will be 12 variables, 6 for speed, and 6 for how far each one can turn. 12 will be spawned. The movements will be random at first, but the two that make it the furthers will 'mate' and the variables for their motion mixed up and mutated slightly, creating 12 offspring. Then the two of them that go furthest... And repeat.

    I know you can hinge one part of another, and I know I can apply basic gravity, and make sure certain parts don't touch the ground. But that't about it.... Making it move as a whole thing, well I cross that bridge when I get there. Gulp. I imagine it's a big bridge....

    Cheers

    Mad Science

  • there are headsets at 10 to 30 bucks

  • Not like this one. This one you train. You start by given it nothing. It reads your brainwaves for 8 seconds, while you think of nothing. Then the fun begins. There is a vitual cube on the screen. And you train the software to move it with your mind. Example: for 8 seconds you think "move forward" or something. And you repeat this several times for different things like rotation, move left, right, up, down forward back ect. Then you set it so control keys on your keyboard.

    Heres where processing comes in. I detect those keys, then send them serially to the arduino. Then from there wirelessly to the rover.

    And that is my plan! Here are some links to the headset:

    Ted Talks:

    This youtube dudes video that convinced me this is the right one:

    The website for it: http://emotiv.com/

    A 10 - 30 dollar one will not suffice unless I attach it to one of those crappy RC cars that only go forward and back. Which I'll probably do for my little bro since hes got one.

    But with this headset, I can also make a robotic arm, attach it to a quadriplegic (or Stephen Hawking) and give them an arm per-say.

Sign In or Register to comment.