Key Bindings not responding - java

I followed an example someone posted on another question for key bindings to control an object. For the sake of simplicity all it is controlling is printing "woo" when VK_UP is pressed but it doesn't do that.
some code from here that I still can't manage to get working.
Heres the main
import javax.swing.*;
#SuppressWarnings("serial")
public class apples extends JFrame {
static boolean running;
public static void main(String[] args){
JFrame f = new JFrame();
Peach p = new Peach();
f.getContentPane().add(new test());
f.add(new test());
f.add(p);
f.setSize(400,250);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
p.run();
}
}
and here is the key binding stuff
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
#SuppressWarnings("serial")
public class Peach extends JPanel {
public void paint(Graphics g){
setOpaque(false);
super.paintComponent(g);
this.setBackground(Color.WHITE);
g.setColor(Color.BLACK);
g.fillOval(x, y, br, br);
g.drawString("Sort of Pong?", 157, 20);
g.setColor(Color.BLACK);
g.fillRect(paddlex, paddley, psizex, psizey);
//g.setColor(new Color(51, 255, 204));
//g.fillRect(100, 100, 80, 100);
repaint();
}
public void Panel(){ Thread go = new Thread();
go.start(); }
int xpos;
final int left = -1; //left increment
final int right = 1; //right increment
int up = -1; // up increment (negative because down is revered in coordinates)
int down = 1; // down increment
boolean check = true; // moving or not
int x =200; // ball position x
int y=100; // ball position y
boolean rightmove = true; // moving right or left
boolean leftmove = false; // moving left
boolean upmove = true; // moving up
boolean downmove = false; // moving down
int paddlex = 100; // paddle position x
int paddley = 100; // paddle position y
int psizex = 100; // paddle size in x dimension
int psizey = 100; // paddles size in y dimension
int cdy; // for checking other side for collisions
int cdx; // for checking other side for collisions
int br = 8; // ball radius
boolean shipupmove = false;
boolean shipdownmove = true;
int shipspeed = 1;
boolean goup;
long counter = 0;
public void calc(){
cdy = psizey + paddley; // for checking other side for collisions
cdx = psizex + paddlex; // for checking other side for collisions
}
public void run(){
while(true){
move();
collisiond();
calc();
counter++;
try
{
Thread.sleep(8);
}
catch(InterruptedException ex)
{
}
}
}
public void move(){
if (rightmove){
if(x <377){
x = (x+right);
}else{rightmove = false; leftmove = true;}
}
if(leftmove)
if(x > 0){
x = (x-right);
}else{rightmove = true; leftmove= false;}
if (downmove){
if(y <205){
y = (y+down);
}else{downmove = false; upmove = true;}
}
if(upmove)
if(y > 0){
y = (y+up);
}else{downmove = true; upmove= false;}
}
public void collisiond(){
if(leftmove && (x ==(cdx+1) || x == (cdx-1) || x == cdx)&& y >= paddley-br && y <= cdy){
leftmove = false; rightmove = true;
}
if(rightmove && (x ==(paddlex-br+1) || x == (paddlex-br-1) || x == paddlex-br) && y >= paddley && y <= cdy){
rightmove = false; leftmove = true;
}
if(upmove && ((y == cdy+1) || (y == cdy-1) || (y == cdy)) && x >= paddlex && x<= cdx){
upmove = false; downmove = true;
}
if(downmove && ((y == paddley - br +1) || (y == paddley - br -1) || (y == paddley - br)) && x > paddlex && x < cdx){
downmove = false; upmove = true;
}
}
public void movepaddle(){
if(shipupmove && paddley !=0){
this.paddley = paddley - 1 ;
}
if (shipdownmove && paddley < (205-psizey)){
this.paddley = paddley + 1;
}
if(paddley < 16){
shipupmove = false; shipdownmove = true;
}
if(cdy > 189){
shipupmove = true; shipdownmove = false;
}
repaint();
}
}
class test extends JPanel{
private static final long serialVersionUID = 1L;
private Map<Direction, Boolean> directionMap = new HashMap<Direction, Boolean>();
int DELAY = 5;
enum Direction {
UP(KeyEvent.VK_UP,true),
DOWN(KeyEvent.VK_DOWN, false);
private int KeyCode;
boolean moveing;
Direction(int KeyCode, boolean moveing) {
this.KeyCode = KeyCode;
this.moveing = moveing;
}
public int getKeyCode(){
return KeyCode;
}
public boolean moveing(){
return moveing;
}
}
public test(){
for(Direction direction : Direction.values()){
directionMap.put(direction, false);
}
setBindings();
Timer timer = new Timer(5, new TimerListener());
timer.start();
}
private void setBindings(){
InputMap in = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap act = getActionMap();
for(final Direction d : Direction.values()){
KeyStroke press = KeyStroke.getKeyStroke(d.getKeyCode(), 0 ,false);
KeyStroke rel = KeyStroke.getKeyStroke(d.getKeyCode(),0,true);
in.put(press, "key pressed");
in.put(rel, "key released");
act.put(d.toString()+"pressed", new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
directionMap.put(d, true);
}
});
act.put(d.toString()+"released", new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
directionMap.put(d, false);
}
});
}
}
public class TimerListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
for(Direction d : Direction.values()){
if(directionMap.get(d)){
if(d.moveing()){
System.out.println("woo");
}
}
}
}
}
}
any insight would be appreciated thank you

