I am learning Java game development and I am having an issue understanding why the "Robot" is not moving. I know the issue is with the repaint but I can not figure it out.
please help
Thank
Game Class
public class GameMain extends Applet implements KeyListener {
private Image image, character;
private Graphics gpx;
private Droid droid;
private URL base;
private static Background bg1, bg2;
@Override
public void init() {
setSize(800, 480);
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("My First Game");
droid = new Droid();
base = getDocumentBase();
character = getImage(base, "data/char.png");
}
@Override
public void start() {
GameThread thread = new GameThread();
thread.start();
System.out.println("Thread Started");
}
@Override
public void stop() {
}
@Override
public void destroy() {
}
@Override
public void update(Graphics g) {
if(image == null){
image = createImage(this.getWidth(), this.getHeight());
gpx = image.getGraphics();
}
gpx.setColor(getBackground());
gpx.fillRect(0, 0, getWidth(), getHeight());
gpx.setColor(getForeground());
paint(gpx);
g.drawImage(image, 0, 0, this);
}
@Override
public void paint(Graphics g) {
g.drawImage(character, droid.getPositionX() - 61, droid.getPositionY()- 63, this);
}
@Override
public void keyPressed(KeyEvent key) {
switch(key.getKeyCode() ){
case KeyEvent.VK_UP:
break;
case KeyEvent.VK_DOWN:
break;
case KeyEvent.VK_LEFT:
droid.moveLeft();
break;
case KeyEvent.VK_RIGHT:
droid.moveRight();
break;
case KeyEvent.VK_SPACE:
droid.jump();
break;
}
}
@Override
public void keyReleased(KeyEvent key) {
switch(key.getKeyCode() ){
case KeyEvent.VK_UP:
break;
case KeyEvent.VK_DOWN:
break;
case KeyEvent.VK_LEFT:
droid.stop();
break;
case KeyEvent.VK_RIGHT:
droid.stop();
break;
case KeyEvent.VK_SPACE:
break;
}
}
@Override
public void keyTyped(KeyEvent key) {
// TODO Auto-generated method stub
}
}
Thread Class
public class GameThread extends Thread {
GameMain game;
Droid droid;
private static Background bg1, bg2;
public GameThread(){
bg1 = new Background(0,0);
bg2 = new Background(2160, 0);
}
@Override
public void run() {
game = new GameMain();
droid = new Droid();
//Game while loop
while(true){
droid.update();
game.repaint();
//bg1.update();
//bg2.update();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Droid Class
public class Droid {
private int positionX = 100;
private int positionY = 382;
private int speedX = 0;
private int speedY = 1;
private boolean jump = false;
public void update(){
//Update X Position
if(speedX < 0){
positionX += speedX;
}else if(speedX == 0){
System.out.println("Do not scroll the background.");
}else{
if(positionX <= 150){
positionX += speedX;
}else{
System.out.println("Scroll Background Here");
}
}
//Update Y Position
if(positionY + speedY >= 382){
positionY = 382;
}else{
positionY += speedY;
}
//update Jump
if(jump == true){
speedY += 1;
if(positionY + speedY >= 382){
positionY = 382;
speedY = 0;
jump = false;
}
}
}
public void moveRight(){
speedX = 6;
System.out.println(speedX);
}
public void moveLeft(){
speedX = -6;
System.out.println(speedX);
}
public void stop(){
speedX = 0;
}
public void jump(){
if(jump == false){
speedY = -15;
jump = true;
}
}
public void setPositionX(int positionX){
this.positionX = positionX;
}
public int getPositionX(){
return positionX;
}
public void setPositionY(int positionY){
this.positionY = positionY;
}
public int getPositionY(){
return positionY;
}
public void setSpeedX(int speedX){
this.speedX = speedX;
}
public int getSpeedX(){
return speedX;
}
public void setSpeedY(int speedY){
this.speedY = speedY;
}
public int getSpeedY(){
return speedY;
}
}
The problem is, the droid you're updating isn't the droid
you're painting...in fact, the GameMain
you're repainting isn't the one that is one the screen...
public class GameMain extends Applet implements KeyListener {
//...
private Droid droid;
//...
@Override
public void init() {
//...
droid = new Droid();
//...
}
@Override
public void paint(Graphics g) {
g.drawImage(character, droid.getPositionX() - 61, droid.getPositionY()- 63, this);
}
And then in you GameThread
;
public class GameThread extends Thread {
GameMain game;
Droid droid;
//...
@Override
public void run() {
// Created a new GameMain
game = new GameMain();
// Created a new Droid...
droid = new Droid();
//Game while loop
while (true) {
droid.update();
game.repaint();
//...
You create new instances of GameMain
and Droid
, these have no connection what so ever to the screen.
Instead, you should be passing a reference of GameMain
to the GameThread
and GameThread
should be telling GameMain
to update the game state...
For example...
Add the method updateGameState
public class GameMain extends Applet implements KeyListener {
//...
public void updateGameState() {
droid.update();
repaint();
}
//...
Then in GameMain
's start method, pass a reference of GameMain
to GameThread
...
GameThread thread = new GameThread(this);
thread.start();
Then in GameMain
, store the reference you are passed and remove any reference to Droid
public class GameThread extends Thread {
//...
private GameMain gameMain;
public GameThread(GameMain gameMain) {
this.gameMain = gameMain;
//...
Then in GameTread#run
, call gameMain.updateGameState();
...
public void run() {
while (true) {
gameMain.updateGameState();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
As a side note...
this.getParent().getParent()
, you may not like the results if you deployed this in a browser.. JApplet
, move you game rendering to something like JPanel
, overriding it's paintComponent
method, this will give you automatic double buffering and use the Key binding API over KeyListener
. It's more easily, programmatically, updatable and doesn't suffer from the same focus related issues as KeyListener
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.