1. 程式人生 > >Java 碰壁小球遊戲例項教程

Java 碰壁小球遊戲例項教程

本教程會舉例用Java實現簡單的小球碰壁反彈遊戲,效果如圖所示:


JFrame: 窗體部分

首先建立一個窗體介面,下面舉一個簡單的例子(Jframe是自己定義的類名,注意和JFrame的區別)

import javax.swing.JFrame; //沒匯入就沒卵用
public class Jframe {
 
public static void main(String[] args) 
{
JFrame frame = new JFrame("小球碰壁"); //建立Jframe物件,引數是窗體標題
frame.setSize(300, 300); //設定視窗大小
frame.setVisible(true); //設定可見性,沒設定的話就看不見
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //這個是退出時的操作,沒加這一行可能關閉後會繼續執行
}
 
}


通過繼承JFrame也可以

import javax.swing.JFrame;
public class Game extends JFrame //繼承父類Jframe
{
 
public static void main(String[] args) {
Game tennis=new Game(); //建立game物件
 
}
Game() //自己的建構函式,同時也會呼叫父類的建構函式來建立物件
{
this.setTitle("碰壁球遊戲");
this.setSize(500,500);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}


如圖:

 

JPanel: 繪圖部分

有窗體接下來就是繪圖部分,繪圖就需要用一個畫布JPanel(Jpanel是自己定義的類名,注意和JPanel的區別)

import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.*;
public class Jpanel extends JPanel{
public void paint(Graphics g)  //paint方法中的Graphics g是從Graphic繼承的物件
{ 
g.setColor(Color.BLUE); //設定顏色
g.fillOval(0, 0, 30, 30); //引數分別為座標x,y,球的寬度,高度
g.drawString("這是一個小球", 0, 50); //引數分別為字串,座標x,y
}
public static void main(String[] args) {
JFrame frame = new JFrame("Tennis");
frame.add(new Jpanel());
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}


如圖:

 

最後整合一下前面兩部分所學的知識建立一個Game類。因為Java不支援多繼承所以建立多一個繼承JPanelDraw類。

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
public class Game extends JFrame //繼承父類Jframe
{
 
public static void main(String[] args) {
Game tennis=new Game(); //建立game物件
 
}
Game() //自己的建構函式,同時也會呼叫父類的建構函式來建立物件
{
Draw ball=new Draw();
this.add(ball);
this.setTitle("碰壁球遊戲");
this.setSize(600,600);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class Draw extends JPanel //這裡建立一個繼承JPanel的子類
{
public void paint(Graphics g) {
super.paint(g); //呼叫父類的paint
Graphics2D g2d = (Graphics2D) g; //進行物件轉型,因為Graphic2D的方法比較好也比較豐富,所以這裡用Graphics2D,Graphics是舊的類
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON); //這個是防止邊緣有鋸齒的
g2d.fillOval(0, 0, 60, 60); 
}
}


g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)的效果圖.

 

 

接下來要讓球移動,球的位置是根據當前所賦值的座標決定的,所以每次繪製小球的時候我們需要通過更改x,y讓小球達到移動的效果,這樣的話我們就把剛才的程式碼改成g2d.fillOval(x, y, 30, 30);然後再通過repaint()方法重新繪製。

原理就是一直更新並重新繪製新的小球使其達到移動的效果。

因此這裡打算寫一個moveBall()的方法來不斷改變x,y的值。

稍微修改一下之前的程式碼:

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
 
public class Game extends JFrame //繼承父類Jframe
{
public static void main(String[] args) throws InterruptedException //這個是丟擲異常用來防止執行緒異常的,需要加
{
Game tennis=new Game(); //建立game物件
Draw ball=new Draw(); //繪製一個新的小球,因為要迴圈呼叫所以放在Draw類裡面x,y會一直重新定義成0所以在這裡定義
while (true) {
tennis.add(ball); //迴圈新增新的小球
ball.moveBall(); //更新小球的位置(只是更新位置,還沒繪製);
tennis.repaint(); //重新繪製
Thread.sleep(5); //延遲5毫秒再繪製,不然小球會移動很快一閃而過
}
}
Game() 
{
this.setTitle("碰壁球遊戲");
this.setSize(600,600);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class Draw extends JPanel 
{
 int x=0; //小球的預設位置
 int y=0;
void moveBall() //這個方法就是不斷更新小球的位置
{
x++;
y++;
}
public void paint(Graphics g) {
super.paint(g); 
Graphics2D g2d = (Graphics2D) g; 
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.fillOval(x, y, 60, 60); 
}
 
}


執行一下小球開始移動了,可以看見小球不斷迴圈的向右下角移動.

 

然後再也回不來了~

然而並沒有什麼卵用,我們要讓小球碰壁再彈回來,改變小球的方向和速度。這裡只要改一下moveBall()方法便可以實現。

class Draw extends JPanel 
{
 int x=0; //小球的預設位置
 int y=0;
 int incx=1; //這是小球位置要移動的方向
 int incy=1;
void moveBall() //這個方法就是不斷更新小球的位置
{
if(x+incx>getWidth()-60) //如果小球移動後的位置超出窗體範圍的話,移動方向就是一直-1;因為要考慮球的大小所以-60
incx=-1;
if(x+incx<0) //同理
incx=1;
if(y+incy>getHeight()-60)
incy=-1;
if(y+incy<0)
incy=1;
x+=incx;
y+=incy;
}
public void paint(Graphics g) {
super.paint(g); 
Graphics2D g2d = (Graphics2D) g; 
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.fillOval(x, y, 60, 60); 
}
 
}


 

現在小球碰到窗體邊緣就會改變方向了,看起來就像是碰壁反彈。

為了使程式碼看起來更簡潔這裡另外建立一個Ball類用來存放小球的各種屬性方法。這裡改了一下窗體高度。

現在總共有兩個類。

Game

import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
 
public class Game extends JFrame //繼承父類Jframe
{
Ball ball=new Ball(this); //這裡建立一個Ball物件,this作為引數讓Ball類可以獲取Game的成員資訊
private void move() //這裡是move方法用來呼叫Ball類中的moveBall
{ 
ball.moveBall();
}
public static void main(String[] args) throws InterruptedException //這個是丟擲異常用來防止執行緒異常的,需要加
{
Game tennis=new Game(); //建立game物件
while (true) {
tennis.move(); //因為訪問限制所以通過move方法來呼叫Ball類中的moveBall方法
tennis.repaint(); //重新繪製
Thread.sleep(5); //延遲5毫秒再繪製,不然小球會移動很快一閃而過
}
}
Game() 
{
this.setTitle("碰壁球遊戲");
this.setSize(600,800);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g) {
super.paint(g);  //不新增這個的話舊的小球不會被擦除
Graphics2D g2d = (Graphics2D) g; 
ball.paint(g2d); //呼叫ball類中的paint方法
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
 
}
}


Ball

import javax.swing.*;
import java.awt.Graphics2D;
 
public class Ball extends JPanel{
 int x=0; //小球的預設位置
 int y=0;
 int incx=1; //這是小球位置要移動的方向
 int incy=1;
 private Game tennis;
public Ball(Game tennis)
{
this.tennis=tennis;
}
void moveBall() //這個方法就是不斷更新小球的位置
{
 
if(x+incx>tennis.getWidth()-60) //如果小球移動後的位置超出窗體範圍的話,移動方向就是一直-1;因為要考慮球的大小所以-60
incx=-1;
if(x+incx<0) //同理
incx=1;
if(y+incy>tennis.getHeight()-60)
incy=-1;
if(y+incy<0)
incy=1;
x+=incx;
y+=incy;
}
public void paint(Graphics2D g)
{
g.fillOval(x, y, 60, 60); 
}
}


執行結果跟剛才的一樣。

小球碰壁遊戲有一個長形狀方塊可以由玩家控制,碰到小球的話可以讓小球反彈回去。所以接下來就是事件監聽部分,監聽鍵盤的事件才可以控制方塊要移動的方向。

這裡舉出一個簡單的鍵盤監聽事件的例子

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
 
import javax.swing.JFrame;
import javax.swing.JPanel;
 
@SuppressWarnings("serial")
public class Keyboard extends JPanel {
String str="還沒按";
public Keyboard()  
{
KeyListener listener = new MyKeyListener(this); //建立一個鍵盤監聽器物件
addKeyListener(listener);  //註冊
setFocusable(true);  //
}
public static void main(String[] args) {
JFrame frame = new JFrame("鍵盤監聽器");
Keyboard keyboardExample = new Keyboard();
frame.add(keyboardExample); //新增物件
frame.setSize(200, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g) {
super.paint(g);  
Graphics2D g2d = (Graphics2D) g; 
g2d.setColor(Color.black);
  g.setFont(new Font("宋體",Font.BOLD,60));  
g2d.drawString(str,100,70);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
 
}
public class MyKeyListener implements KeyListener  //這個是實現介面,所以必須重新定義裡面的方法
{
private Keyboard kb;
 MyKeyListener (Keyboard kb)
 {
this.kb=kb;
 }
 @Override //檢查下面的方法在父類中是否存在
public void keyTyped(KeyEvent e) 
{
}
 
@Override
public void keyPressed(KeyEvent e) //按下鍵盤事件
{
str=KeyEvent.getKeyText(e.getKeyCode());
kb.repaint();
//System.out.println("按下的按鍵"+KeyEvent.getKeyText(e.getKeyCode()));
}
 
@Override
public void keyReleased(KeyEvent e) //放開鍵盤事件
{
//System.out.println("鬆開的按鍵="+KeyEvent.getKeyText(e.getKeyCode()));
}
}
}


執行結果如圖:


所按下的按鍵對應的文字都會顯示在窗體上。

現在按的按鍵都能監聽到了,因為上面的MyKeyListener類中只用了一次,因此我們可以改用為匿名物件並簡化程式碼。

package Tutorial;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class Keyboard2 extends JPanel {
public Keyboard2() {
KeyListener listener = new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
System.out.println("你按下了"+KeyEvent.getKeyText(e.getKeyCode()));
}
@Override
public void keyReleased(KeyEvent e) {
System.out.println("你鬆開了"+KeyEvent.getKeyText(e.getKeyCode()));
}
};
addKeyListener(listener);
setFocusable(true);
}
 
public static void main(String[] args) {
JFrame frame = new JFrame("鍵盤監聽器");
Keyboard2 keyboardExample = new Keyboard2();
frame.add(keyboardExample); 
frame.setSize(200, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
 
}


然後是建立球拍了,ball類一樣,建立一個球拍Racquet類,所做的更動只有以下兩個類,Game類新增一個鍵盤監聽和Racquet物件,Ball類不變.

Racquet

import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
public class Racquet extends JPanel{
int x=0;
int xa=0;
private Game game;
public Racquet(Game game)
{
this.game=game;
}
public void move()
{
if(x+xa<game.getWidth()-120 && x+xa>0)
x+=xa;
}
public void paint(Graphics2D g)
{
g.fillRect(x, 660, 120, 20);
}
public void KeyReleased(KeyEvent e)
{
xa=0;
}
public void KeyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_LEFT)
xa=-2;
if(e.getKeyCode()==KeyEvent.VK_RIGHT)
xa=2;
}
}


Game

import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.*;
public class Game extends JFrame //繼承父類Jframe
{
Ball ball=new Ball(this); //這裡建立一個Ball物件,this作為引數讓Ball類可以獲取Game的成員資訊
Racquet racquet=new Racquet(this);
public Game()
{
this.setTitle("碰壁球遊戲");
this.setSize(600,800);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
KeyListener listener=new KeyListener()
{
 
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
racquet.KeyPressed(e);
}
 
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
racquet.KeyReleased(e);
}
 
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
};
addKeyListener(listener);
setFocusable(true);
}
private void move() //這裡是move方法用來呼叫Ball類中的moveBall
{ 
ball.moveBall();
racquet.move();
}
public static void main(String[] args) throws InterruptedException //這個是丟擲異常用來防止執行緒異常的,需要加
{
Game tennis=new Game(); //建立game物件
while (true) {
tennis.move(); //因為訪問限制所以通過move方法來呼叫Ball類中的moveBall方法
tennis.repaint(); //重新繪製
Thread.sleep(5); //延遲5毫秒再繪製,不然小球會移動很快一閃而過
}
}
 
public void paint(Graphics g) {
super.paint(g);  //不新增這個的話舊的小球不會被擦除
Graphics2D g2d = (Graphics2D) g; 
ball.paint(g2d); //呼叫ball類中的paint方法
racquet.paint(g2d);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
 
}
}


執行如圖:

 

這裡我們先在Game類中新增GameOver()函式。

public void gameOver() {
 	JOptionPane.showMessageDialog(this, "Game Over", "Game Over", JOptionPane.YES_NO_OPTION);
 	System.exit(ABORT);
}

作用就是當遊戲結束會彈出一個提示視窗,點選後並退出遊戲。

 

現在按鍵盤方向鍵可以控制球拍的運行了,那麼問題來了,球和方塊之間並不會產生碰撞。

我們會用兩個矩形來檢測物體之間的碰撞。java.awt.Rectangle裡面有提供一個intersects方法可以用來判斷兩個方形是否相交,如圖3,4會返回true。在圖四中小球是沒有碰到球拍的,但是看做方形的話有碰到球拍,所以還是會返回true。可以不用在意這些細節,因為本教程的目的主要是用來學習。

改一下Racquet

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
 
import javax.swing.JPanel;
 
public class Racquet extends JPanel{
private static final int y= 660; //新增三個球拍屬性的final變數,因為已經確定下來了不會再改
private static final int WIDTH = 120;
private static final int HEIGHT = 20;
int x=0;
int xa=0;
private Game game;
public Racquet(Game game)
{
this.game=game;
}
public void move()
{
if(x+xa<game.getWidth()-120 && x+xa>0)
x+=xa;
}
public void paint(Graphics2D g)
{
g.fillRect(x, y, WIDTH, HEIGHT);
}
public void KeyReleased(KeyEvent e)
{
xa=0;
}
public void KeyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_LEFT)
xa=-2;
if(e.getKeyCode()==KeyEvent.VK_RIGHT)
xa=2;
}
public Rectangle getBounds()  //返回當前Rectangle型別的球拍
{
return new Rectangle(x, y, WIDTH, HEIGHT);
}
 
