我正在学习Java游戏开发,而我正在理解为什么" Robot"没动。 我知道问题在于重画,但我无法弄明白。
请帮助
感谢
游戏类
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
}
}
线程类
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;
}
}
答案 0 :(得分:1)
问题是,您正在更新的机器人不是您正在绘制的droid
......实际上,您重新绘制的GameMain
不是一个就是一个屏幕......
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);
}
然后在你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();
//...
您创建了GameMain
和Droid
的新实例,这些实例与屏幕无关。
相反,您应该将GameMain
的引用传递给GameThread
,而GameThread
应该告诉GameMain
更新游戏状态......
例如......
添加方法updateGameState
public class GameMain extends Applet implements KeyListener {
//...
public void updateGameState() {
droid.update();
repaint();
}
//...
然后在GameMain
的start方法中,将GameMain
的引用传递给GameThread
...
GameThread thread = new GameThread(this);
thread.start();
然后在GameMain
中,存储您传递的引用并删除对Droid
的任何引用
public class GameThread extends Thread {
//...
private GameMain gameMain;
public GameThread(GameMain gameMain) {
this.gameMain = gameMain;
//...
然后在GameTread#run
中,拨打gameMain.updateGameState();
...
public void run() {
while (true) {
gameMain.updateGameState();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
作为旁注......
this.getParent().getParent()
时我会非常小心,如果你在浏览器中部署了这个结果,你可能不喜欢这样的结果。JApplet
时,将游戏渲染移至类似JPanel
的内容,覆盖它的paintComponent
方法,这将为您提供自动双缓冲并使用{{3} } KeyListener
以上。它更容易,以编程方式,可更新,并且不会遇到与KeyListener