Sprite not moving properly Java - java

I am trying to make a Space Shooter using java, but it isn't working. I am currently working on spawning the enemies. To hold the positions of all the enemies, I used an ArrayList called allEnemies. The ArrayList is filled with Point objects. I am updating the Game by calling updateEnemies() in my game loop.
Originally, I had the enemy's y position increment by 1, but that was too fast, so I changed it to 0.2 in an attempt to slow it down. Once I made it 0.2, the sprites spawned at the top but didn't move down. I works for any value above 1, including decimals, but not anything below. Here is my code:
Enemy.java
package main;
import java.awt.Point;
import java.util.ArrayList;
public class Enemy {
static ArrayList<Point> allEnemies = new ArrayList<Point>();
public static ArrayList<Point> createEnemies(int round) {
for (int i = 0; i < round; i++) {
Point newEnemyLocation = new Point((int) (Math.random()*Game.WIDTH - 64), 0);
allEnemies.add(newEnemyLocation);
}
return allEnemies;
}
public static ArrayList<Point> updateEnemies() {
if (allEnemies.size() != 0) {
for (int i = 0; i < allEnemies.size(); i++) {
Point enemyLocation = allEnemies.get(i);
if (enemyLocation.y <= Game.HEIGHT) {
allEnemies.get(i).y += 0.2;
} else {
allEnemies.remove(i);
}
}
}
return allEnemies;
}
}
Game.java
package main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable, KeyListener {
//declare values
private static final long serialVersionUID = 1L;
public static final int WIDTH = 800;
public static final int HEIGHT = 600;
public static final String TITLE = "Space Shooter";
private boolean running = false;
private Thread thread;
private Player player;
private BufferedImage playerImage;
private BufferedImage bulletImage;
private BufferedImage enemyImage;
int playerx;
int playery;
int round = 1;
public Game() {
//
player = new Player((WIDTH/2)-32, HEIGHT-200);
//allocates all file resources
try {
playerImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/player.png"));
bulletImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/bullet.png"));
enemyImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/enemy.png"));
} catch (IOException e) {
e.printStackTrace();
}
addKeyListener(this);
setFocusable(true);
requestFocusInWindow();
}
//starts thread
private synchronized void start() {
if (running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
//stops thread
private synchronized void stop() {
if (!running)
return;
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(1);
}
#Override
//game loop
public void run() {
long lastTime = System.nanoTime();
final double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
int updates = 0;
int frames = 0;
long timer = System.currentTimeMillis();
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if (delta > 1) {
tick();
updates++;
delta--;
}
Shoot.updateBullets();
Enemy.updateEnemies();
render();
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println(updates + " TICKS, " + frames + " FPS");
updates = 0;
frames = 0;
}
}
stop();
}
//updates sprite locations
public void tick() {
playerx = player.getX();
playery = player.getY();
}
//renders sprites
public void render() {
//setting up triple-buffering
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
//////////////////////////////////
g.setColor(Color.BLACK); g.fillRect(0,0,getWidth(), getHeight());
g.drawImage(playerImage, playerx, playery, this);
if (Shoot.allBullets.size() != 0) {
for (int i = 0; i < Shoot.allBullets.size(); i++) {
int bulletx = (int) Shoot.allBullets.get(i).getX();
int bullety = (int) Shoot.allBullets.get(i).getY();
g.drawImage(bulletImage, bulletx + 21, bullety, this);
}
}
if (Enemy.allEnemies.size() != 0) {
for (int i = 0; i < Enemy.allEnemies.size(); i++) {
int enemyx = (int) Enemy.allEnemies.get(i).getX();
int enemyy = (int) Enemy.allEnemies.get(i).getY();
g.drawImage(enemyImage, enemyx, enemyy, this);
}
} else {
Enemy.createEnemies(round);
round++;
}
//////////////////////////////////
g.dispose();
bs.show();
}
#Override
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_SPACE) {
Shoot.addBullet(player.getX(), player.getY());
}
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_UP) {
player.setY(playery -= 20);
} else if (key == KeyEvent.VK_DOWN) {
player.setY(playery += 20);
} else if (key == KeyEvent.VK_RIGHT) {
player.setX(playerx += 20);
} else if (key == KeyEvent.VK_LEFT) {
player.setX(playerx -= 20);
}
}
public void keyTyped(KeyEvent e) {}
public static void main(String[] args) {
Game game = new Game();
JFrame frame = new JFrame(TITLE);
frame.setSize(WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(game);
frame.getContentPane().setBackground(Color.BLACK);
frame.setVisible(true);
game.start();
}
}