public int getTopY()  //返回球拍所在的水平線
{
return y;
}
}


再改一下Ball

import javax.swing.*;
import java.awt.Graphics2D;
import java.awt.Rectangle;
 
public class Ball extends JPanel{
private static final int ballsize=60;
 int x=0; //小球的預設位置
 int y=0;
 int incx=1; //這是小球位置要移動的方向
 int incy=1;
 private Game tennis;
public Ball(Game tennis)
{
this.tennis=tennis;
}
void moveBall() //這個方法就是不斷更新小球的位置
{
 
if(x+incx>tennis.getWidth()-ballsize) //如果小球移動後的位置超出窗體範圍的話,移動方向就是一直-1;因為要考慮球的大小所以-60
incx=-1;
if(x+incx<0) //同理
incx=1;
if(y+incy>tennis.getHeight()-ballsize)
tennis.gameOver(); // 如果碰到底部就遊戲結束
if(y+incy<0)
incy=1;
if (collision()) //如果檢測到碰撞就改變方向
{
incy = -1;
y = tennis.racquet.getTopY() - ballsize;//這個是矯正球的位置,為了防止碰撞導致的就球拍和小球重疊
}
x+=incx;
y+=incy;
}
public void paint(Graphics2D g)
{
g.fillOval(x, y, ballsize, ballsize); 
}
public Rectangle getBounds()//返回Rectangle型別的小球
{
return new Rectangle(x,y,ballsize,ballsize);
}
private boolean collision()  //這個是檢測碰撞
{
return tennis.racquet.getBounds().intersects(getBounds()); //用intersects方法判斷小球是否和球拍相交
}
}


