Java, my image will not update/move - java

I'm quite a newbie to Java stuff, but.. after reading a lot online, I've been trying to work on this game and getting started, I'm working with a few images. I'm trying to update their positions to demonstrate movement of course through KeyListener, I believe. unfortunately, the image remains in the same spot and refuses to move D:
I'm sure I overcomplicated some of this code, but here it is :\
public class Game extends javax.swing.JPanel implements ActionListener, KeyListener{
private Vladimir vlad;
private Timer timer;
public Game() {
addKeyListener(this);
setPreferredSize(new Dimension(1024,768));
setDoubleBuffered(true);
vlad = new Vladimir();
timer = new Timer(15,this);
timer.start();
}
public void actionPerformed (ActionEvent e){
repaint();
}
private void toggleKey(int keyCode, boolean pressed){
if (keyCode == 87){ // W
vlad.move("UP", pressed);
}
if (keyCode == 83){ // S
vlad.move("DOWN", pressed);
}
if (keyCode == 65) // A
{
vlad.move("LEFT", pressed);
}
if (keyCode == 68) // D
{
vlad.move("RIGHT", pressed);
}
}
public void keyPressed(KeyEvent e)
{
toggleKey(e.getKeyCode(), true);
}
public void keyReleased(KeyEvent e)
{
toggleKey(e.getKeyCode(), false);
}
public void keyTyped(KeyEvent e){
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics g2d = (Graphics2D)g;
g2d.drawImage(vlad.getGrassMap(),0,0,this);
g2d.drawImage(vlad.getCharOne(),vlad.getX(),vlad.getY(),this);
repaint();
}
}
And then..
public class Vladimir{
private int x;
private int y;
private Image grassMapOne;
private Image charOne;
private String gMapLocate = "/phantasma/resources/GrassMap1.png";
private String charOneLocate = "/phantasma/resources/moveright1.png";
public Vladimir(){
ImageIcon gMap1 = new ImageIcon(this.getClass().getResource(gMapLocate));
ImageIcon char1 = new ImageIcon(this.getClass().getResource(charOneLocate));
grassMapOne = gMap1.getImage();
charOne = char1.getImage();
x = 512;
y = 350;
}
public void move(String direction, boolean keyHeld){
if (direction == "UP"){
y += 12;
}
if (direction == "DOWN"){
y -= 12;
}
if (direction == "LEFT"){
x -= 12;
}
if (direction == "RIGHT"){
x += 12;
}
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public Image getGrassMap(){
return grassMapOne;
}
public Image getCharOne(){
return charOne;
}
}

First you need to know what is wrong before you can fix it, so you should first ask yourself, not why the image isn't moving, but is the key listener even listening? If you add println statements like this one:
public void keyPressed(KeyEvent e) {
System.out.println("in keyPressed. keyCode is: " + e.getKeyCode());
toggleKey(e.getKeyCode(), true);
}
you'll see that it's not, that it requires a component that is able to receive focus and that actually has focus.
You will need to set the JPanel's focusable property to true and then have it acceptFocusInWindow() after it has been rendered.
Better still -- use key bindings, since they are much more flexible when it comes to focus issues, and are a higher-level construct. They are in fact what Swing itself uses to have components react to key presses.
Next, don't use == to compare Strings as this only checks if two String objects are one and the same, something you don't care about. Instead you want to know if one String has the same characters in the same order as another String, and for this you want to use String's equals(...) method or its equalsIgnoreCase(...) method.

Related

Flappy Bird Graphics Slow

I'm trying to write a simple flappy bird game as a Java Applet. The problem I'm having is that the graphics are extremely unresponsive, typically taking 5-10 seconds to respond after the key is pressed. Also, it only responds if the key is pressed a certain number of times, around 6 or 7. I don't think it's a problem with my computer, since I'm running it on a high-specs MacBook Pro (8 GB RAM, i5 processor). Here's the two main classes I use:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
//The main class I use to run the game
public class Flap extends Applet implements Runnable, KeyListener
{
final int WIDTH = 700, HEIGHT = 500;
Thread thread;
Bird b;
boolean beenPressed = false;
public void init()
{
this.resize(WIDTH, HEIGHT);
this.addKeyListener(this);
b = new Bird();
thread = new Thread(this);
thread.start();
}
public void paint(Graphics g)
{
g.setColor(Color.CYAN);
g.fillRect(0, 0, WIDTH, HEIGHT - 100);
g.setColor(Color.green);
g.fillRect(0, 400, WIDTH, HEIGHT);
b.draw(g);
}
public void update(Graphics g)
{
paint(g);
}
#Override
public void run()
{
for(;;)
{
//Pillar upPillar = new Pillar()
b.move();
repaint();
try
{
Thread.sleep(500);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
#Override
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_UP)
{
if(!beenPressed)
{
b.setUp(true);
}
beenPressed = true;
}
else
{
b.setDown(true);
}
}
#Override
public void keyReleased(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_UP)
{
beenPressed = false;
b.setUp(false);
}
else
{
b.setDown(false);
}
}
#Override
public void keyTyped(KeyEvent arg0)
{
}
}
import java.awt.Color;
import java.awt.Graphics;
//The Bird class, which has the methods for the player to move
public class Bird
{
int x, y, yvel;
boolean goingUp, goingDown;
public Bird()
{
x = 200;
y = 200;
}
public void draw(Graphics g)
{
g.setColor(Color.yellow);
g.fillRect(x, y, 60, 25);
}
public void move()
{
if(goingUp)
{
yvel -= 50;
}
else if(goingDown)
{
yvel += 50;
}
y += yvel;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public void setUp(boolean b)
{
goingUp = b;
}
public void setDown(boolean b)
{
goingDown = b;
}
}
It's still unfinished, but at this stage, I think the bird should at least be moving.
The graphics isn't slow, the time between updates is to large. It basically allows for the key to be pressed and released before a update cycle takes place.
I would reduce Thread.sleep(500); to something more like Thread.sleep(10); and change the movement delta to something more like...
public void move()
{
if(goingUp)
{
yvel -= 1;
}
else if(goingDown)
{
yvel += 1;
}
y += yvel;
}
as a starting point.
Recommendations...
Using applets, bad idea. Applets are deprecated and a dead technology. Applet is also not double buffered, so you're probably going to end up with some horrible flashing going on. KeyListener is will known for having issues (not responding), while it's the only solution when using AWT, the ket bindings API is a better solution when using Swing
The first thing I would suggest, is having a look at using a JPanel as your base component and then have a look at Performing Custom Painting and Painting in Swing to get a better understanding of how painting works
If you "really" need high performance (or just want more control over the painting process), you should also have a look at BufferStrategy and BufferCapabilities
I'd also recommend having a look at JavaFX which has better APIs for this kind of thing

How to change ghost speed in this code

how would I adjust the speed at which the ghost moves in this code? Is the required code already there and i just need to change values? or do I need to add anything? I am fairly new to coding so please try to put this in easiest form possible. thank you.
package basicgame;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class JavaGame extends JPanel {
int x, y;
// private Image dbImage;
//private Graphics dbg;
Image ghost;
Image bg;
public class AL extends KeyAdapter {
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == e.VK_LEFT) {
if (x <= 8)
x = 8;
else
x += -5;
}
if (keyCode == e.VK_RIGHT) {
if (x >= 435)
x = 435;
else
x += +5;
}
if (keyCode == e.VK_UP) {
if (y <= 18)
y = 18;
else
y += -5;
}
if (keyCode == e.VK_DOWN) {
if (y >= 325)
y = 325;
else
y += +5;
}
}
public void keyReleased(KeyEvent e) {
}
}
public JavaGame() throws Exception {
// Load images
ghost = ImageIO.read(new File("ghost.gif"));
bg = ImageIO.read(new File("myBkg.PNG"));
setFocusable(true);
// Game properties
addKeyListener(new AL());
x = 10;
y = 10;
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
repaint();
}
};
Timer timer = new Timer(10,al);
timer.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
// here, you have a 'drawimage' command for each object you're moving
// if you have 2 players, you have another drawImage for that one
// if you have a bullet, you have another for it. You have to keep
//track of each object's x,y coordinates and then draw the image at that position.
//you'll need some collision detection in there to see if bullets/players are
//in the same position and then act accordingly.
g.drawImage(bg, 0, 0, null);
g.drawImage(ghost, x, y, this);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
JFrame f = new JFrame("Java Game");
f.setSize(500, 500);
f.setResizable(false);
f.setVisible(true);
f.setBackground(Color.GRAY);
f.setContentPane(new JavaGame());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
The position is stored in the variables x and y. The "speed" of movement is described simply by the rate of change of these variables on keypress; a brief look at the code shows that this "speed" is set, rather clumsily, to 5. It appears in four different places--once for each direction vector. To change the "speed", you can just change all of these occurrences, but remember that if you forget to change some of them, the object will move at different speeds in different directions!
You could vastly improve this code by replacing all of your magic numbers with named variables. This includes not only the "speed", but also the movement boundaries: 8, 18, 435, and 325. Put these named variables inside the AL class or maybe the JavaGame class, depending on where they need to be available.
There's also an unrelated bug that I want to mention. Your current code will allow you to move out-of-bounds, and then on a subsequent keypress, move in the opposite direction indicated due to the "clipping". For example, say x = 10. If you press Left, you'll change x to 5. If you then press Left again, the boundary condition will trigger and you'll move right, setting x to 8. This is probably not desirable, so you should apply the movement first, then clip to the boundary.
Your AL class (consider a more descriptive name for this as well...) might then look something like this:
public class AL extends KeyAdapter {
private static final int SPEED = 5; // Controls the movement speed in all directions
// Variables controlling the movement boundaries
private static final int BOUND_LEFT = 8;
private static final int BOUND_RIGHT = 435;
private static final int BOUND_BOTTOM = 18;
private static final int BOUND_TOP = 325;
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == e.VK_LEFT) {
x -= SPEED; // Move left
if (x <= BOUND_LEFT) {
x = BOUND_LEFT; // If movement placed us out of bounds, move to boundary instead
}
}
if (keyCode == e.VK_RIGHT) {
x += SPEED;
if (x >= BOUND_RIGHT) {
x = BOUND_RIGHT;
}
}
if (keyCode == e.VK_UP) {
y += SPEED;
if (y >= BOUND_TOP) {
y = BOUND_TOP;
}
}
if (keyCode == e.VK_DOWN) {
y -= SPEED;
if (y <= BOUND_BOTTOM) {
y = BOUND_BOTTOM;
}
}
}
public void keyReleased(KeyEvent e) {
}
}

