Flappy Pong in p5.js (deel 2)

Flappy Pong bouwen

=Deze post is een Google translate vertaling van het Engels naar het Nederlands, en van Java/Processing naar JavaScript/p5.js. Het originele artikel vindt je hier: https://www.toptal.com/game/ultimate-guide-to-processing-simple-game

Dit is het vervolg van deel 1

Floppy Pong in p5.js (deel 1)

Stap # 3: Het racket maken

Nu de bal klaar is hebben we een racket nodig, deze moeten we tekenen en kunnen besturen (met de muis). Dus we beginnen met het maken van een aantal variablen en een functie om het racket te tekenen. Hier is de code:

...

var racketBreedte = 100;
var racketHoogte = 10;

...

function gameScherm() {
{
  ...
  tekenRacket();
}
....

function tekenRacket(){
  fill(255,0,100);
  rectMode(CENTER);
  rect(mouseX, mouseY, racketBreedte, racketHoogte);
}

We definieerden de kleur, breedte en hoogte van het racket als een globale variabele, we zouden willen dat ze tijdens het spelen van het spel zouden veranderen. We hebben een methode geïmplementeerd tekenRacket() die doet wat de naam doet vermoeden. We zetten de rectMode naar CENTER, dus het racket is uitgelijnd met het midden van onze cursor.

...


function gameScherm() {
  // code voor het game scherm
  background(255);
  
  var pBalY = balY;
  
  ....

  // controleer of de bal in X-richting op het racket valt 
  if ( (balX > mouseX-(racketBreedte/2)) && 
       (balX < mouseX+(racketBreedte/2))) {
    
    var pTopRacket = pmouseY - racketHoogte / 2;
    var topRacket = mouseY - racketHoogte / 2;
    
    // controleer of de bal van boven (in Y richting) op het racket valt
    if ( pTopRacket >= (pBalY + balStraal ) ) {    
      if ( topRacket < (balY + balStraal ) ) {

        // versnel de bal als het racket beweegt
        var verschil = pmouseY - mouseY;
        verticaleBalSnelheid = verticaleBalSnelheid + verschil;      
        
    		// set bal precies op de rand van het racket
      	balY = topRacket - balStraal;      

        // richting bal omdraaien
    		verticaleBalSnelheid = verticaleBalSnelheid * -1;

    		// verlaag snelheid door stuiter
    		verticaleBalSnelheid = verticaleBalSnelheid - stuiterWeerstand * verticaleBalSnelheid;       
    	}
    }
  }  
  

  tekenBal();
  tekenRacket();
}

 

En hier is het resultaat:

Nu we het racket hebben gemaakt, moeten we ervoor zorgen dat de bal stuitert op het racket. We willen alleen de bal laten stuiteren als de bal vanaf de bovenkant op het racket komt. Er zijn dus twee dingen die we moeten controleren of dit waar is.

Om te controleren of de bal het racket raakt, gaan we als eerst controleren of de X positie van de bal het racket kan raken.

 

In regel 13/14 wordt gecontroleerd of de balX positie groter is dan (mouseX – racketBreedte/2) EN DAT (de && ) balX kleiner is dan mouseX + racketBreedte/2.

Als niet aan beide voorwaarden is voldaan weten we dat de bal niet het racket raakt, dus d in dat geval hoeven we niets te doen (we gaab verder naar regel 38), Wordt aan beide voorwaarden voldaan, dan kunnen we verder gaan kijken of de bal vanaf de bovenkant het racket raakt (we gaan verder op regel 15).

Om te controleren of de bal van boven komt en dat bal het racket heeft geraakt in vertical richting is nog best lastig. Het probleem is dat de bal beweegt in vertical richting en dat het racket ook kan bewegen in vertical richting. Dus ook hier moeten we meerdere dingen gaan bekijken of de bal het racket raakt vanaf de bovenkant.

Om de vorige balY positie te weten, gaan we aan het begin van de gameScherm() functie de oude balY positie bewaren door deze waarde op de slaan in een nieuwe variable pBalY (regel 8 in bvenstaande code). Gelukkig bewaart p5.js de vorige (verticale) muis positie, deze is opglagen in pmouseY.

Let goed op de kleine verschillen tussen het vorige frame en het nieuwe frame, let ook op dat de Y van boven naar onderen loopt, dus de onderkant van de bal (=balY + balStraal) is groter dan onderkant van de bal (=balY – balStraal)!.

In regel 16 en 17 wordt de bovenkant van het racket uitgerekend voor de vorige mouse positie en de nieuwe muis positie.

In regel 20 wordt gekeken of de vorige situatie juist is, dus is de bovenkant van de oude racket positie onder of gelijk aan de onderkant van de vorige bal positie,

In regel 21 wordt gekeken of de nieuwe situatie juist is, dus is de bovenkant van de nieuwe racket positie boven de onderkant van de nieuwe bal positie.

Als de bal de racket van boven raakt moet de bal gaan stuiteren, eigenlijk moet er precies hetzelfde als de bal op de grond raakt, dit gebeurt in regel 27-34.

We doen nog een extra trucje in regel 24 en 25, we versnellen de bal als het het racket naar boven is bewogen. Hoe meer  de muis verplaatst is tussen de vorige en nieuw situatie hoe meer we de bal willen versnellen. Het verschil kunnnen we eenvoudig uitrekenen door het verschil uit te rekeken ( = pmouseY – mouseY).

Voor de volledigheid, hier de code tot nu toe:

/********* VARIABELEN *********/

// Variable welke bepaalt wel scherm er getoond
// moet worden
//
// 0: startScherm
// 1: gameScherm
// 2: gameOverScherm

var welkScherm = 0;

var balX;
var balY;
var balStraal=6;

var zwaarteKracht = 0.1;
var verticaleBalSnelheid = -10;

var stuiterWeerstand = 0.1;
var luchtWeerstand =  0.001;

var racketBreedte = 100;
var racketHoogte = 10;

var horizontaleBalSnelheid = 4;

/********* SETUP FUNCTIE *********/

function setup() {
  createCanvas(500, 500);
  balX=200;
  balY=100;  
}


/********* DRAW FUNCTIE *********/

function draw() {
  // Bepaal welk scherm getekend moet worden
  if (welkScherm == 0) {
    startScherm();
  } else if (welkScherm == 1) {
    gameScherm();
  } else if (welkScherm == 2) {
    gameOverScherm();
  }
}


/********* De verschillende schermen *********/

function startScherm() {
  // code voor start scherm
  background(0);
  fill(255);
  textSize(32);
  textAlign(CENTER);
  text("Klik om te starten", height/2, width/2);
}

function gameScherm() {
  // code voor het game scherm
  background(255);
  
  var pBalY = balY;
  
  
  balX = balX + horizontaleBalSnelheid;
  if ( balX < balStraal ) {
    balX = balStraal;
    horizontaleBalSnelheid = -1 * horizontaleBalSnelheid;
  }
  if ( balX > (width - balStraal) ) {
    balX = (width - balStraal);
    horizontaleBalSnelheid = -1 * horizontaleBalSnelheid;
  }
  
  // bereken de nieuwe snelheid 
  verticaleBalSnelheid = verticaleBalSnelheid + zwaarteKracht;
   
  // Invloed van de luchtweerstand
  verticaleBalSnelheid = verticaleBalSnelheid - luchtWeerstand * verticaleBalSnelheid;  
  
  // bereken de Y positie van de bal op basis van de vertical bal snelheid
  balY = balY + verticaleBalSnelheid;
  
  // stuiter als de bal de onderkant raakt
  if ( balY  > ( height - balStraal ) ) {
    // set bal precies op de rand
    balY = height - balStraal;
    // richting bal omdraaien
    verticaleBalSnelheid = verticaleBalSnelheid * -1;
    
    // verlaag snelheid door stuiter
    verticaleBalSnelheid = verticaleBalSnelheid - stuiterWeerstand * verticaleBalSnelheid;
  }
  
  // stuiter als de bal de onderkant raakt
  if ( balY  <  balStraal ) {
    // set bal precies op de rand
    balY = balStraal;

    // richting bal omdraaien
    verticaleBalSnelheid = verticaleBalSnelheid * -1;

    // verlaag snelheid door stuiter
    verticaleBalSnelheid = verticaleBalSnelheid - stuiterWeerstand * verticaleBalSnelheid;
  }

  // controleer of de bal in X-richting op het racket valt 
  if ( (balX  > mouseX-(racketBreedte/2)) && 
       (balX  < mouseX+(racketBreedte/2))) {
    
    var pTopRacket = pmouseY - racketHoogte / 2;
    var topRacket = mouseY - racketHoogte / 2;
    
    // controleer of de bal van boven (in Y richting) op het racket valt
    if ( pTopRacket >= (pBalY + balStraal ) ) {    
      if ( topRacket < (balY + balStraal ) ) {

        // versnel de bal als het racket beweegt
        var verschil = pmouseY - mouseY;
        verticaleBalSnelheid = verticaleBalSnelheid + verschil;      
        horizontaleBalSnelheid = (balX - mouseX)/10;
        
    		// set bal precies op de rand van het racket
      	balY = topRacket - balStraal;      

        // richting bal omdraaien
    		verticaleBalSnelheid = verticaleBalSnelheid * -1;

    		// verlaag snelheid door stuiter
    		verticaleBalSnelheid = verticaleBalSnelheid - stuiterWeerstand * verticaleBalSnelheid;       
    	}
    }
  }  
  
  tekenBal();
  tekenRacket();
}

function gameOverScherm() {
  // code voor het game over scherm
  background(255);
}


/********* INVOER *********/

function mousePressed() {
  // als we in het start scherm getoond wordt en de muis knop wordt ingedrukt,
  // dan laten we het startScherm zien
  if (welkScherm==0) {
    startGame();
  }
}


/********* HULP FUNCTIES *********/

// Functie die wordt uitgevoerd als het spelletje moet beginnnen 
function startGame() {
  welkScherm=1;
}

function tekenBal() {
  fill(0);
  ellipse(balX, balY, balStraal * 2);
}

function tekenRacket(){
  fill(255,0,100);
  rectMode(CENTER);
  rect(mouseX, mouseY, racketBreedte, racketHoogte);
}

 

Stap # 4: Horizontaal bewegen en de bal bedienen

In dit gedeelte laten de de bal ook horizontaal bewegen.

...
var horizontaleBalSnelheid = 4;

...

function gameScherm() {
  ...
  balX = balX + horizontaleBalSnelheid;
  if ( balX < balStraal ) {
    balX = balStraal;
    horizontaleBalSnelheid = -1 * horizontaleBalSnelheid;
  }
  if ( balX > (width - balStraal) ) {
    balX = (width - balStraal);
    horizontaleBalSnelheid = -1 * horizontaleBalSnelheid;
  }	
  ...
  
    // controleer of de bal van boven (in Y richting) op het racket valt
    if ( pTopRacket >= (pBalY + balStraal ) ) {    
      if ( topRacket < (balY + balStraal ) ) {

        ...   
        
        horizontaleBalSnelheid = (balX - mouseX)/10;	
    ...
      }
  
}

Het idee hier is hetzelfde als wat we deden voor verticale verplaatsing. We maken als eerste een horizontale snelheid variabele horizontaleBalSnelheid aan (regel 2).

In de gameScherm functie berekenen we de nieuwe X-positie op basis van de horizontaleBalSnelheid (regel 8), daarna controleren we of de X positie van de bal binnen de muren blijft. Als balX kleiner is dan  balStraal (regel 9), dan moet de bal gaan stuiteren. En aan de rechter kant van het scherm, dus als balX groter is dan de scherm breedte in de straal van de bal (regel 13) dan moet de bal gaan stuiteren.

Nu we de horizontale snelheid aan het spel hebben toegevoegd, willen we de bal besturen met het racket. Net als in het beroemde Atari-spel Breakout en in alle andere break-out spellen, moet de bal naar links of rechts gaan op basis van het punt op het racket dat hij raakt. Aan de randen van het racket krijgt de bal meer horizontal snelheid.

Dus we kunnen de horizontale snelheid aanpassen door te kijken naar het verschil tussen balX en het midden van het racket (mouseX). Dit wordt berekent in regel 25.

Als we de snelheid gelijk maken aan het vershil dan wordt de snelheid aan de randen veel te groot, daarom wordt het verschil gedeeld door 10 (/10). Deze waarde hebben we bepaalt door een paar waarden te proberen. Je kunt zelf kijken wat er gebeurt als je de waarde aanpast naar een groter of kleiner getal.

Het resultaat tot nu toe:

;

 

/********* VARIABELEN *********/

// Variable welke bepaalt wel scherm er getoond
// moet worden
//
// 0: startScherm
// 1: gameScherm
// 2: gameOverScherm

var welkScherm = 0;

var balX;
var balY;
var balStraal=6;

var zwaarteKracht = 0.1;
var verticaleBalSnelheid = -10;

var stuiterWeerstand = 0.1;
var luchtWeerstand =  0.001;

var racketBreedte = 100;
var racketHoogte = 10;

var horizontaleBalSnelheid = 4;

/********* SETUP FUNCTIE *********/

function setup() {
  createCanvas(500, 500);
  balX=200;
  balY=100;  
}


/********* DRAW FUNCTIE *********/

function draw() {
  // Bepaal welk scherm getekend moet worden
  if (welkScherm == 0) {
    startScherm();
  } else if (welkScherm == 1) {
    gameScherm();
  } else if (welkScherm == 2) {
    gameOverScherm();
  }
}


/********* De verschillende schermen *********/

function startScherm() {
  // code voor start scherm
  background(0);
  fill(255);
  textSize(32);
  textAlign(CENTER);
  text("Klik om te starten", height/2, width/2);
}

function gameScherm() {
  // code voor het game scherm
  background(255);
  
  var pBalY = balY;
  
  
  balX = balX + horizontaleBalSnelheid;
  if ( balX < balStraal ) {
    balX = balStraal;
    horizontaleBalSnelheid = -1 * horizontaleBalSnelheid;
  }
  if ( balX > (width - balStraal) ) {
    balX = (width - balStraal);
    horizontaleBalSnelheid = -1 * horizontaleBalSnelheid;
  }
  
  // bereken de nieuwe snelheid 
  verticaleBalSnelheid = verticaleBalSnelheid + zwaarteKracht;
   
  // Invloed van de luchtweerstand
  verticaleBalSnelheid = verticaleBalSnelheid - luchtWeerstand * verticaleBalSnelheid;  
  
  // bereken de Y positie van de bal op basis van de vertical bal snelheid
  balY = balY + verticaleBalSnelheid;
  
  // stuiter als de bal de onderkant raakt
  if ( balY  > ( height - balStraal ) ) {
    // set bal precies op de rand
    balY = height - balStraal;
    // richting bal omdraaien
    verticaleBalSnelheid = verticaleBalSnelheid * -1;
    
    // verlaag snelheid door stuiter
    verticaleBalSnelheid = verticaleBalSnelheid - stuiterWeerstand * verticaleBalSnelheid;
  }
  
  // stuiter als de bal de onderkant raakt
  if ( balY  <  balStraal ) {
    // set bal precies op de rand
    balY = balStraal;

    // richting bal omdraaien
    verticaleBalSnelheid = verticaleBalSnelheid * -1;

    // verlaag snelheid door stuiter
    verticaleBalSnelheid = verticaleBalSnelheid - stuiterWeerstand * verticaleBalSnelheid;
  }

  // controleer of de bal in X-richting op het racket valt 
  if ( (balX  > mouseX-(racketBreedte/2)) && 
       (balX  < mouseX+(racketBreedte/2))) {
    
    var pTopRacket = pmouseY - racketHoogte / 2;
    var topRacket = mouseY - racketHoogte / 2;
    
    // controleer of de bal van boven (in Y richting) op het racket valt
    if ( pTopRacket >= (pBalY + balStraal ) ) {    
      if ( topRacket < (balY + balStraal ) ) {

        // versnel de bal als het racket beweegt
        var verschil = pmouseY - mouseY;
        verticaleBalSnelheid = verticaleBalSnelheid + verschil;      
        horizontaleBalSnelheid = (balX - mouseX)/10;
        
    		// set bal precies op de rand van het racket
      	balY = topRacket - balStraal;      

        // richting bal omdraaien
    		verticaleBalSnelheid = verticaleBalSnelheid * -1;

    		// verlaag snelheid door stuiter
    		verticaleBalSnelheid = verticaleBalSnelheid - stuiterWeerstand * verticaleBalSnelheid;       
    	}
    }
  }  
  
  tekenBal();
  tekenRacket();
}

function gameOverScherm() {
  // code voor het game over scherm
  background(255);
}


/********* INVOER *********/

function mousePressed() {
  // als we in het start scherm getoond wordt en de muis knop wordt ingedrukt,
  // dan laten we het startScherm zien
  if (welkScherm==0) {
    startGame();
  }
}


/********* HULP FUNCTIES *********/

// Functie die wordt uitgevoerd als het spelletje moet beginnnen 
function startGame() {
  welkScherm=1;
}

function tekenBal() {
  fill(0);
  ellipse(balX, balY, balStraal * 2);
}

function tekenRacket(){
  fill(255,0,100);
  rectMode(CENTER);
  rect(mouseX, mouseY, racketBreedte, racketHoogte);
}

Stay tuned voor deel 3

 

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *