Using one keyboard for a two player game - java

I'm having some problems with a game I'm making as a project. It consists mainly of two players using the WASD to move and E to stop and the second player uses de arrow keys to move and SHIFT to stop.
The main problem I have is when both players move the rockets at the same time, when one rocket turns to the left or right the other player can't move at all to the sides or it moves forward but slowly and with the same issue, it can't move to the left or right.
Any idea on what could be the issue with the controls or anything I'm not considering in my code?
This are some of the classes for the game:
GameDraw Class, it has the movements of the players and draw the rockets.
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
class GameDraw extends JComponent{
static Jugador rocket1 = new Jugador();
static Jugador rocket2 = new Jugador();
int width = GUI.width;
int height = GUI.height;
public GameDraw() {}
public void paint(Graphics g) {
Graphics2D graphicsSet = (Graphics2D) g;
AffineTransform id = new AffineTransform();
AffineTransform id2 = new AffineTransform();
graphicsSet.setColor(Color.LIGHT_GRAY);
graphicsSet.fillRect(0, 0, getWidth(), getHeight());
graphicsSet.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphicsSet.setPaint(Color.blue);
//Player 1 Controls//
if(GUI.keyHeld_D == true && GUI.keyHeldCode == Controls.D) {
rocket1.increaseRotAngle();
}
else if(GUI.keyHeld_A == true && GUI.keyHeldCode == Controls.A) {
rocket1.decreaseRotAngle();
}
else if(GUI.keyHeld_W == true && GUI.keyHeldCode == Controls.W) {
rocket1.setMovingAngle(rocket1.getRotationAngle());
rocket1.increaseXVel(rocket1.rocketXMoveAngle(rocket1.getMovingAngle())*0.1);
rocket1.increaseYVel(rocket1.rocketYMoveAngle(rocket1.getMovingAngle())*0.1);
}
else if(GUI.keyHeld_S == true && GUI.keyHeldCode == Controls.S) {
rocket1.setMovingAngle(rocket1.getRotationAngle());
rocket1.decreaseXVel(rocket1.rocketXMoveAngle(rocket1.getMovingAngle())*0.1);
rocket1.decreaseYVel(rocket1.rocketYMoveAngle(rocket1.getMovingAngle())*0.1);
}
else if(GUI.keyHeld_E == true && GUI.keyHeldCode == Controls.E) {
rocket1.stopRocket();
}
//Player 2 Controls//
if(GUI.keyHeld_RIGHT == true && GUI.keyHeldCode == Controls.RIGHT) {
rocket2.increaseRotAngle();
}
else if(GUI.keyHeld_LEFT == true && GUI.keyHeldCode == Controls.LEFT) {
rocket2.decreaseRotAngle();
}
else if(GUI.keyHeld_UP == true && GUI.keyHeldCode == Controls.UP) {
rocket2.setMovingAngle(rocket2.getRotationAngle());
rocket2.increaseXVel(rocket2.rocketXMoveAngle(rocket2.getMovingAngle())*0.1);
rocket2.increaseYVel(rocket2.rocketYMoveAngle(rocket2.getMovingAngle())*0.1);
}
else if(GUI.keyHeld_DOWN == true && GUI.keyHeldCode == Controls.DOWN) {
rocket2.setMovingAngle(rocket2.getRotationAngle());
rocket2.decreaseXVel(rocket2.rocketXMoveAngle(rocket2.getMovingAngle())*0.1);
rocket2.decreaseYVel(rocket2.rocketYMoveAngle(rocket2.getMovingAngle())*0.1);
}
else if(GUI.keyHeld_SHIFT == true && GUI.keyHeldCode == Controls.SHIFT) {
rocket2.stopRocket();
}
rocket1.movement();
graphicsSet.setTransform(id);
graphicsSet.translate(rocket1.getXCenter(), rocket1.getYCenter());
graphicsSet.rotate(Math.toRadians(rocket1.getRotationAngle()));
graphicsSet.draw(rocket1);
rocket2.movement();
graphicsSet.setTransform(id2);
graphicsSet.translate(rocket2.getXCenter(), rocket2.getYCenter());
graphicsSet.rotate(Math.toRadians(rocket2.getRotationAngle()));
graphicsSet.draw(rocket2);
}
}
GUI Class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class GUI extends JFrame {
public static int width = 1000;
public static int height = 600;
public static boolean keyHeld_W = false, keyHeld_A = false, keyHeld_S = false, keyHeld_D = false, keyHeld_E = false, keyHeld_UP = false, keyHeld_LEFT = false, keyHeld_DOWN = false, keyHeld_RIGHT = false, keyHeld_SHIFT = false;
public static int keyHeldCode;
public GUI() {
this.setTitle("ROCKET FOOTBALL");
this.setSize(width, height);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
keyHeldCode = keyCode;
//Player 1 Controls//
if(keyHeldCode == Controls.W) {
Jugador.interaction_W = true;
keyHeld_W = true;
}
if(keyHeldCode == Controls.A) {
Jugador.interaction_A = true;
keyHeld_A = true;
}
if(keyHeldCode == Controls.S) {
Jugador.interaction_S = true;
keyHeld_S = true;
}
if(keyHeldCode == Controls.D) {
Jugador.interaction_D = true;
keyHeld_D = true;
}
if(keyHeldCode == Controls.E) {
Jugador.interaction_E = true;
keyHeld_E = true;
}
//Player 2 Controls//
if(keyHeldCode == Controls.UP) {
Jugador.interaction_UP = true;
keyHeld_UP = true;
}
if(keyHeldCode == Controls.LEFT) {
Jugador.interaction_LEFT = true;
keyHeld_LEFT = true;
}
if(keyHeldCode == Controls.DOWN) {
Jugador.interaction_DOWN = true;
keyHeld_DOWN = true;
}
if(keyHeldCode == Controls.RIGHT) {
Jugador.interaction_RIGHT = true;
keyHeld_RIGHT = true;
}
if(keyHeldCode == Controls.SHIFT) {
Jugador.interaction_SHIFT = true;
keyHeld_SHIFT = true;
}
}
public void keyReleased(KeyEvent e) {
//Player 1//
if(keyHeldCode == Controls.W) {
keyHeld_W = false;
}
if(keyHeldCode == Controls.A) {
keyHeld_A = false;
}
if(keyHeldCode == Controls.S) {
keyHeld_S = false;
}
if(keyHeldCode == Controls.D) {
keyHeld_D = false;
}
if(keyHeldCode == Controls.E) {
keyHeld_E = false;
}
//Player 2//
if(keyHeldCode == Controls.UP) {
keyHeld_UP = false;
}
if(keyHeldCode == Controls.LEFT) {
keyHeld_LEFT = false;
}
if(keyHeldCode == Controls.DOWN) {
keyHeld_DOWN = false;
}
if(keyHeldCode == Controls.RIGHT) {
keyHeld_RIGHT = false;
}
if(keyHeldCode == Controls.SHIFT) {
keyHeld_SHIFT = false;
}
}
});
GameDraw gamePanel = new GameDraw();
this.add(gamePanel, BorderLayout.CENTER);
ScheduledThreadPoolExecutor ex = new ScheduledThreadPoolExecutor(2);
ex.scheduleAtFixedRate(new RepaintTheBoard(this), 0L,20L, TimeUnit.MILLISECONDS);
this.setResizable(false);
this.setVisible(true);
}
}

