Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
///////////////////////////////
//////SUPER BOX SHOOTER////////
///////////////////////////////

//Oct 22nd 2016
//Intro to Media Computation
//Instructor: Nicolas Hesler
//Created by: William Lu

//WASD or ARROW KEYS to move. Hold SPACE to shoot. 
//Destroy as many boxes as you can! 
//Don't touch them!
//I know, the game isn't very balanced.

//Defining objects as each class
Player mainChar;
Platform base1;
Platform base2;
Platform middle;
Platform mid2;
Platform mid3;
Platform mid4;
Platform top;
Spawner spawner;
Enemy[] e;
Game_State gs;

Wall leftWall;
Wall rightWall;
Wall topw1;
Wall topw2;
Wall bot1;
Wall bot2;

//boolean to check if the main character is on the ground
boolean grounded;
int arrayN;
boolean[] groundCheck;

//player dead
boolean pDead;

ArrayList<Bullet> bullets;

//player movement
boolean playerRight;
boolean playerLeft;
boolean playerUp;
boolean playerShoot;

boolean facingRight = true;
boolean facingLeft = false;

//The last button held down by the user. 1 = right, 2 =left
int lastHeldButton = 1;
//# of enemies
int enemyNum = 1000;

float gravity;




void setup () {
  size (600, 400);
  frameRate(60);
  noStroke();
  //spawner = new Spawner();

  //defining the objects
  mainChar = new Player();
  base1 = new Platform(0, 400, 260, 380, 0);
  base2 = new Platform(340, 400, 600, 380, 1);
  middle = new Platform(150, 295, 450, 280, 2);
  mid2 = new Platform(0, 195, 200, 180, 3);
  mid3 = new Platform(400, 195, 600, 180, 4);
  mid4 = new Platform(250, 95, 350, 80, 5);
  top = new Platform(0, 20, 600, 0, 6);

  rightWall = new Wall( 580, 400, 600, 0);
  leftWall = new Wall( 0, 400, 20, 0);

  spawner = new Spawner();
  bullets = new ArrayList<Bullet>();
  e = new Enemy[enemyNum];
  gs = new Game_State();

  //assigns random constructor variables for enemies. random speed, and random paths. numbers each monster.
  for (int i = 0; i<enemyNum; i++) {
    e[i] = new Enemy( random( 0.8, 1.2), int(random(1, 5)), i);
  }



  facingRight = true;
  facingLeft = false;
  groundCheck = new boolean[10];
  arrayN = 0;
  grounded = false;
}

void draw () {
  background (255);

  if (bullets==null) {
    return;
  }

  bullets.add(new Bullet());

  //draws every bullet all at once
  for (int i=0; i<bullets.size(); i++) {
    Bullet bullet=bullets.get(i);
    bullet.update();
    bullet.hit();
    bullet.display();
  }

  //removes the first bullet from the array once max size is reached
  if (bullets.size() > 100) {
    bullets.remove(0);
  }



  top.display();
  top.collisionCheck();



  spawner.display();
  spawner.updateCounter();

  direction();
  mainChar.update();
  mainChar.display();
  updateGravity();

  base1.display();
  base1.collisionCheck();

  base2.display();
  base2.collisionCheck();

  middle.display();
  middle.collisionCheck();
  middle.sideCollisionCheck();

  mid2.display();
  mid2.collisionCheck();
  mid2.sideCollisionCheck();

  mid3.display();
  mid3.collisionCheck();
  mid3.sideCollisionCheck();

  mid4.display();
  mid4.collisionCheck();
  mid4.sideCollisionCheck();

  leftWall.display();
  leftWall.sideCollisionCheck();

  rightWall.display();
  rightWall.sideCollisionCheck();

  keyPresses();
  grounding();

  gs.playerDeath();
  gs.updateScore();


  //text used for debugging

  //fill (0);
  //text (mainChar.position.x + " " + mainChar.position.y, 100, 100);
  //text (mainChar.velocity.x + " " + mainChar.velocity.y, 100, 120);
  //text (mainChar.acceleration.x + " " + mainChar.acceleration.y, 100, 140);
  //println (grounded, facingRight, s.counter, e[0].hp, pDead, gs.score);
}