執行玩玩一下,效果圖:


 

到這裡基本大功告成了。接下來就是分數部分,稍微新增些程式碼就可以了。在Game中定義一個score變數用來計數,在collisiontrue時分數遞增,然後通過paint繪製出來。

最終成果:

Class Game

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.*;
public class Game extends JFrame //繼承父類Jframe
{
Ball ball=new Ball(this); //這裡建立一個Ball物件,this作為引數讓Ball類可以獲取Game的成員資訊
Racquet racquet=new Racquet(this);
static int score;
public Game()
{
this.setTitle("碰壁球遊戲");
this.setSize(600,800);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
KeyListener listener=new KeyListener()
{
 
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
racquet.KeyPressed(e);
}
 
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
racquet.KeyReleased(e);
}
 
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
};
addKeyListener(listener);
setFocusable(true);
}
private void move() //這裡是move方法用來呼叫Ball類中的moveBall
{ 
ball.moveBall();
racquet.move();
}
public static void main(String[] args) throws InterruptedException //這個是丟擲異常用來防止執行緒異常的,需要加
{
Game tennis=new Game(); //建立game物件
while (true) {
 
tennis.move(); //因為訪問限制所以通過move方法來呼叫Ball類中的moveBall方法
tennis.repaint(); //重新繪製
Thread.sleep(2); //延遲5毫秒再繪製,不然小球會移動很快一閃而過
}
}
public void gameOver() {
JOptionPane.showMessageDialog(this, "Game Over", "Game Over", JOptionPane.YES_NO_OPTION);
System.exit(ABORT);
}
public void paint(Graphics g) {
 
super.paint(g);  //不新增這個的話舊的小球不會被擦除
Graphics2D g2d = (Graphics2D) g; 
ball.paint(g2d); //呼叫ball類中的paint方法
racquet.paint(g2d);
g2d.setColor(Color.GRAY);
g2d.setFont(new Font("Verdana", Font.BOLD, 50));
g2d.drawString(String.valueOf(score), 20, 120);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
 
}
}


