Reputation: 85
I am trying to create a simple game similar to brick-breaker. I was able to figure out some of the basic concepts of the game (moving the ball, collision detection, etc)
I am trying to move the platform object in an x-direction by using the left and right arrow keys. The if conditions for the keyPressed method work, after testing with some println statements but I am unable to move the platform object using keyListener. Is is something to do with the moveLeft , moveRight methods in the Platform class, because I tried d to changing the values of the dx, so I could maybe see some movement in the platform.
Here are the 3 classes.
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);
}
}
Upvotes: 0
Views: 7173
Reputation: 347204
super.paint
or be prepared for additional weirdnessKeyListener
will only respond to key events when the component it is registered to is focusable and has focusJPanel
and then add it to what ever you wantYou could call, setFocusable(true)
and requestFocusInWindow()
but there's no guarantee that it will work or continue to work 100% of the time.
Instead, update the code to use Swing and take advantage of the key bindings API, which provides you with ability to control the level of focus required into order to trigger the key events
Updated...
You're also not updating the x
position of the Platform
, for example...
public void update(Tennis tg, Ball b) {
x += dx;
checkForCollosion(b);
}
This will now require you to perform range checking on the Platform
to see if passes beyond the visible range of the view, if you about such things...
I also ended up adding a MouseListener
which called requestFocusInWindow
each time it was clicked, for example...
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
requestFocusInWindow();
}
});
This is why I don't like applets or KeyListener
, to much stuffing about
Upvotes: 1
Reputation: 10945
Your first problem is that in your moveRight()
and moveLeft()
methods you are checking the value of and updating dx
, which isn't used anywhere in your code regarding the painting of the platform.
e.g.
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
}
}
Even if we change your methods to use x
instead of dx
your second problem is that incrementing or decrementing by one pixel isn't going to move by very much. However, if you hold down the left arrow key long enough you will the platform slowly creeping along. Nothing will happen when you press the right array (at first) because of your third problem: bounds checking.
The bounds checking in your move methods is based off of a value for x of 20, but the initial value of x
is 275.
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;
}
}
You need to be using values which reflect the size of the applet. This code works, but for time's sake I've just hardcoded the boundary values. You should really calculate them based on the size of the 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
}
}
Upvotes: 1