void keyPresses() {
  //key press visuals
  //up
  rectMode(CENTER);
  if (playerUp == true) {
    //slowly fades away over time
    fill(0, 175 - frameCount/3);
  } else { 
    fill ( 150, 175 - frameCount/3);
  }
  rect ( 250, 180, 15, 15);

  //space
  if (playerShoot == true) {
    fill(0, 175 - frameCount/3);
  } else { 
    fill ( 150, 175 - frameCount/3);
  }
  rect ( 335, 200, 90, 15);

  //left
  if (playerLeft == true) {
    fill(0, 175 - frameCount/3);
  } else { 
    fill ( 150, 175 - frameCount/3);
  }
  rect ( 230, 200, 15, 15);

  //right
  if (playerRight == true) {
    fill(0, 175 - frameCount/3);
  } else { 
    fill ( 150, 175 - frameCount/3);
  }
  rect ( 270, 200, 15, 15);

  //down

  fill ( 150, 175 - frameCount/3);
  rect ( 250, 200, 15, 15);
}


void updateGravity () {
  if (grounded == true) {
    //no gravity if player is on the ground. DONT do this in your own code, I approached this wrong. gravity should never change
    gravity = 0;
  } else { 
    gravity = 0.07;
  }
}


void grounding() {
  //Check every platform to see if a player is standing on any of them. if true, then grounded = true
  for (arrayN=0; arrayN < 9; arrayN = arrayN +1) {
    if (groundCheck[arrayN] == true) {
      grounded = true;
    } else if (groundCheck [arrayN] == false) {
    }
  }
  if (arrayN == 9) {
    arrayN = 0;
  }
}

void keyPressed() {
  if (key == 'a' || key == 'A' || keyCode == LEFT) {
    playerLeft = true;
    lastHeldButton = 2;
  } 
  if (key == 'd' || key == 'D' || keyCode == RIGHT) {
    playerRight = true;
    lastHeldButton = 1;
  } 
  if (key == 'w' || key == 'W' || keyCode == UP) {
    playerUp = true;
  } 
  if (key == ' ') {
    playerShoot = true;
  }
}

void keyReleased() {
  if (key == 'a' || key == 'A' || keyCode == LEFT) {
    playerLeft = false;
  } 
  if (key == 'd' || key == 'D' || keyCode == RIGHT) {
    playerRight = false;
  } 
  if (key == 'w'|| key == 'W' || keyCode == UP) {
    playerUp = false;
  } 
  if (key == ' ') {
    playerShoot = false;
  }
}

void mousePressed() {
  //if you die, and you click the mouse, all the variables are reset
  if (pDead == true) {
    mainChar = new Player();
    base1 = new Platform(0, 400, 260, 380, 0);
    base2 = new Platform(340, 400, 600, 380, 1);
    middle = new Platform(150, 295, 450, 280, 2);
    mid2 = new Platform(0, 195, 200, 180, 3);
    mid3 = new Platform(400, 195, 600, 180, 4);
    mid4 = new Platform(250, 95, 350, 80, 5);
    top = new Platform(0, 20, 600, 0, 6);

    rightWall = new Wall( 580, 400, 600, 0);
    leftWall = new Wall( 0, 400, 20, 0);

    spawner = new Spawner();

    bullets = new ArrayList<Bullet>();
    e = new Enemy[enemyNum];

    gs = new Game_State();
    for (int i = 0; i<enemyNum; i++) {
      e[i] = new Enemy( 1, int(random(1, 5)), i);
    }
    pDead = false;
  }
}


void direction() {
  //determines the direction you're facing based on your x axis acceleration
  if (mainChar.acceleration.x > 0) {
    facingRight = true;
    facingLeft = false;
  }
  if (mainChar.acceleration.x < 0) {
    facingLeft = true;
    facingRight = false;
  }
}
class Bullet {

  PVector position = new PVector(mainChar.position.x, mainChar.position.y);
  PVector velocity = new PVector(0, 0);
  //hit position
  PVector hitPos = new PVector();

  boolean exit = false;
  boolean control = true;
  boolean shot = false;
  boolean wallHit = false;

  //monster hit
  boolean monHit = false;


  int hitAnim = 0;