Class Ball

import javax.swing.*;
import java.awt.Graphics2D;
import java.awt.Rectangle;
 
public class Ball extends JPanel{
private static final int ballsize=60;
 int x=0; //小球的預設位置
 int y=0;
 int incx=1; //這是小球位置要移動的方向
 int incy=1;
 private Game tennis;
public Ball(Game tennis)
{
this.tennis=tennis;
}
void moveBall() //這個方法就是不斷更新小球的位置
{
 
if(x+incx>tennis.getWidth()-ballsize) //如果小球移動後的位置超出窗體範圍的話,移動方向就是一直-1;因為要考慮球的大小所以-60
incx=-1;
if(x+incx<0) //同理
incx=1;
if(y+incy>tennis.getHeight()-ballsize)
tennis.gameOver();
if(y+incy<0)
incy=1;
if (collision()) //如果檢測到碰撞就改變方向
{
incy = -1;
y = tennis.racquet.getTopY() - ballsize;//這個是矯正球的位置,為了防止碰撞導致的就球拍和小球重疊
tennis.score++;
}
x+=incx;
y+=incy;
}
public void paint(Graphics2D g)
{
g.fillOval(x, y, ballsize, ballsize); 
}
public Rectangle getBounds()//返回Rectangle型別的小球
{
return new Rectangle(x,y,ballsize,ballsize);
}
private boolean collision()  //這個是檢測碰撞
{
return tennis.racquet.getBounds().intersects(getBounds()); //用intersects方法判斷小球是否和球拍相交
}
}


