How can I make an object move in a direction efficiently? - java

Is there any way to efficiently move an object from point A to point B without having to use an inefficient While(true) loop? I tried to repaint Draw class, but it did not help with the performance issues. I am unable to trace the root of the huge performance issue. I tried to research moving entities on Google, GitHub, and others and found nothing useful. Any help is appreciated!
Code:
class Draw extends JPanel {
public static int x;
public static int y;
public static int randx;
public static int randy;
public void paintComponent(Graphics g) {
super.paintComponent(g);
BufferedImage image = null;
BufferedImage image1 = null;
try {
image = ImageIO.read(new File("Small Sheep Icon.png"));
image1 = ImageIO.read(new File("Small Sheep Icon.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
g.drawImage(image, x, y, null);
g.drawImage(image1, randx, randy, null);
// g.drawString("Hello, World", x, y);
}
}
public static void sheepmove() {
double starttime = System.nanoTime();
double previoustime = 0;
double waittime = 0;
boolean xright = true;
boolean waitswitch = false;
int counter = 0;
while(true) {
double elapsedtime = (System.nanoTime() - starttime)/(1000000000);
if (elapsedtime-waittime >= 1 || waitswitch == false) {
if (waitswitch == true) {
waitswitch = false;
}
waittime = elapsedtime;
if (elapsedtime >= previoustime + 0.1) {
previoustime = elapsedtime;
if (xright == true) {
Draw.randx += 1;
}
if (Draw.randx - 200 >= 50) {
if (counter == 0) {
waitswitch = true;
xright = false;
}
// System.out.println("Moving south...");
Draw.randy += 1;
if (Draw.randy >= 300) {
Draw.randy -= 1;
break;
}
counter++;
}
frame.repaint();
// System.out.print("=");
// System.out.println("Previous Time: " + previoustime);
}
}
// System.out.println(elapsedtime);
// Thread.sleep(1000);
}
}
public static void main(String[] args) {
new Demo();
}
#Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent e) {
// System.out.println("Mouse Moved!");
Draw.x = e.getX();
Draw.y = e.getY();
frame.repaint();
}

Related

I'm having trouble having the body parts of the snake follow the head's path

Board.Java (Logic part of the program)
package snake;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Board extends JPanel implements KeyListener, Runnable{
private final int WIDTH = 500, HEIGHT = 500,TWIDTH = WIDTH/25, THEIGHT = HEIGHT/25, RAND_POS = 29;
private int foodLocX, foodLocY, snakeHeadX = 240, snakeHeadY = 240;;
private boolean running = true, up = false,down = false,left = false,right = true;
private JFrame frame;
private Thread t;
private ArrayList<BodyPart> body;
public Board() {
frame = new JFrame("Snake");
initBoard();
foodLocX = snakeHeadX + 8*TWIDTH;
foodLocY = snakeHeadY;
body = new ArrayList<BodyPart>();
body.add(new BodyPart(snakeHeadX,snakeHeadY, TWIDTH));
t = new Thread(this);
}
public void initBoard() {
frame.setPreferredSize(new Dimension(518,540));
this.setPreferredSize(new Dimension(WIDTH,HEIGHT));
frame.addKeyListener(this);
frame.pack();
frame.add(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private void locateApple() {
int r = (int) (Math.random() * RAND_POS);
foodLocX = ((r * TWIDTH));
r = (int) (Math.random() * RAND_POS);
foodLocY = ((r * THEIGHT));
while(foodLocX >= WIDTH || foodLocY >= HEIGHT || foodLocX < 0 || foodLocY < 0) {
r = (int) (Math.random() * RAND_POS);
foodLocX = ((r * TWIDTH));
r = (int) (Math.random() * RAND_POS);
foodLocY = ((r * THEIGHT));
}
}
public void paint(Graphics g) {
g.clearRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.GREEN);
for(int i = 0; i<WIDTH;i+=TWIDTH) {
for(int ii = 0; ii<HEIGHT;ii+=THEIGHT) {
g.fillRect(i, ii, TWIDTH, THEIGHT);
}
}
if(foodLocX == body.get(0).getX() && foodLocY == body.get(0).getY()) {
int x = body.get(body.size()-1).getX();
int y = body.get(body.size()-1).getY();
if(right) {
body.add(new BodyPart(x+20,y,TWIDTH));
}if(left) {
body.add(new BodyPart(x-20,y,TWIDTH));
}if(down) {
body.add(new BodyPart(x,y+20,TWIDTH));
}if(up) {
body.add(new BodyPart(x,y-20,TWIDTH));
}
locateApple();
}
g.setColor(Color.RED);
g.fillRect(foodLocX, foodLocY, TWIDTH, THEIGHT);
g.setColor(Color.BLACK);
for(int i = 0; i< body.size();i++) {
body.get(i).draw(g);
}
repaint();
}
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP && !down) {
up = true;
down = false;
left = false;
right = false;
try {
Thread.sleep(55,666);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}else if(e.getKeyCode() == KeyEvent.VK_DOWN && !up) {
up = false;
down = true;
left = false;
right = false;
try {
Thread.sleep(55,666);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}else if(e.getKeyCode() == KeyEvent.VK_RIGHT && !left) {
up = false;
down = false;
left = false;
right = true;
try {
Thread.sleep(55,666);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}else if(e.getKeyCode() == KeyEvent.VK_LEFT && !right) {
up = false;
down = false;
left = true;
right = false;
try {
Thread.sleep(100,666);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
#Override
public void keyReleased(KeyEvent arg0){};
#Override
public void keyTyped(KeyEvent arg0){}
//public void addBodyPart() {
//body.add(previousHead); // Part that I left off on
//}
public void moveSnake() {
if(right) {
for(int i = 0; i<body.size();i++) {
body.get(i).setX(body.get(i).getX()+20);
}
}if(left) {
for(int i = 0; i<body.size();i++) {
body.get(i).setX(body.get(i).getX()-20);
}
}if(down) {
for(int i = 0; i<body.size();i++) {
body.get(i).setY(body.get(i).getY()+20);
}
}if(up) {
for(int i = 0; i<body.size();i++) {
body.get(i).setY(body.get(i).getY()-20);
}
}
}
#Override
public void run() {
while(running) {
if(body.get(0).getX()<0 || body.get(0).getX()>480 || body.get(0).getY()<0 || body.get(0).getY()>480){
System.out.println("Game Over!\nYour snake was " + body.size() + " blocks long");
endGame();
}
moveSnake();
repaint();
try {
Thread.sleep(75,666);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void startGame() {
t.start();
}
public void endGame() {
t.stop();
}
}
Main.java (Runnable program)
package snake;
public class Main {
public static void main(String[] args) {
Board b = new Board();
b.startGame();
}
}
BodyPart.java
package snake;
import java.awt.Color;
import java.awt.Graphics;
public class BodyPart {
private int x,y,tilesize;
public BodyPart(int x, int y, int tilesize) {
this.x = x;
this.y = y;
this.tilesize = tilesize;
}
public void draw(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(x,y,tilesize,tilesize);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}
This troubles me because it adds a body part to the array list, however the parts do not follow the body once I make a move. I'm lost and not sure what to do. Any help would be greatly appreciated. Thank you all so much.
-AbysssCoder
Because in the moveSnake() method you are iterating over the body and moving each part of the body the same amount (you're picking up the entire snake and moving it, not having it "slither").
Instead of moving the entire snake - you need the arrow keys to move just the "head", or the "parent". You then need to code the rest the snake as "children", where each new part of the snake sets its new location to the current location of its parent.
For example, if your snake is only 2 units long, the arrow keys will determine the position of the first unit, the "head" only. Then for each bodypart : yoursnake (psuedocode) you would set the new location to bodyPart.getParentBodyPart.getLocation() or something of similar logic.
This is ugly since I just threw it together with what you had - you can definitely clean it up. But it will work:
public void moveSnake() {
if(right) {
// iterate from the tail forward so we don't overwrite positions that we need
for(int i = body.size()-1; i>=0;i--) {
if (i == 0) {
body.get(i).setX(body.get(i).getX()+20);
} else {
// we dont know what direct we are moving, so we need x and y
body.get(i).setX(body.get(i-1).getX());
body.get(i).setY(body.get(i-1).getY());
}
}
}if(left) {
for(int i = body.size()-1; i>=0;i--) {
if (i == 0) {
body.get(i).setX(body.get(i).getX()-20);
} else {
body.get(i).setX(body.get(i-1).getX());
body.get(i).setY(body.get(i-1).getY());
}
}
}if(down) {
for(int i = body.size()-1; i>=0;i--) {
if (i == 0) {
body.get(i).setY(body.get(i).getY()+20);
} else {
body.get(i).setY(body.get(i-1).getY());
body.get(i).setX(body.get(i-1).getX());
}
}
}if(up) {
for(int i = body.size()-1; i>=0;i--) {
if (i == 0) {
body.get(i).setY(body.get(i).getY()-20);
} else {
body.get(i).setY(body.get(i-1).getY());
body.get(i).setX(body.get(i-1).getX());
}
}
}
}

JAVA Error with loading sprite using BufferedImage

im following a tutorial and im coming across this is the error, i cannot seem to work out what the problem is. All im trying to do is load a Sprite image. Here is the code:
Here is the error:
Exception in thread "Thread-0" java.lang.NullPointerException
at com.mainpkg.game.Handler.gg(Handler.java:27)
at com.mainpkg.game.Game.render(Game.java:107)
at com.mainpkg.game.Game.run(Game.java:83)
at java.base/java.lang.Thread.run(Thread.java:844)
Main Game Class:
public class Game extends Canvas implements Runnable {
public static final int WIDTH = 800, HEIGHT = WIDTH / 12 * 9;
private Thread thread;
private boolean running = false;
private Handler handler;
private BufferedImage grassTile;
public Game() {
new Window(WIDTH, HEIGHT, "MOON EXPOLATION", this);
handler = new Handler(getWidth(), getHeight());
testImage = loadImage("Resources/GrassTile.png");
}
private BufferedImage loadImage(String path) {
try {
BufferedImage loadedImage = ImageIO.read(new FileInputStream(path));
BufferedImage formattedImage = new BufferedImage(loadedImage.getWidth(), loadedImage.getHeight(),
BufferedImage.TYPE_INT_RGB);
formattedImage.getGraphics().drawImage(loadedImage, 0, 0, null);
return formattedImage;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
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() {
int FRAMES = 0;
int TICKS = 0;
long lastTime = System.nanoTime();
double unprocessed = 0;
double nsPerSecs = 1000000000 / 60.0;
long Timer = System.currentTimeMillis();
while (running) {
long now = System.nanoTime();
unprocessed += (now - lastTime) / nsPerSecs;
lastTime = now;
if (unprocessed >= 1) {
TICKS++;
ticks();
unprocessed -= 1;
}
try {
Thread.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
FRAMES++;
render();
if (System.currentTimeMillis() - Timer > 1000) {
System.out.println("Ticks: " + TICKS + " FPS: " + FRAMES);
TICKS = 0;
FRAMES = 0;
Timer += 1000;
}
}
stop();
}
private void ticks() {
}
void render() {
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
super.paint(getGraphics());
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
handler.renderImage(testImage, 0, 0);
handler.render(g);
// g.setColor(Color.BLACK);
// g.fillRect(0,0,WIDTH,HEIGHT);
g.dispose();
bs.show();
}
public static void main(String[] args) {
new Game();
}
Handler Class:
public class Handler {
private BufferedImage view;
private int pixels[];
public Handler(int width, int height) {
view = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
pixels = ((DataBufferInt) view.getRaster().getDataBuffer()).getData();
}
public void render(Graphics g) {
g.drawImage(view, 0, 0, view.getWidth(), view.getHeight(), null);
}
public void renderImage(BufferedImage image, int xPosition,int yPosition) {
int[] imagepixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
for(int y = 0; y < image.getHeight(); y++) {
for(int x = 0; x < image.getWidth(); x++) {
pixels[(x + xPosition) + (y + yPosition ) * view.getWidth()] = imagepixels[x + y * image.getWidth()];
}
}
}
The problem is here:
BufferedImage loadedImage = ImageIO.read(Game.class.getResource(path));
getResource(path) is returning null and that is causing the exception.
Try changing the image path to "Assets/GrassTile.png"
One tip:
You should avoid using absolute paths to locate your resources. This is a really bad idea because if you change the location of your project it will stop working, try using relative paths.

How to fix multiple threads running in java awt graphics

I am programming a game for a school project and when I run the code, it works sometimes and then ill run it again and the paddle or ball won't move and the print statements in my keylistener dont show up.
Now I am running two timers, one for the animation and one for a countdown, could this be an issue? It seems like multiple threads are running or when I close the jframe and then rerun the program is picking up where it left off?
public class LobPong extends JPanel implements KeyListener {
public static double xCoordinate;
public static double yCoordinate;
public static Timer timer;
static int xPaddleLeft;
private static int yPaddle = 800;
private static int score = 0;
private static int level = 1;
public static JLabel scoreLabel = new JLabel(" Score: 0 ");
public static JLabel timeLabel = new JLabel(" ");
public static JLabel levelLabel = new JLabel(" Level: ");
private static int life = 3;
private static int levelTime = 30000;
public static int dx, dy;
private static double times = 0;
public static void main(String[] args) {
JFrame LobPongApp = new JFrame();
LobPong canvas = new LobPong();
canvas.setBackground(Color.BLUE);
LobPongApp.add(canvas);
LobPongApp.setSize(800, 900);
LobPongApp.setTitle("Lob Pong");
LobPongApp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
LobPongApp.setVisible(true);
canvas.setFocusable(true);
LobPongApp.addKeyListener(canvas);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.GREEN);
g.fillOval((int) xCoordinate, (int) yCoordinate, 50, 50);
g.fillRect(xPaddleLeft, yPaddle, 100, 10);
drawLife(g, getLife());
}
public LobPong() {
timer = new Timer(1, new timerCallBack());
timer.start();
setLayout(new FlowLayout());
scoreLabel.setOpaque(true);
timeLabel.setOpaque(true);
levelLabel.setOpaque(true);
scoreLabel.setBackground(Color.black);
timeLabel.setBackground(Color.black);
levelLabel.setBackground(Color.black);
scoreLabel.setForeground(Color.WHITE);
timeLabel.setForeground(Color.WHITE);
levelLabel.setForeground(Color.WHITE);
levelLabel.setText("Level: " + 1);
add(scoreLabel);
add(timeLabel);
add(levelLabel);
xPaddleLeft = 375; //debug
xCoordinate = 0;
yCoordinate = 0;
setTime(levelTime); //sets current level time (increases by 10 seconds every 2 levels)
}
public static void nextLevel(Graphics g, int levels) {
level += 1;
g.drawString("NEXT LEVEL!", 400, 400);
timer.stop();
//TODO call run() ?
}
public static void updateScore(int scoreAdd) {
score += scoreAdd;
scoreLabel.setText("Score: " + score);
}
public static int getScore() {
return score;
}
public static void updateLife(int x) {
life += x;
}
public static int getLife() {
return life;
}
public static void drawLife(Graphics g, int x) {
g.setColor(Color.RED);
for(int i = 0; i < (x * 10); i += 10) { //for loop to offset lives and draw enough balls per lives
g.fillOval(30 + i, 10, 10, 10);
}
}
public static void extraLife(boolean x) {
if (x == true) {
updateLife(1);
}
}
Timer timerDisplay = new Timer(1000, new TimerListener());
private static int totalTime;
public static void setTime(int time) {
totalTime = time;
}
public static int getTime() {
return totalTime;
}
protected class TimerListener implements ActionListener { //handles countdown timer
#Override
public void actionPerformed(ActionEvent arg0) {
setTime(getTime() - 1000);
LobPong.timeLabel.setText("Time Remaining: " + getTime()/1000 + " ");
if(getTime() <= 0) {
timerDisplay.stop();
timer.stop();
}
}
}
public void keyPressed(KeyEvent arg0) {
int key = arg0.getKeyCode();
System.out.println("testing");
if(key == 37) {
if (xPaddleLeft > 0) {
xPaddleLeft -= 50;
System.out.println("TEST"); //debug
}
}
if(key == 39) {
if (xPaddleLeft < (getWidth() - 50)) {
xPaddleLeft += 50;
}
}
if(key == KeyEvent.VK_ENTER) {
dx = 2;
timer.start();
timerDisplay.start();
System.out.println("start"); //debug
}
repaint();
}
boolean horizontal = true; //handles horizontal movement
boolean vertical = true; //handles vertical
double upwards;
public class timerCallBack implements ActionListener {
#Override
public void actionPerformed(ActionEvent arg0) {
times += .01;
if (horizontal == true) { //check
xCoordinate += dx;
}
if(xCoordinate <= 0) { //check
horizontal = true;
}
if(xCoordinate >= getWidth()) { //check
horizontal = false;
}
if(horizontal == false) { //check
xCoordinate -= dx;
}
if(vertical == true) { //check
dy = (int) times;
yCoordinate += dy;
}
if (vertical == false) { //check
dy = (int) (upwards - times);
yCoordinate -= dy;
}
if(dy == 0) { //check
vertical = true;
times = 0;
}
if(yCoordinate == getHeight()) { //check
updateLife(-1);
if (getLife() == 0) {
timer.stop();
timerDisplay.stop();
//TODO you lose and print high score
}
extraLife(false);
xCoordinate = 0;
yCoordinate = 0;
dy = 0;
dx = 0;
vertical = true;
}
if(xCoordinate <= (xPaddleLeft + 100) && xCoordinate >= xPaddleLeft && (yCoordinate + 50) == yPaddle) {
upwards = times;
times = 0;
vertical = false;
updateScore(1);
repaint();
//TODO plus one point, paddle bounce physics, direction
}
repaint();
}
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
}

Why is my ArrayList not looping through all values?

I'm trying to make a small app that bounces balls around the frame of the window. When I add more than 1 ball to the list; it doesn't loop through them as expected.
Here's my code:
The Main Class:
public class Main extends JFrame {
private static final long serialVersionUID = 1L;
private List<Ball> balls = new ArrayList<Ball>();
private List<Ball> tempballs = new ArrayList<Ball>();
private static Timer t;
public void addBall(Ball b) {
tempballs.add(b);
}
public void initUI() {
this.setSize(500, 500);
this.setDefaultCloseOperation(3);
this.setVisible(true);
}
private BufferStrategy bs;
private Random r = new Random();
public void paint() {
if (!tempballs.isEmpty()) {
balls.addAll(tempballs);
tempballs = new ArrayList<Ball>();
}
int i = 0;
System.out.println(balls.size());
for (Ball b : new ArrayList<Ball>(balls)) {
i++;
System.out.println(i);
if ((bs = this.getBufferStrategy()) == null) {
this.createBufferStrategy(2);
return;
}
if (bs.contentsLost() || bs.contentsRestored()) {
return;
}
if (b.y >= this.getHeight() - 100) {
b.ydirection = -r.nextDouble() * 5;
}
if (b.y < 20) {
b.ydirection = r.nextDouble() * 5;
}
if (b.x >= this.getWidth() - 100) {
b.xdirection = -r.nextDouble() * 5;
}
if (b.x < 0) {
b.xdirection = r.nextDouble() * 5;
}
b.x += b.xdirection;
b.y += b.ydirection;
if (b.xdirection > 0)
b.xdirection += 0.1;
else
b.xdirection += -0.1;
if (b.ydirection > 0)
b.ydirection += 0.1;
else
b.ydirection += -0.1;
Graphics g = bs.getDrawGraphics();
g.fillOval((int) b.x, (int) b.y, 100, 100);
bs.show();
g.dispose();
bs.dispose();
}
i = 0;
}
public static void main(String[] args) {
try {
final Main m = new Main();
m.addMouseListener(new Mouse(m));
m.initUI();
t = new Timer();
TimerTask tt = new TimerTask() {
#Override
public void run() {
m.paint();
}
};
t.schedule(tt, Calendar.getInstance().getTime(), 20);
} catch (ConcurrentModificationException e) {
e.printStackTrace();
}
}
}
Here's the Ball class:
public class Ball {
private Random r = new Random();
public double y, x, ydirection, xdirection;
public Ball(int x, int y) {
this.y = y;
this.x = x;
ydirection = r.nextGaussian() * 5;
xdirection = r.nextGaussian() * 5;
}
}
and the mouse listener:
public class Mouse implements MouseListener {
Main m;
public Mouse(Main m) {
this.m = m;
}
#Override
public void mouseClicked(MouseEvent e) {
m.addBall(new Ball(e.getX(), e.getY()));
System.out.println("cl");
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
}
Additional details:
It only loops through the first item in the list, but the list size grows.
I'm using java 6, but I will change versions if needed.
If your loop does not behave as intended, try to find out why it is cancelled. You have two return statements in your loop which could cause this behavior. Make sysouts before those returns to figure out which one is the cause. Then find out why your if around the return is true. To digg deeper you can use your IDE's debugging mode and place breakpoints at interesting lines or use the step mode to run one line of code at a time.
Besides this you can place both if before the loop, the values they are checking should not change while you are in the paint() function (you are using the UI thread which might change them).
You have below return statements inside the loop. If the execution reaches any of the return statements, the loop ends.
Figure out, if you are entering these conditions and returning for the first value in the list.
if ((bs = this.getBufferStrategy()) == null) {
this.createBufferStrategy(2);
return;
}
if (bs.contentsLost() || bs.contentsRestored()) {
return;
}

Paint method is not working

I'm trying to make a 2D game that should draw a character to the screen. But when I run it, I just get a black screen.
The important bits:
public class StartingClass extends Applet implements Runnable, KeyListener {
private static final long serialVersionUID = 1L;
private Walrus walrus;
private Image image, character;
private Graphics second;
private URL base;
#Override
public void init() {
setSize(800, 480);
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Applet");
try {
base = getDocumentBase();
} catch (Exception e) {
// TODO: handle exception
}
// Image Setups
character = getImage(base, "src/data/walrus_right.png");
}
#Override
public void start() {
walrus = new Walrus();
Thread thread = new Thread(this);
thread.start();
}
#Override
public void stop() {
// TODO Auto-generated method stub
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void run() {
while (true) {
walrus.update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void update(Graphics g) {
if (image == null) {
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g) {
g.drawImage(character, walrus.getCenterX() - 61, walrus.getCenterY() - 63, this);
}
}
Also, here's my other class:
public class Walrus {
private int centerX = 100;
private int centerY = 382;
private boolean jumped = false;
private int speedX = 0;
private int speedY = 1;
public void update() {
// Moves Character or Scrolls Background accordingly.
if (speedX < 0) {
centerX += speedX;
} else if (speedX == 0) {
System.out.println("Do not scroll the background.");
} else {
if (centerX <= 150) {
centerX += speedX;
} else {
System.out.println("Scroll Background Here");
}
}
// Updates Y Position
if (centerY + speedY >= 382) {
centerY = 382;
}else{
centerY += speedY;
}
// Handles Jumping
if (jumped == true) {
speedY += 1;
if (centerY + speedY >= 382) {
centerY = 382;
speedY = 0;
jumped = false;
}
}
// Prevents going beyond X coordinate of 0
if (centerX + speedX <= 60) {
centerX = 61;
}
}
public void moveRight() {
speedX = 6;
}
public void moveLeft() {
speedX = -6;
}
public void stop() {
speedX = 0;
}
public void jump() {
if (jumped == false) {
speedY = -15;
jumped = true;
}
}
public int getCenterX() {
return centerX;
}
public int getCenterY() {
return centerY;
}
public boolean isJumped() {
return jumped;
}
public int getSpeedX() {
return speedX;
}
public int getSpeedY() {
return speedY;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public void setJumped(boolean jumped) {
this.jumped = jumped;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
}
I haven't gotten any errors at this point, but it's not working right.
The problem is that your image is not loaded. The line
getImage(base, "src/data/walrus_right.png");
tries to read the image for a deployed applet and will fail quietly (not throw errors), which is what caused the confusion. Try to replace it with
ImageIO.read(new File(getClass().getResource("relative/path.png").getPath()));
where you should replace the path as specified under getResource API.
Edit:
Break the call into several calls:
Class<? extends StartingClass> clas = getClass();
URL url = clas.getResource("relative/path.png");
String path = url.getPath();
File file = new File(path);
try {
Image image = ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
}
and move with the debugger step by step to see which line throws the error. My guess is that the file is not located in the right place, which causes getResource to return null, which causes new File(path) to throw NullPointerException.

Categories

Resources