我试图将applet作为学校的项目,但遇到了我以前从未见过的错误。任何建议都会非常受欢迎,我已经挣扎了几个小时但没有用。此外,这是我在Java中的第一个大项目,因此非常欢迎任何有关编码和风格的建议。我的IDE是blueJ,如果重要的话我在applet查看器中运行它。干杯!
import java.awt.*;
import javax.swing.*;
import java.lang.*;
import java.util.*;
import java.awt.event.*;
public abstract class Renderer extends JApplet implements KeyListener
{
public PlayerShip playerShip;
public static final int CANVAS_SIZE=500;
public static final int FRAMES_PER_SECOND = 20;
public static final int SKIP_TICKS = 1000 / FRAMES_PER_SECOND;
public void initLevel(){
playerShip= new PlayerShip(CANVAS_SIZE);
}
@Override
public void keyPressed(KeyEvent e){
if (e.getKeyCode()== KeyEvent.VK_RIGHT){
playerShip.moveRight();
}
else if (e.getKeyCode()== KeyEvent.VK_LEFT){
playerShip.moveLeft();
}
repaint();
}
public void paint(Graphics g){
int sleep_time = 0;
int next_game_tick = 0;
long sleepTime;
boolean Game= true;
long startTime= System.currentTimeMillis();
setSize(CANVAS_SIZE, CANVAS_SIZE);
while(Game== true){
initLevel();
int leftSide=playerShip.getLeftBound();
int width=playerShip.getWidth();
int topSide=playerShip.getTopBound();
int height=playerShip.getHeight();
g.setColor(Color.blue);
g.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
g.setColor(Color.orange);
g.fillRect (leftSide, topSide, width, height);
long timeElapsed = System.currentTimeMillis() - startTime;
next_game_tick += SKIP_TICKS;
sleepTime= next_game_tick - timeElapsed;
try{
Thread.sleep(sleepTime);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
}
}
编辑:这里也是玩家类
public class PlayerShip
{
// instance variables - replace the example below with your own
public static final int SIZE= 20;
public int shipX;
public int shipY;
public int shipLeft;
public int shipRight;
public PlayerShip(int canvasSize)
{
shipX= canvasSize/2;
shipY= canvasSize*3/4;
}
public void moveLeft(){
shipX -=1;
}
public void moveRight(){
shipX+=1;
}
public int getLeftBound(){
int leftSide = Math.round(shipX - (SIZE/2));
return (leftSide);
}
public int getWidth(){
return SIZE;
}
public int getTopBound(){
int topSide = Math.round(shipY - (SIZE/2));
return (topSide);
}
public int getHeight(){
return SIZE;
}
}
KeyListener
一个问题可能是您只实现了java.awt.event.KeyListener
接口所需的三种方法中的一种。你做了keyPressed
,但省略了keyTyped
和keyReleased
。
@Override
public void keyTyped ( KeyEvent e )
{
…
}
@Override
public void keyPressed ( KeyEvent e )
{
…
}
@Override
public void keyReleased ( KeyEvent e )
{
…
}
您可能需要为import
类添加显式Color
以识别其常量。
import java.awt.Color;
按惯例,Java中的常量以全大写命名。所以,Color.BLUE
。
不是编译器或applet问题,但为了其他程序员阅读代码,您应该遵循Java命名约定。所以boolean Game
应该以小写字母开头。此外,布尔经常用is
前缀命名,所以boolean isGame
。我怀疑你可以设计一个更具描述性的措辞。
顺便说一下,为了简洁起见,将while ( isGame == true )
缩短为while ( isGame )
。
一个更严重的问题:你的isGame
循环中使用的这个while
变量永远不会改变它的状态。所以你的while
循环是无限的。
完成上述更改后,我看到您的applet使用IntelliJ IDE和Java 8(来自Azul Systems的Zulu JVM)通过MacBook Pro上的AppletViewer应用程序版本1.0与macOS Mojave一起启动。
顺便说一句,它看起来像你正在使用你的线Thread.sleep(sleepTime);
睡觉主GUI线程。我不是小程序或AWT的专家,但我记得你永远不应该睡觉主GUI线程。
package work.basil.example;
public class PlayerShip
{
// instance variables - replace the example below with your own
public static final int SIZE = 20;
public int shipX;
public int shipY;
public int shipLeft;
public int shipRight;
public PlayerShip ( int canvasSize )
{
shipX = canvasSize / 2;
shipY = canvasSize * 3 / 4;
}
public void moveLeft ()
{
shipX -= 1;
}
public void moveRight ()
{
shipX += 1;
}
public int getLeftBound ()
{
int leftSide = Math.round( shipX - ( SIZE / 2 ) );
return ( leftSide );
}
public int getWidth ()
{
return SIZE;
}
public int getTopBound ()
{
int topSide = Math.round( shipY - ( SIZE / 2 ) );
return ( topSide );
}
public int getHeight ()
{
return SIZE;
}
}
…和…
package work.basil.example;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Renderer extends JApplet implements KeyListener
{
public PlayerShip playerShip;
public static final int CANVAS_SIZE = 500;
public static final int FRAMES_PER_SECOND = 20;
public static final int SKIP_TICKS = 1000 / FRAMES_PER_SECOND;
public void initLevel ()
{
playerShip = new PlayerShip( CANVAS_SIZE );
}
public void paint ( Graphics g )
{
int sleep_time = 0;
int next_game_tick = 0;
long sleepTime;
boolean isGame = true;
long startTime = System.currentTimeMillis();
setSize( CANVAS_SIZE , CANVAS_SIZE );
while ( isGame )
{
initLevel();
int leftSide = playerShip.getLeftBound();
int width = playerShip.getWidth();
int topSide = playerShip.getTopBound();
int height = playerShip.getHeight();
g.setColor( Color.BLUE );
g.fillRect( 0 , 0 , CANVAS_SIZE , CANVAS_SIZE );
g.setColor( Color.ORANGE );
g.fillRect( leftSide , topSide , width , height );
long timeElapsed = System.currentTimeMillis() - startTime;
next_game_tick += SKIP_TICKS;
sleepTime = next_game_tick - timeElapsed;
try
{
Thread.sleep( sleepTime );
} catch ( InterruptedException ex )
{
Thread.currentThread().interrupt();
}
}
}
//----------| Override `java.awt.event.KeyListener` |------------------
@Override
public void keyPressed ( KeyEvent e )
{
if ( e.getKeyCode() == KeyEvent.VK_RIGHT )
{
playerShip.moveRight();
} else if ( e.getKeyCode() == KeyEvent.VK_LEFT )
{
playerShip.moveLeft();
}
repaint();
}
@Override
public void keyTyped ( KeyEvent e )
{
// No code needed here.
}
@Override
public void keyReleased ( KeyEvent e )
{
// No code needed here.
}
}
我将添加强制性的警告,即Java Applet技术正在被网络浏览器制造商以及Oracle和Java社区逐步淘汰。这个项目很适合学习。但是对于实际工作,您可能希望了解OpenJFX并使用jlink捆绑Java运行时。