Hello it is because the point class holds 2 integers x and y and you are trying to add 0.2 to a integer that only can store values without decimals so you have 2 options 1 is to change the point to a Point2D (holds doubles and a double can hold numbers with decimals) or you could create a enemy class with a x and y float/double but in this case I would go for option 1 because this is a small game, good luck!
Edit:
I was wrong about point2d, just saw that it is a abstract class so do like this
public class Enemy{
public double x,y;
Public Enemy(double x, double y){
this.x = x;
this.y = y;
}
}
And use that as the object in your arraylist

Related

Changing Sprite When You Press a key

I have a sprite sheet that I can change the little slimey's picture from but it only changes like the actual image I want to make them so when I press the right key it takes the pictures and gives it the one where it's facing right. I tried to get it so that it takes a int from the slime's class and uses it when I press right but it only prints the number 2 in the console but isn't changing the picture....... the stuff for the slime....
package com.maprildoll.main;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
public class Slimey extends DollObject{
Random r = new Random();
private int x;
private int y;
public int sprites = 0;
private BufferedImage slimey;
public SpriteSheet slimes;
public Slimey(ID id, int x, int y, Slimeball slimeball) {
super(x, y, id);
this.x = x;
this.y = y;
SpriteSheet slimes = new SpriteSheet(slimeball.getSpriteSheet());
slimey = slimes.grabImage(1, 1, 69, 49);
if(sprites == 2) {
slimey = slimes.grabImage(2, 1, 69, 49);
}
}
public void tick() {
x += speedX;
y += speedY;
x = Slimeball.clamp(x, 0, Slimeball.WIDTH - 82);
y = Slimeball.clamp(y, 88, Slimeball.HEIGHT - 278);
}
public void render(Graphics g) {
g.drawImage(slimey, (int)x, (int)y, null);
}
}
the main window thingy....
package com.maprildoll.main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.swing.ImageIcon;
public class Slimeball extends Canvas implements Runnable{
private static final long serialVersionUID = -2882786666891858852L;
public static final int WIDTH = 1700, HEIGHT = 900;
private Thread thread;
private boolean running = false;
private Random r;
private Handler handler;
private BufferedImage spriteSheetSlimes;
private BufferedImage spriteSheetItem = null;
private BufferedImage items;
private Slimey slimey;
public Slimeball (Slimeball slimeball){
handler = new Handler();
this.addMouseListener(new Mousey(handler));
new Windows(WIDTH, HEIGHT, "Slimeballin' >.<!!", this);
r = new Random();
handler.addObject(new Slimeyball(WIDTH/2-32, HEIGHT/2+186, ID.Slimeyball));
}
public void init() {
requestFocus();
ImageLoader loader = new ImageLoader();
try {
spriteSheetItem = loader.loadImage("C:\\Users\\SPooKykun\\eclipse-workspace\\MaprilDolly\\src\\com\\maprildoll\\main\\Slimeball\\itemsheet.png");
spriteSheetSlimes = loader.loadImage("C:\\Users\\SPooKykun\\eclipse-workspace\\MaprilDolly\\src\\com\\maprildoll\\main\\Slimeball\\slimebox.png");
}catch(IOException e) {
e.printStackTrace();
}
addKeyListener(new Slimekey(this));
SpriteSheetTew itemsheet = new SpriteSheetTew(spriteSheetItem);
items = itemsheet.grabImage(1, 1, 32, 32);
slimey = new Slimey(ID.Slime, 1040, 620, this);
}
public synchronized void start() {
thread = new Thread(this);
thread.start();
running = true;
}
public synchronized void stop() {
try{
thread.join();
running = false;
}catch(Exception e){
e.printStackTrace();
}
}
public void run(){
init();
long lastTime = System.nanoTime();
double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
long timer = System.currentTimeMillis();
int frames = 0;
while(running){
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >=1) {
tick();
delta--;
}
if(running)
render();
frames++;
if(System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println("FPS: " + frames);
frames = 0;
}
}
stop();
}
private void tick() {
handler.tick();
slimey.tick();
}
private void render() {
BufferStrategy bs = this.getBufferStrategy();
if(bs == null){
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
Color cyanie = new Color (231, 255, 254);
g.setColor(cyanie);
g.fillRect(0, 0, WIDTH, HEIGHT);
final ImageIcon background = new ImageIcon("C:\\Users\\SPooKykun\\eclipse-workspace\\MaprilDolly\\src\\com\\maprildoll\\main\\Slimeball\\testbackground.gif");
Image imgback = background.getImage();
g.drawImage(imgback, 0, 0, this);
g.drawImage(items, 865, 636, this);
slimey.render(g);
handler.render(g);
g.dispose();
bs.show();
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
slimey.setSpeedX(-5);
} else if (key == KeyEvent.VK_RIGHT) {
slimey.setSpeedX(+5);
slimey.sprites = 2;
System.out.println(slimey.sprites);
} else if (key == KeyEvent.VK_ALT){
slimey.setSpeedY(-8);
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
slimey.setSpeedX(0);
} else if (key == KeyEvent.VK_RIGHT) {
slimey.setSpeedX(0);
} else if (key == KeyEvent.VK_ALT);{
slimey.setSpeedY(+4);
}
}
public static int clamp(double x, int min, int max){
if(x >= max)
return (int) (x = max);
else if(x <= min)
return (int) (x = min);
else
return (int) x;
}
public BufferedImage getSpriteSheet() {
return spriteSheetSlimes;
}
}
I tried to put a keylistener to the Slimey but for some reason the keyboard would never work when it was in there..... soo how would I take a image from the sheet and add it to the keypressed stuff I want to put the right facing one when it presses right.....

