我正在学习Java游戏开发,并且在理解为什么“机器人”不动时遇到问题。
我知道问题在于重涂,但我无法弄清楚。
请帮忙
谢谢
游戏类
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();
}
}
}
}
机器人类
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;
}
}
最佳答案
问题是,您正在更新的机器人不是您正在绘制的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();
}
}
}
作为旁注...
Applet已过时,您应该使用JApplet
我会非常小心地使用
this.getParent().getParent()
,如果将其部署在浏览器中,您可能会不喜欢结果。当您开始使用
JApplet
时,将游戏渲染移至JPanel
之类,覆盖它的paintComponent
方法,这将为您提供自动双重缓冲并在KeyListener
上使用Key binding API。它更容易通过编程方式进行更新,并且不会遇到与KeyListener
相同的焦点相关问题关于java - Java Applet从另一个类重绘,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19173667/