java - AWT fillOval not drawing new object - java

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

Related

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()

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.

I am trying to repeat an if statement using a while loop, but it keeps freezing

So I am trying to make a game like Snake, but I am running into some issues.
I want to repeat the if statement inside of of the moveup class using a while loop, but
when I try to use the KeyListener to listen for the key press of the up arrow key to break the while loop it acts like it only looped once (moved up 5 pixels). The loop is supposed to make the snake continue going up without having to click multiple times, but it just moves five (the value I set it to do) pixels. Here is the code:
public class Snake extends JFrame implements KeyListener {
int ballX = 50;
int ballY = 50;
int playerX = 250;
int playerY = 250;
boolean up = false;
boolean right = false;
boolean down = false;
boolean left = true;
class DrawPane extends JPanel {
public void paintComponent(Graphics gc) {
Random rand = new Random();
int dotsX = rand.nextInt(500) + 1;
int dotsY = rand.nextInt(500) + 1;
Graphics g = this.getGraphics();
setVisible(true);
super.paintComponents(gc);
gc.setColor(Color.BLUE);
gc.fillRect(ballX, ballY, 10, 10);
gc.setColor(Color.RED);
gc.fillRect(playerX, playerY, 10, 10);
}
}
public Snake(String title) {
super(title);
JFrame frame = new JFrame();
setContentPane(new DrawPane());
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setSize(500, 500);
this.setBackground(Color.YELLOW);
this.setResizable(false);
this.addKeyListener(this);
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() == KeyEvent.VK_UP) {
up = true;
right = false;
down = false;
left = false;
moveup(e);
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
up = false;
right = false;
down = true;
left = false;
movedown(e);
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
up = false;
right = true;
down = false;
left = false;
moveright(e);
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
up = false;
right = false;
down = false;
left = true;
moveleft(e);
}
}
public void moveup(KeyEvent e) {
while (up) {
if (playerX < 500 || playerX > 0) {
playerX = playerX + 5;
repaint();
if (e.getKeyChar() == KeyEvent.VK_UP)
break;
}
}
}
public void moveright(KeyEvent e) {
if (playerX < 500 || playerX > 0) {
playerX = playerX + 5;
repaint();
// moveright();
}
}
public void movedown(KeyEvent e) {
if (playerY < 500 || playerY > 0) {
playerY = playerY + 5;
repaint();
// movedown();
}
}
public void moveleft(KeyEvent e) {
if (playerX < 500 || playerX > 0) {
playerX = playerX - 5;
repaint();
// moveleft();
}
}
public void snakePanel() {
JPanel panel1 = new JPanel();
panel1.setBackground(Color.red);
}
public void ActionListener() {
}
public static void main(String[] args) {
Snake r = new Snake("Snake");
}
}
It never loops because of the break. Effectively you're saying:
if keycode is up
loop
move up
break if keycode is up // Will always be true
More so, you shouldn't be looping in an event handler like that. Event handlers should execute and return quickly else you'll block the event thread. Should be using a timer to act as a heartbeat and update the position/repaint periodically.
Keep in mind that you DON'T want to use Swing for more advanced games in the future.
--- Quick solution:
Just remove your while(). The KeyListener interface lets you abstract the concept of "while this key is pressed, do this". Instead, when you implement the interface, you say: "whenever this key is pressed, do this". It's an event.
Here's your working code:
http://pastebin.com/b0CZDxpD

Key Bindings not responding

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(){...}

PacMan game movement

