Spel: PONG

Pong: bewegende bat

In stap 2 hebben we ons alleen bezig gehouden met de bal: beweging en botsing. Maar om het spel te spelen moet je natuurlijk de ‘bats’ laten bewegen. Dit gaan we laten doen door ervoor te zorgen dat het spel ‘luistert’ naar toetsen op het toetsenbord. Er is voor gekozen om de knoppen ‘w’ en ‘s’ te gebruiken om de linker-bat naar boven en beneden te bewegen. De pijltjes toetsen boven en onder zijn gekozen om de rechter-bat te laten bewegen.

Processing heeft voor het bekijken of een toets is ingedrukt een functie gemaakt die wij kunnen gebruiken: function keyPressed(). Binnen deze functie kan je controleren welke toets er is ingedrukt. Dat doe je als volgt:

//globale variabele
var ball_radius = 30; //radius of the ball
var ballX = 0; //x-coordinate of the ball
var ballY = 0; //y-coordinate of the ball
var ballSpeed = 10; //speed of the ball
var directionX = 0; //x direction of the ball
var directionY = 0; //y direction of the ball
var alpha = 0; //the corner of the triangle made from the directionX and directionY variable
var deltaX = 0; //the amount of pixels in x direction moved per step
var deltaY = 0; //the amount of pixels in y direction moved per step
var bat1X = 20; //x-coordinate of left bat
var bat1Y = 280; //y-coordinate of left bat
var bat2X = 760; //x-coordinate of right bat
var bat2Y = 280; //y-coordinate of right bat
var bat_width = 20; //width of a bat
var bat_height = 40; //height of a bat


// setup() function, everything to setup the game
function setup() {
	let myCanvas = createCanvas(800, 400); // maak deze 800 (breedte) bij 600 (hoogte)
	ballX = 400; //set the x-coordinate for the start position of the ball
	ballY = 300; //set the y-coordinate for the start position of the ball
	directionX = Math.random()*2-1; //Math.random() gets number between 0 and 1,
           //by multiplying with 2 and subtracting 1 it becomes a number between -1 and 1
	directionY = Math.random()*2-1;
} 

// draw() function (repeatedly called), where to draw what
function draw() {
	background(0, 0, 0); //make background black

	fill(255,255,255); //from this line onward draw everything in white
	rect(bat1X, bat1Y, bat_width, bat_height); //draw left bat
	rect(bat2X, bat2Y, bat_width, bat_height); //draw right bat
	ellipse(ballX, ballY, ball_radius, ball_radius); //draw ball
	alpha = Math.atan(directionY/directionX); //calculate direction
	deltaY = ballSpeed*Math.sin(alpha); //change in y-coordinate according to direction
	deltaX = ballSpeed*Math.cos(alpha); //change in x-coordinate according to direction
	if(directionX < 0) //if direction is negative (ball moves down left)
	{
		ballX -= deltaX; //x-coordinate has to decrease
	}
	else //direction is positive (ball moves right)
	{
		ballX += deltaX; //x-coordinate has t increase
	}
	ballY += deltaY; //increase the y-coordinate (deltaY can be negative so ball goes
                     //both up and down)
	//collision detection
	//ball collides with top and bottom of screen
	if(ballY - (0.5 * ball_radius) < 0) //top: center of ball minus half radius < 0
		directionY *= -1;
	if(ballY + (0.5 * ball_radius) > 600) //bottom: center of ball plus half radius > 600
		directionY *= -1;
	textSize(30); //choose the size of the text
	text("Points: 0", 100 ,30); //draw the score for the left player
	text("Points: 0", 600, 30); //draw the score for the right player
              //(600 = 800 – 200 not the 600 from the size of the window)
}

//called when a key on the keyboard is pressed
function keyPressed()
{
	if(key == 'w') //if w is pressed move left bat up
	{
		bat1Y -= 5;
	}
}

De code is vrijwel hetzelfde als bij stap 2 met het verschil nu dat er een aantal variabele weer vast gedefinieerd zijn zodat ze makkelijk aan te passen zijn. Deze variabele zijn de x-, y-coördinaten, hoogte en breedte van de bats. Deze zijn toegepast bij het tekenen van de bats in regel 34 en 35. Verder is er de functie keyPressed() aan toegevoegd om te kijken of een toets is ingedrukt (regels 63-69). Als je deze code draait kan je met de w-toets de linker bat omhoog bewegen.

Opdrachten:

  1. Zorg dat je met de s-knop de linker bat omlaag beweegt.
  2. Zorg ervoor dat je met de pijltjestoets omhoog en omlaag de rechter bat beweegt.