when one rocket turns to the left or right the other player can't move at all
KeyEvents can only be generated for the last key pressed. So basically you need to keep track of a key as it is pressed and you need to use a Timer to schedule the animation. So every time the Timer fires, you check which keys are currently pressed and invoke the appropriate action.
also on using keybindings
Yes, key bindings is the preferred approach as it removes focus issues.
Check out the KeyboardAnimation example found in Motion Using the Keyboard. The example uses the 4 arrow keys for one player and WASD for the other player with a couple of differences:
You can hold two keys down at the same time to have diagonal movement
You need to release the keys to stop the motion

Related

Graphics not moving automatically and also makes copies instead of moving when pressing arrow keys

I'm working on a snake game, and I'm trying to make the snake move to the right. The issue here is the snake isn't actually moving, it just seems to copy itself to the right and also it's not going to the right automatically you have to keep pressing the key.
I am really not sure what the issue is, I made some code without any images. That should make the code run able for testing as it is.
public class Game{
static Graphics g;
public static void main(String[] args) {
JFrame b = new JFrame("Snake");
b.setBounds(300,60,905,700);
b.setBackground(Color.DARK_GRAY);
b.setResizable(false);
Snake snake = new Snake();
b.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
b.add(snake);
b.setVisible(true);
}
}
public class Snake extends JPanel implements KeyListener,ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
private int[] snakeXlength = new int [750];
private int[] snakeYlength = new int [750];
private boolean right = true;
private boolean left = false;
private boolean up = false;
private boolean down = false;
private ImageIcon rightmouth;
private ImageIcon snakeimage;
private ImageIcon leftmouth;
private ImageIcon downmouth;
private ImageIcon upmouth;
private ImageIcon enemy;
private Timer timer;
private int snakeDelay = 100;
private int moves = 1;
private int lengtOfSnake = 3;
public Snake(){
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
timer = new Timer(snakeDelay, this);
timer.start();
}
public void paint(Graphics g) {
g.setColor(Color.WHITE);
g.drawRect (20, 24, 851, 612);
g.setColor(Color.BLACK);
g.fillRect (21, 25, 850, 610);
if (moves == 0) {
snakeXlength[2]= 63;
snakeXlength[1]= 83;
snakeXlength[0]= 100;
snakeYlength[2]= 100;
snakeYlength[1]= 100;
snakeYlength[0]= 98;
rightmouth = new ImageIcon("rightmouth.png");
rightmouth.paintIcon(this, g, snakeXlength[0], snakeYlength[0]);
}
for(int a = 0; a < lengtOfSnake; a++) {
if (a == 0 && right) {
if (a == 0 && right) {
g.setColor(Color.RED);
g.drawRect(5,10,snakeXlength[a],snakeYlength[a]);
g.fillRect (snakeXlength[a],snakeYlength[a],21,21);
g.drawRect(5,10,snakeXlength[a],snakeYlength[a]);
// rightmouth = new ImageIcon("rightmouth.png");
//rightmouth.paintIcon(this, g, snakeXlength[a], snakeYlength[a]);
}
if (a == 0 && left) {
leftmouth = new ImageIcon("leftmouth.png");
leftmouth.paintIcon(this, g, snakeXlength[a], snakeYlength[a]);
}
if (a == 0 && down) {
downmouth = new ImageIcon("downmouth.png");
downmouth.paintIcon(this, g, snakeXlength[a], snakeYlength[a]);
}
if (a == 0 && up) {
upmouth = new ImageIcon("uptmouth.png");
upmouth.paintIcon(this, g, snakeXlength[a], snakeYlength[a]);
}
if (a != 0) {
g.setColor(Color.GREEN);
g.fillOval(snakeXlength[a],snakeYlength[a],17,17);
//snakeimage = new ImageIcon("snakeimage.png");
//snakeimage.paintIcon(this, g, snakeXlength[a], snakeYlength[a]);
}
}
g.dispose();
}
public void keyPressed(KeyEvent e) {
timer.start();
if(right) {
for (int r = lengtOfSnake-1; r >= 0;r--) {
snakeYlength[r+1] = snakeYlength[r];
}
for(int r = lengtOfSnake;r >=0;r--) {
if(r==0) {
snakeXlength[r] = snakeXlength[r] +25;
}
else {
snakeXlength[r] = snakeXlength[r-1];
}
if(snakeXlength[r] > 850){
snakeXlength[r] = 25;
}
}
repaint();
}
if(left) {
}
if(up) {
}
if(down) {
}
}
#Override
public void keyTyped(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
moves++;
right = true;
if(left != true) {
right = true;
}
else
{
right = false;
left = true;
}
down = false;
up = false;
}
if(e.getKeyCode() == KeyEvent.VK_LEFT) {
moves++;
left = true;
if(right != true) {
left = true;
}
else
{
left = false;
right = true;
}
down = false;
up = false;
} if(e.getKeyCode() == KeyEvent.VK_UP) {
moves++;
up = true;
if(down != true) {
up = true;
}
else
{
up = false;
down = true;
}
left = false;
right = false;
}
if(e.getKeyCode() == KeyEvent.VK_DOWN) {
moves++;
down = true;
if(up != true) {
down = true;
}
else
{
up = true;
down = false;
}
left = false;
right = false;
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
it just seems to copy itself to the right
public void paint(Graphics g)
{
g.setColor(Color.WHITE);
Custom painting should be done by overriding paintComponent(...) and then you need to invoke super.paintComponent(...):
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.WHITE);
This will make sure the background of the panel is cleared before doing the custom painting.
it's not going to the right automatically you have to keep pressing the key.
Well, that is usually the way a game is designed. You only have motion when the key is pressed as this will keep generating events. Then if you don't want motion you just don't press any keys.
If you want animation then you use a Swing Timer. Each time the Timer fires you invoke a move(...) method. This method would need to look at your "direction" variable to determine whether to move the snake left, right, up or down.
Check out:
Motion Using the Keyboard for animation when a key is pressed and held and
get width and height of JPanel outside of the class for continuous animation

Repaint Not Always Working

I have the location and previous location of my character repainted every time it moves. This works, most of the time. Occasionally and seemingly randomly, the image of the character will be left behind, and not repainted, even after continued movement.
Class that deals with Graphics and Character Movement:
public class GameState extends JFrame implements KeyListener {
Container contentPane=this.getContentPane();
Graphics bufferGraphics;
int characterX=463;
int characterY=486;
int oldCharacterX=463;
int oldCharacterY=486;
int xAxis;
int yAxis;
Image characterNorth = CustomImages.createImageIcon("Images/characterNorth.jpg").getImage();
Image characterEast = CustomImages.createImageIcon("Images/characterEast.jpg").getImage();
Image characterSouth = CustomImages.createImageIcon("Images/characterSouth.jpg").getImage();
Image characterWest = CustomImages.createImageIcon("Images/characterWest.jpg").getImage();
Image brickWall = CustomImages.createImageIcon("Images/brickWall.jpg").getImage();
Image brickFloor = CustomImages.createImageIcon("Images/brickFloor.jpg").getImage();
Image character=characterNorth;
boolean pressed=false;
ArrayList<RoomState> map = new ArrayList<RoomState>();
RoomState currentRoom = new RoomState();
RoomState currentRoomState=new RoomState();
GameState() {
this.setBounds(0, 0, 1680, 1050);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(this);
setFocusable(true);
requestFocusInWindow();
}
public void move(int x, int y) { //Check Move
currentRoomState=currentRoomState.MoveToNextRoom(true, false, false, false);
currentRoomState=currentRoomState.MoveToNextRoom(false, true, false, false);
currentRoomState=currentRoomState.MoveToNextRoom(false, false, true, false);
currentRoomState=currentRoomState.MoveToNextRoom(false, false, false, true);
}
public void paint(Graphics g) { //Graphics
for(xAxis=58;xAxis<=858;xAxis=xAxis+50) {
for(yAxis=81;yAxis<=881;yAxis=yAxis+50) {
g.drawImage(brickFloor,xAxis,yAxis,null);
}
yAxis=31;
}
for(xAxis=8;xAxis<958;xAxis=xAxis+50) {
g.drawImage(brickWall,xAxis,yAxis,null);
}
yAxis=931;
for(xAxis=8;xAxis<=908;xAxis=xAxis+50) {
g.drawImage(brickWall,xAxis,yAxis,null);
}
xAxis=8;
for(yAxis=81;yAxis<=881;yAxis=yAxis+50) {
g.drawImage(brickWall,xAxis,yAxis,null);
}
xAxis=908;
for(yAxis=81;yAxis<=881;yAxis=yAxis+50) {
g.drawImage(brickWall,xAxis,yAxis,null);
}
if(currentRoom.northDoor) {
g.drawImage(brickFloor,458,31,null);
}
if(currentRoom.eastDoor) {
g.drawImage(brickFloor,908,481,null);
}
if(currentRoom.southDoor) {
g.drawImage(brickFloor,458,931,null);
}
if(currentRoom.westDoor) {
g.drawImage(brickFloor,8,481,null);
}
g.drawImage(character,characterX,characterY,null);
}
#Override
public void keyPressed(KeyEvent arg0) { //Character Rotation/Movement.
if(pressed==false) {
pressed=true;
if(arg0.getKeyCode() == KeyEvent.VK_W || arg0.getKeyCode() == KeyEvent.VK_UP) {
if(character==characterNorth) {
if(characterY>86 && characterX>13 && characterX<913) {
characterY=characterY-50;
}else if(currentRoom.northDoor && characterX==463) {
oldCharacterY=characterY;
characterY=characterY-50;
if(characterY==-14) {
RoomState nextRoom = new RoomState();
nextRoom.southDoor = true;
nextRoom.rs_SouthDoor = currentRoom;
currentRoom.rs_NorthDoor = nextRoom;
map.add(nextRoom);
currentRoom = nextRoom;
nextRoom = null;
characterX=463;
characterY=936;
repaint();
}
}
}else {
character=characterNorth;
}
}
if(arg0.getKeyCode() == KeyEvent.VK_A || arg0.getKeyCode() == KeyEvent.VK_LEFT) {
if(character==characterWest && characterY>36 && characterY<926) {
if(characterX>63) {
oldCharacterX=characterX;
characterX=characterX-50;
}else if(currentRoom.westDoor && characterY==486) {
oldCharacterX=characterX;
characterX=characterX-50;
if(characterX==-37) {
RoomState nextRoom = new RoomState();
nextRoom.eastDoor = true;
nextRoom.rs_EastDoor = currentRoom;
currentRoom.rs_WestDoor = nextRoom;
map.add(nextRoom);
currentRoom = nextRoom;
nextRoom = null;
characterX=913;
characterY=486;
repaint();
}
}
}else {
character=characterWest;
}
}
if(arg0.getKeyCode() == KeyEvent.VK_S || arg0.getKeyCode() == KeyEvent.VK_DOWN) {
if(character==characterSouth) {
if(characterY<871 && characterX>13 && characterX<913) {
oldCharacterY=characterY;
characterY=characterY+50;
}else if(currentRoom.southDoor && characterX==463) {
oldCharacterY=characterY;
characterY=characterY+50;
if(characterY==986) {
RoomState nextRoom = new RoomState();
nextRoom.northDoor = true;
nextRoom.rs_NorthDoor = currentRoom;
currentRoom.rs_SouthDoor = nextRoom;
map.add(nextRoom);
currentRoom = nextRoom;
nextRoom = null;
characterX=463;
characterY=36;
repaint();
}
}
}else {
character=characterSouth;
}
}
if(arg0.getKeyCode() == KeyEvent.VK_D || arg0.getKeyCode() == KeyEvent.VK_RIGHT) {
if(character==characterEast && characterY>36 && characterY<926) {
if(characterX<848) {
oldCharacterX=characterX;
characterX=characterX+50;
}else if(currentRoom.eastDoor && characterY==486) {
oldCharacterX=characterX;
characterX=characterX+50;
if(characterX==963) {
RoomState nextRoom = new RoomState();
nextRoom.westDoor = true;
nextRoom.rs_WestDoor = currentRoom;
currentRoom.rs_EastDoor = nextRoom;
map.add(nextRoom);
currentRoom = nextRoom;
nextRoom = null;
characterX=13;
characterY=486;
repaint();
}
}
}else {
character=characterEast;
}
}
repaint(oldCharacterX,oldCharacterY,40,40);
repaint(characterX,characterY,40,40);
}
}
#Override
public void keyReleased(KeyEvent arg0) { //Prevents Holding Down Keys.
if(arg0.getKeyCode() == KeyEvent.VK_W || arg0.getKeyCode() == KeyEvent.VK_UP) {
pressed=false;
}
if(arg0.getKeyCode() == KeyEvent.VK_A || arg0.getKeyCode() == KeyEvent.VK_LEFT) {
pressed=false;
}
if(arg0.getKeyCode() == KeyEvent.VK_S || arg0.getKeyCode() == KeyEvent.VK_DOWN) {
pressed=false;
}
if(arg0.getKeyCode() == KeyEvent.VK_D || arg0.getKeyCode() == KeyEvent.VK_RIGHT) {
pressed=false;
}
}
#Override
public void keyTyped(KeyEvent arg0) {
}
}
You set either oldCharacterX or oldCharacterY in your keyPressed() method, depending on which key is pressed. Yet, sometimes you set both the X and Y coordinates! It looks like the one of the sets should be a no-op, but why take the risk?
Instead you should unconditionally set both at the top of the function. Then, you can remove the redundant settings of oldCharacterX/Y in each keypress case.
public void keyPressed(KeyEvent arg0) {
if(pressed==false) {
pressed=true;
oldCharacterX = characterX;
oldCharacterY = characterY;
//... keypress handling ...
if (oldCharacterX != characterX || oldCharacterY != characterY) {
// Only need to repaint old position if it is different from the new
repaint(oldCharacterX, oldCharacterY, 40, 40);
}
repaint(characterX, characterY, 40, 40);
}
}

Why does my image flicker in java jframe?

This is the code for my game. The entire image flickers every 30 ms (aprox)
public class MainGame extends Canvas implements Runnable, KeyListener, MouseListener, MouseMotionListener {
boolean isRunning = false;
public boolean isClicked, isReleased, lClick, rClick, down, up, upPressed;
public boolean drawArrow;
public boolean lastLeft, lastRight, goingLeft, goingRight, left, right;
public int x = 0, y = 0, aX = 250, aY = 250;
double modifier = 4;
public Graphics g;
ImageIcon background = new ImageIcon("F:/workspace/RPGGame/src/healy.jpg");
Image picture = background.getImage();
Image offscreen;
ControlBase base = new ControlBase();
Graphics buffer;`
private boolean fireLeft;
private boolean fireRight;
private int arrowCounter = 0;
public MainGame () {
base.frame.setVisible(true);
base.frame.setResizable(false);
base.frame.setMinimumSize(new Dimension(1024, 768));
base.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
base.frame.setLocationRelativeTo(null);
base.frame.addMouseListener(this);
base.frame.addKeyListener(this);
JPanel panel = new JPanel();
Container pane = base.frame.getContentPane();
pane.add(panel);
pane.paint(g);
base.frame.setVisible(true);
Graphics g = base.frame.getGraphics();
g.drawImage(picture, x, y, this);
}
public void run() {
while(isRunning) {
paint(base.frame.getGraphics());
//moves left
if (left == true){
x+=1;
lastLeft = true;
lastRight = false;
}
//moves right
if (right == true){
x-=1;
lastLeft = false;
lastRight = true;
}
//moves down
if (down == true){
y-=1;
}
if (goingLeft == true) {
aX--;
}
if (goingRight == true) {
aX++;
}
if(attackStyle == 1) {
melee();
}
else if (attackStyle == 2) {
range();
}
else {
magic();
}
System.out.println(arrowCounter);
base.arrowMech();
fireLeft = base.fireLeft;
fireRight = base.fireRight;
base.frame.repaint();
}
}
#Override
public void paint(Graphics g) {
super.paint(g);
g.clearRect(0, 0, 1024, 768);
g.setColor(Color.red);
g.fillOval(250, 250, 20, 20);
g.drawImage(picture, x, y, this);
if (drawArrow == true) {
if (fireLeft) {
arrowCounter++;
goingLeft = true;
goingRight = false;
base.drawArrow(g);
}
if (fireRight) {
arrowCounter++;
goingLeft = false;
goingRight = true;
base.drawArrow(g);
}
}
if ((arrowCounter >=450) || (!drawArrow)){
arrowCounter = 0;
aX = 250;
aY = 250;
}
}
public void update(Graphics g) {
repaint();
}
public void start() {
isRunning = true;
new Thread(this).start();
}
public void stop() {
isRunning = false;
}
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void mouseClicked(MouseEvent click) {
if(click.getButton() == 1) {
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
/** This method handles mouse clicks
*/
public void mousePressed(MouseEvent click) {
if(SwingUtilities.isLeftMouseButton(click)) {
lClick = true;
}
else if (SwingUtilities.isRightMouseButton(click)) {
rClick = true;
}
}
/** This method handles the release of mouse clicks
*/
public void mouseReleased(MouseEvent release) {
if(SwingUtilities.isLeftMouseButton(release)) {
lClick = false;
}
else if (SwingUtilities.isRightMouseButton(release)) {
rClick = false;
}
}
/**
* This method handle the movement for the character and all other key binds
*/
public void keyPressed(KeyEvent e) {
//left arrow
if(e.getKeyCode() == 37 || e.getKeyCode() == 65){
left = true;
}
//up arrow
if(e.getKeyCode() == 38 || e.getKeyCode() == 87){
up = true;
upPressed = true;
down = false;
}
//right arrow
if(e.getKeyCode() == 39 || e.getKeyCode() == 68){
right = true;
}
//down arrow
if(e.getKeyCode() == 40 || e.getKeyCode() == 83){
down = true;
}
}
/**
* This method handles the stopping of movement for the character and stoping all other key binds
*/
public void keyReleased(KeyEvent e) {
//left arrow
if(e.getKeyCode() == 37 || e.getKeyCode() == 65){
left = false;
}
//up arrow
if(e.getKeyCode() == 38 || e.getKeyCode() == 87){
up = false;
upPressed = false;
}
//right arrow
if(e.getKeyCode() == 39 || e.getKeyCode() == 68){
right = false;
}
//down arrow
if(e.getKeyCode() == 40 || e.getKeyCode() == 83){
down = false;
}
}
public void keyTyped(KeyEvent e) {
}
Any help would be appreciated. Have tried using a bufferstrategy to no avail. Is there any other way to do it without using a bufferstrategy?
I don't think you need to call the paint(Graphics g) method. It should be called automatically by the parent when needed. Especially since you are calling repaint at the end of the code

Having trouble with java keyPressed and keyReleased in pong

So I'm trying to move the paddles by incrementing them when the certain key is pressed. I'm doing it this way because because when I didn't use keyrelease, you could not move both of them at the same time.
The problem I am running into now is if I press a direction it will go(both of them can go at the same time which is good), but it will stop once I press the opposite key, and will not be able to move again. Any tips?
Here is all of that stuff I'm talking about
public void paddleMove(){
if(leftDown==true){
y-=10;
}
if(leftUp ==true){
y+=10;
}
if(rightDown ==true){
ytwo-=10;
}
if(rightUp ==true){
ytwo+=10;
}
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_A || e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_QUOTE || e.getKeyCode() == KeyEvent.VK_SEMICOLON){
if(e.getKeyCode() == KeyEvent.VK_A){
// y-=10;
leftDown = true;
}
if(e.getKeyCode() == KeyEvent.VK_S){
// y+=10;
leftUp = true;
}
if(e.getKeyCode() == KeyEvent.VK_QUOTE){
// ytwo-=10;
rightDown = true;
}
if(e.getKeyCode() == KeyEvent.VK_SEMICOLON){
//ytwo+=10;
rightUp = true;
}
}
}
public void keyRelease(KeyEvent r){
if(r.getKeyCode() == KeyEvent.VK_A){
leftDown = false;
}
if(r.getKeyCode() == KeyEvent.VK_S){
leftUp = false;
}
if(r.getKeyCode() == KeyEvent.VK_QUOTE){
rightDown = false;
}
if(r.getKeyCode() == KeyEvent.VK_SEMICOLON){
rightUp = false;
}
}
Here is the full code
import java.awt.Color;
import java.awt.Event;
import java.awt.Graphics;
import java.util.Random;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Pong extends JFrame implements ActionListener{
//implement constants
PongPanel pongPanel = new PongPanel();
//JFrame pong x and y coordinates
static final int jfpX = 150;
static final int jfpY = 20;
// JFrame pong width and height
static final int jfpW = 800;
static final int jfpH = 600;
Thread thrd;
public static void main(String[] args) {
Pong jfp = new Pong();
jfp.setVisible(true);
}
public Pong(){
setBounds(jfpX,jfpY,jfpW,jfpH);
setTitle("Pong");
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setBackground(Color.black);
add(pongPanel);
addKeyListener(pongPanel);
thrd = new Thread (pongPanel);
thrd.start();
}
public void actionPerformed(ActionEvent e) {
}
}
class PongPanel extends JPanel implements Runnable, KeyListener{
Random random = new Random();
static final int jpW = 800;
static final int jpH = 600;
int paddleStart = (jpH/2)-35;
int paddleStarttwo = (jpH/2)-35;
int ballStartX = (jpW/2)-20;
int ballStartY = (jpH/2)-20;
int ytwo,x,y;
int ballD = 30;
int paddleW1 = 20;
int paddleH1 = 100;
int paddleW2 = 20;
int paddleH2 = 100;
int min = -2;
int max = 2;
int randomBallx, randomBally;
boolean leftUp = false;
boolean leftDown = false;
boolean rightUp = false;
boolean rightDown = false;
// int randomBallx = random.nextInt(max-min+1)+min;
// int randomBally = random.nextInt(max-min+1)+min;
int rand1 = random.nextInt(2-1 + 1)+1; // random for function to determine ballx and bally
int rand2 = random.nextInt(2-1+2)+1;
int dx = 4;
int dy = 4; //direction of y
public void ballNotZero(){// makes sure the ball doesnt go straight up and down
if (randomBallx ==0){
randomBallx = random.nextInt(max-min+1)+min;
}
if(randomBally == 0){
randomBally=random.nextInt(max-min+1)+min;
}
// if(rand1 ==1){
// randomBallx=-1;
// }
// if(rand1 ==2){
// randomBallx=1;
// }
// if(rand2 ==1){
// randomBally =-1;
// }
// if(rand2==2){
// randomBally = 1;
// }
}
public PongPanel(){
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Color ball;
Color paddleOne;
Color paddleTwo;
ball = new Color(255,0,255);
paddleOne = new Color(255,0,0);
paddleTwo = new Color(0,0,255);
g.setColor(ball);
g.fillOval(ballStartX+randomBallx,ballStartY+randomBally,ballD,ballD);
g.setColor(paddleOne);
g.fillRect(20,paddleStart+y,paddleW1,paddleH1);
g.setColor(paddleTwo);
g.fillRect(760,paddleStarttwo+ytwo,paddleW2,paddleH2);
}
public void run() {
while(true){
ballNotZero();
detectPaddle();
paddleMove();
randomBall();
ballMove();
repaint();
try {Thread.sleep(75); } catch(Exception e){
}
}
}
public static boolean intervallContains(int low, int high, int n) { //determines if something is in a certain range
return n >= low && n <= high;
}
public void detectPaddle(){ //determines if ball is close enough to paddle for detection
int withinY = (paddleStart+y) -(ballStartY+randomBally);
int withinY1 = (paddleStarttwo+ytwo)-(ballStartY+randomBally);
if (ballStartX+randomBallx <=20 && intervallContains(-50,50,withinY)){
dx = -dx;
}
if(ballStartX+randomBallx >=760 && intervallContains(-50,50,withinY1)){
dx = -dx;
}
}
public void randomBall(){
if(randomBallx >=0 ){
randomBallx+=dx;
}
if(randomBallx<0){
randomBallx-=dx;
}
if(randomBally>=0){
randomBally+=dy;
}
if(randomBally<0){
randomBally-=dy;
}
// randomBallx+=randomBallx;
// randomBally+=randomBally;
}
public void ballMove(){
if(ballStartY+randomBally > jpH-60){
dy= -dy;
}
if(ballStartY+randomBally <0){
dy = -dy;
}
}
public void paddleMove(){
if(leftDown==true){
y-=10;
}
if(leftUp ==true){
y+=10;
}
if(rightDown ==true){
ytwo-=10;
}
if(rightUp ==true){
ytwo+=10;
}
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_A || e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_QUOTE || e.getKeyCode() == KeyEvent.VK_SEMICOLON){
if(e.getKeyCode() == KeyEvent.VK_A){
// y-=10;
leftDown = true;
}
if(e.getKeyCode() == KeyEvent.VK_S){
// y+=10;
leftUp = true;
}
if(e.getKeyCode() == KeyEvent.VK_QUOTE){
// ytwo-=10;
rightDown = true;
}
if(e.getKeyCode() == KeyEvent.VK_SEMICOLON){
//ytwo+=10;
rightUp = true;
}
}
}
public void keyRelease(KeyEvent r){
if(r.getKeyCode() == KeyEvent.VK_A){
leftDown = false;
}
if(r.getKeyCode() == KeyEvent.VK_S){
leftUp = false;
}
if(r.getKeyCode() == KeyEvent.VK_QUOTE){
rightDown = false;
}
if(r.getKeyCode() == KeyEvent.VK_SEMICOLON){
rightUp = false;
}
}
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Take a look at your logic...
if (e.getKeyCode() == KeyEvent.VK_A) {
// y-=10;
leftDown = true;
}
if (e.getKeyCode() == KeyEvent.VK_S) {
// y+=10;
leftUp = true;
}
This basically says that if I press the A AND S then leftDown and leftUp can be true simultaneously, which is, obviously not possible (for what you want to do), they need to cancel each other out...
It should read more like...
if (e.getKeyCode() == KeyEvent.VK_A) {
// y-=10;
leftDown = true;
leftUp = false;
}
if (e.getKeyCode() == KeyEvent.VK_S) {
// y+=10;
leftUp = true;
leftDown = false
}
Instead. This means if I press A, leftDown is true and leftUp is false, but if I then also press S, then leftDown is false and leftUp is true. This means that the player can only move in a single direction, regardless of what sequence of keys they press.
While I'm here...
This if (e.getKeyCode() == KeyEvent.VK_A || e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_QUOTE || e.getKeyCode() == KeyEvent.VK_SEMICOLON) { is redundant and adds no value to your code, you're going to check for these states any way...
Rather then using a bunch of disconnected if statements like...
if (e.getKeyCode() == KeyEvent.VK_A) {
//...
}
if (e.getKeyCode() == KeyEvent.VK_S) {
//...
}
if (e.getKeyCode() == KeyEvent.VK_QUOTE) {
//...
}
if (e.getKeyCode() == KeyEvent.VK_SEMICOLON) {
//...
}
You should be using if-else statements....
if (e.getKeyCode() == KeyEvent.VK_A) {
//...
} else if (e.getKeyCode() == KeyEvent.VK_S) {
//...
} else if (e.getKeyCode() == KeyEvent.VK_QUOTE) {
//...
} else if (e.getKeyCode() == KeyEvent.VK_SEMICOLON) {
//...
}
It's really, really, minor, but makes it more obvious that you are intending to check a single state, as the KeyEvent is only ever going to be for a single key...
Oh, I should also add, use Key Bindings instead of KeyListeners. KeyListener suffers from to many focus related issues which you will not want to have to deal with...

Java key listener press once

I have a key listener in my program and for most keys I want the user to be able to hold down a key. However the key for screenshots I want the user to be able to hold down the key yet it only takes one screenshot any ideas?
package me.bevilacqua.game;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class InputHandler implements KeyListener{
private boolean[] keys = new boolean[120];
public boolean up , down , left , right , screen_shot;
public void tick() {
up = keys[KeyEvent.VK_UP] || keys[KeyEvent.VK_W]; //Will be Jump
down = keys[KeyEvent.VK_DOWN] || keys[KeyEvent.VK_S]; //Will not be down but maybe slide or better yet action key or maybe shoot
left = keys[KeyEvent.VK_LEFT] || keys[KeyEvent.VK_A];
right = keys[KeyEvent.VK_RIGHT] || keys[KeyEvent.VK_D];
screen_shot = keys[KeyEvent.VK_F5] || keys[KeyEvent.VK_BACK_SLASH];
}
public void keyPressed(KeyEvent e) {
keys[e.getKeyCode()] = true;
}
public void keyReleased(KeyEvent e) {
keys[e.getKeyCode()] = false;
}
public void keyTyped(KeyEvent e) {
}
}
EDIT:
Why doesn't this work:
package me.bevilacqua.game;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Timer;
public class InputHandler implements KeyListener{
private boolean[] keys = new boolean[120];
public long current , last = -1;
public boolean up , down , left , right , screen_shot;
public boolean shotFlag = true; //True if allowed
public void tick() {
up = keys[KeyEvent.VK_UP] || keys[KeyEvent.VK_W]; //Will be Jump
down = keys[KeyEvent.VK_DOWN] || keys[KeyEvent.VK_S]; //Will not be down but maybe slide or better yet action key or maybe shoot
left = keys[KeyEvent.VK_LEFT] || keys[KeyEvent.VK_A];
right = keys[KeyEvent.VK_RIGHT] || keys[KeyEvent.VK_D];
screen_shot = keys[KeyEvent.VK_F5];
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() != KeyEvent.VK_F5) keys[e.getKeyCode()] = true;
else if (e.getKeyCode() == KeyEvent.VK_F5 && shotFlag) {
keys[e.getKeyCode()] = true;
shotFlag = false;
}
}
public void keyReleased(KeyEvent e) {
keys[e.getKeyCode()] = false;
if(e.getKeyCode() == KeyEvent.VK_F5) shotFlag = true;
}
public void keyTyped(KeyEvent e) {
}
}
From what I understand, the action associated with every key repeats when the appropriate key is held down and you want to stop one of those actions from repeating even when the corresponding key is held down. I think you can solve this with an additional flag that is set when keyPressed() is called. Then screen_shot is only set in tick() when this flag is set and the flag is unset every time tick() is called (after reading its value of course). Alternatively, you can unset the flag only when it is set and you are setting the screen_shot flag. I don't think it makes any difference either way.
You could try it like this:
public boolean up = false;
public boolean down = false;
public boolean left = false;
public boolean right = false;
public boolean screen_shot = false;
//...
f.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_D)
{
right = true;
}
if (e.getKeyCode() == KeyEvent.VK_A)
{
left = true;
}
if (e.getKeyCode() == KeyEvent.VK_S)
{
down = true;
}
if (e.getKeyCode() == KeyEvent.VK_W)
{
up = true;
}
if (e.getKeyCode() == KeyEvent.VK_F5)
{
screen_shot = true;
}
}
public void keyReleased(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_D)
{
right = false;
}
if (e.getKeyCode() == KeyEvent.VK_A)
{
left = false;
}
if (e.getKeyCode() == KeyEvent.VK_S)
{
down = false;
}
if (e.getKeyCode() == KeyEvent.VK_W)
{
up = false;
}
if (e.getKeyCode() == KeyEvent.VK_F5)
{
screen_shot = false;
}
}
//...
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
this.setBackground(Color.white);
g.drawImage(character, characterLocation.x, characterLocation.y, this);
if (right)
{
characterLocation.x += 1;
}
if (left)
{
characterLocation.x -= 1;
}
if (down)
{
characterLocation.y += 1;
}
if (up)
{
characterLocation.y -= 1;
}
if (screen_shot)
{
BufferedImage shot = character.createScreenCapture(new Rectangle(100,100));
}
repaint();
}
}
Might not work up to par as you might have to change the "if" statement for screen shot above.

Categories

Resources