import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.Random; import static java.awt.event.KeyEvent.*; public class Tiles extends JPanel implements KeyListener { static final int tilesPerRow = 8, tilesPerColumn = 6; static final int ballDiameter = 20; static final Color ballColor = Color.BLACK; static Random rand = new Random(); double speedX = 0, speedY = 0; double posX = 20, posY = 20; // position of the ball Color[][] tileMap; int tileWidth, tileHeight, tileMapWidth, tileMapHeight; public static void main(String[] args) throws Exception { JFrame frame = new JFrame(); Tiles panel = new Tiles(); panel.setPreferredSize(new Dimension(800, 600)); frame.addKeyListener(panel); frame.add(panel); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); panel.run(); } public Tiles() { tileMap = new Color[20][20]; for(int y = 0; y < tileMap.length; y++) { for(int x = 0; x < tileMap[0].length; x++) { tileMap[y][x] = new Color(rand.nextInt(0xFFFFFF)); } } } public void run() throws Exception { tileWidth = getWidth()/tilesPerRow; tileHeight = getHeight()/tilesPerColumn; tileMapWidth = tileMap[0].length*tileWidth; tileMapHeight = tileMap.length*tileHeight; while(true) { posX += speedX; posY += speedY; if(posX < 0) posX = 0; if(posY < 0) posY = 0; if(posX > tileMapWidth) posX = tileMapWidth; if(posY > tileMapHeight) posY = tileMapHeight; Thread.sleep(16); repaint(); } } public void keyPressed(KeyEvent e) { switch(e.getKeyCode()) { case VK_LEFT: speedX = -5; break; case VK_RIGHT: speedX = 5; break; case VK_UP: speedY = -5; break; case VK_DOWN: speedY = 5; break; } } public void keyReleased(KeyEvent e) { switch(e.getKeyCode()) { case VK_LEFT: if(speedX < 0) speedX = 0; break; case VK_RIGHT: if(speedX > 0) speedX = 0; break; case VK_UP: if(speedY < 0) speedY = 0; break; case VK_DOWN: if(speedY > 0) speedY = 0; break; } } public void keyTyped(KeyEvent e) { } public void paint(Graphics g) { //calculate coordinates of the upper left corner of the tileMap int originX = getWidth()/2-(int)posX; int originY = getHeight()/2-(int)posY; if(originX > 0) originX = 0; if(originY > 0) originY = 0; //calculate the lower right corner of the tileMap int lrX = originX + tileMapWidth; int lrY = originY + tileMapHeight; if(lrX < getWidth()) { originX = getWidth()-tileMapWidth; lrX = getWidth(); } if(lrY < getHeight()) { originY = getHeight()-tileMapHeight; lrY = getHeight(); } //draw the tiles for(int y = 0; y < tileMap.length; y++) { for(int x = 0; x < tileMap[0].length; x++) { int tx = x*tileWidth + originX; int ty = y*tileHeight + originY; if(tx + tileWidth >= 0 && ty + tileHeight >= 0 && tx < getWidth() && ty < getHeight()) { g.setColor(tileMap[y][x]); g.fillRect(tx, ty, tileWidth, tileHeight); } } } g.setColor(ballColor); g.fillOval(originX+(int)posX-ballDiameter/2, originY+(int)posY-ballDiameter/2, ballDiameter, ballDiameter); } }