Class Racquet

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
 
import javax.swing.JPanel;
 
public class Racquet extends JPanel{
private static final int y= 660; //新增三個球拍屬性的final變數,因為已經確定下來了不會再改
private static final int WIDTH = 120;
private static final int HEIGHT = 20;
int x=0;
int xa=0;
private Game game;
public Racquet(Game game)
{
this.game=game;
}
public void move()
{
if(x+xa<game.getWidth()-120 && x+xa>0)
x+=xa;
}
public void paint(Graphics2D g)
{
g.fillRect(x, y, WIDTH, HEIGHT);
 
}
public void KeyReleased(KeyEvent e)
{
xa=0;
}
public void KeyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_LEFT)
xa=-2;
if(e.getKeyCode()==KeyEvent.VK_RIGHT)
xa=2;
}
public Rectangle getBounds()  //返回當前Rectangle的球拍
{
return new Rectangle(x, y, WIDTH, HEIGHT);
}
 
public int getTopY()  //返回球拍所在的水平線
{
return y;
}
}


 

到這裡大家就可以根據自己的喜好對小球,球拍的速度做調整,也可以自己新增一個開始按鈕來開始遊戲。

希望生成可執行檔案的可以通過File>Export>Java>Runnable Jar File 來匯出jar檔案。

本教程到此結束,講解中的不足之處請見諒,謝謝大家了~

