I'd like to stop my shapes from being able to move so far left or right that they go off the screen, but my outOfBounds method which I've implemented in my KeyHandler is receiving this error:
1 error found: File: .../Tetris.java [line: 46] Error: The method outOfBounds(int, int) is undefined for the type package.Tetromino
Here are my classes
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class BigBang extends JComponent implements KeyListener, ActionListener {
Timer timer;
World world;
int score = 0;
JLabel statusbar = new JLabel("Score: " + score);
BigBang(int delay, World world) {
timer = new Timer(delay, this);
this.world = world;
JFrame frame = new JFrame("Tetris");
frame.add(statusbar, BorderLayout.SOUTH);
statusbar.setVisible(true);
frame.getContentPane().add(this );
frame.addKeyListener(this);
frame.setVisible(true);
frame.setSize(Tetris.COLUMNS * Block.SIZE + 27, Tetris.ROWS * Block.SIZE + 60);
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
public void start() {
timer.start();
}
BigBang(World world) {
this(1000, world);
}
public void paintComponent(Graphics g) {
world.draw(g);
}
public void actionPerformed(ActionEvent e) {
world.update();
if (world.hasEnded())
timer.stop();
this.repaint();
score += 5;
statusbar.setText("Score: " + score);
}
public void keyPressed(KeyEvent e) {
world.keyPressed(e);
this.repaint();
}
public void keyTyped(KeyEvent e) { }
public void keyReleased(KeyEvent e) { }
}
__
import java.awt.*;
class Block {
final static int SIZE = 20;
int x, y;
Color color;
Block(int x, int y, Color c) {
this.x = x;
this.y = y;
this.color = c;
}
void outOfBounds(int left, int right)
{
if (this.x > right)
this.x = right;
else if (this.x < left)
this.x = left;
}
void draw(Graphics g) {
int xp = this.x * SIZE,
yp = this.y * SIZE;
g.setColor(this.color);
g.fillRect(xp + 85, yp, SIZE, SIZE);
g.setColor(Color.BLACK);
g.drawRect(xp + 85, yp, SIZE, SIZE);
}
void move(int dx, int dy) {
this.x += dx;
this.y += dy;
}
public String toString() {
return "[" + this.x + ", " + this.y + "]";
}
void rotateCW(Point c) {
int newX, newY;
newX = c.x + c.y - this.y;
newY = c.y + this.x - c.x;
this.x = newX;
this.y = newY;
}
boolean equals(Block other) {
return this.x == other.x && this.y == other.y;
}
void setColor(Color c) {
this.color = c;
}
}
class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
void move(int dx, int dy) {
this.x += dx;
this.y += dy;
}
public String toString() {
return "(" + this.x + ", " + this.y + ")";
}
}
__
import java.awt.*;
import java.util.*;
class SetOfBlocks extends ArrayList<Block> {
void draw(Graphics g) {
for (Block b : this)
b.draw(g);
}
void move(int dx, int dy) {
for (Block b : this)
b.move(dx, dy);
}
void rotateCW(Point center) {
for (Block b : this)
b.rotateCW(center);
}
boolean contains(Block block) {
if (this.size() != 0)
for (Block b : this)
if (b.equals(block))
return true;
return false;
}
boolean subset(SetOfBlocks blocks) {
if (this.size() != 0)
for (Block b : this)
if (! blocks.contains(b))
return false;
return true;
}
boolean equals(SetOfBlocks blocks) {
return this.subset(blocks) && blocks.subset(this);
}
SetOfBlocks intersect(SetOfBlocks other) {
SetOfBlocks result = new SetOfBlocks();
for (Block b : this)
if (other.contains(b))
result.add(b);
return result;
}
SetOfBlocks union(SetOfBlocks other) {
SetOfBlocks result = new SetOfBlocks();
for (Block b : this)
if (! result.contains(b) )
result.add(b);
for (Block b : other)
if (! result.contains(b) )
result.add(b);
return result;
}
int count() {
return this.size();
}
int maxY() {
int result = 0;
for (Block b : this)
if (b.y > result)
result = b.y;
return result;
}
int minX() {
int result = Tetris.COLUMNS;
for (Block b : this)
if (b.x < result)
result = b.x;
return result;
}
int maxX() {
int result = 0;
for (Block b : this)
if (b.x > result)
result = b.x;
return result;
}
void changeColor(Color color) {
for (Block b : this)
b.setColor(color);
}
boolean overflow() {
for (Block b : this)
if (b.y <= 0)
return true;
return false;
}
SetOfBlocks row(int row) {
SetOfBlocks result = new SetOfBlocks();
for (Block b : this)
if (b.y == Tetris.ROWS - row)
result.add(b);
return result;
}
boolean fullRow(int row) {
int a = this.row(row).count();
int b = Tetris.COLUMNS;
// System.out.println( a + " vs " + b );
return a == b;
}
void eliminateRow(int i) { // i == 0 indicates bottom row
SetOfBlocks row = new SetOfBlocks();
for (Block b : this)
if (b.y == (Tetris.ROWS - i))
row.add(b);
for (Block b : row)
this.remove(b);
for (Block b : this)
if (b.y < (Tetris.ROWS - i))
b.move(0, 1);
}
void eliminateFullRows() {
for (int i = 0; i < Tetris.ROWS; ) {
if (this.fullRow(i)) {
// System.out.println("Eliminating: " + i);
this.eliminateRow(i);
} else i++;
}
}
}
__
import java.awt.*;
import java.awt.event.*;
class Tetris implements World {
static final int ROWS = 20;
static final int COLUMNS = 10;
Tetromino t;
SetOfBlocks blocks;
Tetris(Tetromino t, SetOfBlocks s) {
this.t = t;
this.blocks = s;
}
public void draw(Graphics g) {
t.draw(g);
blocks.draw(g);
g.drawRect(5, 0, Tetris.COLUMNS * Block.SIZE, Tetris.ROWS * Block.SIZE);
for (int i = 0; i < COLUMNS; i++)
g.drawLine((20*i) + 5, 400, (20*i) + 5, 0);
for (int i = 0; i < ROWS; i++)
g.drawLine(5, 20*i, 205, 20*i);
}
public void update() {
if (this.landed())
this.touchdown();
else
this.t.move(0, 1);
}
public boolean hasEnded() { return false; }
public void keyPressed(KeyEvent e) {
if (this.landed())
this.touchdown();
int keycode = e.getKeyCode();
switch (keycode) {
case KeyEvent.VK_LEFT:
{ this.t.move(-1, 0);
this.t.outOfBounds(0, 400);}
break;
case KeyEvent.VK_RIGHT:
{ this.t.move( 1, 0); }
break;
case KeyEvent.VK_DOWN:
{ this.t.move( 0, 1); }
break;
case 'r':
{ this.t.rotateCW(); }
break;
case KeyEvent.VK_SPACE:
{ this.jumpDown(); }
break;
}
}
public static void main(String[] args) {
BigBang game = new BigBang(new Tetris(Tetromino.sQuare(), new SetOfBlocks()));
game.start();
}
public void touchdown() {
this.blocks = this.blocks.union(this.t.blocks);
this.blocks.eliminateFullRows();
this.t = Tetromino.pickRandom();
}
void jumpDown() {
if (! this.landed()) {
this.t.move(0, 1);
this.jumpDown();
}
}
boolean landedOnBlocks() {
this.t.move(0, 1);
if (this.t.overlapsBlocks(this.blocks)) {
this.t.move(0, -1);
return true;
} else {
this.t.move(0, -1);
return false;
}
}
boolean landedOnFloor() {
return this.t.blocks.maxY() == Tetris.ROWS - 1;
}
boolean landed() {
return this.landedOnFloor() || this.landedOnBlocks();
}
}
__
class Tetromino {
static Tetromino sQuare() {
return new Tetromino(new Point(0, -1),
makeBlocks(new int[] {0, -1, 0, -2, 1, -1, 1, -2},
Color.GREEN ));
}
static Tetromino liNe() {
return new Tetromino(new Point(1, -1),
makeBlocks(new int[] {0, -1, 1, -1, 2, -1, 3, -1},
Color.BLUE ));
}
static Tetromino l() {
return new Tetromino(new Point(1, -1),
makeBlocks(new int[] {0, -1, 1, -1, 2, -1, 2, -2},
Color.MAGENTA ));
}
static Tetromino MirroredL() {
return new Tetromino(new Point(1, -1),
makeBlocks(new int[] {0, -1, 1, -1, 2, -1, 0, -2},
Color.CYAN ));
}
static Tetromino t() {
return new Tetromino(new Point(1, -1),
makeBlocks(new int[] {0, -1, 1, -1, 2, -1, 1, -2},
Color.ORANGE ));
}
static Tetromino s() {
return new Tetromino(new Point(1, -1),
makeBlocks(new int[] {0, -1, 1, -1, 1, -2, 2, -2},
Color.RED ));
}
static Tetromino z() {
return new Tetromino(new Point(1, -2),
makeBlocks(new int[] {0, -2, 1, -2, 1, -1, 2, -1},
Color.PINK ));
}
static SetOfBlocks makeBlocks(int[] c, Color color) {
SetOfBlocks a = new SetOfBlocks();
a.add(new Block( c[0], c[1], color));
a.add(new Block( c[2], c[3], color));
a.add(new Block( c[4], c[5], color));
a.add(new Block( c[6], c[7], color));
return a;
}
Point center;
SetOfBlocks blocks;
Tetromino(Point center, SetOfBlocks blocks) {
this.center = center;
this.blocks = blocks;
}
void draw(Graphics g) {
this.blocks.draw(g);
}
void move(int dx, int dy) {
this.center.move(dx, dy);
this.blocks.move(dx, dy);
}
public String toString() {
return this.center + " " + this.blocks ;
}
void rotateCW() {
this.blocks.rotateCW(this.center);
}
boolean overlapsBlocks(SetOfBlocks blocks) {
return this.blocks.intersect(blocks).count() > 0;
}
void changeColor(Color color) {
this.blocks.changeColor(color);
}
static Tetromino pickRandom() {
int value = (int)(Math.random() * 7);
if (value == 0) return Tetromino.sQuare();
else if (value == 1) return Tetromino.liNe();
else if (value == 2) return Tetromino.l();
else if (value == 3) return Tetromino.MirroredL();
else if (value == 4) return Tetromino.t();
else if (value == 5) return Tetromino.s();
else return Tetromino.z();
}
}
__
import java.awt.*;
import java.awt.event.*;
interface World {
public void draw(Graphics g);
public void update();
public boolean hasEnded();
public void keyPressed(KeyEvent e);
}
The error message is telling you the exact problem:
Your
outOfBounds(int,int)
method could not be found when you attempt to call it from yourKeyHandler
Here is the snippet of the case statement where you are trying to call it.
You are calling the method on your poorly named
t
variable (variable names should be descriptive and appears to part of the cause of your woes), which is a variable of typeTetromino
class. YourTetromino
class clearly does not have a method calledoutOfBounds(int, int)
defined. And hence the error.Your
outOfBounds(int, int)
is clearly defined on yourBlocks
class, but as aprivate
method, meaning only theBlocks
class its self can access it.