Where do I put public static void main(String[] args)?

I am new to java, and after attempting to create a small snake type game, and error occurred
Error: Main method not found in class Game.GamePanel, please define the main method as: public static void main(String[] args)"
Could someone please help me as to fixing the error? It would be a big help as a beginner to java. Im using Eclipse latest version
package Game;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements Runnable, KeyListener {
public static final int WIDTH = 1000;
public static final int HEIGHT = 1000;
//Render
private Graphics2D g2d;
private BufferedImage image;
//GameLoop
private Thread thread;
private boolean running;
private long targetTime;
//Game Stuff
private final int SIZE = 10;
Entity head;
ArrayList<Entity> snake;
//movement
private int dx, dy;
//key input
private boolean up,down,right,left,start;
public GamePanel() {
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);
requestFocus();
addKeyListener(this);
}
public void addNotify() {
super.addNotify();
thread = new Thread(this);
thread.start();
}
private void setFPS(int fps) {
targetTime = 1000 / fps;
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
int k = e.getKeyCode();
if(k == KeyEvent.VK_UP) up = true;
if(k == KeyEvent.VK_DOWN) down = true;
if(k == KeyEvent.VK_LEFT) left = true;
if(k == KeyEvent.VK_RIGHT) right = true;
if(k == KeyEvent.VK_ENTER) start = true;
}
#Override
public void keyReleased(KeyEvent e) {
int k = e.getKeyCode();
if(k == KeyEvent.VK_UP) up = false;
if(k == KeyEvent.VK_DOWN) down = false;
if(k == KeyEvent.VK_LEFT) left = false;
if(k == KeyEvent.VK_RIGHT) right = false;
if(k == KeyEvent.VK_ENTER) start = false;
}
#Override
public void run() {
if(running) return;
init();
long startTime;
long elapsed;
long wait;
while(running){
startTime = System.nanoTime();
update();
requestRender();
elapsed = System.nanoTime() - startTime;
wait = targetTime - elapsed / 1000000;
if(wait > 0) {
try {
Thread.sleep(wait);
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
private void init() {
image = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_ARGB);
g2d = image.createGraphics();
running = true;
setUplevel();
setFPS (10);
}
private void setUplevel() {
snake = new ArrayList<Entity>();
head = new Entity(SIZE);
head.setPosition(WIDTH / 2, HEIGHT / 2);
snake.add(head);
for(int i = 1;i < 10;i++) {
Entity e = new Entity(SIZE);
e.setPosition(head.getX() + (i * SIZE), head.getY());
snake.add(e);
}
}
private void requestRender() {
render(g2d);
Graphics g = getGraphics();
g.drawImage(image, 0,0,null);
g.dispose();
}
private void update() {
if(up && dy == 0) {
dy = -SIZE;
dx = 0;
}
if(down && dy == 0) {
dy = SIZE;
dx = 0;
}
if(left && dx == 0) {
dy = 0;
dx = -SIZE;
}
if(right && dx == 0) {
dy = 0;
dx = SIZE;
}
if(dx != 0 || dy != 0) {
for(int i = snake.size() - 1;i > 0;i--) {
snake.get(i).setPosition(
snake.get(i - 1).getX(),
snake.get(i - 1).getY()
);
}
head.move(dx, dy);
}
if(head.getX() < 0 ) head.getX(WIDTH);
if(head.getY() < 0 ) head.getY(HEIGHT);
if(head.getX() > WIDTH ) head.getX(0);
if(head.getY() > HEIGHT ) head.getY (0);
}
public void render(Graphics2D g2d) {
g2d.clearRect(0, 0, WIDTH, HEIGHT);
g2d.setColor(Color.GREEN);
for(Entity e : snake) {
e.render(g2d);
}
}
}
You can add it to GamePanel, but you need to create a JFrame and you want to add an instance of your GamePanel to it. Something like,
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.add(new GamePanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}

Rectangle is not moving if i set the x y from another class.

Alright, so I got two classes here, the main and the keylistener class which i use to pass keyboard inputs to the main class.
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable{
private static final long serialVersionUID = 1L;
private final static int WIDTH = 240;
private final static int HEIGHT = WIDTH / 12 * 9;
private final static int SCALE = 2;
private String TITLE = "Game";
private boolean running = false;
private Thread thread;
Random r = new Random();
ArrayList<Point> snakePart = new ArrayList<Point>();
Point head;
KeyHandle keyhandle;
public static void main(String[] args) {
new Game();
}
public Game() {
init();
JFrame frame = new JFrame(TITLE);
Dimension size = new Dimension(WIDTH * SCALE, HEIGHT * SCALE);
setMinimumSize(size);
setMaximumSize(size);
setPreferredSize(size);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.pack();
frame.setVisible(true);
start();
}
public void init() {
head = new Point(0,0);
addKeyListener(new KeyHandle());
}
#Override
public void run() {
final double ticks = 60.0;
long initTime = System.nanoTime();
double ns = 1000000000 / ticks;
double delta = 0;
long timer = System.currentTimeMillis();
double updates = 0;
int frames = 0;
while (running) {
long nowTime = System.nanoTime();
delta += (nowTime - initTime) / ns;
initTime = nowTime;
if (delta >= 1) {
tick();
updates++;
delta--;
}
render();
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println("Ticks: " + updates + " Frames: " + frames);
updates = 0;
frames = 0;
}
}
stop();
}
public void tick() {
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.white);
g.drawRect(head.x, head.y, 10, 10);
bs.show();
g.dispose();
}
private synchronized void start() {
if (running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
private synchronized void stop() {
if (!running)
return;
running = false;
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.exit(1);
}
}
and then i've got the keylistener class which looks like this
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class KeyHandle implements KeyListener {
Game game;
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP){
} else if(e.getKeyCode() == KeyEvent.VK_DOWN){
game.head.y += 10;
} else if(e.getKeyCode() == KeyEvent.VK_LEFT){
} else if(e.getKeyCode() == KeyEvent.VK_RIGHT){
} else if(e.getKeyCode() == KeyEvent.VK_ESCAPE){
}
}
#Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP){
} else if(e.getKeyCode() == KeyEvent.VK_DOWN){
} else if(e.getKeyCode() == KeyEvent.VK_LEFT){
} else if(e.getKeyCode() == KeyEvent.VK_RIGHT){
} else if(e.getKeyCode() == KeyEvent.VK_ESCAPE){
}
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Now the problem appears when I try to edit the "head" y and x values as seen in the second class.
if(e.getKeyCode() == KeyEvent.VK_DOWN){
game.head.y += 10;
What am I doing wrong here and is there a better way to pass and set x and y values more efficiently.
Your KeyHandle class contains a reference to a Game but no intantiation of game. Instead of creating new Game() in your main method and dropping the instance on the floor, allocate that instance to the reference contained in KeyHandle.
keyhandle.game = new Game();

Testing out simple features for a game, cannot get an object to jump

I am trying to get a ball to bounce up and down when you press the up arrow key. I can get the ball to move up but it will not stop moving up. I have written the code for the ball movement in my update method. I am trying to get the ball to stop at y coordinate 400, but it just passes it up.
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
public class Game extends Canvas implements Runnable {
int x,y;
public static int width = 300;
public static int height = width / 16 * 9;
public static int scale = 3;
private boolean running = false;
public Thread thread;
public JFrame frame;
public Keyboard key;
private BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
private int[] pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
public Game() {
Dimension size = new Dimension(width * scale, height * scale);
setPreferredSize(size);
frame = new JFrame();
key = new Keyboard();
addKeyListener(key);
}
public synchronized void start() {
running = true;
thread = new Thread(this, "Display");
thread.start();
}
public synchronized void stop(){
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public void run() {
long lastTime = System.nanoTime();
final double nanoSeconds = 1000000000.0 / 60.0;
double delta = 0;
int frames = 0;
int gameUpdates = 0;
long timer = System.currentTimeMillis();
requestFocus();
while(running){
long now = System.nanoTime();
delta += (now - lastTime) / nanoSeconds;
lastTime = now;
//this ensures that delta only updates the screen 60 times each second
while (delta >= 1){
update();
gameUpdates++;
delta--;
}
render();
frames++;
//this if statement happens once a second
if (System.currentTimeMillis() - timer > 1000){
timer += 1000;
frame.setTitle("Bouncy Ball! ~ ~ ~ Updates per second: " + gameUpdates + ". Frames per second: " + frames + ".");
gameUpdates = 0;
frames = 0;
}
}
stop();
}
int yy;
public void update() {
key.update();
y = y + yy;
if(key.up){
yy = -5;
if(y == 400){
yy = 0;}
}
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null){
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.drawImage(image,0,0,getWidth(),getHeight(),null);
g.setColor(Color.DARK_GRAY);
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(Color.MAGENTA);
g.fillOval(300,y+435,50,50);
g.dispose();
bs.show();
}
public static void main(String[] args) {
Game game = new Game();
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setResizable(false);
game.frame.setVisible(true);
game.frame.add(game);
game.frame.pack();
game.frame.setTitle("Bouncy Ball");
game.start();
}
}
This is my keylisener class
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Keyboard implements KeyListener{
private boolean[] keys = new boolean[120];
public boolean up, down, left, right;
public void update(){
up = keys[KeyEvent.VK_UP];
down = keys[KeyEvent.VK_DOWN];
left = keys[KeyEvent.VK_LEFT];
right = keys[KeyEvent.VK_RIGHT];
}
#Override
public void keyPressed(KeyEvent e) {
keys[e.getKeyCode()] = true;
}
#Override
public void keyReleased(KeyEvent e) {
keys[e.getKeyCode()] = false;
}
#Override
public void keyTyped(KeyEvent e) {
}
}
Your issue is in the key.update() method. key.up will only be true while you're holding the up key, not just if you press the up key once. If, for now, you only care about a single button press, change it to:
public void update() {
if (keys[KeyEvent.VK_UP]) {
up = true;
}
}
Which will only update once, once you press up, and keys.up will stay true.
Also, y is decreasing, not increasing (you're subtracting 5 from it), so you want to change
== 400 to == 400, or even better, <= 400, in case you don't increment with whole numbers (as per the other answer).
As a general debugging idea: At that if statement, I printed out the value of y, and noticed it only printed out 3 or 4 values (corresponding to how long I was holding it down), which meant that the if statement wasn't being checked, or wasn't returning true (which was the case here).
Instead of:
if(key.up){
yy = -5;
if(y == 400){
yy = 0;}
}
try:
if(key.up){
yy = -5;
if(y >= 400){
yy = 0;}
}
If your ball is moving at 5px per update then it may pass 400px without actually
equaling 400px, this is why you check if it is greater than 400px.

JFrame, leaves trail of rectangle

i'm trying to create a game. And almost everytime I move, it's leaving a trail
Code:
package lt.mchackers.gametest.main;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import lt.mchackers.gametest.handlers.InputHandler;
/**
* Main class for the game
*/
public class Main extends JFrame
{
private static final long serialVersionUID = -828018325337767157L;
boolean isRunning = true;
int fps = 30;
int windowWidth = 320;
int windowHeight = 320;
int speed;
BufferedImage backBuffer;
Insets insets;
InputHandler input;
int x = 0;
int y = 0;
int xa = 0;
int ya = 0;
Coordinates coords = new Coordinates(0, 0);
public static void main(String[] args)
{ Main game = new Main();
game.run();
System.exit(0);
}
/**
* This method starts the game and runs it in a loop
*/
public void run()
{
initialize();
while(isRunning)
{
long time = System.currentTimeMillis();
update();
draw();
// delay for each frame - time it took for one frame
time = (1000 / fps) - (System.currentTimeMillis() - time);
if (time > 0)
{
try
{
Thread.sleep(time);
}
catch(Exception e){}
}
}
setVisible(false);
}
/**
* This method will set up everything need for the game to run
*/
void initialize()
{
setTitle("Game Tutorial");
setSize(windowWidth, windowHeight);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
insets = getInsets();
setSize(insets.left + windowWidth + insets.right,
insets.top + windowHeight + insets.bottom);
backBuffer = new BufferedImage(windowWidth, windowHeight, BufferedImage.TYPE_INT_RGB);
input = new InputHandler(this);
Graphics bbg = backBuffer.getGraphics();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("map"));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
String line = null;
try {
BufferedImage gray = ImageIO.read(new File("gray.png"));
BufferedImage black = ImageIO.read(new File("black.png"));
while ((line = reader.readLine()) != null) {
for(String s : line.split(""))
{
if (s.contains("*"))
{
bbg.drawImage(gray, xa-32, ya, null);
}
else if (s.contains("#"))
{
bbg.drawImage(black, xa-32, ya, null);
}
if (xa < 320)
{
xa += 32;
}
else
{
ya += 32;
xa = 0;
}
System.out.println(xa);
System.out.println(ya);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* This method will check for input, move things
* around and check for win conditions, etc
*/
void update()
{
if (input.isKeyDown(KeyEvent.VK_NUMPAD0))
{
speed -= 1;
}
if (input.isKeyDown(KeyEvent.VK_NUMPAD1))
{
speed += 1;
}
if (input.isKeyDown(KeyEvent.VK_RIGHT))
{
coords.setCoords(coords.getX() + 32, coords.getY());
}
if (input.isKeyDown(KeyEvent.VK_LEFT))
{
coords.setCoords(coords.getX() - 32, coords.getY());
}
if (input.isKeyDown(KeyEvent.VK_UP))
{
coords.setCoords(coords.getX(), coords.getY() - 32);
}
if (input.isKeyDown(KeyEvent.VK_DOWN))
{
coords.setCoords(coords.getX(), coords.getY() + 32);
}
//System.out.println(x);
//System.out.println(y);
//System.out.println(speed);
if (coords.getY() < 0)
{
coords.setCoords(coords.getX(), 0);
}
if (coords.getX() < 0)
{
coords.setCoords(0, coords.getY());
}
if (coords.getX() > windowWidth - 32)
{
coords.setCoords(windowWidth - 32, coords.getY());
}
if (coords.getY() > windowHeight - 32)
{
coords.setCoords(coords.getX(), windowHeight - 32);
// y = windowHeight - 32;
}
}
/**
* This method will draw everything
*/
void draw()
{
Graphics g = getGraphics();
//this.setBackground(Color.BLACK);
//super.paintComponents(g);
backBuffer.setRGB(x, y, Color.BLACK.getRGB());
Graphics bbg = backBuffer.getGraphics();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("map"));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
String line = null;
try {
BufferedImage gray = ImageIO.read(new File("gray.png"));
BufferedImage black = ImageIO.read(new File("black.png"));
while ((line = reader.readLine()) != null) {
for(String s : line.split(""))
{
if (s.contains("*") && xa + 32!= coords.getX() && ya - 32 != coords.getY())
{
bbg.drawImage(gray, xa-32, ya, null);
}
else if (s.contains("#") && xa + 32 != coords.getX() && ya - 32 != coords.getY())
{
bbg.drawImage(black, xa-32, ya, null);
}
if (xa < 320)
{
xa += 32;
}
else
{
ya += 32;
xa = 0;
}
//System.out.println(xa);
//System.out.println(ya);
}
}
} catch (IOException e) {
e.printStackTrace();
}
bbg.setColor(Color.WHITE);
xa = 0;
ya = 0;
System.out.println(coords.getX());
bbg.setColor(Color.WHITE);
bbg.fillRect(coords.getX(),coords.getY(), 32,32);
System.out.println(coords.getY());
//bbg.setColor(Color.BLACK);
//bbg.drawOval(x, y, 20, 20);
g.drawImage(backBuffer, insets.left, insets.top, this);
}
}
Thanks for help.
Check out my code from here, to get a hint as to how to paint stuff in a game loop properly.
Basically what you need to take care of is double buffering to prevent any flickering and also repainting the background so that you don't leave out any trail of rectangles.
You can also check out the Killer Game Programming in Java online book, which can help you learn the game programming concepts and their implementation.
The concept of double buffering is simple. Since painting on the screen takes more time than updating the states of the objects in the gameplay, we use two canvas to prevent any flickering issues which arise when objects are painted directly on the screen.
When the object states are updated in the game loop, it is rendered in a background canvas. The background canvas is then copied to the screen which takes less time compared to painting directly on the screen. And while this copying is happening, the object states are updated again and they are rendered on the background canvas again, which is then copied to the screen. Repeat this over and over, and you get the double buffering.
Basically you keep a buffer of screen which is to be painted and your game renders objects in the buffer which is then copied to the screen.
Here's a code which I think might help you understand the concept:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class GamePanel extends JPanel implements Runnable
{
private static final long serialVersionUID = 6892533030374996243L;
public static final int WIDTH = 800;
public static final int HEIGHT = 600;
private Thread animator;
private volatile boolean running = false;
private volatile boolean isGameOver = false;
private volatile boolean isUserPaused = false;
private volatile boolean isWindowPaused = false;
private Graphics dbg;
private Image dbImage = null;
private static final int NO_DELAYS_PER_YIELD = 16;
private static final int MAX_FRAME_SKIPS = 5;
private static final Color backgroundColor = new Color(245, 245, 245);
private static long fps = 30;
private static long period = 1000000L * (long) 1000.0 / fps;
private static volatile boolean isPainted = false;
public GamePanel()
{
setBackground(backgroundColor);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);
requestFocus();
readyForPause();
// Add key listeners here...
}
public void addNotify()
{
super.addNotify();
startGame();
}
void startGame()
{
if (animator == null || !running)
{
animator = new Thread(this);
animator.start();
}
}
void stopGame()
{
running = false;
}
private void readyForPause()
{
addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if ((keyCode == KeyEvent.VK_ESCAPE) || (keyCode == KeyEvent.VK_Q)
|| (keyCode == KeyEvent.VK_END) || (keyCode == KeyEvent.VK_P)
|| ((keyCode == KeyEvent.VK_C) && e.isControlDown()))
{
if (!isUserPaused)
setUserPaused(true);
else
setUserPaused(false);
}
}
});
}
// This is the game loop. You can copy-paste it even in your own code if you want to.
public void run()
{
long beforeTime, afterTime, timeDiff, sleepTime;
long overSleepTime = 0L;
int noDelays = 0;
long excess = 0L;
beforeTime = System.nanoTime();
running = true;
while (running)
{
requestFocus();
gameUpdate();
gameRender();
paintScreen();
afterTime = System.nanoTime();
timeDiff = afterTime - beforeTime;
sleepTime = (period - timeDiff) - overSleepTime;
if (sleepTime > 0)
{
try
{
Thread.sleep(sleepTime / 1000000L);
}
catch (InterruptedException e)
{
}
overSleepTime = (System.nanoTime() - afterTime - sleepTime);
}
else
{
excess -= sleepTime;
overSleepTime = 0L;
if (++noDelays >= NO_DELAYS_PER_YIELD)
{
Thread.yield();
noDelays = 0;
}
}
beforeTime = System.nanoTime();
int skips = 0;
while ((excess > period) && (skips < MAX_FRAME_SKIPS))
{
excess -= period;
gameUpdate();
skips++;
}
isPainted = true;
}
System.exit(0);
}
private void gameUpdate()
{
if (!isUserPaused && !isWindowPaused && !isGameOver)
{
// Update the state of your game objects here...
}
}
private void gameRender()
{
if (dbImage == null)
{
dbImage = createImage(WIDTH, HEIGHT);
if (dbImage == null)
{
System.out.println("Image is null.");
return;
}
else
dbg = dbImage.getGraphics();
}
dbg.setColor(backgroundColor);
dbg.fillRect(0, 0, WIDTH, HEIGHT);
// Render your game objects here....
// like: xyzObject.draw(dbg);
// or dbg.drawOval(...);
if (isGameOver)
gameOverMessage(dbg);
}
private void gameOverMessage(Graphics g)
{
// Paint a game over message here..
}
private void paintScreen()
{
Graphics g;
try
{
g = this.getGraphics();
if ((g != null) && (dbImage != null))
g.drawImage(dbImage, 0, 0, null);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
catch (Exception e)
{
System.out.println("Graphics context error : " + e);
}
}
public void setWindowPaused(boolean isPaused)
{
isWindowPaused = isPaused;
}
public void setUserPaused(boolean isPaused)
{
isUserPaused = isPaused;
}
}
Then you can simply add your game panel to your JFrame like following:
import java.awt.GridBagLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
public class GameFrame extends JFrame
{
private static final long serialVersionUID = -1624735497099558420L;
private GameFrame gamePanel = new GamePanel();
public GameFrame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Game");
addWindowListener(new FrameListener());
getContentPane().setLayout(new GridBagLayout());
getContentPane().add(gamePanel);
pack();
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
}
public class FrameListener extends WindowAdapter
{
public void windowActivated(WindowEvent we)
{
gamePanel.setWindowPaused(false);
}
public void windowDeactivated(WindowEvent we)
{
gamePanel.setWindowPaused(true);
}
public void windowDeiconified(WindowEvent we)
{
gamePanel.setWindowPaused(false);
}
public void windowIconified(WindowEvent we)
{
gamePanel.setWindowPaused(true);
}
public void windowClosing(WindowEvent we)
{
gamePanel.stopGame();
}
}
public static void main(String args[])
{
new GameFrame();
}
}

Categories

Resources