The "actionMapKey" Object assign to the InputMap MUST be the same you use in the ActionMap
For example...
in.put(press, "key pressed");
in.put(rel, "key released");
act.put("key pressed", new AbstractAction(){...}

Related

Ball will not bounce off paddle nor wall in my brick breaker game

I have been sitting here for 5 hours trying to make my ball bounce off the paddle and the walls when it hits it but it just goes straight through the walls and paddle then re enters through the top and the same cycle continues. I don't know where I am going wrong
My MainWindow class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
public class MainWindow extends JPanel implements KeyListener, ActionListener {
private boolean gameRunning = true;
private int BOARD_WIDTH = 500;
private int BOARD_HEIGHT = 500;
private Thread animator;
private BufferedImage img;
private Dimension dimension;
private int ballX = 20;
private int ballY = 200;
private int ballSpeedX = 4;
private int ballSpeedY = 5;
private int ballWidth = 20;
private Brick[] bricks = new Brick[24];
private boolean[] showBrick = new boolean[24];
private int paddleX = BOARD_WIDTH/2;
private int paddleY = BOARD_HEIGHT-50;
private int paddleW = 100;
private int paddleH = 10;
boolean paddleLeft = false;
boolean paddleRight = true;
private Timer timer;
private int delay = 50;
public MainWindow(){
addKeyListener(this);
//addMouseListener(this);
setFocusable(true);
dimension = new Dimension(BOARD_WIDTH, BOARD_HEIGHT);
setBackground(Color.BLACK);
int x = 20;
int y = 20;
int count = 1;
for(int i = 0; i < bricks.length; i++){
bricks[i] = new Brick(x, y, 50, 10);
showBrick[i] = true;
x += 55;
if (count%8 == 0){
x = 20;
y += 20;
}
count++;
}
timer = new Timer(delay, this);
timer.start();
//if (animator == null || !gameRunning) {
// animator = new Thread(this);
//animator.start();
//}
setDoubleBuffered(true);
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.pink);
g.fillRect(0,0, dimension.width, dimension.height);
g.setColor(Color.black);
// for the bricks
for(int i = 0; i<bricks.length; i++) {
if(showBrick[i])
g.fillRect(bricks[i].getBrickX(), bricks[i].getBrickY(),bricks[i].getBrickW(),bricks[i].getBrickH());
}
// for the paddle
g.fillRect(paddleX, paddleY, paddleW, paddleH);
// for the ball
g.fillOval(ballX, ballY, ballSpeedX,ballSpeedY);
//if (gameRunning){
//ballX+=ballSpeedX;
// movingBall();
//repaint();
//}
g.dispose();
}
private void movingBall(){
}
#Override
public void keyTyped(KeyEvent e) {
//if (e.getKeyCode() == KeyEvent.VK_RIGHT){
// paddleX+=5;
//}
}
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (e.getKeyCode() == KeyEvent.VK_RIGHT){
if(paddleX >= 385){
paddleRight = false;
}
else {
//ballX+=ballSpeedX;
paddleRight = true;
paddleX+=5;
repaint();
}
}
if (e.getKeyCode() == KeyEvent.VK_LEFT){
if(paddleX <= 10){
paddleLeft = false;
}
else {
paddleLeft = false;
paddleX-=5;
repaint();
}
}
}
#Override
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (e.getKeyCode() == KeyEvent.VK_RIGHT){
paddleRight = false;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT){
paddleLeft = false;
}
}
#Override
public void actionPerformed(ActionEvent e) {
timer.start();
if(ballX < 0 || ballX > BOARD_WIDTH){
ballSpeedX = ballSpeedX * -1;
}
if(ballY < 0){
ballSpeedY = ballSpeedY * -1;
}
if(ballY > BOARD_HEIGHT){
ballX = 20;
ballY = 200;
ballSpeedY *= -1;
}
if(ballX == paddleX && ballY == paddleY){
ballSpeedY *= -1;
}
if(ballX + ballWidth > paddleX && ballX < paddleX + paddleW && ballY + ballWidth > paddleY && ballY < paddleY + paddleH) {
ballSpeedY *= -1;
}
ballX += ballSpeedX;
ballY += ballSpeedY;
repaint();
//System.out.println("its working");
}
}
My Window class:
import javax.swing.*;
public class Window {
public Window() {
JFrame frame = new JFrame("Brick Builder Game");
frame.setDefaultCloseOperation(frame.DISPOSE_ON_CLOSE);
frame.setSize(500,500);
frame.add(new MainWindow());
frame.setVisible(true);
frame.setResizable(false);
}
public static void main(String[] args){
new Window();
}
}
My brick class:
public class Brick {
// X-position of brick
private int brickX;
// Y-position of brick
private int brickY;
// width of brick
private int brickW;
// height of brick
private int brickH;
public Brick(int brickX, int brickY, int brickW, int brickH) {
this.brickX = brickX;
this.brickY = brickY;
this.brickW = brickW;
this.brickH = brickH;
}
public int getBrickX(){
return brickX;
}
public int getBrickY(){
return brickY;
}
public int getBrickW(){
return brickW;
}
public int getBrickH(){
return brickH;
}
}
the signature for fillOval is as follows: (x_position, y_position, width, height). And in your signature, you try to use ballSpeedX and ballSpeedY as the width and height.
So when you do ballSpeedX or ballSpeedY *= -1. Swing tries to draw an oval, with negative measures, which is not possible, and thus fails to show the ball