Need help on KeyEvents

simple question. I'm trying to re-create the game Pong. I've got the graphics that I want on the screen with the two paddles moving with KeyEvents. My only problem is that when I release one key the other paddle stops as well (if both are moving at the same time) I know exactly why this is happening but can't figure out the fix. It's happening because when the keyReleased method is called, both paddles are being set to velocity 0. How can I code it differently where I can move/stop both paddles separately with the keyReleased method?
Code:
package pong.main;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PongGame extends JPanel implements ActionListener,KeyListener {
private final int WIDTH = 750;
private final int HEIGHT = 750;
private int DELAY = 20;
private int IMAGE_SIZE = 35;
private ImageIcon paddle_one;
private ImageIcon paddle_two;
private ImageIcon pong_logo;
private ImageIcon pong_ball;
private Timer timer = new Timer(DELAY, this);
private int p1_x = 10;
private int p1_y = 325;
private int p2_x = 710;
private int p2_y = 325;
private int p1_moveX;
private int p1_moveY;
private int p2_moveX;
private int p2_moveY;
public PongGame(){
timer.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
paddle_one = new ImageIcon("C:\\Users\\Bryan\\Pictures\\paddle.gif");
paddle_two = new ImageIcon("C:\\Users\\Bryan\\Pictures\\paddle.gif");
pong_logo = new ImageIcon("C:\\Users\\Bryan\\Pictures\\pong_logo.gif");
pong_ball = new ImageIcon("C:\\Users\\Bryan\\Pictures\\pong_ball.gif");
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setBackground(Color.black);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
paddle_one.paintIcon(this, g, p1_x, p1_y);
paddle_two.paintIcon(this, g, p2_x, p2_y);
pong_ball.paintIcon(this, g, 350, 350);
pong_logo.paintIcon(this, g, 220, -100);
}
public void actionPerformed(ActionEvent e){
repaint();
p1_x += p1_moveX;
p1_y += p1_moveY;
p2_x += p2_moveX;
p2_y += p2_moveY;
}
public void paddle_one_up(){
p1_moveX = 0;
p1_moveY = -5;
}
public void paddle_one_down(){
p1_moveX = 0;
p1_moveY = 5;
}
public void paddle_two_up(){
p2_moveX = 0;
p2_moveY = -5;
}
public void paddle_two_down(){
p2_moveX = 0;
p2_moveY = 5;
}
public void keyPressed(KeyEvent e){
int code = e.getKeyCode();
if(code == KeyEvent.VK_W){
paddle_one_up();
}
if(code == KeyEvent.VK_S){
paddle_one_down();
}
if(code == KeyEvent.VK_UP){
paddle_two_up();
}
if(code == KeyEvent.VK_DOWN){
paddle_two_down();
}
}
public void keyReleased(KeyEvent e){
int code = e.getKeyCode();
if(code != KeyEvent.VK_W){
p1_moveX = 0;
p1_moveY = 0;
}
if(code != KeyEvent.VK_S){
p1_moveX = 0;
p1_moveY = 0;
}
if(code != KeyEvent.VK_UP){
p2_moveX = 0;
p2_moveY = 0;
}
if(code != KeyEvent.VK_DOWN){
p2_moveX = 0;
p2_moveY = 0;
}
public void keyTyped(KeyEvent e){}
}
Look at the difference between your keyPressed method and your keyReleased method.
Do a similar thing in keyReleased -- check the KeyEvent object's key code and act accordingly. The differences between these two methods and your inability to solve this suggests that your keyPressed code is borrowed code. It's OK to borrow code as long as you understand it first. Better to borrow ideas, and then write your own code.
Even better -- use Key Bindings which is a safer and better solution than using KeyListeners.
Using the structure of your keyPressed() method's conditional logic, you need a similar check in keyReleased() to determine which key was released before you set either paddle's velocity. As it is, you can release ANY key and keyReleased() will assign the p1 and p2's values to zero.

ActionListener and KeyListener not working at all

package Objects;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class PowerBar extends JPanel implements ActionListener, KeyListener {
private double x;
private final double y = 420;
private double xv = 0;
private final int width, height;
private boolean left = false, right = false;
private Timer t = new Timer(5, this);
public PowerBar(JPanel j) {
width = j.getWidth();
height = j.getHeight();
x = 180;
t.start();
this.addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void move() {
}
public void powerbarPosition() {
}
#Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Rectangle2D rect = new Rectangle2D.Double(x, y, 100, 15);
g2.setColor(Color.DARK_GRAY);
g2.fill(rect);
}
#Override
public void actionPerformed(ActionEvent ae) {
x += xv;
repaint();
}
#Override
public void keyPressed(KeyEvent ev) {
if (ev.getKeyCode() == KeyEvent.VK_LEFT) {
left = !left;
if (left == true) {
xv = -2;
} else if (ev.getKeyCode() == KeyEvent.VK_RIGHT) {
right = !right;
if (right == true) {
xv = 2;
}
}
}
}
#Override
public void keyReleased(KeyEvent ev) {
}
#Override
public void keyTyped(KeyEvent ke) {
}
}
Im kinda new to programming and this is my very first game to program. Im trying to get the power bar to move with the left and right key but there is no response from these keys when pressed. The power bar is drawn in a separate class called DrawMain which uses the paintComponent method.
A JPanel doesn't listen to Action, it is a container rather than a controller. Hence, it doesn't have a addActionListener(actionListener) function.
For listening to Key event- presse, release etc, the target component must have focus. However, you can invoke requestFocusInWindow() on target component to gain focus if you wish to.
It is preferable not to implement a listener to class which doesn't listen to such listener, in your context it is ActionListener. Make use of inline anonymous class or declare another class implementing the ActionListener
As #AndrewThompson and other swing gigs of stackoverflow will suggest, It is preferable using Key binding using key input map and action input map to a component which is rather higher level implementation. Try avoiding make use of lower level AWT implementation KeyListener as much as possible.
Check the official tutorial page:
How to use Key Bingings
How to Write a Key Listener
How to Write an Action Listener
1) Your ActionListener doesn't attached to JPanel and components on it, because of that it doesn't work.
2) Don't use KeyListener instead of use Key Bindings:
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0), "doSomething1");
getActionMap().put("doSomething1", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent arg0) {
left = !left;
if (left == true) {
xv = -2;
}
}
});
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0), "doSomething2");
getActionMap().put("doSomething2", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent arg0) {
right = !right;
if (right == true) {
xv = 2;
}
}
});