相關推薦

Java 碰壁小球遊戲例項教程

本教程會舉例用Java實現簡單的小球碰壁反彈遊戲,效果如圖所示: JFrame: 窗體部分 首先建立一個窗體介面,下面舉一個簡單的例子(Jframe是自己定義的類名,注意和JFrame的區別) import javax.swing.JFrame; //沒匯入就沒卵用

Java例項教程(上)

第一個Java程式 Java 列舉 Java註釋 Java建立物件 Java訪問例項變數和方法 Java區域性變數例項 Java編譯錯誤 J

java例項教程

Java 例項 - 如何編譯 Java 檔案 Java 例項 - 如何執行編譯過 Java 檔案 Java 例項 - 如何執行指定class檔案目錄(classpath) Java 例項 - 如何檢視當前 Jav

Java例項教程(下)

Java當前日期/時間 Java將字串轉換為日期 Java當前工作目錄 Java正則表示式 Java立方體 編譯並執行Java Online 用於連線兩

Java例項教程(中)

Java.util.Scanner.nextBigDecimal() 方法 Java.util.Scanner.nextBigInteger() 方法 Java.util.Scanner.nextBigInteger(int

Java中的策略模式例項教程

原文連結   作者:Pankaj Kumar 譯者:f0tlo <[email protected]> 策略模式是一種行為模式。用於某一個具體的專案有多個可供選擇的演算法策略,客戶端在其執行時根據不同需求決定使用某一具體演算法策略。 策略模式也被稱作政策模式。實現過程為,

JAVA中的備忘錄模式例項教程

原文連結  作者:Pankaj Kumar 譯者:f0tlo <[email protected]> 備忘錄模式是一種行為模式。備忘錄模式用於儲存物件當前狀態,並且在之後可以再次使用此狀態。備忘錄模式實現的方式需要保證,被儲存的物件狀態不能被物件從外部訪問,目的為了被儲存

JAVA中的觀察者模式例項教程

觀察者模式例子 在此例中,我們將完成一個簡單的主題討論,觀察者能夠註冊此主題。任何在此主題上的內容提交導致的變化都會通知所有在註冊的觀察者。 基於Subject被觀察者的需求,這個是實現一個基本的Subject介面,此介面定了一系列具體的方法需要在隨後實現介面的具體類中被實現。 package com.jo

JAVA中的命令模式例項教程

命令模式客戶端 現在完成一個簡單的聊天程式來完成組群聊天。 package com.journaldev.design.mediator; public class ChatClient { public static void main(String[] args) { ChatM

Java中的狀態模式例項教程

狀態模式是一種行為設計模式。適用於當物件的內在狀態改變它自身的行為時。 如果想基於物件的狀態來改變自身的行為,通常利用物件的狀態變數及if-else條件子句來扮演針對物件的不同行為。狀態模式Context(環境)和State(狀態)分離的方式既保證狀態與行為的聯動變化,又使得這種變化是條理明晰且鬆耦合的。

Java實現AOP面向切面程式設計的例項教程

介紹 眾所周知,AOP(面向切面程式設計)是Spring框架的特色功能之一。通過設定橫切關注點(cross cutting concerns),AOP提供了極高的擴充套件性。那AOP在Spring中是怎樣運作的呢?當你只能使用core java,卻需要AOP技術時,這個問題的解答變得極為關鍵。不僅如此,

Intellij IDEA的java環境與安卓sdk配置例項教程

一、Intellij IDEA的安裝 第一步:進入官網下載intellij idea,download–>選擇作業系統–>選擇版本; 第二步:將下載下來的“.exe”檔案開啟 註釋:接下來傻瓜式操作一直下一步即可,最後彈出註冊資訊,將上面的註冊

Java遊戲之鬥地主遊戲例項Map集合

Map的特點是什麼? 1、Map物件是一個雙列的容器 2、兩列分別對應key和value,二者一一對應,是對映關係 3、Map中的資料以鍵值對的形式儲存 4、鍵值是唯一的,不能重複的 HashSet()和HashMap()之間的關係? HashSet()底層是HashMap

Java中的策略模式,完成一個簡單地購物車,兩種付款策略例項教程

**策略模式是一種行為模式**。用於某一個具體的專案有多個可供選擇的演算法策略,客戶端在其執行時根據不同需求決定使用某一具體演算法策略。 策略模式也被稱作政策模式。實現過程為,首先定義不同的演算法策略,然後客戶端把演算法策略作為它的一個引數。使用這種模式最好的例子是Collection.sort()方法了,

java web後端方向)如何讓你的簡歷為你爭取到更多的面試機會,內容來自java web輕量級開發面試教程

java web輕量級開發面試教程 我們在做培訓時,會發現一個不合理的情況,一些程序員能力不錯,在公司裏也是技術牛人,但發出去的簡歷往往會石沈大海,沒有回復。對於剛畢業的大學生或工作年限在2年之內的程序員,這個情況會更嚴重。 這種情況下,其實不是你的能力有問題,而是簡歷篩選人(往往是人事

使用純java 黃金點遊戲

pri art name 自己 rem 輸入 println 入參 cnblogs   最近自己使用純java寫的黃金點遊戲,寫的不是很好,希望各位度偶倒指點。本來想使用swing來做幾個按鈕的,但是對這個確實不是很懂,還是放棄了,采用了控制臺輸入的方式。主要是 使用has

Photon多人遊戲開發教程

udp 隨機 r12 dom pid log 時機 觸發器 動作 http://gad.qq.com/article/detail/26112 PUN介紹 入門 Photon Unity Networking(首字母縮寫PUN)是一個Unity多人遊戲插件包。它提供了身份驗

java黃金點遊戲

ext 需要 log nts r12 tor map.entry help void 在同學的幫組下用java寫的黃金點遊戲,寫的不是很好,希望各位多多指點。本來想使用swing來做幾個按鈕的,但是對這個確實不是很懂,還是放棄了,采用了控制臺輸入的方式。主要是 使用hash

軟件工程——Java版2048遊戲學習報告

extends 解決 class awt ner 操作 boolean 長度 移動端 2048遊戲學習報告 姓名:王浩 專業:計算機科學與技術 年級:15級4班 學號:201510411420 目錄 一. 前言

Java SSM開發大眾點評後端項目實戰教程 Java SSM項目實戰教程 共9章

Java第1章 課程概覽 介紹課程目標、開發內容、功能劃分、開發順序,開發所需要的前置知識及環境準備,並且介紹了與課程相關的前後端分離的思想,架構演進過程。第2章 開發準備 演示前端工程環境搭建以及啟動步驟,介紹了後臺工程初始SSM框架目錄結構,將前後端打通,並將後臺管理使用的界面原型加入後臺工程