How to add text to a game in Java

I have been working on a snake game, but an improvement I wanted to make was adding text to the game, giving instructions and keeping track of points. I messed around with JPanel and a few other things that all open a new, mini window that displays the text rather than printing it on the primary window
EDIT:
Thanks to several helpful people, I understand the correct use, but when I use it while attempting to change the color, it changes the color of the background as well. I was under the assumption this is because it's in the same class as the background, so when I put g.setColor under the background's color, it changed it.
I tried making a new object using paintComponent() while the background was in paint(), and the text didn't show up.
Any advice?
Here is the main java file:
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Random;
public class Gamepanel extends JPanel implements Runnable, KeyListener {
private static final long serialVersionUID = 1L;
public static final int WIDTH = 500, HEIGHT = 500; //window size
private Thread thread;
private boolean running; //allows the game to be started/stopped
private boolean right = true, left = false, up = false, down = false; //setting default movement
private BodyPart b;
private ArrayList<BodyPart> snake;
private Food food;
private ArrayList<Food> foods;
private Random r; //creating random integer for food spawn
private int xCoor = 10, yCoor = 10, size = 5; //setting location and coordinate size, along with snake length
private int ticks = 0;
private int points = 0;
public Gamepanel() {
setFocusable(true);
setPreferredSize(new Dimension(WIDTH, HEIGHT)); //window size
addKeyListener(this); //allows key input from user
snake = new ArrayList <BodyPart>();
foods = new ArrayList <Food>();
r = new Random(); //random integer
}
public void start() {
running = true; //allows the game to start
thread = new Thread(this);
thread.start();
}
public void stop() {
running = false; //stops the game from running
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void tick() {
if(snake.size() == 0) { //sets location
b = new BodyPart(xCoor, yCoor, 10);
snake.add(b);
}
ticks++; //constant tick increase
if(ticks > 750000) { //sets speed (higher = slower)
if(right) xCoor ++;
if(left) xCoor --;
if(up) yCoor --;
if(down) yCoor ++;
ticks = 0;
b = new BodyPart(xCoor, yCoor, 10);
snake.add(b);
if(snake.size() > size) {
snake.remove(0); //removes earliest value in snake size
}
}
if(foods.size() == 0) { //sets food in window range(multiplies by 10)
int xCoor = r.nextInt(48);
int yCoor = r.nextInt(48);
points++;
food = new Food(xCoor, yCoor, 10);
foods.add(food);
}
for (int i = 0 ; i < foods.size(); i++) { //spawns new food when old food is eaten
if(xCoor == foods.get(i).getxCoor() && yCoor == foods.get(i).getyCoor()) {
size ++;
foods.remove(i);
i++;
}
}
//player body collision
for(int i = 0 ; i < snake.size(); i++) {
if(xCoor == snake.get(i).getxCoor() && yCoor == snake.get(i).getyCoor()) {
if(i != snake.size() - 1) {
System.out.print("Game Over! " + "Points: " + points);
stop();
}
}
}
//border collision
if(xCoor < 0 || xCoor > 49 || yCoor < 0 || yCoor > 49) {
System.out.println("Game Over! " + "Points: " + points);
stop();
}
}
public void paint(Graphics g) { //background color/size setter
g.clearRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLACK); //background color
g.fillRect(0, 0, WIDTH, HEIGHT);
for(int i = 0; i < WIDTH/10 ; i++) {
g.drawLine(i * 10, 0, i * 10, HEIGHT);
}
for(int i = 0; i < HEIGHT/10 ; i++) {
g.drawLine(0, i * 10, HEIGHT, i * 10);
}
for(int i = 0 ; i < snake.size(); i++) {
snake.get(i).draw(g);
}
for(int i = 0 ; i < foods.size(); i++) {
foods.get(i).draw(g);
}
}
#Override
public void run() {
while(running) {
tick(); //runs ticks while running is true
repaint();
}
}
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT && !left) { //right key = right movement
right = true;
up = false;
down = false;
}
if(key == KeyEvent.VK_LEFT && !right) { //left key = left movement
left = true;
up = false;
down = false;
}
if(key == KeyEvent.VK_UP && !down) { //up key = up movement
up = true;
right = false;
left = false;
}
if(key == KeyEvent.VK_DOWN && !up) { //down key = down movement
down = true;
right = false;
left = false;
}
if(key == KeyEvent.VK_SPACE) {
snake.clear();
start();
size = 5;
points = 0;
xCoor = 10;
yCoor = 10;
}
}
#Override
public void keyReleased(KeyEvent arg0) {
}
#Override
public void keyTyped(KeyEvent arg0) {
}
}
Did you try this ?
public void paintComponent(Graphics g) {
super.paintComponent(g);
Font font = new Font("Verdana", Font.BOLD, 14);
g.setFont(font);
g.setColor(Color.black);
g.drawString("instructions", 75, 75);
}
as noted by #Hovercraft maybe you should be overriding the paintComponent() method instead of paint()

