[英]Java Applet repaint from another class
I am learning Java game development and I am having an issue understanding why the "Robot" is not moving. 我正在学习Java游戏开发,并且在理解为什么“机器人”不动时遇到问题。 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... 问题是,您要更新的
droid
不是您正在绘画的droid
...实际上,您要重新绘画的GameMain
不是屏幕上的那个droid
...
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
; 然后在您的
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. 您创建
GameMain
和Droid
新实例, GameMain
与屏幕之间没有任何连接。
Instead, you should be passing a reference of GameMain
to the GameThread
and GameThread
should be telling GameMain
to update the game state... 相反,您应该
GameMain
的引用GameMain
给GameThread
并且GameThread
应该告诉GameMain
更新游戏状态...
For example... 例如...
Add the method updateGameState
添加方法
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
... 然后在
GameMain
的start方法中,将GameMain
的引用GameMain
给GameThread
...
GameThread thread = new GameThread(this);
thread.start();
Then in GameMain
, store the reference you are passed and remove any reference to Droid
然后在
GameMain
,存储您传递的引用,并删除对Droid
任何引用
public class GameThread extends Thread {
//...
private GameMain gameMain;
public GameThread(GameMain gameMain) {
this.gameMain = gameMain;
//...
Then in GameTread#run
, call gameMain.updateGameState();
然后在
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();
}
}
}
As a side note... 作为旁注...
this.getParent().getParent()
, you may not like the results if you deployed this in a browser.. this.getParent().getParent()
,我会非常小心,如果将其部署在浏览器中,则可能不喜欢结果。 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
. JApplet
,将游戏渲染移至JPanel
,并覆盖其paintComponent
方法,这将为您提供自动双重缓冲并在KeyListener
使用Key绑定API 。 It's more easily, programmatically, updatable and doesn't suffer from the same focus related issues as KeyListener
KeyListener
相同的焦点相关问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.