  void update() {
    // if the bullet hasn't left the chamber, then it's inside the player.
    if (exit == false || wallHit == true) {
      position.x = mainChar.position.x; 
      position.y = mainChar.position.y;
      control = true;
    } 
    //when you press space, the bullet exits. restricted by frame count so you dont shoot like crazy when you hold down space.
    if (playerShoot == true && shot == false &&frameCount% 15 ==0 && pDead == false) {
      exit = true;
    }

    // when the bullet exits:
    if (exit == true && wallHit == false) {
      //shoots bullet right if facing right. can no longer control the direction of the bullet based on where you are facing
      if (facingRight ==true &&control == true) {
        position.x = mainChar.position.x+15;
        velocity.x = abs(mainChar.velocity.x) +6;
        control = false;
        shot = true;
        //bullet left
      } else if (facingLeft ==true &&control == true) {
        position.x = mainChar.position.x-15;
        velocity.x =-abs(mainChar.velocity.x)-6;
        control = false;
        shot = true;
      }
    }

    //if bullet somehow exits the screen
    if (position.x > width || position.x < 0 && exit == true && shot == true) {
      position.x = mainChar.position.x; 
      position.y = mainChar.position.y;
      exit = false;
    } 

    //Controls bullet position
    position.add(velocity);
  }

  void hit() {
    //collision for Walls. If the bullet hit the wall, play the animation
    if (position.x + 5> rightWall.x1 || position.x - 5< leftWall.x2) {
      hitAnim = 1;
    }

    //platform collision for middle
    if (position.x -5 < middle.x2 && position.x +5 > middle.x1&& position.y-5< middle.y1 && position.y+5> middle.y2 && hitAnim ==0) {
      hitAnim = 1;
    }
    //mid2
    if (position.x -5 < mid2.x2 && position.x +5 > mid2.x1&& position.y-5< mid2.y1 && position.y+5> mid2.y2 && hitAnim ==0) {
      hitAnim = 1;
    }
    //mid3
    if (position.x -5 < mid3.x2 && position.x +5 > mid3.x1&& position.y-5< mid3.y1 && position.y+5> mid3.y2 && hitAnim ==0) {
      hitAnim = 1;
    }
    //mid4
    if (position.x -5 < mid4.x2 && position.x +5 > mid4.x1&& position.y-5< mid4.y1 && position.y+5> mid4.y2 && hitAnim ==0) {
      hitAnim = 1;
    }

    //bullet monster hit collision
    //numbers every monster, using i.
    for (int i =0; i<enemyNum; i++) {
      //checks the collision of every bullet and every enemy at once. if the bullet enters ANY enemy:
      if (pDead == false && e[i].bottomLeft.x <= position.x + 5 && e[i].topRight.x >= position.x - 5) {
        if (monHit == false && e[i].topRight.y - 15 <= position.y + 5 && e[i].bottomLeft.y >= position.y - 5) {
          //plays animation, enemyHP goes down
          velocity.x = 0;
          hitAnim = 1;
          e[i].hp--;
          monHit = true;
        }
      }
    }


    //bullet explosion animation
    if (hitAnim == 1) {
      wallHit = true;    
      hitAnim = 2;
      hitPos = position;
      fill( 255, 41, 41);
      rectMode (CENTER);
      rect (hitPos.x, hitPos.y, 25, 25);
    }
  }

  void display() {
    if (exit == true && wallHit == false) {
      fill( 255, 87, 41);
      rectMode (CENTER);
      rect (position.x, position.y, 10, 10);
    }
  }
}
class Enemy {

  PVector position= new PVector(width/2, 0);
  PVector bottomLeft = new PVector();
  PVector topRight = new PVector();
  PVector velocity= new PVector();
  PVector acceleration= new PVector();

  // determines which path the enemy takes
  int path;
  // which stage of the path the enemy is on
  int pathStage =1;
  int hp = 20;
  int monNum;


  float eGravity = 0.07;
  float speed;
  float radius = 12;
  boolean spawned = false;
  boolean dead;

//constructors for each enemy, speed, the path it takes, and the assigned # of each monster
  Enemy(float tempSpeed, int tempPath, int tempMonNum) {
    speed = tempSpeed;
    path = tempPath;
    monNum = tempMonNum;
  }


