Ok, how to i move from keyboard a ball using an Applet?
I have so far this code, that don't do anything.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class KeyboardGame extends Applet implements KeyListener
{
private static final long serialVersionUID = 1L;
private static boolean keyboadrRightPressed = false;
public void init()
{
addKeyListener(this);
}
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_RIGHT)
{
keyboadrRightPressed = true;
}
else
{
keyboadrRightPressed = false;
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public void paint(Graphics g)
{
g.fillOval(20,20,20,20);
g.drawString("String :"+keyboadrRightPressed,20,30);
}
}
And also i have to understand how it works. I don't get why my action listener won't work, do i need an
while(true)
or an Thread?
Your action listener might actually be working fine, but you need to repaint the applet when the key is pressed so that your string actually appears. Try changing the keyPressed to this:
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_RIGHT)
{
keyboadrRightPressed = true;
}
else
{
keyboadrRightPressed = false;
}
repaint();
}
Actually moving the ball will differ depending on how you want the ball to actually move. I'm guessing you want it to continue moving right while the key is held down, so what I would do is implement a timer or some other form of thread that every .25 seconds (or however long you want) checks the keyboardRightPressed and will move the ball right if it is true. Then in the keyReleased portion of your code you should also add logic to set keyboardRightPressed back to false when you let up on the key.
Related
So I am basically creating a platformer game in java. Here is a simple question. Can I respond to two different KeyEvents simultaneously? For example, I am pressing the right arrow key and my player is moving right. Now, I want my player to jump but keep moving right. For this I would need to respond to two different KeyEvents simultaneously. How do I achieve this? I have not tried any code yet because I don't know where to start with. Thank you for the answer in advance.
You can use seperate "KeyDown" and "KeyUp"-events and set state values for your player.
You need a State-Machine for your player.
public class KeyboardListener extends JFrame implements KeyListener {
public KeyboardListener() {
addKeyListener(this);
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right key pressed");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left key pressed");
}
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right key Released");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left key Released");
}
}
public static void main(String[] args) {
new KeyboardListener();
}
}
Use the keyPressed and keyReleased-EventHandlers from the KeyListener Interface and save your current player states like walking, jumping, walk_left, walk_right etc as booleans for example.
In your mainloop you can check what state your player is in and change its coordinates. Like:
if(player.left) { player.x += speed } //etc.
You might want to use Threads and then add pressed keys to a list the player physics class.
public class KeysListener implements KeyListener
...
//FIRST THREAD
new Thread(new Runnable() {
#Override
public void run() {
public void keyEvent(KeyEvent e) {
int key = e.getKeyCode();
//TODO ADD KEY TO A LIST IN THE CLASS THAT HANDLES YOUR PHYSYICS
}
}
}).start();
//SECOND THREAD
new Thread(new Runnable() {
#Override
public void run() {
public void keyEvent(KeyEvent e) {
int key = e.getKeyCode();
//TODO ADD KEY TO A LIST IN THE CLASS THAT HANDLES YOUR PHYSICS
}
}
}).start();
...
}
Add as many threads as the number of simultaneous keys you require.
I have a Graphics project that contains KeyListener, where the arrow keys and space bar controls the movement of a spaceship. However, when a key is held down, it registers the next key presses after a delay after the first. I would like for a held down key to register continuously.
I suspect that this is due to my computer's setting for key repeat delay, so is there any way to temporarily override this in my program, or a workaround for it?
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 38) { //Up Arrow
currentLevel.moveSpiffUp();
} else if (e.getKeyCode() == 40) { //Down Arrow
currentLevel.moveSpiffDown();
} else if (e.getKeyCode() == 32 && !currentLevel.getFrapRayActive()) {
currentLevel.shoot();
}
repaint();
}
I would suggest using key press and key released
public class MyKeyListener implements KeyListener {
//class gets the input from the player
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if(KeyEvent.getKeyText(e.getKeyCode()).equals("Left")) {
//left arrow key
} else if (KeyEvent.getKeyText(e.getKeyCode()).equals("Right")) {
//right arrow key
}
}
public void keyReleased(KeyEvent e) {
if(KeyEvent.getKeyText(e.getKeyCode()).equals("Left"){
//left key released
}
if(KeyEvent.getKeyText(e.getKeyCode()).equals("Right")) {
//right key released
}
}
}
I then used this bit of code in my main constructor
main() {
KeyListener listener = new MyKeyListener();
addKeyListener(listener);
setFocusable(true);
}
This way you wont have your delay when hitting keys.
How do I use MouseListener and KeyListener at the same time?
For example, how to do something like this
public void keyPressed( KeyEvent e){
// If the mouse button is clicked while any key is held down, print the key
}
Use a boolean value for whether a mouse button is held down, and then update that variable in a MouseListener.
boolean buttonDown = false;
public class ExampleListener implements MouseListener {
public void mousePressed(MouseEvent e) {
buttonDown = true;
}
public void mouseReleased(MouseEvent e) {
buttonDown = false;
}
//Other implemented methods unimportant to this post...
}
Then, in your KeyListener class, just test the buttonDown variable.
Try creating a boolean isKeyPressed. In keyPressed, set it to true and in keyReleased set it to false. Then, when the mouse is clicked, first check if isKeyPressed is true.
You could try checking the state of the KeyEvent modifiers, for example...
addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
int mods = e.getModifiers();
System.out.println(mods);
if ((mods & KeyEvent.BUTTON1_MASK) != 0) {
System.out.println("Button1 down");
}
}
});
I should also point out, you can do...
int ext = e.getModifiersEx();
if ((ext & KeyEvent.BUTTON1_DOWN_MASK) != 0) {
System.out.println("Button1_down_mask");
}
Which, as I've just discovered, produces results for other mouse buttons...
I am currently trying to implement a keylistener in my program so that it does an action when I pressed an arrow key, the object in my program either moves left or right.
Here is the moving method in my program
public void moveDirection(KeyEvent e)
{
int move = 0;
int r = K.getRow();
int c = K.getCol();
if (e.getKeyCode() == 39) move = 1; //KeyEvent.VK_RIGHT
if (e.getKeyCode() == 37) move = 2; //KeyEvent.VK_LEFT
//if (e.getKeyCode() == KeyEvent.VK_DOWN) move = 3;
switch (move)
{
case 1: if (inBound(r, c+1))
K.setLocation(r ,c+1);
if (inBound(r, c-1) && frame2[r][c-1] == K)
frame2[K.getRow()][K.getCol()-1] = null;
break; //move right 39
case 2: K.setLocation(K.getRow(), K.getCol()-1); break; //move left 37
//case 3: b.setLocation(b.getRow()+1, b.getCol()); break; //move down
default: return;
}
processBlockList();
}
I am wondering how the program is supposed to read in (KeyEvent) e. I cannot really type in an arrowkey....
Please help!
edit: I also need to know what I need to add to my code so that my program waits about 700 milliseconds for a keyinput before moving on to another method
http://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html
Check this tutorial
If it's a UI based application , then " I also need to know what I need to add to my code so that my program waits about 700 milliseconds for a keyinput before moving on to another method" you can use GlassPane or Timer class to fulfill the requirement.
For key Event:
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = -1;
}
if (key == KeyEvent.VK_RIGHT) {
dx = 1;
}
if (key == KeyEvent.VK_UP) {
dy = -1;
}
if (key == KeyEvent.VK_DOWN) {
dy = 1;
}
}
check this game example http://zetcode.com/tutorials/javagamestutorial/movingsprites/
Here is an SSCCE,
package experiment;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class KeyListenerTester extends JFrame implements KeyListener {
JLabel label;
public KeyListenerTester(String s) {
super(s);
JPanel p = new JPanel();
label = new JLabel("Key Listener!");
p.add(label);
add(p);
addKeyListener(this);
setSize(200, 100);
setVisible(true);
}
#Override
public void keyTyped(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right key typed");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left key typed");
}
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right key pressed");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left key pressed");
}
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right key Released");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left key Released");
}
}
public static void main(String[] args) {
new KeyListenerTester("Key Listener Tester");
}
}
Additionally read upon these links : How to Write a Key Listener and How to Use Key Bindings
The class which implements KeyListener interface becomes our custom key event listener. This listener can not directly listen the key events. It can only listen the key events through intermediate objects such as JFrame. So
Make one Key listener class as
class MyListener implements KeyListener{
// override all the methods of KeyListener interface.
}
Now our class MyKeyListener is ready to listen the key events. But it can not directly do so.
Create any object like JFrame object through which MyListener can listen the key events. for that you need to add MyListener object to the JFrame object.
JFrame f=new JFrame();
f.addKeyListener(new MyKeyListener);
In addition to using KeyListener (as shown by others' answers), sometimes you have to ensure that the JComponent you are using is Focusable. This can be set by adding this to your component(if you are subclassing):
#Override
public void setFocusable(boolean b) {
super.setFocusable(b);
}
And by adding this to your constructor:
setFocusable(true);
Or, if you are calling the function from a parent class/container:
JComponent childComponent = new JComponent();
childComponent.setFocusable(true);
And then doing all the KeyListener stuff mentioned by others.
I'm a beginner trying to create a game. The game is empty, I didn't start to write it.
My problem: when I click in the start button I want to start the game in the same frame, but with this code when I'll click on start the program opens another frame with the menu, and in the original frame will delete the panel.
How can I do this simple menu?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import panelimage.Image;
public class Project0 extends JFrame{
private static final long serialVersionUID = 1L;
private Game JPanelGame;
private Image MainMenu = new Image(new File("src/img/menu_background.jpg"));
JButton start = new JButton("START GAME"), exit = new JButton ("LEAVE GAME");
public Project0() {
super();
initFrame();
initMenu();
this.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent evt) {
JPanelGame.keyPressed(evt);
}
public void keyReleased(KeyEvent evt) {
JPanelGame.keyReleased(evt);
}
});
}
private void initFrame() {
setResizable(false);
setBounds(new Rectangle(400, 400, 600, 400));
MainMenu.setLayout(new BorderLayout());
}
private void initMenu() {
initButtons();
MainMenu.setLayout(null);
MainMenu.add(start);
MainMenu.add(exit);
add(MainMenu);
setContentPane(MainMenu);
setTitle("Project0");
}
private void initButtons() {
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
JPanelGame = new Game();
remove(MainMenu);
add(JPanelGame, BorderLayout.CENTER);
setContentPane(JPanelGame);
invalidate(); validate();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Project0 Game = new Project0();
Game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Game.setVisible(true);
}
});
}
});
start.setLocation(225,100);
start.setSize(150,50);
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
System.exit(0);
}
});
exit.setLocation(225,200);
exit.setSize(150,50);
}
public static void main(String[] args) {
Project0 Game = new Project0();
Game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Game.setVisible(true);
}
}
and this frame will start
import java.awt.*;
import java.awt.event.KeyEvent;
import javax.swing.*;
import java.io.File;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import highscores.*;
public class Game extends JPanel implements Runnable {
private static final long serialVersionUID = 1L;
Thread game;
BufferedImage background;
HighscoreManager scores = new HighscoreManager();
public Game(){
super(true);
try{
background = ImageIO.read(new File(""));
}catch(Exception e) {}
game=new Thread(this);
game.start();
}
public void paintComponent(Graphics graphic2d){
setOpaque(false);
super.paintComponent(graphic2d);
graphic2d.drawImage(background, 0, 0, null);
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
}
if (key == KeyEvent.VK_RIGHT) {
}
if (key == KeyEvent.VK_UP) {
}
if (key == KeyEvent.VK_DOWN) {
}
if (key == KeyEvent.VK_A) {
}
if (key == KeyEvent.VK_D) {
}
if (key == KeyEvent.VK_W) {
}
if (key == KeyEvent.VK_S) {
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
}
if (key == KeyEvent.VK_RIGHT) {
}
if (key == KeyEvent.VK_UP) {
}
if (key == KeyEvent.VK_DOWN) {
}
if (key == KeyEvent.VK_A) {
}
if (key == KeyEvent.VK_D) {
}
if (key == KeyEvent.VK_W) {
}
if (key == KeyEvent.VK_S) {
}
}
public void run(){
try {Thread.sleep(50);}catch(InterruptedException ex){}
}
}
I see two options, depending on your needs. Either you just remove all components from the frame and add the new contents. But by doing so, you loose your 'menu-frame'. The other option (and IMO the best of the two) is to opt for a CardLayout, where one card is your menu and the other your game. The 'start' button would then simply switch from the 'menu-card' to the 'game-card' (and if needed start the game). In your game, you can have a button/key/... which does the inverse (switching from the game card to the menu card)
I was going through your code but I gave up (certainly since #orzechowskid already pointed out what you need to adjust). A few tips in case you are going to post more code on this site:
Read the SSCCE.org website and try to post code as described there
Follow the Java naming conventions (e.g. classes start with an uppercase letter, variables with a lowercase letter)
Do not give your own classes the same names as standard JDK classes. Makes it very hard for someone not familiar with your code (but probably rather familiar with the JDK classes) to read the code. E.g. it took me some time before I realized you have your own panelimage.Image class which has nothing to do with the java.awt.Image class
And then a few Swing related tips based on what I saw of your code:
Learn how to use LayoutManagers and get rid of the null layouts. The Visual guide to layout managers might be a good starting point
Swing is designed to work with KeyBindings and not with KeyListeners. See the tutorial
Be careful with the Thread.sleep usage and running multiple Threads in combination with a Swing UI. Make sure you are aware of the Swing threading rules
when you call SwingUtilities.invokeLater() inside your button's action listener, you're creating a second Project0 object. And whenever you create a Project0, you get a JFrame drawn on screen with a main menu inside of it. Remove the call to SwingUtilities.invokeLater() and you should be left with a single frame.