I am creating a pacman game in Java and I have 1 problem I can't get rid of.. The problem is as follows:
I have 4 buttons in the game screen for each way: up, down, left, right. The problem is that I can not use the buttons in the same time in x position as in the y position because I always get a value of 0 ( you understand this if you see my code below )
Below you can find my class for the pacman that i think is related to the problem ( see setBesturing(int besturing) method )
package h04PacMan;
/*
* PacMan laten bewegen
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PacMan extends JPanel implements ActionListener {
private int horizontalePlaats = 250; // x location
private int verticalePlaats = 150; // y location
private int richtingEnSnelheid = +10; // speed
private final int WACHTTIJD = 500; // DELAY
int diameter;
int waarde;
public PacMan() {
// create timer and start timer
javax.swing.Timer autoKlik = new javax.swing.Timer(WACHTTIJD, this);
autoKlik.start();
}
public int getHorPlaats() {
return horizontalePlaats;
}
// current y positie
public int getVerPlaats() {
return verticalePlaats;
}
// speed and way;
public int getRichtingEnSnelheid() {
return richtingEnSnelheid;
}
// new x position
public void setHorPlaats(int nieuweHorPlaats) {
if(nieuweHorPlaats > getWidth()) {
nieuweHorPlaats = 0;
}
else if(nieuweHorPlaats < 0) {
nieuweHorPlaats = getWidth();
}
horizontalePlaats = nieuweHorPlaats;
}
// new y position
public void setVerPlaats(int nieuweVerPlaats) {
if(nieuweVerPlaats > getHeight()) {
nieuweVerPlaats = 0;
}
else if(nieuweVerPlaats < 0) {
nieuweVerPlaats = getHeight();
}
verticalePlaats = nieuweVerPlaats;
}
public void setRichtingEnSnelheid(int nieuweRichtingEnSnelheid) {
richtingEnSnelheid = nieuweRichtingEnSnelheid;
}
//movement
public void setBesturing(int besturing) {
besturing = waarde;
if(waarde == 0) {
setVerPlaats( getVerPlaats() + richtingEnSnelheid);
}
else if(waarde == 1){
setHorPlaats( getHorPlaats() + richtingEnSnelheid);
}
}
#Override
public void actionPerformed(ActionEvent e) {
setBesturing(waarde);
System.out.println(waarde);
repaint();
}
DrawPacMan pacman = new DrawPacMan();
DrawPacMan ghost1 = new DrawPacMan();
DrawPacMan ghost2 = new DrawPacMan();
public void paintComponent(Graphics g) {
super.paintComponent(g);
// pacman movement
diameter = 75;
pacman.drawPacMan(g, getHorPlaats(), getVerPlaats(), diameter, Color.yellow);
// ghosts movement
int g1x;
for(g1x = 0; g1x < 10; g1x++) {
pacman.drawGhost(g, g1x, 40, diameter, Color.red);
}
pacman.drawGhost(g, 170, 70, diameter, Color.blue);
}
}
and this is the actionListener in my gamecontrol class
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == links) {
pacman.setRichtingEnSnelheid( -10 );
pacman.setBesturing(1);
System.out.println("links");
}
else if(e.getSource() == rechts) {
pacman.setRichtingEnSnelheid( +10 );
pacman.setBesturing(1);
System.out.println("rechts");
}
else if(e.getSource() == boven) {
pacman.setRichtingEnSnelheid( -10);
pacman.setBesturing(0);
System.out.println("boven");
}
else {
pacman.setRichtingEnSnelheid( +10);
pacman.setBesturing(0);
System.out.println("beneden");
}
}
Here is your problem:
//movement
public void setBesturing(int besturing) {
besturing = waarde; <-- THIS LINE
if(waarde == 0) {
setVerPlaats( getVerPlaats() + richtingEnSnelheid);
}
else if(waarde == 1){
setHorPlaats( getHorPlaats() + richtingEnSnelheid);
}
}
You are overwriting the value of besturing with the old value waarde. It should be the other way around.
//movement
public void setBesturing(int besturing) {
waarde = besturing; <-- THIS LINE
if(waarde == 0) {
setVerPlaats( getVerPlaats() + richtingEnSnelheid);
}
else if(waarde == 1){
setHorPlaats( getHorPlaats() + richtingEnSnelheid);
}
}
I think inside the method setBesturing(int besturing) should be:
waarde = besturing;
In your setBesturing method: -
besturing = waarde;
This line never changes the value of your waarde.. It is always zero.
You should do the assignment the other way : -
this.waarde = besturing;
You'll need to keep track of whether the button is pressed or not indepentently. Also, you're model doesn't support a diagonal movement at all (I'm not sure what your nederlands names exactly mean, i can interprete snelheid=Schnelligkeit=speed and some more).
You'll need to put diagonal movement into the model (e.g. give him an x and y velocity indepent from each other)

Categories

Resources