  void update() {
  // PVectors for the corners of the enemy, just to make things easier
    bottomLeft.x = position.x-radius;
    bottomLeft.y = position.y+radius;
    topRight.x = position.x+radius;
    topRight.y = position.y-radius;


    //death check
    if (hp <0) {
      spawned = false;
      dead = true;
      gs.score++;
      hp=3;
    }    

    //Spawning, counter is controlled by the spawner class
    if (spawner.counter== monNum && spawned == false) {
      position.y =0;
      spawned = true;
      //if hasn't spawned, stays off screen
    } else if (spawned == false|| dead == true) {
      position.y = -200;
      position.x = width/2;
      velocity.x = 0;
      velocity.y =0;
      acceleration.y =0;
    }


    //terminal horizontal velocity
    if (velocity.x >1.5) {
      velocity.x = 1.5*speed;
    } else if (velocity.x < -1.5) {
      velocity.x = -1.5*speed;
    }

    //horizontal movement controls
    //left spawn
    if (path ==1) {
      //when it hits the wall, go to stage 2
      if (bottomLeft.x < leftWall.x2) {
        pathStage = 2;
      }
      if (topRight.x > rightWall.x1) {
        pathStage = 4;
      }
      if (pathStage == 1) {
        acceleration.x = -0.5;
      } else if (pathStage == 2) {
        //turns around
        acceleration.x = 0.5;
      } else if (pathStage == 4) {
        acceleration.x = -0.5;
      }
    } 

    //left-right spawn
    if (path ==2) {
      if (bottomLeft.x < leftWall.x2) {
        pathStage = 2;
      }
      //when it reaches the center, reach stage 3
      if (topRight.x > width/2+50) {
        pathStage = 3;
      }
      if (pathStage == 1) {
        acceleration.x = -0.5;
      } else if (pathStage == 2) {
        acceleration.x = 0.5;
      } else if (pathStage == 3) {
        acceleration.x = -0.5;
      }
    }


    //right spawn
    if (path ==3) {
      if (bottomLeft.x < leftWall.x2) {
        pathStage = 2;
      }
      if (topRight.x > rightWall.x1) {
        pathStage = 4;
      }
      if (pathStage == 1) {
        acceleration.x = 0.5;
      } else if (pathStage == 2) {
        acceleration.x = 0.5;
      } else if (pathStage == 4) {
        acceleration.x = -0.5;
      }
    }
    //right-left spawn
    if (path ==4) {
      if (topRight.x > rightWall.x1) {
        pathStage = 2;
      }
      if (bottomLeft.x < width/2-50) {
        pathStage = 3;
      }
      if (pathStage == 1) {
        acceleration.x = 0.5;
      } else if (pathStage == 2) {
        acceleration.x = -0.5;
      } else if (pathStage == 3) {
        acceleration.x = 0.5;
      }
    }

    //vertical movement controls
    // controls collision based on which platform
    //for mid4
    if (bottomLeft.y> mid4.y2 && topRight.y < mid4.y1 && bottomLeft.x < mid4.x2 && topRight.x > mid4.x1) {
      position.y = mid4.y2 - radius;
      velocity.y = 0;
      acceleration.y=0;
    }
    //for mid3
    if (bottomLeft.y> mid3.y2 && topRight.y < mid3.y1 && bottomLeft.x < mid3.x2 && topRight.x > mid3.x1) {
      position.y = mid3.y2 - radius;
      velocity.y = 0;
      acceleration.y=0;
    }
    //for mid2
    if (bottomLeft.y> mid2.y2 && topRight.y < mid2.y1 && bottomLeft.x < mid2.x2 && topRight.x > mid2.x1) {
      position.y = mid2.y2 - radius;
      velocity.y = 0;
      acceleration.y=0;
    }
    //for middle
    if (bottomLeft.y> middle.y2 && topRight.y < middle.y1 && bottomLeft.x < middle.x2 && topRight.x > middle.x1) {
      position.y = middle.y2 - radius;
      velocity.y = 0;
      acceleration.y=0;
    }
    //for base1
    if (bottomLeft.y> base1.y2 && topRight.y < base1.y1 && bottomLeft.x < base1.x2 && topRight.x > base1.x1) {
      position.y = base1.y2 - radius;
      velocity.y = 0;
      acceleration.y=0;
    }
    //for base2
    if (bottomLeft.y> base2.y2 && topRight.y < base2.y1 && bottomLeft.x < base2.x2 && topRight.x > base2.x1) {
      position.y = base2.y2 - radius;
      velocity.y = 0;
      acceleration.y=0;
    }
    //as long as it's alive, it moves
    if (dead == false) {
      acceleration.y += eGravity;
      velocity.add(acceleration);
      position.add(velocity);
    }
  }

