I'm creating a game like zType
and I have a problem in validating the input. As you can see in the picture below it select two words. How can I fix this problem, please help.
This is My Game class
import java.awt.Canvas;
import java.awt.event.KeyListener;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.LinkedList;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable, KeyListener
{
public static final int WIDTH = 640;
public static final int HEIGHT = 680;
public final String TITLE = "Game";
private boolean running = false;
private Thread thread;
private BufferedImage spriteSheet = null;
private BufferedImage background = null;
public int level = 1;
public int fps = 0;
public int score = 0;
private int enemy_count = 15;
private int enemy_killed = 0;
private int enemy_notkilled = 0;
private boolean target = false;
public String t = "";
private Controller c;
private Textures tex;
private LinkedList<Enemy> e = new LinkedList<Enemy>();
private Enemy enemy;
public void init()
{
requestFocus();
try
{
spriteSheet = ImageIO.read(getClass().getResource("/sprite_sheet.png"));
background = ImageIO.read(getClass().getResource("/background.png"));
}
catch(IOException e)
{
e.printStackTrace();
}
tex = new Textures(this);
c = new Controller(tex, this);
addKeyListener(this);
c.createEnemy(enemy_count);
e = c.getEnemy();
}
private synchronized void start()
{
if(running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
private synchronized void stop()
{
if(!running)
return;
running = false;
try
{
thread.join();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.exit(1);
}
public void run()
{
init();
long lastTime = System.nanoTime();
final double amountOfTicks= 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
int frames = 0;
long timer = System.currentTimeMillis();
while(running)
{
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if(delta >= 1)
{
update();
delta--;
}
render();
frames++;
if(System.currentTimeMillis() - timer > 1000)
{
timer += 1000;
fps = frames;
frames = 0;
}
}
stop();
}
private void update()
{
c.update();
if(enemy_killed + enemy_notkilled >= enemy_count)
{
e.clear();
t = "";
level++;
enemy_killed = 0;
enemy_notkilled = 0;
c.createEnemy(enemy_count);
}
}
private void render()
{
BufferStrategy bs = this.getBufferStrategy();
if(bs == null)
{
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.drawImage(background, 0, 0, null);
c.render(g);
g.dispose();
bs.show();
}
public void keyPressed(KeyEvent ek)
{
int key = ek.getKeyCode();
char character = Character.toLowerCase(ek.getKeyChar());
boolean result = isValid(key);
if(result && !target)
{
for(int i = 0; i < e.size(); i++)
if(e.get(i).getFirstLetter() == character && e.get(i).getOnScreen())
{
enemy = e.get(i);
t = enemy.getText();
if(enemy.getCurrentIndex() == 0)
enemy.addCurrentIndex();
target = true;
System.out.println("---"+enemy.text);
break;
}
}
else if(result && t.charAt(enemy.getCurrentIndex()) == character)
enemy.addCurrentIndex();
}
public void keyReleased(KeyEvent ek){ }
public void keyTyped(KeyEvent ek){ }
public static void main(String[] args)
{
Game game = new Game();
game.setPreferredSize(new Dimension(WIDTH, HEIGHT));
game.setMaximumSize(new Dimension(WIDTH, HEIGHT));
game.setMinimumSize(new Dimension(WIDTH, HEIGHT));
JFrame frame = new JFrame(game.TITLE);
frame.add(game);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
game.start();
}
public boolean isValid(int key)
{
return key >= 65 && key <= 90 ? true : false;
}
public BufferedImage getSpriteSheet()
{
return spriteSheet;
}
public int getEnemy_count()
{
return enemy_count;
}
public void setEnemy_count(int enemy_count)
{
this.enemy_count = enemy_count;
}
public int getEnemy_killed()
{
return enemy_killed;
}
public void setEnemy_killed(int enemy_killed)
{
this.enemy_killed = enemy_killed;
}
public int getEnemy_notkilled()
{
return enemy_notkilled;
}
public void setEnemy_notkilled(int enemy_notkilled)
{
this.enemy_notkilled = enemy_notkilled;
}
public void addScore(int k)
{
score += k;
}
public void falseTarget()
{
target = false;
}
public String getT()
{
return t;
}
public void setT(String k)
{
t = k;
}
}
This is my Enemy Class
import java.awt.*;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
public class Enemy
{
private double x ,y;
public String text;
private char firstLetter;
private AttributedString as;
private Controller c;
private Textures tex;
private Game game;
private int currentIndex = 0;
private int textLength = 0;
private double speed = 0.0;
private int stringWidth = 0;
private boolean onScreen = false;
public Enemy(double x, double y, double speed, Textures tex, Controller c, Game game, String text, int stringWidth)
{
this.x = x;
this.y = y;
this.tex = tex;
this.text = text;
this.game = game;
this.c = c;
this.speed = speed;
firstLetter = this.text.charAt(0);
textLength = this.text.length();
this.stringWidth = stringWidth;
}
public void update()
{
y += speed;
if(y >= 0)
onScreen = true;
if(currentIndex >= textLength)
{
game.addScore(5);
game.setT("");
c.removeEnemy(this);
game.setEnemy_killed(game.getEnemy_killed() + 1);
game.falseTarget();
}
if(y >= Game.HEIGHT - 50)
{
//game.decreaseHealth();
game.setT("");
c.removeEnemy(this);
game.setEnemy_notkilled(game.getEnemy_notkilled() + 1);
game.falseTarget();
game.t ="";
}
}
public void render(Graphics g)
{
g.drawImage(tex.enemy, (int)x, (int)y, null);
as = new AttributedString(text);
if(currentIndex >= 1)
as.addAttribute(TextAttribute.FOREGROUND, Color.WHITE, 0, currentIndex);
as.addAttribute(TextAttribute.FONT, new Font("Consolas", Font.BOLD, 12), 0, text.length());
g.drawString(as.getIterator(), (int)x + getAdd(stringWidth), (int)y + 13);
}
public double getX()
{
return x;
}
public double getY()
{
return y;
}
public String getText()
{
return text;
}
public char getFirstLetter()
{
return firstLetter;
}
public void addCurrentIndex()
{
currentIndex++;
}
public int getCurrentIndex()
{
return currentIndex;
}
public int getTextLength()
{
return textLength;
}
public int getAdd(int width)
{
return (96 / 2) - (width / 2);
}
public boolean getOnScreen()
{
return onScreen;
}
}
The problem is that you're calling falseTarget() whenever an enemy moves out of the screen. In your example, you assigned target = true when you pressed the 'o' (for the enemy named "owe"), but then a different enemy (maybe "jet", maybe an enemy that is no longer visible) finished "dropping" out of the screen (y >= Game.HEIGHT - 50), so you called falseTarget() - and thus, when you pressed 'i' you started a new enemy ("ice").
What you want to do is call falseTarget() in this case only if the enemy that dropped out of the screen is the one that's currently being targeted:
if(y >= Game.HEIGHT - 50)
{
//game.decreaseHealth();
//game.setT(""); // <-- Commented this line out
c.removeEnemy(this);
game.setEnemy_notkilled(game.getEnemy_notkilled() + 1);
if(game.getT().equals(text)) // <-- Added this if before calling falseTarget()
{ // and clearing the game's current enemy text
game.falseTarget();
game.t ="";
}
}
Related
To be frank i have not the slightest clue how to fix this whats so ever. It works until you get to the part that only 1 brick shows and its kinda frustrating... If anyone could help me i would appreciate it. I did look up how to fix this but i didn't even find anyone that had this problem. Google searching isn't really that good. Oh and i used Eclipse for this program.
Board Class
package Final;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JPanel;
public class Board extends JPanel implements Commons {
private Timer timer;
private String message = "Your Fired";
private Ball ball;
private Paddle paddle;
private Brick bricks[];
private boolean ingame = true;
public Board() {
initBoard();
}
private void initBoard() {
addKeyListener(new TAdapter());
setFocusable(true);
bricks = new Brick[N_OF_BRICKS];
setDoubleBuffered(true);
timer = new Timer();
timer.scheduleAtFixedRate(new ScheduleTask(), DELAY, PERIOD);
}
#Override
public void addNotify() {
super.addNotify();
gameInit();
}
private void gameInit() {
ball = new Ball();
paddle = new Paddle();
int k = 0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 6; j++) {
bricks[k] = new Brick(j * 40 + 30, i * 10 + 50);
k++;
}
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
if (ingame) {
drawObjects(g2d);
} else {
gameFinished(g2d);
}
Toolkit.getDefaultToolkit().sync();
}
private void drawObjects(Graphics2D g2d) {
g2d.drawImage(ball.getImage(), ball.getX(), ball.getY(),
ball.getWidth(), ball.getHeight(), this);
g2d.drawImage(paddle.getImage(), paddle.getX(), paddle.getY(),
paddle.getWidth(), paddle.getHeight(), this);
for (int i = 0; i < N_OF_BRICKS; i++) {
if (!bricks[i].isDestroyed()) {
g2d.drawImage(bricks[i].getImage(), bricks[i].getX(),
bricks[i].getY(), bricks[i].getWidth(),
bricks[i].getHeight(), this);
}
}
}
private void gameFinished(Graphics2D g2d) {
Font font = new Font("Verdana", Font.BOLD, 18);
FontMetrics metr = this.getFontMetrics(font);
g2d.setColor(Color.BLACK);
g2d.setFont(font);
g2d.drawString(message,
(Commons.WIDTH - metr.stringWidth(message)) / 2,
Commons.WIDTH / 2);
}
private class TAdapter extends KeyAdapter {
#Override
public void keyReleased(KeyEvent e) {
paddle.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
paddle.keyPressed(e);
}
}
private class ScheduleTask extends TimerTask {
#Override
public void run() {
ball.move();
paddle.move();
checkCollision();
repaint();
}
}
private void stopGame() {
ingame = false;
timer.cancel();
}
private void checkCollision() {
if (ball.getRect().getMaxY() > Commons.BOTTOM_EDGE) {
stopGame();
}
for (int i = 0, j = 0; i < N_OF_BRICKS; i++) {
if (bricks[i].isDestroyed()) {
j++;
}
if (j == N_OF_BRICKS) {
message = "Pay Day";
stopGame();
}
}
if ((ball.getRect()).intersects(paddle.getRect())) {
int paddleLPos = (int) paddle.getRect().getMinX();
int ballLPos = (int) ball.getRect().getMinX();
int first = paddleLPos + 8;
int second = paddleLPos + 16;
int third = paddleLPos + 24;
int fourth = paddleLPos + 32;
if (ballLPos < first) {
ball.setXDir(-1);
ball.setYDir(-1);
}
if (ballLPos >= first && ballLPos < second) {
ball.setXDir(-1);
ball.setYDir(-1 * ball.getYDir());
}
if (ballLPos >= second && ballLPos < third) {
ball.setXDir(0);
ball.setYDir(-1);
}
if (ballLPos >= third && ballLPos < fourth) {
ball.setXDir(1);
ball.setYDir(-1 * ball.getYDir());
}
if (ballLPos > fourth) {
ball.setXDir(1);
ball.setYDir(-1);
}
}
for (int i = 0; i < N_OF_BRICKS; i++) {
if ((ball.getRect()).intersects(bricks[i].getRect())) {
int ballLeft = (int) ball.getRect().getMinX();
int ballHeight = (int) ball.getRect().getHeight();
int ballWidth = (int) ball.getRect().getWidth();
int ballTop = (int) ball.getRect().getMinY();
Point pointRight = new Point(ballLeft + ballWidth + 1, ballTop);
Point pointLeft = new Point(ballLeft - 1, ballTop);
Point pointTop = new Point(ballLeft, ballTop - 1);
Point pointBottom = new Point(ballLeft, ballTop + ballHeight + 1);
if (!bricks[i].isDestroyed()) {
if (bricks[i].getRect().contains(pointRight)) {
ball.setXDir(-1);
} else if (bricks[i].getRect().contains(pointLeft)) {
ball.setXDir(1);
}
if (bricks[i].getRect().contains(pointTop)) {
ball.setYDir(1);
} else if (bricks[i].getRect().contains(pointBottom)) {
ball.setYDir(-1);
}
bricks[i].setDestroyed(true);
}
}
}
}
}
Brick Class
package Final;
import javax.swing.ImageIcon;
public class Brick extends Sprite {
private boolean destroyed;
public Brick(int x, int y) {
ImageIcon ii = new ImageIcon("images/bricks.png");
image = ii.getImage();
i_width = image.getWidth(null);
i_heigth = image.getHeight(null);
destroyed = false;
}
public boolean isDestroyed() {
return destroyed;
}
public void setDestroyed(boolean val) {
destroyed = val;
}
}
Commons Class
package Final;
public interface Commons {
public static final int WIDTH = 300;
public static final int HEIGTH = 400;
public static final int BOTTOM_EDGE = 390;
public static final int N_OF_BRICKS = 30;
public static final int INIT_PADDLE_X = 200;
public static final int INIT_PADDLE_Y = 360;
public static final int INIT_BALL_X = 230;
public static final int INIT_BALL_Y = 355;
public static final int DELAY = 1000;
public static final int PERIOD = 10;
}
Sprite Class
package Final;
import java.awt.Image;
import java.awt.Rectangle;
public class Sprite {
protected int x;
protected int y;
protected int i_width;
protected int i_heigth;
protected Image image;
public void setX(int x) {
this.x = x;
}
public int getX() {
return x;
}
public void setY(int y) {
this.y = y;
}
public int getY() {
return y;
}
public int getWidth() {
return i_width;
}
public int getHeight() {
return i_heigth;
}
Image getImage() {
return image;
}
Rectangle getRect() {
return new Rectangle(x, y,
image.getWidth(null), image.getHeight(null));
}
}
Breakout Class
package Final;
import java.awt.EventQueue;
import javax.swing.JFrame;
public class Breakout extends JFrame {
public Breakout() {
initUI();
}
private void initUI() {
add(new Board());
setTitle("Lord Carl's Demolition Job");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(Commons.WIDTH, Commons.HEIGTH);
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Breakout game = new Breakout();
game.setVisible(true);
}
});
}
}
The problem is in checkCollision(). Inside the loop, j will never equal N_OF_BRICKS because of the loop condition. You could change to:
private void checkCollision() {
if (ball.getRect().getMaxY() > Commons.BOTTOM_EDGE) {
stopGame();
}
int j = 0;
for (int i = 0; i < N_OF_BRICKS; i++) {
if (bricks[i].isDestroyed()) {
j++;
}
}
if (j == N_OF_BRICKS) {
message = "Pay Day";
stopGame();
}
}
Also, in the Brick class you neglect to store the x,y coords:
public class Brick extends Sprite {
....
public Brick(int x, int y) {
ImageIcon ii = new ImageIcon("images/bricks.png");
image = ii.getImage();
i_width = image.getWidth(null);
i_heigth = image.getHeight(null);
destroyed = false;
// Save these
this.x = x;
this.y = y
}
....
}
Or, add a constructor to the Sprite class and call that from the Brick constructor:
public class Sprite {
....
public Sprite(int x, int y) {
this.x = x;
this.y = y;
}
....
}
public class Brick extends Sprite {
....
public Brick(int x, int y) {
// Call the sprite constructor
super(x, y);
ImageIcon ii = new ImageIcon("images/bricks.png");
image = ii.getImage();
i_width = image.getWidth(null);
i_heigth = image.getHeight(null);
destroyed = false;
}
....
}
I am currently making a Space Shooter in Java. I am able to make bullets shoot and enemies come from the top, but I am not sure how to check if they intersect. I understand that the Rectangle class has a intersects method, but I am not sure how I would place the rectangles around the bullets and the enemies, since I don't know beforehand how many may be on the screen. How can I do this? Here is my code:
Game.java
package main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable, KeyListener {
//declare values
private static final long serialVersionUID = 1L;
public static final int WIDTH = 800;
public static final int HEIGHT = 600;
public static final String TITLE = "Space Shooter";
private boolean running = false;
private Thread thread;
private Player player;
private BufferedImage playerImage;
private BufferedImage bulletImage;
private BufferedImage enemyImage;
int playerx;
int playery;
int round = 1;
public Game() {
//
player = new Player((WIDTH/2)-32, HEIGHT-200);
//allocates all file resources
try {
playerImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/player.png"));
bulletImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/bullet.png"));
enemyImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/enemy.png"));
} catch (IOException e) {
e.printStackTrace();
}
addKeyListener(this);
setFocusable(true);
requestFocusInWindow();
}
//starts thread
private synchronized void start() {
if (running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
//stops thread
private synchronized void stop() {
if (!running)
return;
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(1);
}
#Override
//game loop
public void run() {
long lastTime = System.nanoTime();
final double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
int updates = 0;
int frames = 0;
long timer = System.currentTimeMillis();
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if (delta > 1) {
tick();
updates++;
delta--;
}
Shoot.updateBullets();
Enemy.updateEnemies();
render();
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println(updates + " TICKS, " + frames + " FPS");
updates = 0;
frames = 0;
}
}
stop();
}
//updates sprite locations
public void tick() {
playerx = player.getX();
playery = player.getY();
}
//renders sprites
public void render() {
//setting up triple-buffering
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
//////////////////////////////////
g.setColor(Color.BLACK); g.fillRect(0,0,getWidth(), getHeight());
g.drawImage(playerImage, playerx, playery, this);
if (Shoot.allBullets.size() != 0) {
for (int i = 0; i < Shoot.allBullets.size(); i++) {
int bulletx = (int) Shoot.allBullets.get(i).x;
int bullety = (int) Shoot.allBullets.get(i).y;
g.drawImage(bulletImage, bulletx + 21, bullety, this);
}
}
if (Enemy.allEnemies.size() != 0) {
for (int i = 0; i < Enemy.allEnemies.size(); i++) {
int enemyx = (int) Enemy.allEnemies.get(i).x;
int enemyy = (int) Enemy.allEnemies.get(i).y;
g.drawImage(enemyImage, enemyx, enemyy, this);
}
} else {
Enemy.createEnemies(round);
round++;
}
//////////////////////////////////
g.dispose();
bs.show();
}
#Override
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_SPACE) {
Shoot.addBullet(player.getX(), player.getY());
}
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_UP) {
player.setY(playery -= 20);
} else if (key == KeyEvent.VK_DOWN) {
player.setY(playery += 20);
} else if (key == KeyEvent.VK_RIGHT) {
player.setX(playerx += 40);
} else if (key == KeyEvent.VK_LEFT) {
player.setX(playerx -= 40);
}
}
public void keyTyped(KeyEvent e) {}
public static void main(String[] args) {
Game game = new Game();
JFrame frame = new JFrame(TITLE);
frame.setSize(WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(game);
frame.getContentPane().setBackground(Color.BLACK);
frame.setVisible(true);
game.start();
}
}
Shoot.java
package main;
import java.util.ArrayList;
public class Shoot {
static ArrayList<Point> allBullets = new ArrayList<Point>();
public static void addBullet(int x, int y) {
allBullets.add(new Point(x, y));
}
public static ArrayList<Point> getAllBulletPosistions() {
return allBullets;
}
public static void updateBullets() {
if (allBullets.size() != 0) {
for (int i = 0; i < allBullets.size(); i++) {
allBullets.get(i).y -= 1;
}
}
}
}
Enemy.java
package main;
import java.util.ArrayList;
public class Enemy {
static ArrayList<Point> allEnemies = new ArrayList<Point>();
public static ArrayList<Point> createEnemies(int round) {
for (int i = 0; i < round; i++) {
Point newEnemyLocation = new Point((int) (Math.random()*Game.WIDTH - 64), 0);
if (newEnemyLocation.x < 64) {
newEnemyLocation.x += 70;
}
allEnemies.add(newEnemyLocation);
}
return allEnemies;
}
int validate(int xpos) {
if (xpos > Game.WIDTH - 64) {
xpos -= 64;
}
if (xpos < 64) {
xpos += 64;
}
return xpos;
}
public static ArrayList<Point> updateEnemies() {
if (allEnemies.size() != 0) {
for (int i = 0; i < allEnemies.size(); i++) {
Point enemyLocation = allEnemies.get(i);
if (enemyLocation.y <= Game.HEIGHT) {
allEnemies.get(i).y += 0.1;
} else {
allEnemies.remove(i);
}
}
}
return allEnemies;
}
}
for(int i = 0; i < Shoot.allBullets.size(); i++){
for(int j = 0; j < Enemy.allEnemys.size(); j++){
if(new Rectangle(Shoot.allBullets.get(i).x,Shoot.allBullets.get(i).y, width, height).intersects(new Rectangle(Enemy.allEnemys.get(j).x, Enemy.allEnemys.get(j).y, width, height)){
//on intersect
}
}
}
This would work but you shouldn't create new rectangles like this instead you should create a bullet class and a Enemy class that both contains the position and Rectangle anyways good luck!
I try running this program and I get a static void error. I am new to this and I have no idea how to fix this problem so any input would be helpful, thank you!
package johnbarthelmes.Java;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Board extends JPanel implements ActionListener {
private final int B_WIDTH = 300;
private final int B_HEIGHT = 300;
private final int DOT_SIZE = 10;
private final int ALL_DOTS = 900;
private final int RAND_POS = 29;
private final int DELAY = 140;
private final int x[] = new int[ALL_DOTS];
private final int y[] = new int[ALL_DOTS];
private int dots;
private int apple_x;
private int apple_y;
private boolean leftDirection = false;
private boolean rightDirection = true;
private boolean upDirection = false;
private boolean downDirection = false;
private boolean inGame = true;
private Timer timer;
private Image ball;
private Image apple;
private Image head;
public Board() {
addKeyListener(new TAdapter());
setBackground(Color.black);
setFocusable(true);
setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
loadImages();
initGame();
}
private void loadImages() {
ImageIcon iid = new ImageIcon("dot.png");
ball = iid.getImage();
ImageIcon iia = new ImageIcon("apple.png");
apple = iia.getImage();
ImageIcon iih = new ImageIcon("head.png");
head = iih.getImage();
}
private void initGame() {
dots = 3;
for (int z = 0; z < dots; z++) {
x[z] = 50 - z * 10;
y[z] = 50;
}
locateApple();
timer = new Timer(DELAY, this);
timer.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
private void doDrawing(Graphics g) {
if (inGame) {
g.drawImage(apple, apple_x, apple_y, this);
for (int z = 0; z < dots; z++) {
if (z == 0) {
g.drawImage(head, x[z], y[z], this);
} else {
g.drawImage(ball, x[z], y[z], this);
}
}
Toolkit.getDefaultToolkit().sync();
} else {
gameOver(g);
}
}
private void gameOver(Graphics g) {
String msg = "Game Over";
Font small = new Font("Helvetica", Font.BOLD, 14);
FontMetrics metr = getFontMetrics(small);
g.setColor(Color.white);
g.setFont(small);
g.drawString(msg, (B_WIDTH - metr.stringWidth(msg)) / 2, B_HEIGHT / 2);
}
private void checkApple() {
if ((x[0] == apple_x) && (y[0] == apple_y)) {
dots++;
locateApple();
}
}
private void move() {
for (int z = dots; z > 0; z--) {
x[z] = x[(z - 1)];
y[z] = y[(z - 1)];
}
if (leftDirection) {
x[0] -= DOT_SIZE;
}
if (rightDirection) {
x[0] += DOT_SIZE;
}
if (upDirection) {
y[0] -= DOT_SIZE;
}
if (downDirection) {
y[0] += DOT_SIZE;
}
}
private void checkCollision() {
for (int z = dots; z > 0; z--) {
if ((z > 4) && (x[0] == x[z]) && (y[0] == y[z])) {
inGame = false;
}
}
if (y[0] >= B_HEIGHT) {
inGame = false;
}
if (y[0] < 0) {
inGame = false;
}
if (x[0] >= B_WIDTH) {
inGame = false;
}
if (x[0] < 0) {
inGame = false;
}
if(!inGame) {
timer.stop();
}
}
private void locateApple() {
int r = (int) (Math.random() * RAND_POS);
apple_x = ((r * DOT_SIZE));
r = (int) (Math.random() * RAND_POS);
apple_y = ((r * DOT_SIZE));
}
#Override
public void actionPerformed(ActionEvent e) {
if (inGame) {
checkApple();
checkCollision();
move();
}
repaint();
}
private class TAdapter extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if ((key == KeyEvent.VK_LEFT) && (!rightDirection)) {
leftDirection = true;
upDirection = false;
downDirection = false;
}
if ((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {
rightDirection = true;
upDirection = false;
downDirection = false;
}
if ((key == KeyEvent.VK_UP) && (!downDirection)) {
upDirection = true;
rightDirection = false;
leftDirection = false;
}
if ((key == KeyEvent.VK_DOWN) && (!upDirection)) {
downDirection = true;
rightDirection = false;
leftDirection = false;
}
}
}
}
If it helps at all this is the code for the snake game that I got from a Dr Java tutorial in which I followed all the steps correctly as far as I know. There was no errors compiling but when I ran the program I got that error message.
In order to run an application, your class needs a main method with a certain signature, so Java knows what to do. Probably you want to start up the program by showing your JFrame:
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Board b = new Board();
b.setVisible(true);
}
});
}
You need to add a main method. It's the entry point to every Java application. It looks like it should have this implementation, based on your code sample.
public static void main(String[] args) {
Board board = new Board();
// need to do something else with board here maybe?
}
I am writing the Snake game. I am stuck with the animations, because I want to get smooth animation. I don't how to double buffer images so that to get double-buffering. What has to be done so that this becomes double-buffered?
I use main frame that extends JFrame, and here I add two JPanels - one for status bar and one for animation.
Here are the classes used for snake animation:
Player.class
package snake;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class Player
{
private int headSizeX;
private int headSizeY;
private int tailSizeX;
private int tailSizeY;
private int x;
private int y;
private int speed = 5;
private int snakeSize = 40;
private Image[] snake = new Image[5];
private ArrayList<Integer> X,Y;
private static int imageNr = 0;
private int c = 0;
private int tmp;
private boolean death = false;
static int player;
private static boolean inverse = false;
private boolean left = false;
private boolean right = false;
private boolean up = true;
private boolean down = false;
public Player()
{
initPlayer();
headSizeX = snake[0].getWidth(null);
headSizeY = snake[0].getHeight(null)-2;
tailSizeX = snake[4].getWidth(null);
tailSizeY = snake[4].getHeight(null);
System.out.println("tail: "+tailSizeX+" "+tailSizeY);
x = MainGamePanel.getSizeX()/2;
y= MainGamePanel.getSizeY()-130;
}
public void initPlayer()
{
int imgNr = 5;
X = new ArrayList<Integer>();
Y = new ArrayList<Integer>();
String name = "green";
switch (player)
{
case 1:
name = "green"; break;
case 2:
name = "red"; break;
case 3:
name = "blue"; break;
}
for (int nr = 1; nr <= imgNr; nr++)
{
snake[nr-1] = new ImageIcon("img/" +name+"/snake" +nr+".png").getImage();
}
X.add(MainGamePanel.getSizeX()/2);
Y.add( MainGamePanel.getSizeY()-200);
X.add( MainGamePanel.getSizeX()/2);
Y.add( MainGamePanel.getSizeX()/2+33);
for (int i = 2; i < snakeSize; i++) {
X.add( MainGamePanel.getSizeX()/2);
Y.add( MainGamePanel.getSizeX()/2 + i*20+13);
}
}
public void paint(Graphics g)
{
//g.drawImage(snake[imageNr], x,y,headSizeX,headSizeY,null);
for (int i = 0; i < snakeSize; i++) {
if (i == 0)
g.drawImage(snake[imageNr], X.get(i), Y.get(i), null);
else
g.drawImage(snake[4], X.get(i), Y.get(i), null);
}
/*g.drawImage(snake[4],x, y+headSizeY, tailSizeX, tailSizeY, null);
for (int i = 1;i<snakeSize;i++)
g.drawImage(snake[4],x, y+i*tailSizeY+headSizeY, tailSizeX, tailSizeY, null);*/
}
public void update()
{
y = MainGamePanel.getSizeY()-headSizeY - 35;
for (int i = snakeSize-1; i > 0; i--) {
X.set(i, X.get(i-1));
Y.set(i, Y.get(i-1));
}
if (left) {
tmp = X.get(0);
X.set(0, tmp-20);
imageNr = 3;
}
if (right) {
tmp = X.get(0);
X.set(0, tmp+20);
imageNr = 1;
}
if (up) {
tmp = Y.get(0);
Y.set(0, tmp-20);
imageNr = 0;
}
if (down) {
tmp = Y.get(0);
Y.set(0, tmp+20);
imageNr = 2;
}
}
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if ((key == KeyEvent.VK_LEFT) && (!right)) {
left = true;
up = false;
down = false;
System.out.println("LEWO");
}
if ((key == KeyEvent.VK_RIGHT) && (!left)) {
right = true;
up = false;
down = false;
System.out.println("PRAWO");
}
if ((key == KeyEvent.VK_UP) && (!down)) {
up = true;
right = false;
left = false;
System.out.println("GÓRA");
}
if ((key == KeyEvent.VK_DOWN) && (!up)) {
down = true;
right = false;
left = false;
System.out.println("DÓŁ");
}
}
public void collision()
{
death = true;
}
public void reset()
{
imageNr = 0;
death = false;
}
public void setInverse(boolean set)
{
inverse = set;
}
public void increaseSpeed(int inc)
{
speed += inc;
}
public void decreaseSpeed(int dec)
{
speed -=dec;
}
public int getSnakeSize()
{
return snakeSize;
}
public void increaseSnakeSize()
{
snakeSize += 1;
}
public void decreaseSnakeSize(int dec)
{
snakeSize -= dec;
}
}
MainGamePanel.class
package snake;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class MainGamePanel extends JPanel implements KeyListener{
private Image bounds;
private Player player;
public static int sizex;
private Image tail;
private Image background;
private int lives;
private int speed;
private int levels;
private int counter = 0;
private int appleCounter = 0;
private static int level = 1;
public static int sizeX = 784;
public static int sizeY = 617;
public static int applesNumber;
private boolean gameover = false;
private boolean gameend = false;
private boolean death = false;
private boolean levelCompleted = false;
private Graphics buffer;
private BufferedImage img;
public MainGamePanel(int[] settings)
{
lives = settings[0];
speed = settings[1];
levels = settings[2];
bounds = new ImageIcon("img/bounds.jpg").getImage();
setFocusable(true);
addKeyListener(this);
//new Apple();
}
public void init()
{
player = new Player();
img = new BufferedImage(sizeX, sizeY, 2);
Levels.getLevel(1);
this.applesNumber = Levels.getApplesNumber();
this.background = new ImageIcon("img/bg/" + Levels.getBackground()).getImage();
}
public void addNotify()
{
super.addNotify();
init();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
buffer = img.getGraphics();
buffer.drawImage(background, 0,0, sizeX, sizeY, null);
player.paint(buffer);
for (int i = 0; i <= getWidth(); i += 12) {
buffer.drawImage(bounds, i, 0, this);
buffer.drawImage(bounds, i, getHeight()-12, this);
}
for (int i = 12; i < getHeight(); i += 12) {
buffer.drawImage(bounds, 0, i, this);
buffer.drawImage(bounds, getWidth()-12, i, this);
}
g.drawImage(this.img, 0, 0, getWidth(), getHeight(), null);
buffer.clearRect(12, 12, sizeX, sizeY);
}
public void play()
{
if (level == this.levels) gameend = true;
this.player.reset();
this.counter = 0;
this.appleCounter = 0;
long StartTime = System.currentTimeMillis();
player.update();
repaint();
/*do
{
Thread.yield();
}
while (System.currentTimeMillis() - StartTime < this.speed);*/
}
public void gameLoop()
{
while(true)
{
play();
try
{
Thread.sleep(150);
}
catch (InterruptedException ex)
{
}
if (death)
{
lives -= 1;
death = false; continue;
}
levelCompleted = false;
level+=1;
Levels.getLevel(level);
applesNumber = Levels.getApplesNumber();
}
}
public static int getApp()
{
return applesNumber;
}
public static int getSizeX()
{
return sizeX;
}
public static int getSizeY()
{
return sizeY;
}
public void setGameOver()
{
gameover = true;
}
#Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) System.exit(0);
player.keyPressed(e);
}
#Override
public void keyReleased(KeyEvent e) {}
#Override
public void keyTyped(KeyEvent e) {}
}
and Game.class for JFrame
package snake;
import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import java.awt.BorderLayout;
#SuppressWarnings("serial")
public class Game extends JFrame {
//public SnakeTheGame start;
private ImageIcon icon;
StatBar statbar;
private MainGamePanel start;
public static final int WIDTH = 800;
public static final int HEIGHT = 700;
public static final int MIN_WIDTH = 450;
public static final int MIN_HEIGHT = 450;
public Game()
{
start = new MainGamePanel(new int[] { Settings.getLives(), Settings.getSpeed(), Settings.getLevels() });
statbar = new StatBar();
icon = new ImageIcon("img//icon.png");
setBounds(200, 200, WIDTH, HEIGHT);
setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
setTitle("Snake The Game");
setIconImage(this.icon.getImage());
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
getContentPane().add(statbar, BorderLayout.SOUTH);
getContentPane().add(start, BorderLayout.CENTER);
// this.createBufferStrategy(2);
this.start.setVisible(true);
start.requestFocus();
}
public void start()
{
start.gameLoop();
}
}
JPanel is double-buffered by default. What you need to do is remove the loop in favour of a timer which does 60 FPS, calling play() and invoking one of the repaint methods.
Sample code
(Import from java.util. I did not use your names.)
private class AnimationTask extends TimerTask {
#Override
public void run() {
play();
animationPanel.repaint();
}
}
private Timer timer;
/**
* Creates new form AnimationDemoFrame
*/
public AnimationDemoFrame() {
timer = new Timer();
initComponents();
timer.schedule(new AnimationTask(), 150);
}
private void play() {
;
}
Hello i`ve got a problem: when i run this code i get this:
on some java forum they said i need to add Graphics2DObject.clearRect(x1, y1, x2, y2);
(where`s x1 and y1 is coordinates of the image and x2 y2 is width height of the image.) when i add it to the code i get this:
The code(with added function):
Main:
import java.awt.*;
import javax.swing.*;
public class Main {
public static void main(String []args){
Main b = new Main();
b.run();
}
private Sprite sprite;
private Animation a;
private ScreenManager s;
public double sk = 0;
private static final DisplayMode modes1[] = {
new DisplayMode(800, 600, 32, DisplayMode.REFRESH_RATE_UNKNOWN),
};
//load images and add scenes
public void loadImages() {
Image face1 = new ImageIcon("C:\\1.jpg").getImage();
Image face2 = new ImageIcon("C:\\2.jpg").getImage();
a = new Animation();
a.addScene(face1, 50);
a.addScene(face2, 50);
sprite = new Sprite(a);
sprite.setVelocityX(0.3f);
sprite.setVelocityY(0.3f);
}
//main method called from main
public void run() {
s = new ScreenManager();
try {
DisplayMode dm = s.findFirstCompatibleMode(modes1);
s.setFullScreen(dm);
loadImages();
movieLoop();
}finally {
s.restoreScreen();
}
}
//play movie
public void movieLoop() {
long startingTime = System.currentTimeMillis();
long cumTime = startingTime;
while(cumTime - startingTime < 5000) {
long timePassed = System.currentTimeMillis() - cumTime;
cumTime += timePassed;
update(timePassed);
//draw and update the screen
Graphics2D g = s.getGraphics();
draw(g);
g.dispose();
s.update();
try{
Thread.sleep(20);
}catch(Exception ex) {
System.err.println("Error: " + ex);
}
}
}
// Graphics with new function
public void draw(Graphics g) {
g.drawImage(sprite.getImage(), Math.round(sprite.getX()), Math.round(sprite.getY()), null);
if(sk != 1){
g.clearRect(Math.round(sprite.getoX()),Math.round(sprite.getoY()),Math.round(sprite.getWidth()),Math.round(sprite.getHeight()));
}else{
sk = 1;
}
}
//update sprite
public void update(long timePassed) {
if(sprite.getX() < 0) {
sprite.setVelocityX(Math.abs(sprite.getVelocityX()));
} else if (sprite.getX() + sprite.getWidth() >= s.getWidth()) {
sprite.setVelocityX(-Math.abs(sprite.getVelocityX()));
}
if(sprite.getY() < 0) {
sprite.setVelocityY(Math.abs(sprite.getVelocityY()));
} else if (sprite.getY() + sprite.getHeight() >= s.getHeight()) {
sprite.setVelocityY(-Math.abs(sprite.getVelocityY()));
}
sprite.oldX();
sprite.oldY();
sprite.update(timePassed);
}
}
The sprite (movement class):
import java.awt.Image;
public class Sprite {
private Animation a;
private float x;
private float y;
private float vx;
private float vy;
private float ox;
private float oy;
//Constructor
public Sprite(Animation a) {
this.a = a;
}
// Get old x and y to delete them later
public void oldX(){
this.ox = x;
}
public void oldY(){
this.oy = y;
}
public float getoX(){
return ox;
}
public float getoY(){
return oy;
}
//Change position
public void update(long timePassed) {
x += vx * timePassed;
y += vy * timePassed;
a.update(timePassed);
}
//get x position
public float getX() {
return x;
}
//get y position
public float getY() {
return y;
}
//set x position
public void setX(float x) {
this.x = x;
}
//set y position
public void setY(float y) {
this.y = y;
}
// get sprite width
public int getWidth() {
return a.getImage().getWidth(null);
}
// get sprite height
public int getHeight() {
return a.getImage().getHeight(null);
}
//get horizontal velocity
public float getVelocityX() {
return vx;
}
//get vertical velocity
public float getVelocityY() {
return vy;
}
//set horizontal velocity
public void setVelocityX(float vx) {
this.vx = vx;
}
//set vertical velocity
public void setVelocityY(float vy) {
this.vy = vy;
}
//get sprite/image
public Image getImage() {
return a.getImage();
}
}
Screen manager class:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class ScreenManager {
private GraphicsDevice vc;
//Constructor // give vc access to monitor screen
public ScreenManager() {
GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
vc = e.getDefaultScreenDevice();
}
//get all compatible DM's
public DisplayMode[] getCompatibleDisplayModes() {
return vc.getDisplayModes();
}
//compares DM passed in to vc and see if they match
public DisplayMode findFirstCompatibleMode(DisplayMode modes[]) {
DisplayMode goodModes[] = vc.getDisplayModes();
for(int x = 0; x <modes.length; x++){
for(int y = 0; y < goodModes.length; y++){
if(displayModesMatch(modes[x], goodModes[y])) {
return modes[x];
}
}
}
return null;
}
//get current DM
public DisplayMode getCurrentDisplayMode() {
return vc.getDisplayMode();
}
//checks if two modes match each other
public boolean displayModesMatch(DisplayMode m1, DisplayMode m2) {
if(m1.getWidth() != m2.getWidth() || m1.getHeight() != m2.getHeight()) {
return false;
}
if(m1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m1.getBitDepth() != m2.getBitDepth()) {
return false;
}
if(m1.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && m2.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && m1.getRefreshRate() != m2.getRefreshRate()) {
return false;
}
return true;
}
//make frame full screen
public void setFullScreen(DisplayMode dm) {
JFrame f = new JFrame();
f.setUndecorated(true);
f.setIgnoreRepaint(true);
f.setResizable(false);
vc.setFullScreenWindow(f);
if(dm != null && vc.isDisplayChangeSupported()) {
try{
vc.setDisplayMode(dm);
}catch(Exception e) {System.out.println("");}
}
f.createBufferStrategy(2);
}
//we will set Graphics object = to this
public Graphics2D getGraphics() {
Window w = vc.getFullScreenWindow();
if(w != null) {
BufferStrategy s = w.getBufferStrategy();
return (Graphics2D)s.getDrawGraphics();
}
else {
return null;
}
}
//updates display
public void update() {
Window w = vc.getFullScreenWindow();
if(w != null) {
BufferStrategy s = w.getBufferStrategy();
if(!s.contentsLost()) {
s.show();
}
}
}
//returns full screen window
public Window getFullScreenWindow() {
return vc.getFullScreenWindow();
}
//get width
public int getWidth() {
Window w = vc.getFullScreenWindow();
if(w != null) {
return w.getWidth();
}
else {
return 0;
}
}
//get height
public int getHeight() {
Window w = vc.getFullScreenWindow();
if(w != null) {
return w.getHeight();
}
else {
return 0;
}
}
//get out of full screen
public void restoreScreen(){
Window w = vc.getFullScreenWindow();
if(w != null) {
w.dispose();
vc.setFullScreenWindow(null);
}
}
//create image compatible with monitor
public BufferedImage createCompatibleImage(int w, int h, int t) {
Window win = vc.getFullScreenWindow();
if(win != null) {
GraphicsConfiguration gc = win.getGraphicsConfiguration();
return gc.createCompatibleImage(w, h, t);
}
return null;
}
}/////////END///////////
Animation class
import java.util.ArrayList;
import java.awt.Image;
public class Animation {
private ArrayList scenes;
private int sceneIndex;
private long movieTime;
private long totalTime;
//Constructor
public Animation() {
scenes = new ArrayList();
totalTime = 0;
start();
}
//add scenes to the array list and set time for each scene
public synchronized void addScene(Image i, long t) {
totalTime += t;
scenes.add(new Onescene(i, totalTime));
}
//start animation from beginning
public synchronized void start() {
movieTime = 0;
sceneIndex = 0;
}
//change scenes
public synchronized void update(long timePassed) {
if(scenes.size() > 1 ) {
movieTime += timePassed;
if(movieTime >= totalTime) {
movieTime = 0;
sceneIndex = 0;
}
while(movieTime > getScene(sceneIndex).endTime) {
sceneIndex++;
}
}
}
//get animations current scene
public synchronized Image getImage() {
if(scenes.size() == 0) {
return null;
}
else {
return getScene(sceneIndex).pic;
}
}
//get scene
private Onescene getScene(int x) {
return (Onescene)scenes.get(x);
}
/////PRIVAT INNER CLASS/////
private class Onescene{
Image pic;
long endTime;
public Onescene(Image pic, long endTime) {
this.pic = pic;
this.endTime = endTime;
}
}
}////END/////
EDIT:
Could someone try running this code ?
Maybe You'll find the mistakes I made...
clearRect goes before drawImage.
I also had a problem with this and you need a "do while loop" in stead of while loop
like this:
do{
Graphics2D g = s.getGraphics();
long timePassed = System.currentTimeMillis() - cumTime;
cumTime += timePassed;
update(timePassed);
//draw and update
draw(g);
g.dispose();
s.update();
try{
Thread.sleep(20);
}catch(Exception ex){
System.out.println("Can't sleep :(");
}
}
while(cumTime - startingTime < 20000); //the Time
And the clearRect must be ABOVE the drawImage
Your loop looks a bit incorrect
Graphics2D g = s.getGraphics();
while(cumTime - startingTime < 5000) {
long timePassed = System.currentTimeMillis() - cumTime;
cumTime += timePassed;
update(timePassed);
//draw and update the screen
draw(g);
g.dispose();
s.update();
try{
Thread.sleep(20);
}catch(Exception ex) {
System.err.println("Error: " + ex);
}
}
}
also try this for your draw method.
// Graphics with new function
public void draw(Graphics g) {
g.clearRect(0,0,800,600);
g.drawImage(sprite.getImage(), Math.round(sprite.getX()), Math.round(sprite.getY()), null);
}