java - AWT fillOval not drawing new object

I'm trying to modify the sample code of an old ping-pong game from the website by adding second ball to the panel as practice. So far I'm duplicating the steps that generate the first ball. However, somehow I failed. Although the program is executable, the second ball I added didn't show up. I don't know where the problem is. The ball method is under PanelPelota class. So far I simply duplicate the variables and some functions. Here is the code:
Main class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main extends JFrame {
private static final long serialVersionUID = 1L; // Eclipse added this automatically
private JPanel jContentPane = null;
private PanelPelota panel = null; // This is the panel of the game class
private PanelPelota getPanel() {
if (panel == null) {
panel = new PanelPelota(); // The panel is created
}
return panel;
}
/**
* This is the default constructor
*/
public Main() {
super();
initialize();
// Listeners for the keyboard
this.addKeyListener(new KeyAdapter() {
// Method for the key pressed
public void keyPressed(KeyEvent evt) {
formKeyPressed(evt);
}
// Method for the key released
public void keyReleased(KeyEvent evt) {
formKeyReleased(evt);
}
});
}
// Here i'm stating the method that will send the key pressed to the game class
private void formKeyPressed(KeyEvent evt) {
panel.keyPressed(evt);
}
// Here i'm stating the method that will send the key released to the game class
private void formKeyReleased(KeyEvent evt) {
panel.keyReleased(evt);
}
/**
* This method initializes this
*
* #return void
*/
private void initialize() {
this.setResizable(false);
this.setBounds(new Rectangle(312, 184, 250, 250)); // Position on the desktop
this.setMinimumSize(new Dimension(250, 250));
this.setMaximumSize(new Dimension(250, 250));
this.setContentPane(getJContentPane());
this.setTitle("Pong");
}
/**
* This method initializes jContentPane
*
* #return javax.swing.JPanel
*/
private JPanel getJContentPane() {
if (jContentPane == null) {
jContentPane = new JPanel();
jContentPane.setLayout(new BorderLayout());
jContentPane.add(getPanel(), BorderLayout.CENTER);
}
return jContentPane;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Main thisClass = new Main();
thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thisClass.setVisible(true);
}
});
}
}
PanelPelota class
import java.awt.*;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class PanelPelota extends JPanel implements Runnable {
private static final long serialVersionUID = 1L;
// Positions on X and Y for the ball, player 1 and player 2
private int pelotaX = 10, pelotaY = 100, pelota2X = 230, pelota2Y = 100, jug1X = 10, jug1Y = 100, jug2X = 230, jug2Y = 100;
Thread hilo;
int derecha = 5;// to the right
int izquierda = -5; // to the left
int arriba = 5; // upward
int abajo = -5; // down
int ancho, alto; // Width and height of the ball
int ancho2, alto2;
// Scores
int contPlay1 = 0, contPlay2 = 0;
boolean player1FlagArr, player1FlagAba, player2FlagArr, player2FlagAba;
boolean juego, gameOver;
public PanelPelota() {
juego = true;
hilo = new Thread(this);
hilo.start();
}
// Draw ball and ships
public void paintComponent(Graphics gc) {
setOpaque(false);
super.paintComponent(gc);
// Draw ball
gc.setColor(Color.black);
gc.fillOval(pelotaX, pelotaY, 8, 8);
gc.fillOval(pelota2X, pelota2Y, 8, 8);
// Draw ships
gc.fillRect(jug1X, jug1Y, 10, 25);
gc.fillRect(jug2X, jug2Y, 10, 25);
// Draw scores
gc.drawString("Jugador1: " + contPlay1, 25, 10);
gc.drawString("Jugador2: " + contPlay2, 150, 10);
if (gameOver) {
//gc.drawString("Game Over", 100, 125);
Restart replay = new Restart();
JPanel midPanel = new JPanel();
replay.setVisible(true);
if(contPlay1 == 6)
midPanel.add(new JLabel("Player1 wins!"));
if(contPlay2 == 6)
midPanel.add(new JLabel("Player2 wins!"));
replay.setTitle("Game Over!");
replay.setSize(300, 100);
replay.setLocationRelativeTo(null);
midPanel.add(new JLabel(""));
replay.add(midPanel, BorderLayout.CENTER);
replay.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
// Positions on X and Y for the ball
public void dibujarPelota(int nx, int ny) {
pelotaX = nx;
pelotaY = ny;
this.ancho = this.getWidth();
this.alto = this.getHeight();
repaint();
}
public void dibujarPelota2(int nx, int ny) {
pelotaX = nx;
pelotaY = ny;
this.ancho2 = this.getWidth();
this.alto2 = this.getHeight();
repaint();
}
// Here we receive from the game container class the key pressed
public void keyPressed(KeyEvent evt) {
switch (evt.getKeyCode()) {
// Move ship 1
case KeyEvent.VK_W:
player1FlagArr = true;
break;
case KeyEvent.VK_S:
player1FlagAba = true;
break;
// Move ship 2
case KeyEvent.VK_UP:
player2FlagArr = true;
break;
case KeyEvent.VK_DOWN:
player2FlagAba = true;
break;
}
}
// Here we receive from the game container class the key released
public void keyReleased(KeyEvent evt) {
switch (evt.getKeyCode()) {
// Mover Nave1
case KeyEvent.VK_W:
player1FlagArr = false;
break;
case KeyEvent.VK_S:
player1FlagAba = false;
break;
// Mover nave 2
case KeyEvent.VK_UP:
player2FlagArr = false;
break;
case KeyEvent.VK_DOWN:
player2FlagAba = false;
break;
}
}
// Move player 1
public void moverPlayer1() {
if (player1FlagArr == true && jug1Y >= 0)
jug1Y += abajo;
if (player1FlagAba == true && jug1Y <= (this.getHeight() - 25))
jug1Y += arriba;
dibujarPlayer1(jug1X, jug1Y);
}
// Move player 2
public void moverPlayer2() {
if (player2FlagArr == true && jug2Y >= 0)
jug2Y += abajo;
if (player2FlagAba == true && jug2Y <= (this.getHeight() - 25))
jug2Y += arriba;
dibujarPlayer2(jug2X, jug2Y);
}
// Position on Y for the player 1
public void dibujarPlayer1(int x, int y) {
this.jug1X = x;
this.jug1Y = y;
repaint();
}
// Position on Y for the player 2
public void dibujarPlayer2(int x, int y) {
this.jug2X = x;
this.jug2Y = y;
repaint();
}
public void run() {
// TODO Auto-generated method stub
boolean izqDer = false;
boolean arrAba = false;
boolean izqDer2 = false;
boolean arrAba2 = false;
while (true) {
if (juego) {
// The ball move from left to right
if (izqDer) {
// a la derecha
pelotaX += derecha;
if (pelotaX >= (ancho - 8))
izqDer = false;
} else {
// a la izquierda
pelotaX += izquierda;
if (pelotaX <= 0)
izqDer = true;
}
// The ball moves from up to down
if (arrAba) {
// hacia arriba
pelotaY += arriba;
if (pelotaY >= (alto - 8))
arrAba = false;
} else {
// hacia abajo
pelotaY += abajo;
if (pelotaY <= 0)
arrAba = true;
}
dibujarPelota(pelotaX, pelotaY);
// The second ball move from left to right
if (izqDer2) {
// a la derecha
pelota2X += derecha;
if (pelota2X >= (ancho - 8))
izqDer2 = false;
} else {
// a la izquierda
pelota2X += izquierda;
if (pelota2X <= 0)
izqDer2 = true;
}
// The ball moves from up to down
if (arrAba2) {
// hacia arriba
pelota2Y += arriba;
if (pelota2Y >= (alto - 8))
arrAba2 = false;
} else {
// hacia abajo
pelota2Y += abajo;
if (pelota2Y <= 0)
arrAba2 = true;
}
dibujarPelota2(pelota2X, pelota2Y);
// Delay
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
}
// Move player 1
moverPlayer1();
// Move player 2
moverPlayer2();
// The score of the player 1 increase
if (pelotaX >= (ancho - 8))
contPlay1++;
// The score of the player 2 increase
if (pelotaX == 0)
contPlay2++;
// Game over. Here you can change 6 to any value
// When the score reach to the value, the game will end
if (contPlay1 == 6 || contPlay2 == 6) {
juego = false;
gameOver = true;
}
// The ball stroke with the player 1
if (pelotaX == jug1X + 10 && pelotaY >= jug1Y && pelotaY <= (jug1Y + 25))
izqDer = true;
// The ball stroke with the player 2
if (pelotaX == (jug2X - 5) && pelotaY >= jug2Y && pelotaY <= (jug2Y + 25))
izqDer = false;
// The ball2 stroke with the player 1
if (pelota2X == jug1X + 10 && pelota2Y >= jug1Y && pelota2Y <= (jug1Y + 25))
izqDer2 = true;
// The ball2 stroke with the player 2
if (pelota2X == (jug2X - 5) && pelota2Y >= jug2Y && pelota2Y <= (jug2Y + 25))
izqDer2 = false;
}
}
}
}
Restart class (created by me)
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Restart extends JFrame{
private static final long serialVersionUID = 1L;
public JButton restart = new JButton("Restart");
public Restart() {
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
JPanel bottomPanel = new JPanel();
bottomPanel.add(restart);
cp.add(bottomPanel, BorderLayout.SOUTH);
restart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Creating the window with all its awesome snaky features
Main thisClass= new Main();
thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thisClass.setVisible(true);
//Close Menu once select
String cmd = e.getActionCommand();
if(cmd.equals("Restart"))
{
dispose();
}
};
});
}
}
I'm using eclipse IDE, if it matters.
Thank you in advance.
dibujarPelota and dibujarPelota2 are assigning values to the same instance fields, effective overriding them.
public void dibujarPelota(int nx, int ny) {
pelotaX = nx;
pelotaY = ny;
this.ancho = this.getWidth();
this.alto = this.getHeight();
repaint();
}
public void dibujarPelota2(int nx, int ny) {
pelotaX = nx;
pelotaY = ny;
this.ancho2 = this.getWidth();
this.alto2 = this.getHeight();
repaint();
}
So, yes, your second ball was been updated and paint, but just at the same location as the first.
Change dibujarPelota2 to assign the nx to pelota2X and ny to pelota2Y
public void dibujarPelota2(int nx, int ny) {
pelota2X = nx;
pelota2Y = ny;
this.ancho2 = this.getWidth();
this.alto2 = this.getHeight();
repaint();
}
Also, be aware that the example you're using isn't the best example because it's updating state information that the UI relies on out side of the context of the EDT, while it might only be a minor issue, it can quickly escalate