  void playerCollision() {
    //if enemy touches the player, you die
    if (mainChar.position.x - 15 <= position.x + radius && mainChar.position.x +15 >= position.x - radius) {

      if (mainChar.position.y - 15 <= position.y + radius && mainChar.position.y + 15 >= position.y - radius) {
        pDead = true;
      }
    }
  }

  void display() {

    fill(53, 129, 184);
    rectMode(CORNERS);
    if (dead == false) {
      rect (bottomLeft.x, bottomLeft.y, topRight.x, topRight.y);
    }
    //  noStroke();
  }
}
class Game_State {

  int anim = 0;  
  int score = 0;

  void playerDeath() {
    if (pDead == true) {
      //death screen
      anim +=1; 
      fill (0, anim*2);
      rectMode (CENTER);
      rect (width/2, height/2, 600, 400);
      fill (255);
      textSize(24);
      textAlign(CENTER);
      text ("GAME OVER", width/2, height/2-20);
      textSize(46);
      text (score, width/2, height/2+30);
      textSize(14);
      text ("click to try again", width/2, height/2+60);
    }
  }

  void updateScore() {
    textSize(20);
    fill(50, 70);
    text (score, width/2-5, height/2+150);
  }
}
class Platform {

  float x1;
  float y1;
  float x2;
  float y2;

  int platformNum;



  Platform(float tempX1, float tempY1, float tempX2, float tempY2, int tempPlatformNum) {

    x1 = tempX1;
    y1 = tempY1;
    x2 = tempX2;
    y2 = tempY2;
    platformNum = tempPlatformNum;
  }

  void display() {
    rectMode(CORNERS);
    fill (50);
    rect (x1, y1, x2, y2);
  }

//if the player lands on top of the platform
  void collisionCheck() {
    if (mainChar.position.y > y2-mainChar.pHeight/2  && mainChar.position.x > x1 - mainChar.pWidth/2 && mainChar.position.x < x2 + mainChar.pWidth/2 && mainChar.position.y < y1-mainChar.pHeight/2) {
      mainChar.position.y = y2-mainChar.pHeight/2;
      groundCheck[platformNum] = true;
      mainChar.velocity.y = 0;
      mainChar.acceleration.y = 0;
    } else if (mainChar.position.y < y2-mainChar.pHeight/2) { 
      groundCheck[platformNum] = false;
      grounded = false;
    } 
    if (mainChar.position.x+mainChar.pHeight/2 < x1 || mainChar.position.x-mainChar.pHeight/2 > x2) {
      groundCheck[platformNum] = false;
      grounded = false;
    }
    //ceiling check, if player bumps his head on the bottom of the platform
    if (mainChar.position.y > y2-mainChar.pHeight/2 && mainChar.position.y < y1+mainChar.pHeight/2 && mainChar.position.x > x1 +20 - mainChar.pWidth/2 && mainChar.position.x < x2 -20 + mainChar.pWidth/2) {
      mainChar.velocity.y = 0;
      mainChar.position.y = y1+mainChar.pHeight/2;
      //slows you down if you bump your head
      mainChar.velocity.x *= 0.8;    
    }
  }

  void sideCollisionCheck() {
    //if the player touches the side of a platform, stops their movement
    if (mainChar.position.y-mainChar.pHeight/2<y1 && mainChar.position.y+mainChar.pHeight/2>y2 && mainChar.position.x+15 > x1 && mainChar.position.x-15 < x2) {
      mainChar.velocity.x = 0;
      mainChar.acceleration.x = 0;
      //slows your fall
      mainChar.velocity.y *= 0.8;
      if (abs(mainChar.position.x+mainChar.pWidth/2- x2) > abs(mainChar.position.x-mainChar.pWidth/2- x1)) {
        mainChar.position.x = x1 - mainChar.pWidth/2;
      } else {
        mainChar.position.x = x2 +mainChar.pWidth/2 ;
      }
    }
  }
}
class Player {

  float pHeight = 30;
  float pWidth = 30;

  PVector position = new PVector(300, 120); //350
  PVector velocity = new PVector(0, 0);
  PVector acceleration = new PVector (0, 0);
  float airResistance =0.9;


