Search code examples
processing

Using Keys to move object and shooting mini squares


In my key pressed section, I'm not too sure what I need to do in order for the square to move up and down. It is currently very slow. I also am trying to figure out how Mini square would be shot from the big square;

boolean updown = false;
int squareX = 20;
int squareY = 20;
int speed = 30;
int circleX = 150;

void setup () {
  size (700,700);
}

void draw () {
  background (0);

  fill(100);
  ellipse (circleX,140,150,150);
  circleX -=2;
  if (circleX < - 20) {
    circleX = 550;
  }

  fill (225);
  rect (squareX, squareY, 70, 70);
  if (updown) squareY = squareY + speed;
  
   if (squareY>width || squareY <0) {
     speed=speed*-1;

   }
}

Solution

  • Currently you're directly incrementing squareY by 1 pixel. Ideally you'd simply control velocity by setting it to a value > 0 when you want to move the square or reset it back to 0 when you want the movement to stop.

    There are a couple of other things that could make this nicer, such as:

    • using the size of the square when checking if the square is outside the screen area or not
    • remembering the last good y position before the square went offscreen to reset the position to when flipping the position.

    Here's a modified version of your sketch with the above notes as well as naming variables in way the keeps related elements grouped:

    int squarePositionX = 20;
    int squarePositionY = 20;
    int squareVelocityY = 0;
    int squareLastGoodY = squarePositionY;
    int squareSize = 70;
    int squareSpeed = 9;
    
    int circleX = 150;
    
    void setup () {
      size (700, 700);
    }
    
    void draw () {
      // handle keys
      if(keyPressed){
        if(key == 'w'){
          squareVelocityY = -squareSpeed;
        }
        if(key == 's'){
          squareVelocityY =  squareSpeed;
        }
      }else{
        // reset velocity (stop square from moving)
        squareVelocityY = 0;
      }
      
      // update big square position based on velocity
      squarePositionY += squareVelocityY;
      // check if square is still on screen (reset velocity if it's not otherwise keep track of it's last 
      if (squarePositionY >= width - squareSize || squarePositionY <= 0) {
        // flip Y velocity
        squareVelocityY *= -1;
        // reset to last good known Y position
        squarePositionY = squareLastGoodY;
      }else{
        squareLastGoodY = squarePositionY;
      }
      
      // clear screen
      background (0);
    
      // render big square
      fill (225);
      rect (squarePositionX, squarePositionY, squareSize, squareSize);
      
      // render circle
      fill(100);
      ellipse (circleX, 140, 150, 150);
      // update circle position
      circleX -= 2;
      if (circleX < - 20) {
        circleX = 550;
      }
    }
    

    Hopefully the comments help explain in more detail what's going on.

    Regarding shooting mini squares you'd need to keep track of the positions of each mini square. You could use an array and append() to expand it as new bullets are shot, or just go for an array type with dynamic size such as ArrayList or IntList. To keep the list efficient and not flood it with bullets that are outside of the screen area you could do a similar test to the large square to check when the small squares are offscreen remove from the list. The last thing left to do is simply rendering the small squares as long as long as they are visible.

    Here's a commented sketch to illustrate the idea:

    int squareSize = 70;
    int squarePositionX = squareSize;
    int squarePositionY = squareSize;
    int squareVelocityY = 0;
    int squareLastGoodY = squarePositionY;
    int squareSpeed = 3;
    
    int circleX = 150;
    
    // store positions for 
    IntList miniSquarePositionsX = new IntList();
    IntList miniSquarePositionsY = new IntList();
    int miniSquareSpeed = 9;
    int miniSquareSize  = 35;
    
    void setup () {
      size (700, 700);
      rectMode(CENTER);
    }
    
    void draw () {
      // handle keys
      if(keyPressed){
        if(key == 'w' && key != ' '){
          squareVelocityY = -squareSpeed;
        }else
        if(key == 's' && key != ' '){
          squareVelocityY =  squareSpeed;
        }
      }else{
        // reset velocity (stop square from moving)
        squareVelocityY = 0;
      }
      
      // update big square position based on velocity
      squarePositionY += squareVelocityY;
      // check if square is still on screen (reset velocity if it's not otherwise keep track of it's last 
      if (squarePositionY >= width - (squareSize * 0.5) || squarePositionY <= (squareSize * 0.5)) {
        // flip Y velocity
        squareVelocityY *= -1;
        // reset to last good known Y position
        squarePositionY = squareLastGoodY;
      }else{
        squareLastGoodY = squarePositionY;
      }
      
      // update mini squares: assumes the size of both x and y lists match
      for(int i = 0 ; i < miniSquarePositionsX.size(); i++){
        // update X position
        miniSquarePositionsX.set(i, miniSquarePositionsX.get(i) + miniSquareSpeed);
        // remove element if it's outside the screen
        if(miniSquarePositionsX.get(i) > width){
          miniSquarePositionsX.remove(i);
          miniSquarePositionsY.remove(i);
        }
      }
      // clear screen
      background (0);
    
      // render circle
      fill(100);
      ellipse (circleX, 140, 150, 150);
      
      // render big square
      fill (225);
      rect (squarePositionX, squarePositionY, squareSize, squareSize);
      
      // update circle position
      circleX -= 2;
      if (circleX < - 20) {
        circleX = 550;
      }
      // render mini squares: assumes the size of both x and y lists match
      for(int i = 0 ; i < miniSquarePositionsX.size(); i++){
        rect(miniSquarePositionsX.get(i), miniSquarePositionsY.get(i), miniSquareSize, miniSquareSize);
      }
    }
    
    void keyReleased(){
      // SPACE key shoot
      if(key == ' '){
        // add position entries for a mini square
        miniSquarePositionsX.append(squarePositionX);
        miniSquarePositionsY.append(squarePositionY);
        println(miniSquarePositionsY);
      }
    }
    

    If you're familiar with Object Oriented Programming (OOP) basics the above can be nicely encapsulated using a couple of classes (such as a Square class for the "ship" and a MiniSquare class for the "bullets"). Have fun!