My "Snake" app. is not displaying fully even though there are no compilation errors

I'm trying to create a version of the snake game but it is not working correctly. What it is doing now is displaying a black screen without any of the components in the paintComponent section. Occasionally it displays my "Game Over" message after a while so something is working but the snake and food are not displaying.
I've tried for hours to look for any logic error but have not been able to find any. If anyone would be able to guide me on what I am doing wrong, I would be very grateful.
Below is my code that sets up the board and underneath that is my main class that runs the program. I put the entire code just in case you wanted to run it on your own devices but the important pieces of code have 2 stars surrounding them. Any advice or suggestions would be greatly appreciated.
public class Board2 extends JPanel implements ActionListener{
private int bWidth = 500;
private int bHeight = 500;
private int segmentSize = 10;
private int bodyMax = 2500;
private int randomPos = 29;
private int delay = 140;
private int x[] = new int[bodyMax];
private int y[] = new int[bodyMax];
private int bodySize, foodX, foodY;
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 head;
private Image food;
private Image body;
Board2(){
addKeyListener(new changeDirection());
setBackground(Color.BLACK);
setPreferredSize(new Dimension(bWidth, bHeight));
loadImages();
init();
}
**private void loadImages(){
ImageIcon headImage = new ImageIcon("Square-Freemason-Symbols-300x300.png");
head = headImage.getImage();
ImageIcon foodImage = new ImageIcon("Square-Freemason-Symbols-300x300.png");
food = foodImage.getImage();
ImageIcon bodyImage = new ImageIcon("Flat1.jpg");
body = bodyImage.getImage();
}**
private void init(){
bodySize = 3;
for(int z = 0; z < bodySize; z++){
x[z] = 50 - z * 10;
y[z] = 50;
}
findFood();
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(food, foodX, foodY, this);
for(int z = 0; z < bodySize; z++){
if(z == 0){
g.drawImage(head, x[z], y[z], this);
} else {
g.drawImage(body, x[z], y[z], this);
}
}
Toolkit.getDefaultToolkit().sync();
} else {
gameOver(g);
}
}**
private void gameOver(Graphics g){
String msg = "Game Over";
Font small = new Font("Helvetiva", Font.BOLD, 14);
FontMetrics metr = getFontMetrics(small);
g.setColor(Color.WHITE);
g.setFont(small);
g.drawString(msg, (bWidth - metr.stringWidth(msg)/2), bHeight/2);
}
private void findFood(){
int r = (int) Math.random() * randomPos;
foodX = r * segmentSize;
int s = (int) Math.random() * randomPos;
foodY = s * segmentSize;
}
private void checkFood(){
if(x[0] == foodX && y[0] == foodY){
bodySize += 3;
findFood();
}
}
private void checkCollision(){
for(int z = bodySize; z > 0; z--){
if(z > 4 && x[0] == x[z] && y[0] == y[z]){
inGame = false;
}
}
if(x[0] > bWidth){
inGame = false;
}
if(x[0] < 0){
inGame = false;
}
if(y[0] >bHeight){
inGame = false;
}
if(y[0] < 0){
inGame = false;
}
}
private void Move(){
for(int z = bodySize; z > 0; z--){
x[z] = x[z - 1];
y[z] = y[z - 1];
}
if(leftDirection){
x[0] -= segmentSize;
}
if(rightDirection){
x[0] += segmentSize;
}
if(upDirection){
y[0] -= segmentSize;
}
if(downDirection){
y[0] += segmentSize;
}
}
public void actionPerformed(ActionEvent e){
if(inGame){
checkFood();
checkCollision();
Move();
}
}
public class changeDirection extends KeyAdapter{
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;
leftDirection = false;
rightDirection = false;
}
if(key == KeyEvent.VK_DOWN && !upDirection){
downDirection = true;
leftDirection = false;
rightDirection = false;
}
}
}
}
Here is the main class:
public class SnakeV2 extends JFrame{
SnakeV2(){
add(new Board2());
setResizable(false);
pack();
setTitle("SnakeV2");
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args){
EventQueue.invokeLater(new Runnable(){
#Override
public void run(){
JFrame ex = new SnakeV2();
ex.setVisible(true);
}
});
}
}

