mirror of
https://github.com/usatiuk/nand2tetris.git
synced 2025-10-28 16:17:48 +01:00
224 lines
6.2 KiB
Plaintext
224 lines
6.2 KiB
Plaintext
class Game {
|
|
field int hbricks, vbricks;
|
|
field int gameOver;
|
|
|
|
field Rect paddle;
|
|
field Ball ball;
|
|
field Array bricks;
|
|
|
|
constructor Game new() {
|
|
var int i, j;
|
|
var Rect curBrick;
|
|
|
|
let gameOver = 0;
|
|
let hbricks = 8;
|
|
let vbricks = 3;
|
|
|
|
let paddle = Rect.new(250,220,50,10);
|
|
let ball = Ball.new(250, 200, 6, 1, 1);
|
|
let bricks = Array.new(hbricks * vbricks);
|
|
|
|
while (i < hbricks) {
|
|
while (j < vbricks) {
|
|
let bricks[i * 3 + j] = Rect.new(i * 60 + 20, j * 30 + 20, 50, 15);
|
|
let curBrick = bricks[i * 3 + j];
|
|
do curBrick.draw();
|
|
let j = j + 1;
|
|
}
|
|
let j = 0;
|
|
let i = i + 1;
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
method void loop() {
|
|
var int keyPressed;
|
|
|
|
while(true) {
|
|
// Approximately 60 updates per second
|
|
do Sys.wait(16);
|
|
|
|
if (gameOver = 0) {
|
|
do movePaddle();
|
|
do ball.update();
|
|
do chackBallPaddleCol();
|
|
do checkBallBricksCol();
|
|
|
|
do checkGameOver();
|
|
} else {
|
|
let keyPressed = Keyboard.keyPressed();
|
|
if (keyPressed = 82) {
|
|
do resetGame();
|
|
}
|
|
}
|
|
|
|
}
|
|
return;
|
|
}
|
|
|
|
method void resetGame() {
|
|
var int i, end;
|
|
var Rect brick;
|
|
|
|
do Screen.clearScreen();
|
|
|
|
do paddle.setPos(250, 220);
|
|
do ball.setPos(250, 200);
|
|
do ball.setSpeed(1, 1);
|
|
|
|
let end = hbricks * vbricks;
|
|
while (i < end) {
|
|
let brick = bricks[i];
|
|
|
|
do brick.setHidden(0);
|
|
do brick.draw();
|
|
|
|
let i = i + 1;
|
|
}
|
|
|
|
let gameOver = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
method void checkGameOver() {
|
|
var int bBottom;
|
|
|
|
let bBottom = ball.getBottom();
|
|
|
|
if (bBottom > 240) {
|
|
let gameOver = 1;
|
|
|
|
do Output.moveCursor(0,0);
|
|
do Output.println();
|
|
do Output.printString("game over");
|
|
do Output.println();
|
|
do Output.printString("press r to restart");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
method void movePaddle() {
|
|
var int keyPressed, paddleLeft, paddleRight;
|
|
|
|
let keyPressed = Keyboard.keyPressed();
|
|
let paddleLeft = paddle.getLeft();
|
|
let paddleRight = paddle.getRight();
|
|
// Move left
|
|
if((keyPressed = 130) & (paddleLeft > 0)) {
|
|
do paddle.moveLeft(2);
|
|
}
|
|
// Move right
|
|
if((keyPressed = 132) & (paddleRight < 510)) {
|
|
do paddle.moveRight(2);
|
|
}
|
|
do paddle.draw();
|
|
|
|
return;
|
|
}
|
|
|
|
method void chackBallPaddleCol() {
|
|
var int paddleLeft, paddleRight, paddleTop, paddleBottom, paddleMiddle;
|
|
var int bLeft, bRight, bTop, bBottom, bMiddle, bVspeed;
|
|
|
|
let paddleLeft = paddle.getLeft();
|
|
let paddleRight = paddle.getRight();
|
|
let paddleTop = paddle.getTop();
|
|
let paddleBottom = paddle.getBottom();
|
|
let paddleMiddle = (paddleRight + paddleLeft) / 2;
|
|
|
|
let bLeft = ball.getLeft();
|
|
let bRight = ball.getRight();
|
|
let bTop = ball.getTop();
|
|
let bBottom = ball.getBottom();
|
|
let bMiddle = (bRight + bLeft) / 2;
|
|
let bVspeed = ball.getVspeed();
|
|
|
|
if((bLeft > paddleLeft) & (bRight < paddleRight)) {
|
|
if((bBottom > paddleTop) & (bVspeed > 0)) {
|
|
if (bMiddle > paddleMiddle) {
|
|
do ball.setSpeed(1, -1);
|
|
} else {
|
|
do ball.setSpeed(-1, -1);
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
method void checkBallBricksCol() {
|
|
var int brLeft, brRight, brTop, brBottom, brHidden;
|
|
var int bLeft, bRight, bTop, bBottom, bVspeed;
|
|
var int overlapLeft, overlapRight, overlapTop, overlapBottom, fromLeft, fromTop;
|
|
var int minOverlapX, minOverlapY;
|
|
var int i, end;
|
|
var Rect brick;
|
|
|
|
let bLeft = ball.getLeft();
|
|
let bRight = ball.getRight();
|
|
let bTop = ball.getTop();
|
|
let bBottom = ball.getBottom();
|
|
let bVspeed = ball.getVspeed();
|
|
|
|
let end = hbricks * vbricks;
|
|
while (i < end) {
|
|
let brick = bricks[i];
|
|
|
|
let brLeft = brick.getLeft();
|
|
let brRight = brick.getRight();
|
|
let brTop = brick.getTop();
|
|
let brBottom = brick.getBottom();
|
|
let brHidden = brick.getHidden();
|
|
|
|
if(brHidden < 1) {
|
|
do brick.draw();
|
|
|
|
// Check if there's intersection at all first
|
|
if((bLeft > brLeft) & (bRight < brRight)) {
|
|
if((bBottom > brTop) & (bTop < brBottom)) {
|
|
do brick.setHidden(1);
|
|
do brick.draw();
|
|
|
|
// Now calculate the collision side
|
|
// Algorithm basically copied from this video
|
|
// https://youtu.be/_4K3tsKa1Uc?t=1820
|
|
|
|
let overlapLeft = bRight - brLeft;
|
|
let overlapRight = brRight - bLeft;
|
|
let overlapTop = bBottom - brTop;
|
|
let overlapBottom = brBottom - bTop;
|
|
|
|
if(Util.abs(overlapLeft) < Util.abs(overlapRight)) {
|
|
let fromLeft = 1;
|
|
let minOverlapX = overlapLeft;
|
|
} else {
|
|
let minOverlapX = overlapRight;
|
|
}
|
|
|
|
if(Util.abs(overlapTop) < Util.abs(overlapBottom)) {
|
|
let fromTop = 1;
|
|
let minOverlapY = overlapTop;
|
|
} else {
|
|
let minOverlapY = overlapBottom;
|
|
}
|
|
|
|
if(Util.abs(minOverlapX) < Util.abs(minOverlapY)) {
|
|
do ball.invertHspeed();
|
|
} else {
|
|
do ball.invertVspeed();
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
let i = i + 1;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
} |