Java 2D Game KeyListener Not Fulfilling It's Destiny

I've decided it's time to take my programming to the next step: Making A Game. So far I've been able to code everything alright, maybe having to Google some stuff I'm not too familiar with, but I feel like it should work. The graphics are being painted and all that's nice and dandy, but when it comes to the Key Listeners, that's where things went wrong. I made an inner class that implemented Key Listener, then added it in the Board constructor. I guess you'll just have to look at the code but it's pretty long and a bit messy. This is my first time doing this, so some stuff is probably unnecessary and I may just be forgetting something really obvious.
Main Class:
import javax.swing.*;
public class Game extends JFrame{
public static void main(String[] args){
new Game();
}
public Game(){
add(new Board());
setTitle("Hi mom");
setSize(555,330);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(3);
setVisible(true);
}
}
Board Class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Board extends JPanel implements ActionListener {
Image background;
Player p;
int k;
boolean moving;
public Board() {
setFocusable(true);
Timer timer = new Timer(25, this);
timer.start();
ImageIcon img = new ImageIcon(getClass().getResource("images/map.png"));
background = img.getImage();
addKeyListener(new Kl());
p = new Player();
}
public void paint(Graphics g) {
g.drawImage(background, 0, 0, null);
g.drawImage(p.getPlayer(), p.setX(30), p.setY(187), null);
}
public void actionPerformed(ActionEvent e) {
if (k == 'W' && moving == true) {
p.move(0,-5);
}
if (k == 'S' && moving == true) {
p.move(0,5);
}
if (k == 'D' && moving == true) {
p.move(5,0);
}
if (k == 'A' && moving == true) {
p.move(-5,0);
}
repaint();
}
public class Kl implements KeyListener {
public void keyPressed(KeyEvent e) {
k = e.getKeyCode();
moving = true;
}
public void keyReleased(KeyEvent e) {
moving = false;
}
public void keyTyped(KeyEvent e) {
}
}
}
Player Class:
import javax.swing.*;
import java.awt.*;
public class Player{
int x, y;
Image player;
public Player(){
ImageIcon img = new ImageIcon(getClass().getResource("images/player.png"));
player = img.getImage();
}
public Image getPlayer(){
return player;
}
public void move(int x, int y){
this.x += x;
}
public int setX(int x){
this.x = x;
return x;
}
public int setY(int y){
this.y = y;
return y;
}
}
The problem is KeyListener will only trigger key events when the component it is registered to is focusable AND has keyboard focus. Simply calling setFocsuable isn't enough. This just means that the component is "capable" of receiving keyboard focus, not that it has it.
Instead, you should be using the Key Bindings API, which has the means to over come this limitation, amongst other things.

Categories