How do I add a reset option to this game?

I want players to be able to press "r" after dying and be able to restart. I think I'm supposed to put my entire code into a reset method, but I am only a beginner, and I'm not quite there yet.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JPanel;
public class Screen extends JPanel implements Runnable {
private static final long serialVersionUID = 1L;
public static final int WIDTH = 800, HEIGHT = 800;
private Thread thread;
private boolean running = false;
private BodyPart b;
private ArrayList<BodyPart> snake;
private Apple apple;
private ArrayList<Apple> apples;
private Random r;
private int xCoor = 10, yCoor = 10;
private int size = 20;
private boolean right = true, left = false, up = false, down = false;
private int ticks = 0;
private Key key;
public Screen() {
setFocusable(true);
key = new Key();
addKeyListener(key);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
r = new Random();
snake = new ArrayList<BodyPart>();
apples = new ArrayList<Apple>();
start();
}
public void tick() {
if(snake.size() == 0) {
b = new BodyPart(xCoor, yCoor, 10);
snake.add(b);
}
if(apples.size() == 0) {
int xCoor = r.nextInt(80);
int yCoor = r.nextInt(80);
apple = new Apple(xCoor, yCoor, 10);
apples.add(apple);
}
for(int i = 0; i < apples.size(); i++) {
if(xCoor == apples.get(i).getxCoor() && yCoor == apples.get(i).getyCoor()) {
size++;
apples.remove(i);
i--;
}
}
for(int i = 0; i < snake.size(); i++) {
if(xCoor == snake.get(i).getxCoor() && yCoor == snake.get(i).getyCoor()) {
if(i != snake.size() - 1) {
stop();
}
}
}
if(xCoor < -1) xCoor = 80;
if(xCoor > 80) xCoor = -1;
if(yCoor < -1) yCoor = 80;
if(yCoor > 80) yCoor = -1;
ticks++;
if(ticks > 250000) {
if(right) xCoor++;
if(left) xCoor--;
if(up) yCoor--;
if(down) yCoor++;
ticks = 185000;
b = new BodyPart(xCoor, yCoor, 10);
snake.add(b);
if(snake.size() > size) {
snake.remove(0);
}
}
}
public void paint(Graphics g) {
g.clearRect(0, 0, WIDTH, HEIGHT);
g.setColor(new Color(10, 50, 0));
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLACK);
for(int i = 0; i < WIDTH / 10; i++) {
g.drawLine(i * 10, 0, i * 10, HEIGHT);
}
for(int i = 0; i < HEIGHT / 10; i++) {
g.drawLine(0, i * 10, WIDTH, i * 10);
}
for(int i = 0; i < snake.size(); i++) {
snake.get(i).draw(g);
}
for(int i = 0; i < apples.size(); i++) {
apples.get(i).draw(g);
}
}
public void start() {
running = true;
thread = new Thread(this, "Game Loop");
thread.start();
}
public void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
while(running) {
tick();
repaint();
}
}
private class Key implements KeyListener {
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT && !left) {
up = false;
down = false;
right = true;
}
if(key == KeyEvent.VK_LEFT && !right) {
up = false;
down = false;
left = true;
}
if(key == KeyEvent.VK_UP && !down) {
left = false;
right = false;
up = true;
}
if(key == KeyEvent.VK_DOWN && !up) {
left = false;
right = false;
down = true;
}
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
}
}
Any help is greatly appreciated!
You can modify your code as follows:
I've added comments to explain my modifications
//this resets the position/size of the snake and clears the array
public void reset() {
snake.clear();
apples.clear();
xCoor = 10;
yCoor = 10;
size = 20;
running = true;
}
private class Key implements KeyListener {
//reset when you are dead and the user presses r
if (!running && (e.getKeyChar() == 'r' || e.getKeyChar() == 'R')){
reset();
}
}
public void tick() {
while (running){
//prev code
for(int i = 0; i < snake.size(); i++) {
if(xCoor == snake.get(i).getxCoor() && yCoor == snake.get(i).getyCoor()) {
if(i != snake.size() - 1) {
//don't kill the process, just stop the game and wait for the user to press 'r'
//you may need to do additional stuff here
running = false;
}
}
}
//remaining code
}
}
First of all, yes you are on the right track. The best way is to put the initilization code (setting all variables to their initial values) in a seperate method. Then when you press 'r' you simply call this method and it will 'reset' itself.
To make this happen you should do ALL variable initializations at the start. Currently you initialize b = new BodyPart(xCoor, yCoor, 10); in tick(). Since this only ever happens once (when the game started) this is better to put in your initilization method.
A rough proposal of an initilization method:
public void initialize() {
snake = new ArrayList<BodyPart>();
apples = new ArrayList<Apple>();
b = new BodyPart(xCoor, yCoor, 10);
snake.add(b);
}
This method initializes all variables that are 'resettable'. You can then call this method when the int key = e.getKeyCode(); is KeyCode.R.

Categories

Resources