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.
Related
noob here trying to make a simple snake game. followed along with tutorial on youtube and my code mayches the working code as best i can tell...snake not responding to commands, seems KeyListener not working. printed out requestFocusInWindow in jpanel constructor to make sure it was in focus and got back false, even though i entered setFocusable(true) asfirst arg in panel constructor.
please help me figure out why snake not responding to movement commands
package otherSnake;
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 Panel extends JPanel implements Runnable {
public static final int width = 800, height = 800;
private boolean running = false;
private Thread thread;
private Bodypart b;
private ArrayList<Bodypart> snake;
private Apple apple;
private ArrayList<Apple> apples;
private Random r;
private int size = 5;
private int x = 10, y = 10;
private boolean right = true, left = false, up = false, down = false;
private int ticks = 0;
private Key key;
public Panel() {
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(x, y, 10);
snake.add(b);
}
if (apples.size() == 0) {
int xCord = r.nextInt(79);
int yCord = r.nextInt(79);
apple = new Apple(xCord, yCord, 10);
apples.add(apple);
}
ticks++;
if (ticks > 250000) {
if (right)
x++;
if (left)
x--;
if (up)
y--;
if (down)
y++;
ticks = 0;
b = new Bodypart(x, y, 10);
snake.add(b);
if (snake.size() > size) {
snake.remove(0);
}
}
}
public void paint(Graphics g) {
g.clearRect(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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void run() {
while (running) {
tick();
repaint();
}
}
private class Key implements KeyListener {
#Override
public void keyTyped(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_RIGHT ) {
up = false;
down = false;
right = true;
//left=false;
}
if (key == KeyEvent.VK_LEFT ) {
up = false;
down = false;
left = true;
//right=false;
}
if (key == KeyEvent.VK_UP ) {
up = true;
down = false;
left = false;
right = false;
}
if (key == KeyEvent.VK_DOWN ) {
up = false;
down = true;
left = false;
right = false;
}
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
}
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()
When I try to control my character with the arrow keys, everything works fine but after a while I get this error:
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
and then
at java.awt.AWTEventMulticaster.keyPressed(AWTEventMulticaster.java:249)
multiple times. The class that I have isn't even 249 lines of code long so I don't know where to look for the problem. My code is very messy right now but I'll post it if it helps anyone come up with the answer.
import javax.swing.JButton;
import javax.swing.JComponent;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.image.*;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class mainFrame extends JPanel implements Runnable, KeyListener {
static boolean gameIsRunning = false;
static final int TARGET_FPS = 1;
static int x = 100;
static int y = 100;
static long startTime = 0;
static long elapsedTime = 0;
static long waitTime = 0;
JFrame window = new JFrame("Out from Eden");
JPanel panel = new JPanel();
getResources get = new getResources();
BufferedImage player = get.getImg("player");
static int playerVal = 0;
static int i = 0;
static String currentState = "";
static int lastFacing = 0;
public void createFrame() {
gameIsRunning = true;
gameStart();
}
public void setGame(boolean game) {
gameIsRunning = game;
}
public void gameStart() {
(new Thread(new mainFrame())).start();
}
public void run() {
while (gameIsRunning == true) {
startTime = System.nanoTime();
updateGame();
renderGame();
elapsedTime = System.nanoTime() - startTime;
waitTime = (TARGET_FPS * 10) - (elapsedTime / 1000000);
if (waitTime < 0) {
waitTime = 5;
}
try {
Thread.sleep(waitTime);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void updateGame() {
if (x > 800) {
x = 0;
}
if (currentState == "left") {
x--;
}
if (currentState == "right") {
x++;
}
player = royImage();
}
public BufferedImage royImage() {
if (currentState == "right") {
lastFacing = 2;
i++;
if (playerVal == 0) {
playerVal = 1;
i = 0;
player = get.getImg("royWalk1");
}
if (playerVal == 1 && i > 20) {
playerVal = 2;
i = 0;
return get.getImg("royWalk2");
}
if (playerVal == 2 && i > 20) {
playerVal = 3;
i = 0;
player = get.getImg("royWalk3");
}
if (playerVal == 3 && i > 20) {
playerVal = 4;
i = 0;
player = get.getImg("royWalk4");
}
if (playerVal == 4 && i > 20) {
playerVal = 0;
i = 0;
player = get.getImg("royWalk1");
}
}
if (currentState == "left") {
lastFacing = 1;
i++;
if (playerVal == 0) {
playerVal = 1;
i = 0;
player = get.getImg("royWalkL1");
}
if (playerVal == 1 && i > 20) {
playerVal = 2;
i = 0;
player = get.getImg("royWalkL2");
}
if (playerVal == 2 && i > 20) {
playerVal = 3;
i = 0;
player = get.getImg("royWalkL3");
}
if (playerVal == 3 && i > 20) {
playerVal = 4;
i = 0;
player = get.getImg("royWalkL4");
}
if (playerVal == 4 && i > 20) {
playerVal = 0;
i = 0;
player = get.getImg("royWalkL1");
}
}
if (currentState == "null") {
i = 0;
playerVal = 0;
if (lastFacing == 1) {
player = get.getImg("playerL");
}
if (lastFacing == 2) {
player = get.getImg("player");
}
}
return player;
}
public void renderGame() {
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 700, 500);
panel.setLayout(new BorderLayout());
window.getContentPane().add(panel);
panel.add(this);
window.setFocusable(true);
window.setFocusTraversalKeysEnabled(false);
window.setVisible(true);
window.addKeyListener(this);
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawString("Hello", x, y);
g2.drawLine(0, 63, 700, 63);
g2.drawImage(player, x - 100, y - 100, null);
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP) {
currentState = "up";
}
if (code == KeyEvent.VK_DOWN) {
currentState = "down";
}
if (code == KeyEvent.VK_LEFT) {
currentState = "left";
}
if (code == KeyEvent.VK_RIGHT) {
currentState = "right";
}
}
public void keyReleased(KeyEvent e) {
currentState = "null";
}
}
Could anyone help me figure out why I am getting the stack overflow error and how to avoid it?
Your while true loop is shooting you in the foot as you're adding a KeyListener umpteen thousand times within that loop. Don't do that, in particular your renderGame() method. Why would you even want to call a method that is for setting the GUI that many times? It would make much more sense to call that method once.
Also, instead use a Swing Timer (Google the tutorial) in place of your while loop, avoid KeyListeners in favor of Key Binding (Google the tutorial, and have a look at this example) and do your set-up code only once.
Also, your code is at risk of causing Swing threading errors as you're calling Thread.sleep(...) and while (true) in a non-background thread. For safety's sake, use a Swing Timer instead.
Also, you're comparing Strings wrong. Don't compare Strings using == or !=. Use the equals(...) or the equalsIgnoreCase(...) method instead. Understand that == checks if the two object references are the same which is not what you're interested in. The methods on the other hand check if the two Strings have the same characters in the same order, and that's what matters here. So instead of
if (fu == "bar") {
// do something
}
do,
if ("bar".equals(fu)) {
// do something
}
or,
if ("bar".equalsIgnoreCase(fu)) {
// do something
}
I want to be able to display the score to players, and have the score go up by 10 every time you get an apple. To do this though, I need to add extra space on the window to allow room for the score counter, but I can't find where to do that in my code.
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 = 900;
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 = 20, yCoor = 20;
private int size = 10;
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 reset() {
snake.clear();
apples.clear();
xCoor = 20;
yCoor = 20;
size = 10;
running = true;
}
public void tick() {
if(snake.size() == 0) {
b = new BodyPart(xCoor, yCoor, 20);
snake.add(b);
}
if(apples.size() == 0) {
int xCoor = r.nextInt(40);
int yCoor = r.nextInt(40);
apple = new Apple(xCoor, yCoor, 20);
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) {
reset();
}
}
}
if(xCoor < 0) xCoor = 40;
if(xCoor > 40) xCoor = 0;
if(yCoor < 0) yCoor = 40;
if(yCoor > 40) yCoor = 0;
ticks++;
if(ticks > 250000) {
if(right) xCoor++;
if(left) xCoor--;
if(up) yCoor--;
if(down) yCoor++;
ticks = 185000;
b = new BodyPart(xCoor, yCoor, 20);
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(20, 50, 0));
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLACK);
for(int i = 0; i < WIDTH / 20; i++) {
g.drawLine(i * 20, 0, i * 20, HEIGHT);
}
for(int i = 0; i < HEIGHT / 20; i++) {
g.drawLine(0, i * 20, WIDTH, i * 20);
}
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
}
}
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
}
Add a label on the jPanel
or add string inside your paint() method
g.drawString("Score: " + intScore, 10, 10);
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(){...}