  void update() {
    if (pDead == false) {
      //horizontal movement. has a terminal velocity cap
      if (playerRight == true) {
        acceleration.x = 0.3;
        if (velocity.x > 4) {
          acceleration.x = 0;
          velocity.x = 4;
        }
      }  
      if (playerLeft == true) {
        acceleration.x = -0.3;
        if (velocity.x < -4) {
          acceleration.x = 0;
          velocity.x = -4;
        }
      }  
      //when you hold down right and left, and let go of one, it should retain the movement of the (still held down) direction.
      if (playerLeft == true && playerRight == true) {
        if (lastHeldButton == 1) {
          acceleration.x = 0.5;
          if (velocity.x > 4) {
            acceleration.x = 0;
            velocity.x = 4;
          }
        } else if (lastHeldButton == 2) {
          acceleration.x = -0.5;
          if (velocity.x < -4) {
            acceleration.x = 0;
            velocity.x = -4;
          }
        }
      }

      //slows your speed (like friction) when you stop moving
      if (playerLeft == false &&  playerRight == false && grounded == true) {
        velocity.x *= 0.90;
        if (velocity.x < 0.01 && velocity.x > -0.01) {
          velocity.x = 0;
          acceleration.x = 0;
        }
      } 
      //limiting speed in the air
      if (playerLeft == false &&  playerRight == false && grounded == false) {
        if (velocity.x < -4) {
          velocity.x = -4;
          velocity.x *= 0.95;
        }
        if (velocity.x > 4) {
          velocity.x = 4;
          velocity.x *= 0.95;
        }
      }


      //Jumping
      if (playerUp == true & grounded == true) {
        velocity.y += -8.3;
      }

      //Out of bounds, fall to the top
      if (position.y > 400) {
        position.y = 0;
      }        
      if (position.y <0) {
        position.y = 400;
      }      

      acceleration.y += gravity;
      acceleration.mult(airResistance);
      velocity.add(acceleration);
      position.add(velocity);
    }
  }

  void display() {
    fill (150);
    rectMode(CENTER);
    rect (position.x, position.y, pHeight, pWidth);

    //gun
    fill ( 200);
    rectMode(CORNERS);
    if (facingRight == true) {
      rect (position.x + 15, position.y-5, position.x + 20, position.y+5);
    } else {
      rect (position.x - 15, position.y-5, position.x - 20, position.y+5);
    }
  }
}
class Spawner {

  int counter = -1;  
  int spawnRate = 100;

  Spawner() {
  }

  void display() {

    //all enemy objects, displayed all at once
    for (int i=0; i<enemyNum; i++) {
      e[i].update();
      e[i].display();
      e[i].playerCollision();

      //Spawning pad
      rectMode (CORNERS);
      fill(242, 58, 34);
      rect (250, 20, 350, 0);
    }
  }

  void updateCounter() {
    //spawn enemies faster as time goes on
    if (frameCount%spawnRate == 0) {
      counter+= 1;
      if (spawnRate > 10) {
        spawnRate -= 1;
      } else if (spawnRate < 10) {
        spawnRate = 10;
      }
    }
  }
}
class Wall {

  float x1;
  float y1;
  float x2;
  float y2;


  Wall(float tempX1, float tempY1, float tempX2, float tempY2) {

    x1 = tempX1;
    y1 = tempY1;
    x2 = tempX2;
    y2 = tempY2;
  }

  void display() {
    rectMode(CORNERS);
    fill (50);
    rect (x1, y1, x2, y2);
  }

//wall collision
  void sideCollisionCheck() {
    if ( mainChar.position.x+mainChar.pWidth/2 > x1 && mainChar.position.x-mainChar.pWidth/2 < x2 &&mainChar.position.y-mainChar.pHeight/2< y1 &&mainChar.position.y+mainChar.pHeight/2> y2 ) {
      mainChar.velocity.x = 0;
      mainChar.acceleration.x = 0;
      //determines which side of the wall you're on, and sets your position to the correct side
      if (abs(mainChar.position.x+mainChar.pWidth/2- x2) > abs(mainChar.position.x-mainChar.pWidth/2- x1)) {
        mainChar.position.x = x2 +mainChar.pWidth/2;
      } else {
        mainChar.position.x = x1 - mainChar.pWidth/2;
      }
    }
  }
}