Zoals je ziet beweegt de bat op de manier hierboven niet heel erg soepel (of maar 1 keer). Dit komt door de manier waarop de processing werkt. Als er een toets wordt ingedrukt zet processing ergens in het geheugen welke toets ingedrukt is. Dan wordt er elke keer gekeken of die toets nog steeds ingedrukt is. Dit zorgt ervoor dat het er schokkerig uitziet. Dit kan op een slimme manier opgelost worden. Hierboven hebben we het verplaatsen in de keyPressed() functie geplaatst. Naast deze keyPressed() functie is er ook een keyReleased() functie. Deze functie wordt uitgevoerd als, zoals de naam zegt, een toets wordt lasgelaten. Als er nu aan het begin een variabele wordt gedefinieerd die van waarde veranderd als de toets wordt ingedrukt en weer terug veranderd als die wordt losgelaten kunnen we in de draw functie de verplaatsing van de bat plaatsen. Er is dus nu een extra variabele (bv var keyW = false) nodig die veranderd wordt in de functie keyPressed() en keyReleased(). De code wordt dan:

// De volgende code is nodig om in het htmldocument alleen het canvas op
// de toetsen "Space","ArrowUp","ArrowDown","ArrowLeft","ArrowRight" te laten
// reageren
window.addEventListener("keydown", function(e) {
    if(["Space","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].indexOf(e.code) > -1) {
        e.preventDefault();
    }
}, false);

//globale variabele
var ball_radius = 30; //radius of the ball
var ballX = 0; //x-coordinate of the ball
var ballY = 0; //y-coordinate of the ball
var ballSpeed = 10; //speed of the ball
var directionX = 0; //x direction of the ball
var directionY = 0; //y direction of the ball
var alpha = 0; //the corner of the triangle made from the directionX and directionY variable
var deltaX = 0; //the amount of pixels in x direction moved per step
var deltaY = 0; //the amount of pixels in y direction moved per step
var bat1X = 20; //x-coordinate of left bat
var bat1Y = 280; //y-coordinate of left bat
var bat2X = 760; //x-coordinate of right bat
var bat2Y = 280; //y-coordinate of right bat
var bat_width = 20; //width of a bat
var bat_height = 40; //height of a bat
var bat1Speed = 10; //speed of the right bat
var keyW = false; //w key is not pressed


// setup() function, everything to setup the game
function setup() {
	let myCanvas = createCanvas(800, 600); // maak deze 800 (breedte) bij 600 (hoogte)
	ballX = 400; //set the x-coordinate for the start position of the ball
	ballY = 300; //set the y-coordinate for the start position of the ball
	directionX = Math.random()*2-1; //Math.random() gets number between 0 and 1, by multiplying with 2 and subtracting 1 it becomes a number between -1 and 1
	directionY = Math.random()*2-1;
} 

// draw() function (repeatedly called), where to draw what
function draw() {
	background(0, 0, 0); //make background black

	fill(255,255,255); //from this line onward draw everything in white
	rect(bat1X, bat1Y, bat_width, bat_height); //draw left bat
	rect(bat2X, bat2Y, bat_width, bat_height); //draw right bat
	ellipse(ballX, ballY, ball_radius, ball_radius); //draw ball
	
	//move the bats
	if(keyW && bat1Y > 0) //if key w is pressed (than variable keyW equals true) and the bat is inside the screen move it up
	{
		bat1Y -= bat1Speed;
	}
	
	alpha = Math.atan(directionY/directionX); //calculate direction
	deltaY = ballSpeed*Math.sin(alpha); //change in y-coordinate according to direction
	deltaX = ballSpeed*Math.cos(alpha); //change in x-coordinate according to direction
	if(directionX < 0) //if direction is negative (ball moves down left)
	{
		ballX -= deltaX; //x-coordinate has to decrease
	}
	else //direction is positive (ball moves right)
	{
		ballX += deltaX; //x-coordinate has t increase
	}
	ballY += deltaY; //increase the y-coordinate (deltaY can be negative so ball goes both up and down)
	//collision detection
	//ball collides with top and bottom of screen
	if(ballY - (0.5 * ball_radius) < 0) //top: center of ball minus half radius < 0
		directionY *= -1;
	if(ballY + (0.5 * ball_radius) > 600) //bottom: center of ball plus half radius > 600
		directionY *= -1;
	textSize(30); //choose the size of the text
	text("Points: 0", 100 ,30); //draw the score for the left player
	text("Points: 0", 600, 30); //draw the score for the right player (600 = 800 – 200 not the 600 from the size of the window)
}

//called when a key on the keyboard is pressed
function keyPressed()
{
	if(key == 'w') //if w is pressed set variable to true so it will move
	{
		keyW = true;
	}
}

//called when a key on the keyboard is released
function keyReleased()
{
	if(key == 'w') //if w is released set variable to false so it will not move
	{
		keyW = false;
	}
}

Als je deze code uitvoert merk je dat de bat een stuk soepeler beweegt.

Opdrachten:

  1. Zorg dat je deze verandering voor alle andere toetsen ook doorvoert (toets s, pijl omhoog en pijl omlaag)