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.
Related
I'm making a top-down shooter game in java where I have a stationary player who can turn side to side and can shoot a gun at enemies that move to the center(where the player is). I have made different faces for each side when my player turns, but I'm not able to figure out how to switch the faces when I use the arrow keys. Here is my main panel:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
public class FinalPanel extends JPanel
{
private static final int FRAME = 1600;
private static final Color BACKGROUND = new Color(255, 255, 255);
private Player player;
private ImageIcon faces;
private ImageIcon playerFace = new ImageIcon("PlayerUpImage.png");
private BufferedImage myImage;
private Graphics myBuffer;
private Timer timer;
public FinalPanel()
{
myImage = new BufferedImage(FRAME, FRAME, BufferedImage.TYPE_INT_RGB);
myBuffer = myImage.getGraphics();
addKeyListener(new Key());
setFocusable(true);
}
private class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
ImageIcon player = new ImageIcon("PlayerUpImage.png");
myBuffer.drawImage(player.getImage(), 800, 800, null);
repaint();
}
}
public void paintComponent(Graphics g)
{
super.paintComponenet(g);
g.drawImage(myImage, 0, 0, getWidth(), getHeight(), null);
}
private class Key extends KeyAdapter//The arrow keys make the player change directions and it replaces his face with a different animation to show the change in direction
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_W)
{
playerFace = new ImageIcon("PlayerUpImage.png");
}
if(e.getKeyCode() == KeyEvent.VK_S)
{
playerFace = new ImageIcon("PlayerDownImage.png");
}
if(e.getKeyCode() == KeyEvent.VK_A)
{
playerFace = new ImageIcon("PlayerLeftImage.png");
}
if(e.getKeyCode() == KeyEvent.VK_D)
{
playerFace = new ImageIcon("PlayerRightImage.png");
}
repaint();
}
}
}
Player class:
import java.awt.*;
import javax.swing.*;
public class Player
{
//Private fields for player class
private int myX;
private int myY;
private int myXWidth;
private int myYWidth;
public Player()
{
myX = 775;
myY = 775;
myXWidth = 50;
myYWidth = 50;
}
public Player(int x, int y, int xWidth, int yWidth)
{
myX = x;
myY = y;
myXWidth = xWidth;
myYWidth = yWidth;
}
//I borrowed this health code from: https://stackoverflow.com/questions/9834609/how-to-make-a-player-class-that-holds-lives-inheritance//
int liveCount = 10;
public boolean damage() {
--liveCount;
return isDead();
}
public boolean isDead() {
return liveCount < 1;
}
public void boostLives(int moreLives) {
liveCount += moreLives;
}
//Accessor Methods//
public int getX()
{
return myX;
}
public int getY()
{
return myY;
}
public int getXWidth()
{
return myXWidth;
}
public int getYWidth()
{
return myYWidth;
}
//Modifier Methods//
public void setX(int x)
{
myX = x;
}
public void setY(int y)
{
myY = y;
}
public void setXWidth(int xWidth)
{
myXWidth = xWidth;
}
public void setYWidth(int yWidth)
{
myYWidth = yWidth;
}
}
I have some suggestions that might help:
Don’t use the variable faces, instead, have an ImageIcon called playerFace with a default direction of up
private ImageIcon playerFace = new ImageIcon(“PlayerUpImage.png”);
Your paint method could then look like this
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(playerFace.getImage(), 800, 800, null);
}
In your keyPressed method, all you have to do is change the player image and call the method repaint so that the panel calls the paintComponent method again:
public void keyPressed(KeyEvent e) {
//pressed d for example
if(e.getKeyCode() == KeyEvent.VK_D)
playerFace = new ImageIcon(“PlayerImageRight.png”);
... //if else’s for other keys
repaint();
}
Preferably, you’d want to have playerFaces as an attribute of the Player class with a getter method to get the playerFace direction (so making playerFace a variable of Player). But this is to get you started
You’ll also want to set up a frame instead of using your current variable FRAME
public FinalPanel() {
JFrame frame = new JFrame();
frame.setSize(1600, 1600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.setVisible(true);
addKeyListener(new Key());
setFocusable(true);
}
I have a very strange problem.
I am making a simple 2d platformer using Java.
The collision detection with the player and a platform, doesn't work.
But the strange thing is, when I print something to the screen to see if the collision if-statement is executed, the collision works o_O
Maybe it's a bit confusing, please see my code.
The Main class(which is good I think):
import javax.swing.*;
public class Main extends JFrame{
private static final long serialVersionUID = 1L;
GameClass gc = new GameClass();
public Main(){
setSize(gc.WIDTH,gc.HEIGHT);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Flying GoatZ!");
add(new GameClass());
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
new Main();
}
}
GameClass class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
public class GameClass extends JPanel implements ActionListener, KeyListener, MouseListener{
//OBJECTS
Text text = new Text();
openImages open_img = new openImages();
Random ran = new Random();
//VARIABLES
static final long serialVersionUID = 1L;
final int WIDTH = 800;
final int HEIGHT = 600;
int goatx = WIDTH/2;
int goaty = 350;
int goatspeed = 0;
int fallspeed = 15;
int maxy = 150;
boolean up = false;
boolean flying = true;
ArrayList<Integer> xes = new ArrayList<Integer>();
ArrayList<Integer> yes = new ArrayList<Integer>();
//FPS SETTER AND KEYLISTENERS
public GameClass(){
Timer time = new Timer(15, this);
time.start();
this.addKeyListener(this);
this.setFocusable(true);
open_img.openImage();
}
public void update(){
Collision();
goatx += goatspeed;
if(up){
if(goaty > maxy){
goaty -= 5;
}else{
up = false;
}
}else
if(goaty < 350)
goaty += fallspeed;
}
public void print(String msg){
System.out.println(msg);
}
public void platformDrawing(Graphics g,int x,int y,int x1,int y1, int x2, int y2){
g.setColor(Color.RED);
g.drawImage(open_img.block,x, y, null);
g.drawImage(open_img.block,x1, y1, null);
g.drawImage(open_img.block,x2, y2, null);
xes.addAll(Arrays.asList(x,x1,x2));
yes.addAll(Arrays.asList(y,y1,y2));
}
//HERE IS THE COLLISION METHOD(I NEED THE PLAYER TO STAND STILL WHEN IT IS ON THE PLATFORM.
public void Collision(){
for(int x : xes){
for(int y : yes){
if( ( (goatx > x-20) && (goatx < (x + 150)) ) && ( (goaty+open_img.goat.getHeight(null)) <= y ) ){
//print("TEST");
fallspeed = 0;
}else{
fallspeed = 10;
}
}
}
}
//ALL TEH DRAWING
public void paintComponent(Graphics g){
//MAP
g.setColor(Color.CYAN);
g.fillRect(0,0,WIDTH,HEIGHT);
g.setColor(Color.ORANGE);
g.fillRect(0, HEIGHT-100, WIDTH, 100);
g.setColor(Color.GREEN);
g.fillRect(0, HEIGHT-125, WIDTH, 25);
//PLAYER & PLATFORMS
platformDrawing(g,50,350,300,350,600,350);
g.drawImage(open_img.goat, goatx, goaty, null);
g.dispose();
}
//THIS IS EXECUTED EVERYTIME
public void actionPerformed(ActionEvent e){
update();
repaint();
}
//KEY DETECTION
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_LEFT){
goatspeed = -5;
}
if(e.getKeyCode() == KeyEvent.VK_RIGHT){
goatspeed = 5;
}
if(e.getKeyCode() == KeyEvent.VK_SPACE){
if(flying){
flying = false;
up = true;
}
}
}
public void keyReleased(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_LEFT){
goatspeed = 0;
}
if(e.getKeyCode() == KeyEvent.VK_RIGHT){
goatspeed = 0;
}
if(e.getKeyCode() == KeyEvent.VK_SPACE){
flying = true;
}
}
//SOME STUFF THAT YOU HAVE TO IGNORE LEL
public void keyTyped(KeyEvent e){}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
}
I don't understand why a print statement can make the difference...
Any help is appreaciated, thanks!
Oh, and sorry for bad English or unclear question.
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) {
}
}
Trying to make pong in java but can't move both paddles at once. You can move one or the other but not both at the same time. Do I need to create 2 threads with 2 different pannels?
Here is where I am specifying the key events
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;
}
if(e.getKeyCode() == KeyEvent.VK_S){
y+=10;
}
if(e.getKeyCode() == KeyEvent.VK_QUOTE){
ytwo-=10;
}
if(e.getKeyCode() == KeyEvent.VK_SEMICOLON){
ytwo+=10;
}
}
}
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;
// 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();
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 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;
}
if(e.getKeyCode() == KeyEvent.VK_S){
y+=10;
}
if(e.getKeyCode() == KeyEvent.VK_QUOTE){
ytwo-=10;
}
if(e.getKeyCode() == KeyEvent.VK_SEMICOLON){
ytwo+=10;
}
}
}
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Don't use while (true) but rather a Swing timer.
Don't use KeyListeners but rather Key Bindings.
Consider turning on a Swing Timer (which can act as your "background thread") that moves one paddle when the bindings detect the correct key has been pressed,
and stopping the timer that moves the paddle when the same key is released.
Same for the other paddle but of course having its actions respond to a bindings of a different pair of keys.
When attempting to get something like this working, try to get it working in a very simple program first, one without all the other junk required for your main program, but one which will allow you to test and prove your concept. Then if you get things working in your small program, great, you add the functionality to your main program. And if your small program code doesn't work and you need our help, you can post the small self-contained program here (an sscce) for us to test and modify.
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.