我正在尝试创建一个类似于破砖机的简单游戏。我能够弄清楚游戏的一些基本概念(移动球,碰撞检测等)
我正在尝试使用左右箭头键在x方向上移动平台对象。在使用一些println语句测试之后,keyPressed方法的if条件工作,但我无法使用keyListener移动平台对象。是与Platform类中的moveLeft,moveRight方法有关,因为我试图改变dx的值,所以我可能会看到平台中的一些动作。
以下是3个班级。
import java.applet.*;
import java.awt.*;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
public class tennisGame extends Applet implements Runnable, KeyListener{
Ball b;
Platform p;
public void init() {
setSize(640, 480);
addKeyListener(this);
}
public void start () {
b= new Ball();
p= new Platform();
Thread thread = new Thread (this);
thread.start ();
}
public void paint(Graphics g) {
b.paint(g);
p.paint(g);
}
public void run(){
while (true){
b.update(this);
p.update(this,b);
repaint();
try {
Thread.sleep(20);
}
catch (InterruptedException e){
//e.printStackTrace();
}
}
}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == e.VK_RIGHT){
System.out.println("Pressed RIGHT");
p.moveRight();
}
if(e.getKeyCode() == e.VK_LEFT){
System.out.println("Pressed LEFT");
p.moveLeft();
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
import java.awt.*;
public class Ball{
private int x=0;
private int y=0;
private double dx=10;
private double dy=10;
private int width=20;
private int height=20;
private int radius=10;
public Ball() {
}
public void update(tennisGame tg){
if ( x + dx > tg.getWidth()-radius-1){
x = tg.getWidth()-radius-1;
dx= -dx;
}
else if ( x + dx < 0 + radius ){
x= 0 + radius;
dx= -dx;
}
else{
x+=dx;
}
if ( y + dy> tg.getHeight()-radius-1){
y = tg.getHeight()-radius-1;
dy= -dy;
}
else if ( y + dy < 0 + radius ){
y= 0 + radius;
dy= -dy;
}
else{
y+=dy;
}
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public double getDx() {
return dx;
}
public void setDx(int dx) {
this.dx = dx;
}
public void setDy(double dy) {
this.dy = dy;
}
public double getDy() {
return dy;
}
public int getRadius() {
return radius;
}
public void paint(Graphics g) {
g.setColor(new Color(0,0,250,250));
g.fillOval(x-radius,y-radius,width, height);
}
}
import java.awt.Color;
import java.awt.Graphics;
public class Platform {
private int x=275;
private int y=400;
int dx=0;
private int width=120;
private int height=20;
public void update(tennisGame tg,Ball b) {
checkForCollosion(b);
}
private void checkForCollosion(Ball b) {
int ballX= b.getX();
int ballY= b.getY();
int radius= b.getRadius();
if (ballY + radius > y && ballY + radius < y + height){
if (ballX > x && ballX < x + width){
double newDy= b.getDy()* -1 ;
b.setDy(newDy);
}
}
}
public void moveRight() {
if ( dx + 1 < 20){
dx+=1;
}
}
public void moveLeft() {
if ( dx -1 > -20){
dx-=1;
}
}
public void paint(Graphics g){
g.setColor(Color.red);
g.fillRect(x , y, width, height);
}
}
答案 0 :(得分:1)
super.paint
或为其他奇怪做好准备KeyListener
只会在注册的组件具有焦点并且具有焦点时才会响应关键事件JPanel
开始,然后将其添加到您想要的内容您可以致电setFocusable(true)
和requestFocusInWindow()
,但不能保证它会在100%的时间内正常工作或继续工作。
相反,更新代码以使用Swing并利用key bindings API,这使您能够控制触发关键事件所需的焦点水平
<强>更新... 强>
您还没有更新x
的{{1}}位置,例如......
Platform
现在要求您对public void update(Tennis tg, Ball b) {
x += dx;
checkForCollosion(b);
}
执行范围检查,以查看是否超出了视图的可见范围,如果你有关于这些事情......
我最后还添加了一个Platform
,每次点击都会调用MouseListener
,例如......
requestFocusInWindow
这就是为什么我不喜欢小程序或addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
requestFocusInWindow();
}
});
,以及大量的内容
答案 1 :(得分:1)
您的第一个问题是,在您的moveRight()
和moveLeft()
方法中,您正在检查dx
的值并更新public void moveRight() {
if (dx + 1 < 20) {
dx += 1; // updating dx, but x is used to paint
}
}
public void moveLeft() {
if (dx - 1 > -20) {
dx -= 1; // updating dx, but x is used to paint
}
}
,这在您的代码中的任何位置都不会用于绘制平台。
e.g。
x
即使我们更改您的方法以使用dx
而不是x
,您的第二个问题是增加或减少一个像素也不会移动太多。但是,如果你按住左箭头键足够长的话,平台会慢慢地沿着它移动。当你按下正确的数组(首先)时,由于你的第三个问题:边界检查,什么都不会发生。
移动方法中的边界检查基于 20 的x值,但public void moveRight() {
if (x + 1 < 20) { // can't move very far from the left side of the screen
x += 1;
}
}
public void moveLeft() {
if (x - 1 > -20) { // goes left only a little bit off the screen
x -= 1;
}
}
的初始值 275 。
tennisGame
您需要使用反映小程序大小的值。这段代码可以工作,但是出于时间的考虑,我只是对边界值进行了硬编码。你应该根据public void moveRight() {
if (x < 520) { // enable moving to the edge of the screen
x += 10; // move a little faster
}
}
public void moveLeft() {
if (x > 0) { // enable moving to the edge of the screen
x -= 10; // move a little faster
}
}
:
{{1}}