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
Related
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
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I am programming a game , where i am working on right now is that the player rotates with no succes though. Heres the error message:
Exception in thread "Thread-2" java.lang.NullPointerException
at Schoo.NewGame.SafeIcon.getIconWidth(SafeIcon.java:29)
at Schoo.NewGame.TheRealGame.turn(TheRealGame.java:412)
at Schoo.NewGame.TheRealGame.turnPlayer(TheRealGame.java:427)
at Schoo.NewGame.TheRealGame.RepaintPlayer(TheRealGame.java:377)
at Schoo.NewGame.TheRealGame$2.run(TheRealGame.java:225)
at java.lang.Thread.run(Unknown Source)
Line 29 in SafeIcon:
return wrappee.getIconHeight();
More of it:
private Icon wrappee;
private Icon standIn;
public SafeIcon(Icon icon) {
wrappee = icon;
}
#Override
public int getIconHeight() {
return wrappee.getIconHeight();
}
#Override
public int getIconWidth() {
return wrappee.getIconWidth();
}
Line 412 in TheRealGame:
BufferedImage bi = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_RGB);
More of it:
Icon icon;
public void turn(Direction d){
if (pt == Playere.Kaneki){
icon = new SafeIcon(playerImage.getIcon());
BufferedImage bi = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D) bi.getGraphics();
if (d == Direction.LEFT && p.getDirection() == Direction.UP){
g.rotate(Math.PI / 2, playerImage.getWidth(), playerImage.getHeight());
playerImage.getIcon().paintIcon(null, g, 0, 0);
g.dispose();
}
}
if (pt == Playere.Touka){
}
}
This is where i found safeIcon.
if you need my whole main class:
public class TheRealGame{
private static Bullets b = new Bullets();
private static boolean running = false;
private static boolean paused = false;
private static boolean right = false, left = false, up = false, down = false;
private static JFrame f;
private static ArrayList<JLabel> ae = new ArrayList<JLabel>();
private static Player p;
private static Playere pt;
private static JLabel playerImage;
private static Icon playerIcon;
private static ImageIcon imageIcon;
private static boolean attacking = false;
private static boolean info = false;
private static JLabel iy, ix, im, in, iu;
private static Enemys enemys = new Enemys();
private static ArrayList<JLabel> bullets = new ArrayList<JLabel>();
public static void main(Playere playertype){
pt = playertype;
p = new Player(pt);
f = new JFrame();
f.setVisible(true);
f.setSize(700, 700);
f.setResizable(false);
f.setLocationRelativeTo(null);
f.addKeyListener(new KeyListener(){
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyChar() == KeyEvent.VK_W){
up = true;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyChar() == KeyEvent.VK_A){
left = true;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyChar() == KeyEvent.VK_S){
down = true;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyChar() == KeyEvent.VK_D){
right = true;
}
if (e.getKeyCode() == KeyEvent.VK_SPACE || e.getKeyCode() == KeyEvent.VK_ENTER){
if (attacking == false){
p.attack();
}
}
if (e.getKeyCode() == KeyEvent.VK_F3){
if (info == true){
info = false;
iy.setVisible(false);
ix.setVisible(false);
im.setVisible(false);
in.setVisible(false);
iu.setVisible(false);
}else if (info == false){
info = true;
iy.setVisible(true);
ix.setVisible(true);
im.setVisible(true);
in.setVisible(true);
iu.setVisible(true);
}
}
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyChar() == KeyEvent.VK_W){
up = false;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyChar() == KeyEvent.VK_A){
left = false;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyChar() == KeyEvent.VK_S){
down = false;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyChar() == KeyEvent.VK_D){
right = false;
}
if (e.getKeyCode() == KeyEvent.VK_SPACE || e.getKeyCode() == KeyEvent.VK_ENTER){
if (attacking == true)
p.attack();
}
}
#Override
public void keyTyped(KeyEvent e) {
}
});
playerImage = new JLabel();
iy = new JLabel();
ix = new JLabel();
im = new JLabel();
in = new JLabel();
iu = new JLabel();
iy.setLocation(0, 10);
ix.setLocation(0, 20);
im.setLocation(0, 30);
in.setLocation(0, 40);
iu.setLocation(0, 50);
iy.setBounds((int) iy.getLocation().getX(), (int) iy.getLocation().getY(), 100, 15);
ix.setBounds((int) ix.getLocation().getX(), (int) ix.getLocation().getY(), 100, 15);
im.setBounds((int) im.getLocation().getX(), (int) im.getLocation().getY(), 100, 15);
in.setBounds((int) in.getLocation().getX(), (int) in.getLocation().getY(), 100, 15);
iu.setBounds((int) iu.getLocation().getX(), (int) iu.getLocation().getY(), 300, 15);
f.add(ix);
f.add(iy);
f.add(im);
f.add(in);
f.add(iu);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("free play - tokyo ghoul");
Start();
p.Paint();
}
public static void resume(){
if (paused == false){
return;
}
}
public static void pause(){
if (paused == true){
return;
}
}
public static void Stop(){
if (running == false){
return;
}
running = false;
}
public static void move(JLabel l, int newX, int newY){
l.setLocation(newX, newY);
l.repaint();
f.repaint();
}
public static void remove(JLabel l){
f.remove(l);
l.setVisible(false);
}
public static JLabel getPlayerImage(){
return playerImage;
}
public static Player getPlayer(){
return p;
}
public static void Start(){
running = true;
new Thread(new Runnable(){
#Override
public void run() {
int last = 0, u = 0;
while (running == true){
if (paused != true){
if (up == true){
p.move(p.getX(), p.getY()-1);
if (p.getDirection() != Direction.UP)
turnPlayer(Direction.UP);
}
if (down == true){
p.move(p.getX(), p.getY()+1);
if (p.getDirection() != Direction.DOWN)
turnPlayer(Direction.DOWN);
}
if (left == true){
p.move(p.getX()-1, p.getY());
if (p.getDirection() != Direction.LEFT)
turnPlayer(Direction.LEFT);
}
if (right == true){
p.move(p.getX()+1, p.getY());
if (p.getDirection() != Direction.RIGHT)
turnPlayer(Direction.RIGHT);
}
if (info == true){
int l = 10-last;
iy.setText("y: "+p.getY());
ix.setText("x: "+p.getX());
im.setText("enemys: "+ae.size());
in.setText("next enemy: "+l);
iu.setText("Updated "+u+" times.");
RefreshInfo();
}
if (p.getY() >= +334){
p.move(p.getX(), +334);
}
if (p.getY() <= -334){
p.move(p.getX(), -334);
}
if (p.getX() >= 675){
p.move(675, p.getY());
}
if (p.getX() <= -12){
p.move(-12, p.getY());
}
RepaintAllEnemys();
Enemy.UpdateAll();
playerImage.repaint();
RepaintPlayer();
enemys.Update();
b.Update();
f.repaint();
if (info != true){
f.repaint();
}
if (last == 10){
Random r = new Random();
int x = 1+r.nextInt(2), y = 1+r.nextInt(2), distance = 1+r.nextInt(570), nx = 0, ny = 0;
if (x == 1){
}
last = 0;
}
last++;
u++;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
public static void RefreshInfo(){
f.remove(iy);
f.remove(ix);
f.remove(im);
f.remove(in);
f.remove(iu);
f.add(ix);
f.add(iy);
f.add(im);
f.add(in);
f.add(iu);
iy.setLocation(0, 10);
ix.setLocation(0, 20);
im.setLocation(0, 30);
in.setLocation(0, 40);
iu.setLocation(0, 50);
iu.setBounds((int) iu.getLocation().getX(), (int) iu.getLocation().getY(), 200, 15);
iy.setBounds((int) iy.getLocation().getX(), (int) iy.getLocation().getY(), 100, 15);
ix.setBounds((int) ix.getLocation().getX(), (int) ix.getLocation().getY(), 100, 15);
im.setBounds((int) im.getLocation().getX(), (int) im.getLocation().getY(), 100, 15);
in.setBounds((int) in.getLocation().getX(), (int) in.getLocation().getY(), 100, 15);
f.repaint();
}
public static void UpdateAll(){
}
public static void Paint(JLabel imgs, int x, int y, Icon file){
Icon img = file;
imgs.setIcon(img);
imgs.setBounds(x, y, img.getIconWidth(), img.getIconHeight());
imgs.setLocation(x, y);
imgs.setVisible(true);
f.add(imgs);
imgs.setVisible(true);
}
public static void addBullet(JLabel l, int x, int y, Icon icon){
Paint(l, x, y, icon);
bullets.add(l);
}
public static void moveBullet(int newX, int newY, JLabel label){
if (bullets.contains(label)){
label.setLocation(newX, newY);
label.repaint();
f.repaint();
label.setVisible(true);
}
}
public static void Repaint(JLabel l){
f.remove(l);
l.setBounds((int)l.getLocation().getX(), (int)l.getLocation().getY(), l.getWidth(), l.getHeight());
f.add(l);
}
public static void addAE(JLabel l){
ae.add(l);
}
public static void RepaintAllEnemys(){
for (int i = 0; i < ae.size(); i++){
ae.get(i).repaint();
}
}
public static void MovePlayer(int x, int y){
playerImage.setLocation(x, y);
playerImage.repaint();
f.repaint();
}
public static void paint(JLabel l, int Y, int X){
l.setLocation(X, Y);
l.setBounds(X, Y, l.getIcon().getIconWidth(), l.getIcon().getIconHeight());
l.setVisible(true);
f.add(l);
l.setVisible(true);
l.repaint();
f.repaint();
}
public static void RepaintPlayer(){
if (p.isAttacking() == true){
if (pt == Playere.Kaneki){
if (attacking == false){
ImageIcon img = new ImageIcon(StartMenu.class.getResource("/Schoo/NewGame/Kaneki_hit.png"));
playerImage.setIcon(img);
playerIcon = img;
attacking = true;
imageIcon = img;
}
}
if (pt == Playere.Touka){
if (attacking == false){
ImageIcon img = new ImageIcon(StartMenu.class.getResource("/Schoo/NewGame/touka_shoot.png"));
playerImage.setIcon(img);
playerIcon = img;
attacking = true;
imageIcon = img;
}
}
}else{
if (pt == Playere.Kaneki){
if (attacking == true){
ImageIcon img = new ImageIcon(StartMenu.class.getResource("/Schoo/NewGame/Kaneki_walk.png"));
playerImage.setIcon(img);
playerIcon = img;
attacking = false;
imageIcon = img;
}
}
if (pt == Playere.Touka){
if (attacking == true){
ImageIcon img = new ImageIcon(StartMenu.class.getResource("/Schoo/NewGame/touka_walk.png"));
playerImage.setIcon(img);
playerIcon = img;
attacking = false;
imageIcon = img;
}
}
}
turnPlayer(p.getDirection());
MovePlayer(p.getX(), p.getY());
playerImage.repaint();
f.repaint();
}
public static void paintplayer(){
if (pt == Playere.Kaneki){
ImageIcon imgs = new ImageIcon(StartMenu.class.getResource("/schoo/NewGame/kaneki_walk.png"));
playerImage.setIcon(imgs);
playerImage.setBounds(p.getX(), p.getY(), imgs.getIconWidth(), imgs.getIconHeight());
playerImage.setLocation(274, 277);
playerImage.setVisible(true);
f.add(playerImage);
playerImage.setVisible(true);
imageIcon = imgs;
}
if (pt == Playere.Touka){
playerImage.setIcon(new ImageIcon(StartMenu.class.getResource("/schoo/NewGame/touka_walk.png")));
playerImage.setBounds(p.getX(), p.getY(), new ImageIcon(StartMenu.class.getResource("/schoo/NewGame/touka_walk.png")).getIconWidth(), new ImageIcon(StartMenu.class.getResource("/schoo/NewGame/touka_walk.png")).getIconHeight());
playerImage.setLocation(274, 277);
playerImage.setVisible(true);
f.add(playerImage);
playerImage.setVisible(true);
playerIcon = playerImage.getIcon();
}
}
public static Bullets getBullets(){
return b;
}
Icon icon;
public void turn(Direction d){
if (pt == Playere.Kaneki){
icon = new SafeIcon(playerImage.getIcon());
BufferedImage bi = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D) bi.getGraphics();
if (d == Direction.LEFT && p.getDirection() == Direction.UP){
g.rotate(Math.PI / 2, playerImage.getWidth(), playerImage.getHeight());
playerImage.getIcon().paintIcon(null, g, 0, 0);
g.dispose();
}
}
if (pt == Playere.Touka){
}
}
public static void turnPlayer(Direction d){
try {
TheRealGame.class.newInstance().turn(d);
} catch (InstantiationException e) {
System.out.println("Something went wrong!");
e.printStackTrace();
} catch (IllegalAccessException e) {
System.out.println("Something went wrong!");
e.printStackTrace();
}
}
public enum Direction{
LEFT, UP, RIGHT, DOWN;
}
}
That's because when you are creating a SafeIcon instance in icon = new SafeIcon(playerImage.getIcon()); you are defining null to wrapee variable.
If you need wrapee to be a non null value, adjust constructor to be more safe, so it will be much more easy to detect root cause of NPEs:
public SafeIcon(Icon icon) {
if (icon == null) {
throw new NullPointerException("icon"); // or IllegalArgumentException
}
this.wrapee = icon;
}
Then check if playerImage JLabel instance should always have an icon defined. If so, define an icon to it and your problem will be solved.
So I am trying to make a game like Snake, but I am running into some issues.
I want to repeat the if statement inside of of the moveup class using a while loop, but
when I try to use the KeyListener to listen for the key press of the up arrow key to break the while loop it acts like it only looped once (moved up 5 pixels). The loop is supposed to make the snake continue going up without having to click multiple times, but it just moves five (the value I set it to do) pixels. Here is the code:
public class Snake extends JFrame implements KeyListener {
int ballX = 50;
int ballY = 50;
int playerX = 250;
int playerY = 250;
boolean up = false;
boolean right = false;
boolean down = false;
boolean left = true;
class DrawPane extends JPanel {
public void paintComponent(Graphics gc) {
Random rand = new Random();
int dotsX = rand.nextInt(500) + 1;
int dotsY = rand.nextInt(500) + 1;
Graphics g = this.getGraphics();
setVisible(true);
super.paintComponents(gc);
gc.setColor(Color.BLUE);
gc.fillRect(ballX, ballY, 10, 10);
gc.setColor(Color.RED);
gc.fillRect(playerX, playerY, 10, 10);
}
}
public Snake(String title) {
super(title);
JFrame frame = new JFrame();
setContentPane(new DrawPane());
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setSize(500, 500);
this.setBackground(Color.YELLOW);
this.setResizable(false);
this.addKeyListener(this);
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() == KeyEvent.VK_UP) {
up = true;
right = false;
down = false;
left = false;
moveup(e);
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
up = false;
right = false;
down = true;
left = false;
movedown(e);
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
up = false;
right = true;
down = false;
left = false;
moveright(e);
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
up = false;
right = false;
down = false;
left = true;
moveleft(e);
}
}
public void moveup(KeyEvent e) {
while (up) {
if (playerX < 500 || playerX > 0) {
playerX = playerX + 5;
repaint();
if (e.getKeyChar() == KeyEvent.VK_UP)
break;
}
}
}
public void moveright(KeyEvent e) {
if (playerX < 500 || playerX > 0) {
playerX = playerX + 5;
repaint();
// moveright();
}
}
public void movedown(KeyEvent e) {
if (playerY < 500 || playerY > 0) {
playerY = playerY + 5;
repaint();
// movedown();
}
}
public void moveleft(KeyEvent e) {
if (playerX < 500 || playerX > 0) {
playerX = playerX - 5;
repaint();
// moveleft();
}
}
public void snakePanel() {
JPanel panel1 = new JPanel();
panel1.setBackground(Color.red);
}
public void ActionListener() {
}
public static void main(String[] args) {
Snake r = new Snake("Snake");
}
}
It never loops because of the break. Effectively you're saying:
if keycode is up
loop
move up
break if keycode is up // Will always be true
More so, you shouldn't be looping in an event handler like that. Event handlers should execute and return quickly else you'll block the event thread. Should be using a timer to act as a heartbeat and update the position/repaint periodically.
Keep in mind that you DON'T want to use Swing for more advanced games in the future.
--- Quick solution:
Just remove your while(). The KeyListener interface lets you abstract the concept of "while this key is pressed, do this". Instead, when you implement the interface, you say: "whenever this key is pressed, do this". It's an event.
Here's your working code:
http://pastebin.com/b0CZDxpD
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...
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.