java swing开发工具写游戏入门有什么值得参考的demo

29被浏览7,588分享邀请回答0添加评论分享收藏感谢收起122 条评论分享收藏感谢收起他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)&&java swing实现的简单的坦克大战小游戏只实现了简单的绘制敌我坦克,开炮,移动功能,击中没有实现,可以做为swing游戏开发的初学参考下。
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyE
import java.awt.event.KeyL
public class Tank3 extends JFrame {
private static final long serialVersionUID = 1L;
Tank3(String title) { //重构
this.setTitle(title); //窗体名称
this.setSize(415, 500); //窗体大小
this.setLocation(300, 300); //窗体位置
this.setBackground(Color.WHITE);
MyTank3 singlePlayer1 = new MyTank3();// 类Mytank3中包含所有游戏信息
this.add(singlePlayer1);
this.addKeyListener(singlePlayer1);
new Thread(singlePlayer1).start();
MyBullet3 singlePlayer2 = new MyBullet3();
this.add( singlePlayer2 );
this.addKeyListener(singlePlayer2);
new Thread(singlePlayer2).start();
public static void main(String[] args) {
Tank3 h = new Tank3(&坦克大战(版本1.1)&);
h.setVisible(true);
// 存储地图网格数据的类,以判断坦克碰撞,0为可行区域,大于0为不可行区域
class groundData {
volatile public int ground[][] = new int[18][18];
//主线程,我方坦克线程,paint线程
(这里应该更明确地对象化)
class MyTank3 extends JPanel implements KeyListener, Runnable {
private static final long serialVersionUID = 1L;
groundData o = new groundData();//地图数据,会在本线程中实时更新
int perStep = 1, sleepTime = 7;//线程的睡眠时间以及每次睡眠后坦克移动的像素
int x = 105, y = 355;//我方坦克出生点
int op = 0; // 0:up 1:right 2:down 3:left 方向指示
int tankStep = 0; //用于在tank移动中计数
int life = 100, score = 0, difficulty = 20; //生命,得分,难度
int enemyNum = 0, enemyMax = 6;//现有敌人数量,画面允许敌人的最大数量
boolean stuck =//坦克是否无法前行
MyBullet3 bullet = new MyBullet3();//我方坦克炮弹
//敌方坦克炮弹
MyBullet3 sBullet = new MyBullet3();
MyBullet3 enemyBullet[] = {sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet,
sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet,
sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet,
sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet, sBullet};
//敌方坦克
EnemyTank sEnemy = new EnemyTank(2, 5, 5, o, -2);
EnemyTank enemy[] = {sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy,
sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy,
sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy,
sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy, sEnemy};
//绘制坦克方法,i为坦克标号,我方为1,敌方大于1
public void drawTank(Graphics g, int op, int x, int y, int i) {
if (i == 1) {
g.setColor(Color.yellow);//我方黄色,敌方红色
g.setColor(Color.red);
if (op == 0) {
g.fillRect(x, y, 40, 40); //坦克体
g.setColor(Color.black);
g.drawRect(x + 10, y + 5, 20, 20);//轮廓
g.drawRect(x, y, 40, 40);
g.drawRect(x - 5, y - 5, 10, 50);//左右两侧履带
g.fillOval(x - 5, y - 5, 10, 10);
g.fillOval(x - 5, y + 5, 10, 10);
g.fillOval(x - 5, y + 15, 10, 10);
g.fillOval(x - 5, y + 25, 10, 10);
g.fillOval(x - 5, y + 35, 10, 10);
g.drawRect(x + 35, y - 5, 10, 50);
g.fillOval(x + 35, y - 5, 10, 10);
g.fillOval(x + 35, y + 5, 10, 10);
g.fillOval(x + 35, y + 15, 10, 10);
g.fillOval(x + 35, y + 25, 10, 10);
g.fillOval(x + 35, y + 35, 10, 10);
g.fillRect(x + 15, y - 20, 10, 40); //炮口
g.fillOval(x + 5, y + 30, 10, 10); //天线
g.fillOval(x + 25, y + 30, 10, 10);
}// end of if ( op == 1 )
if (op == 1) {
g.fillRect(x, y, 40, 40);
g.setColor(Color.black);
g.drawRect(x + 15, y + 10, 20, 20);
g.drawRect(x, y, 40, 40);
g.drawRect(x - 5, y - 5, 50, 10);
g.fillOval(x - 5, y - 5, 10, 10);
g.fillOval(x + 5, y - 5, 10, 10);
g.fillOval(x + 15, y - 5, 10, 10);
g.fillOval(x + 25, y - 5, 10, 10);
g.fillOval(x + 35, y - 5, 10, 10);
g.drawRect(x - 5, y + 35, 50, 10);
g.fillOval(x - 5, y + 35, 10, 10);
g.fillOval(x + 5, y + 35, 10, 10);
g.fillOval(x + 15, y + 35, 10, 10);
g.fillOval(x + 25, y + 35, 10, 10);
g.fillOval(x + 35, y + 35, 10, 10);
g.fillRect(x + 20, y + 15, 40, 10);
g.fillOval(x, y + 5, 10, 10);
g.fillOval(x, y + 25, 10, 10);
}// end of if (op==2)
if (op == 2) {
g.fillRect(x, y, 40, 40);
g.setColor(Color.black);
g.drawRect(x + 10, y + 15, 20, 20);
g.drawRect(x, y, 40, 40);
g.drawRect(x - 5, y - 5, 10, 50);
g.fillOval(x - 5, y - 5, 10, 10);
g.fillOval(x - 5, y + 5, 10, 10);
g.fillOval(x - 5, y + 15, 10, 10);
g.fillOval(x - 5, y + 25, 10, 10);
g.fillOval(x - 5, y + 35, 10, 10);
g.drawRect(x + 35, y - 5, 10, 50);
g.fillOval(x + 35, y - 5, 10, 10);
g.fillOval(x + 35, y + 5, 10, 10);
g.fillOval(x + 35, y + 15, 10, 10);
g.fillOval(x + 35, y + 25, 10, 10);
g.fillOval(x + 35, y + 35, 10, 10);
g.fillRect(x + 15, y + 20, 10, 40);
g.fillOval(x + 5, y, 10, 10);
g.fillOval(x + 25, y, 10, 10);
} //end of if ( op == 3 )
if (op == 3) {
g.fillRect(x, y, 40, 40);
g.setColor(Color.black);
g.drawRect(x + 5, y + 10, 20, 20);
g.drawRect(x, y, 40, 40);
g.drawRect(x - 5, y - 5, 50, 10);
g.fillOval(x - 5, y - 5, 10, 10);
g.fillOval(x + 5, y - 5, 10, 10);
g.fillOval(x + 15, y - 5, 10, 10);
g.fillOval(x + 25, y - 5, 10, 10);
g.fillOval(x + 35, y - 5, 10, 10);
g.drawRect(x - 5, y + 35, 50, 10);
g.fillOval(x - 5, y + 35, 10, 10);
g.fillOval(x + 5, y + 35, 10, 10);
g.fillOval(x + 15, y + 35, 10, 10);
g.fillOval(x + 25, y + 35, 10, 10);
g.fillOval(x + 35, y + 35, 10, 10);
g.fillRect(x - 20, y + 15, 40, 10);
g.fillOval(x + 30, y + 5, 10, 10);
g.fillOval(x + 30, y + 25, 10, 10);
} //end of if ( op == 4 )
public void paint(Graphics g) {
super.paint(g);
this.setBackground(Color.WHITE);
//设置下方血条和得分的显示
g.setColor(Color.black);
g.fillRect(0, 400, 415, 100);
g.setColor(Color.red);
g.fillRect(50, 420, life * 3, 10);
//为坦克的阻塞区域填色,调试用
for ( int i = 0; i & 18 ; i++ )
for ( int j = 0; j & 18 ; j++ )
if (o.ground[i][j] == 1 ) {
g.setColor(Color.red) ;
g.fillRect((i-1)*25, (j-1)*25, 25, 25);}
else if (o.ground[i][j] == 2 ) {
g.setColor(Color.blue) ;
g.fillRect((i-1)*25, (j-1)*25, 25, 25);}
else if (o.ground[i][j] == 3 ) {
g.setColor(Color.yellow) ;
g.fillRect((i-1)*25, (j-1)*25, 25, 25);}
else if (o.ground[i][j] == 4 ) {
g.setColor(Color.green) ;
g.fillRect((i-1)*25, (j-1)*25, 25, 25);}
else if (o.ground[i][j] == 5 ) {
g.setColor(Color.gray) ;
g.fillRect((i-1)*25, (j-1)*25, 25, 25);}
g.setColor(Color.white);
g.drawString(&生命:&, 10, 430);
g.drawRect(50, 420, 300, 10);
g.drawString(&得分:
& + score, 10, 450);
g.setColor(Color.gray);
//画网格线,调试用
for ( int i = 0; i &= 405 ; i = i+50) {
g.drawLine(0, i , 425, i);
g.drawLine(i, 0, i, 450);
//绘制本方坦克
drawTank(g, op, x, y, 1);
//绘制本方炮弹
if (bullet.flying) {
g.fillOval(bullet.bx, bullet.by, 10, 10);
//绘制敌方坦克与炮弹
for (int i = 0; i & enemyN i++)
if (enemy[i] != null)
if (enemy[i].alive) {
drawTank(g, enemy[i].op, enemy[i].x, enemy[i].y, i + 2);
if (enemyBullet[i].flying) g.fillOval(enemyBullet[i].bx, enemyBullet[i].by, 10, 10);
//坦克前行
public void stepForward(MyTank3 ref) {
if (tankStep & 0) {//为对齐格子,每次必须行进25像素
switch (op) {
ref.y = ref.y - perS
ref.tankStep--;
ref.x = ref.x + perS
ref.tankStep--;
ref.y = ref.y + perS
ref.tankStep--;
ref.x = ref.x - perS
ref.tankStep--;
public void run() {
int j = 0, i = 0;
//将地图四周设置成最高的阻塞等级
for (i = 0; i & 18; i++) {
o.ground[0][i] = 255;
o.ground[17][i] = 255;
o.ground[i][0] = 255;
o.ground[i][17] = 255;
//我方坦克出生点,坦克的阻塞等级为坦克标号,即1
o.ground[(int) ((x + 20) / 25)][(int) ((y + 20) / 25)] = 1;
o.ground[(int) ((x + 45) / 25)][(int) ((y + 20) / 25)] = 1;
o.ground[(int) ((x + 20) / 25)][(int) ((y + 45) / 25)] = 1;
o.ground[(int) ((x + 45) / 25)][(int) ((y + 45) / 25)] = 1;//由像素坐标转到游戏坐标
for (int a = 0; a & 60000; a++) {
stepForward(this);//行进
if (tankStep == 13) {//行进一半时移动格子的阻塞属性以配合坦克移动
switch (op) {
i = (int) ((x + 20) / 25);
j = (int) ((y + 32) / 25);
o.ground[i][j - 1] = 1;
o.ground[i + 1][j - 1] = 1;
o.ground[i][j + 1] = 0;
o.ground[i + 1][j + 1] = 0;
i = (int) ((x + 8) / 25);
j = (int) ((y + 20) / 25);
o.ground[i + 2][j] = 1;
o.ground[i + 2][j + 1] = 1;
o.ground[i][j] = 0;
o.ground[i][j + 1] = 0;
i = (int) ((x + 20) / 25);
j = (int) ((y + 8) / 25);
o.ground[i][j + 2] = 1;
o.ground[i + 1][j + 2] = 1;
o.ground[i][j] = 0;
o.ground[i + 1][j] = 0;
i = (int) ((x + 32) / 25);
j = (int) ((y + 20) / 25);
o.ground[i - 1][j] = 1;
o.ground[i - 1][j + 1] = 1;
o.ground[i + 1][j] = 0;
o.ground[i + 1][j + 1] = 0;
}// if step == 13
try { //sleep,否则游戏太快
Thread.sleep(sleepTime);
} catch (Exception e) {
e.printStackTrace();
//以下是敌军回合
if (enemyNum & enemyMax) {//若场上坦克数未达到最大
i = 5 + 175 * (int) (3 * Math.random());//三个随即出生点
if (enemy[k] != null)
//若该出生点未被堵塞
if (o.ground[(int) ((i + 20) / 25)][1] + o.ground[(int) ((i + 45) / 25)][1] + o.ground[(int) ((i + 20) / 25)][2] + o.ground[(int) ((i + 45) / 25)][2] & 1) {
for (int k = 0; k & enemyM k++)
//坦克少或坦克死了,则出生
if ((k &= enemyNum) || (enemy[k].alive == false)) {
groundData a1 = new groundData();
enemy[k] = new EnemyTank(2, i, j, a1, k);//k是坦克数组的标号,k+2即为坦克及其地面标号
this.o.ground[(int) ((i + 20) / 25)][(int) ((j + 20) / 25)] = k + 2;
this.o.ground[(int) ((i + 45) / 25)][(int) ((j + 20) / 25)] = k + 2;
this.o.ground[(int) ((i + 20) / 25)][(int) ((j + 45) / 25)] = k + 2;
this.o.ground[(int) ((i + 45) / 25)][(int) ((j + 45) / 25)] = k + 2;
//出生点阻塞
new Thread(enemy[k]).start();//开始活动
enemy[k].getGroundData(this);//敌军载入全局地图
enemyNum++;//敌军数加1
//跳出循环,一次只出生一辆坦克
for (int k = 0; k & enemyN k++)
if (enemy[k].alive)//如果活动
enemy[k].getGroundData(this);//刷新全局地图
//将自己的位置写入全局地图
if ((enemy[k].tankStep == 13) && (enemy[k].stepping) && (!enemy[k].stuck))
regGround(enemy[k].op, enemy[k].x, enemy[k].y, this, k);
//判断自己的子弹是否击中阻塞
if ((enemyBullet[k].flying) && ((enemyBullet[k].bx + 5) &= 4) && ((enemyBullet[k].by + 5) &= 4))
bulletHit(enemyBullet[k], o, enemyBullet[k].bk);
//己方坦克是否击中阻塞
if ((bullet.flying) && ((bullet.bx + 5) &= 4) && ((bullet.by + 5) &= 4))
bulletHit(bullet, o, bullet.bk);
this.repaint();
//敌军坦克对地图的刷新(注册)
public void regGround(int op, int x, int y, MyTank3 ref, int k) {
ref.enemy[k].stepping = //stepping为真时,进行地面阻塞移动,移动后将stepping置为false,即一次移动只注册一次
switch (op) {
i = (int) ((x + 20) / 25);
j = (int) ((y + 32) / 25);
ref.o.ground[i][j - 1] = 2 +
ref.o.ground[i + 1][j - 1] = 2 +
ref.o.ground[i][j + 1] = 0;
ref.o.ground[i + 1][j + 1] = 0;
i = (int) ((x + 8) / 25);
j = (int) ((y + 20) / 25);
ref.o.ground[i + 2][j] = 2 +
ref.o.ground[i + 2][j + 1] = 2 +
ref.o.ground[i][j] = 0;
ref.o.ground[i][j + 1] = 0;
i = (int) ((x + 20) / 25);
j = (int) ((y + 8) / 25);
ref.o.ground[i][j + 2] = 2 +
ref.o.ground[i + 1][j + 2] = 2 +
ref.o.ground[i][j] = 0;
ref.o.ground[i + 1][j] = 0;
i = (int) ((x + 32) / 25);
j = (int) ((y + 20) / 25);
ref.o.ground[i - 1][j] = 2 +
ref.o.ground[i - 1][j + 1] = 2 +
ref.o.ground[i + 1][j] = 0;
ref.o.ground[i + 1][j + 1] = 0;
//按键功能
public void keyPressed(KeyEvent e) {
i = (int) ((x + 20)) / 25;
j = (int) ((y + 20)) / 25;
if (e.getKeyCode() == KeyEvent.VK_UP) {
if (tankStep &= 0) {
tankStep = 25;
if ((o.ground[i][j - 1] & 0) || (o.ground[i + 1][j - 1] & 0)) { //转弯后判断是否阻塞
tankStep = 0;//如果阻塞则不移动
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
if (tankStep &= 0) {
tankStep = 25;
if ((o.ground[i + 2][j] & 0) || (o.ground[i + 2][j + 1] & 0)) {
tankStep = 0;
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
if (tankStep &= 0) {
tankStep = 25;
if ((o.ground[i][j + 2] & 0) || (o.ground[i + 1][j + 2] & 0)) {
tankStep = 0;
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
if (tankStep &= 0) {
tankStep = 25;
if ((o.ground[i - 1][j] & 0) || (o.ground[i - 1][j + 1] & 0)) {
tankStep = 0;
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
if (bullet.flying == false) {//若炮弹在飞则发不出第二发
new Thread(bullet).start();
bullet.bx = x + 15;
bullet.by = y + 15;
bullet.bop =
bullet.flying =
//esc直接退出
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
System.exit(0);
this.repaint();
public void keyReleased(KeyEvent arg0) {
public void keyTyped(KeyEvent arg0) {
//判断子弹是否击中
public void bulletHit(MyBullet3 ref, groundData o, int k) {
i = (int) ((ref.bx + 5) / 25);
j = (int) ((ref.by + 5) / 25);
System.out.print(&hit: i &+i+& , j &+j+&
if (k == 1) {//我方击中
if (o.ground[i][j] & 1) {
ref.flying =
if (o.ground[i][j] & 100) killTank(o.ground[i][j] - 2, this);
if (o.ground[i + 1][j] & 1) {
ref.flying =
if (o.ground[i + 1][j] & 100) killTank(o.ground[i + 1][j] - 2, this);
if (o.ground[i][j + 1] & 1) {
ref.flying =
if (o.ground[i][j + 1] & 100) killTank(o.ground[i][j + 1] - 2, this);
if (o.ground[i + 1][j + 1] & 1) {
ref.flying =
if (o.ground[i + 1][j + 1] & 100) killTank(o.ground[i + 1][j + 1] - 2, this);
if (k & 1) {//敌方击中
if ((o.ground[i][j] & 0) && (o.ground[i][j] != k)) {
ref.flying =
if (o.ground[i][j] == 1) life = life -
if ((o.ground[i + 1][j] & 0) && (o.ground[i + 1][j] != k)) {
ref.flying =
if (o.ground[i + 1][j] == 1) life = life -
if ((o.ground[i][j + 1] & 0) && (o.ground[i][j + 1] != k)) {
ref.flying =
if (o.ground[i][j + 1] == 1) life = life -
if ((o.ground[i + 1][j + 1] & 0) && (o.ground[i + 1][j + 1] != k)) {
ref.flying =
if (o.ground[i + 1][j + 1] == 1) life = life -
if (life &= 0) {
// 弹出对话框
JOptionPane.showMessageDialog(null,
: & + score,
&游戏结束!&,
JOptionPane.ERROR_MESSAGE);
// 结束游戏
System.exit(0);
//击毁敌方坦克
public void killTank(int k, MyTank3 ref) {
int i, j, m,
if (ref.enemy[k].alive) {
ref.enemyNum--;
ref.enemy[k].alive =
score = score + 100;
i = (int) ((ref.enemy[k].x + 20) / 25);
j = (int) ((ref.enemy[k].y + 20) / 25);
System.out.print(&explose:
i &+i+& , j &+j+& , k&+k +& \n&);
for (n = i - 1; n & i + 3; n++)
for (m = j - 1; m & j + 3; m++)
if ((m & 0) && (m & 18) && (n & 0) && (n & 18))
if (ref.o.ground[n][m] == k + 2) {
ref.o.ground[n][m] = 0; //消除地面阻塞
System.out.print(&m &+m+&, n &+n+&
class MyBullet3 extends Thread {
int bx = 0, by = 0, bop = 0, speed = 8, bk = 1;//bk为射出当前炮弹的坦克标号
boolean flying =
public void run() {
if (bk & 1) speed = 6;
for (int a = 0; a & 60000; a++) {
if (flying) {
switch (bop) {
if ((bx & 0) || (bx & 400) || (by & 0) || (by & 400)) {
System.out.print(& Bullet out of Frame!&);
if (flying == false)
Thread.sleep(25);
} catch (Exception e) {
e.printStackTrace();
}// end of for
}// end of run
}// end of class
//敌方坦克类
class EnemyTank extends Thread {
int x = 0, y = 0, op = 0, tk = 0;
boolean alive = false, stuck = false, stepping =
int tankStep = 0, perStep = 1;
//重构方法
EnemyTank(int top, int tx, int ty, groundData to, int k) {
this.alive =
this.o.ground[(int) ((x + 20) / 25)][(int) ((y + 20) / 25)] = k + 2;
this.o.ground[(int) ((x + 45) / 25)][(int) ((y + 20) / 25)] = k + 2;
this.o.ground[(int) ((x + 20) / 25)][(int) ((y + 45) / 25)] = k + 2;
this.o.ground[(int) ((x + 45) / 25)][(int) ((y + 45) / 25)] = k + 2;
public void run() {
for (int a = 0; a & 60000; a++) {
if (alive) {
if (tankStep == 0) {
if ((stuck) || (Math.random() & 0.1)) turnAround(this); //遇到阻塞或者随机 转弯
tankStep = 25;
stepping =
judgeStuck(this);
//判断是否被堵塞
proceed(this);
if ((Math.random() & 0.3) && (enemyBullet[tk].flying == false)) shootBullet();//未发射炮弹情况下随即发射
Thread.sleep(20);
} catch (Exception e) {
e.printStackTrace();
}//end of for
}//end of run
void shootBullet() {
//申请新的炮弹
new Thread(enemyBullet[tk]).start();
enemyBullet[tk].speed = 6;
enemyBullet[tk].bx = x + 15;
enemyBullet[tk].by = y + 15;
enemyBullet[tk].bop =
enemyBullet[tk].bk = tk + 2;
enemyBullet[tk].flying =
void judgeStuck(EnemyTank ref) {
i = (int) ((x + 20)) / 25;
j = (int) ((y + 20)) / 25;
switch (op) {
if ((o.ground[i][j - 1] & 0) || (o.ground[i + 1][j - 1] & 0)) {
ref.stuck =
if ((o.ground[i + 2][j] & 0) || (o.ground[i + 2][j + 1] & 0)) {
ref.stuck =
if ((o.ground[i][j + 2] & 0) || (o.ground[i + 1][j + 2] & 0)) {
ref.stuck =
if ((o.ground[i - 1][j] & 0) || (o.ground[i - 1][j + 1] & 0)) {
ref.stuck =
void turnAround(EnemyTank ref) {
int i = (int) (Math.random() * 2) + 1;//i= 1 2 3
中的随机数
ref.op = (op + i) % 4;//随机转弯
void getGroundData(MyTank3 d) {
this.o = d.o;
//载入地图
void proceed(EnemyTank ref) {
if (tankStep & 0) {
if (stuck == false)
switch (op) {
ref.y = ref.y - perS
ref.tankStep--;
ref.x = ref.x + perS
ref.tankStep--;
ref.y = ref.y + perS
ref.tankStep--;
ref.x = ref.x - perS
ref.tankStep--;
else tankStep--;//遇到堵塞后停止一会再转弯
}//end of class
}猜你喜欢0个牛币请下载代码后再发表评论精精精精原精精原精原原原原原原原相关分享原原精最近下载最近浏览暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级扫描二维码关注最代码为好友"/>扫描二维码关注最代码为好友有谁喜欢玩java的游戏吗!分享java Swing游戏总结【达内吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:254,899贴子:
有谁喜欢玩java的游戏吗!分享java Swing游戏总结收藏
达内江苏「中国高端IT培训」,16年,12万名企内部就业通道,60万学员高薪见证!达内22大课程体系:Java/Web/H5/安卓/iOS/测试/C++/ARM/Linux/PHP/UI设计/会计/营销/..
一个月了,老师用swing讲过两个游戏,加上有经典案例的电子书,照着书上敲了下代码,通过调试修改,最后总结了下,其实java用swing写的游戏有很多共性,或者说很多的桌面游戏都有的共性吧。
一句话归结,这类游戏就是一副可以与人交互的与人交互的、能够根据状态控制画面的动态画面。然后我将它划作三个大块(以下就以设计游戏为例):静态,动态和可控制的动态。以下就根据这三步分析
初始化实体--位置,图片
paintHero(g);
paintAirplane(g);
paintBee(g);
paintScore(g);
paintState(g);
第一步到此结束,因为各种游戏的第二步都不甚相同,关键是思想要走到&游戏如何动,怎么动,动了会怎样&那里去,只要有想法,然后一步一步地,将各个类的行为和联系理清,最终连成一条非线性链,那么游戏已经完成一大半。
最后一小步就要考虑&游戏在什么时候该怎么动&,设计几种状态,例如出现几率最多的几种:start,running,gameover...开始状态需要初始化一部分实体在窗口,但是窗口应该是静态的,运行状态就是游戏最疯狂的时候,各种实体都动起来,如果检测到游戏已经结束,需要销毁窗口上的东西,重新初始化又进入到开始状态。
可能总结得不完善,也有很多说得本身就不对的地方,只是阐述了一下个人对窗口游戏设计的思想的理解。求勿喷
楼主实在北京达内学的吗
我想去达内学习,但是对达内不是很了解
达内的老师怎么样呀,认真负责教的仔细吗
我想学ios请问一下和这个有什么区别吗,哪个简单一点
我还想请问一下达内可以贷款吗,我现在还是大学生,暂时支付不了学费
而且是不是只有北京才有老师教学啊,外地都是视频吗
达内的就业有保障吗,可以包就业或者推荐吗
楼主的帖子总结的好仔细啊。看来是学的不错
登录百度帐号博客分类:
  在Swing中不但用轻量级的组件替代了AWT中的重量级的组件,而且Swing的替代组件中都包含有一些其他的特性。例如,Swing的按钮和标签可显示图标和文本,而AWT的按钮和标签只能显示文本。Swing中的大多数组件都是AWT组件名前面加了一个"J"。
7.2.1 组件的分类
 Jcomponent是一个抽象类,用于定义所有子类组件的一般方法,其类层次结构如下所示:
)
   java.lang.Object
       
       +--java.awt.Component
            
            +--java.awt.Container
               
                +--javax.swing.JComponent
  并不是所有的Swing组件都继承于JComponent类,JComponent类继承于Container类,所以凡是此类的组件都可作为容器使用。
  组件从功能上分可分为:
 1) 顶层容器:JFrame,JApplet,JDialog,JWindow共4个
 2) 中间容器:JPanel,JScrollPane,JSplitPane,JToolBar 
 3) 特殊容器:在GUI上起特殊作用的中间层,如JInternalFrame,JLayeredPane,JRootPane.
 4) 基本控件:实现人际交互的组件,如Jbutton, JComboBox, JList, JMenu, JSlider, JtextField。
 5) 不可编辑信息的显示:向用户显示不可编辑信息的组件,例如JLabel, JProgressBar, ToolTip。
 6) 可编辑信息的显示:向用户显示能被编辑的格式化信息的组件,如JColorChooser, JFileChoose, JFileChooser, Jtable, JtextArea
JComponent类的特殊功能又分为: 1) 边框设置:使用setBorder()方法可以设置组件外围的边框,使用一个EmptyBorder对象能在组件周围留出空白。 2) 双缓冲区:使用双缓冲技术能改进频繁变化的组件的显示效果。与AWT组件不同,JComponent组件默认双缓冲区,不必自己重写代码。如果想关闭双缓冲区,可以在组件上施加setDoubleBuffered(false)方法。 3) 提示信息:使用setTooltipText()方法,为组件设置对用户有帮助的提示信息。4) 键盘导航:使用registerKeyboardAction( ) 方法,能使用户用键盘代替鼠标来驱动组件。JComponent类的子类AbstractButton还提供了便利的方法--用setMnemonic( )方法指明一个字符,通过这个字符和一个当前L&F的特殊修饰共同激活按钮动作。 5) 可插入L&F:每个Jcomponent对象有一个相应的ComponentUI对象,为它完成所有的绘画、事件处理、决定尺寸大小等工作。 ComponentUI对象依赖当前使用的L&F,用UIManager.setLookAndFeel( )方法可以设置需要的 6) 支持布局:通过设置组件最大、最小、推荐尺寸的方法和设置X、Y对齐参数值的方法能指定布局管理器的约束条件,为布局提供支持。
7.2.2 使用Swing的基本规则
  与AWT组件不同,Swing组件不能直接添加到顶层容器中,它必须添加到一个与Swing顶层容器相关联的内容面板(content pane)上。内容面板是顶层容器包含的一个普通容器,它是一个轻量级组件。基本规则如下:
  (1)把Swing组件放入一个顶层Swing容器的内容面板上
  (2)避免使用非Swing的重量级组件。 对JFrame添加组件有两种方式:
  1) 用getContentPane( )方法获得JFrame的内容面板,再对其加入组件:frame.getContentPane().add(childComponent)J
  2) 建立一个Jpanel或 JDesktopPane之类的中间容器,把组件添加到容器中,用setContentPane()方法把该容器置为JFrame的内容面板:
    Jpanel contentPane=new Jpanel( );
  ……//把其它组件添加到Jpanel中;
    frame.setContentPane(contentPane); J
    //把contentPane对象设置成为frame的内容面板
7.2.3 各种容器面板和组件
 根面板由一个玻璃面板(glassPane)、一个内容面板(contentPane)和一个可选择的菜单条(JMenuBar)组成,而内容面板和可选择的菜单条放在同一分层。玻璃面板是完全透明的,缺省值为不可见,为接收鼠标事件和在所有组件上绘图提供方便。
 根面板提供的方法:
  Container getContentPane(); //获得内容面板
  setContentPane(Container); //设置内容面
  JMenuBar getMenuBar( ); //活动菜单条
  setMenuBar(JMenuBar); //设置菜单条
  JLayeredPane getLayeredPane(); //获得分层面板
 setLayeredPane(JLayeredPane); //设置分层面板
 Component getGlassPane(); //获得玻璃面板
  setGlassPane(Component); //设置玻璃面板
7.2.3.2 分层面板(JLayeredPane)
 Swing提供两种分层面板:JlayeredPane和JDesktopPane。 JDesktopPane是JLayeredPane的子类,专门为容纳内部框架(JInternalFrame)而设置。
 向一个分层面板种添加组件,需要说明将其加入哪一层,指明组件在该层中的位置:add(Component c, Integer Layer, int position)。
m7.2.3.3 面板(JPanel)
  面板(JPanel)是一个轻量容器组件,用法与Panel相同,用于容纳界面元素,以便在布局管理器的设置下可容纳更多的组件,实现容器的嵌套。Jpanel, JscrollPane, JsplitPane, JinteralFrame都属于常用的中间容器,是轻量组件。Jpanel的缺省布局管理器是FlowLayout。
java.lang.Object
   +--java.awt.Component
         +--java.awt.Container
             +--javax.swing.JComponent
                  |
                  +--javax.swing.JPanel
7.2.3.4 滚动窗口(JScrollPane)
  JscrollPane是带滚动条的面板,主要是通过移动JViewport(视口)来实现的。JViewport是一种特殊的对象,用于查看基层组件,滚动条实际就是沿着组件移动视口,同时描绘出它在下面"看到"的内容。
7.2.3.5 分隔板(JSplitPane)
 java.lang.Object
     |
     +--java.awt.Component
         |
        +--java.awt.Container
             |
            +--javax.swing.JComponent
                  +--javax.swing.JSplitPane
 JSplitPane提供可拆分窗口,支持水平拆分和垂直拆分并带有滑动条。常用方法有:
  addImpl(Component comp,Object constraints,int index)//增加指定的组件
  setTopComponent(Component comp) //设置顶部的组件
  setDividerSize(int newSize) //设置拆分的大小
  setUI(SplitPaneUI ui) //设置外观和感觉
7.2.3.6 选项板(JTabbedPane)]
  JTabbedPane提供一组可供用户选择的带有标签或图标的开关键。常用方法:
  add(String title,Component component) //增加一个带特定标签的组件
o \{ y0S5^6|*n  addChangeListener(ChangeListener l) //选项板注册一个变化监听器
7.2.3.7 工具栏(JToolBar)
                工具栏在左上角
    
               工具栏在右侧
 JtoolBar是用于显示常用工具控件的容器。用户可以拖拽出一个独立的可显示工具控件的窗口。
  常用方法有:
       getComponentIndex(Component c) //返回一个组件的序号
       getComponentAtIndex(int i) //得到一个指定序号的组件
7.2.3.8 内部框架(JInternalFrame)
 内部框架JInternalFrame就如同一个窗口在另一个窗口内部,其特点如下:
 1) 必须把内部框架添加到一个容器中(通常为JDesktopPane),否则不显示;
& 2) 不必调用show()或setVisible()方法,内部框架随所在的容器一起显示;
 3) 必须用setSize()或pack()或setBounds方法设置框架尺寸,否则尺寸为零,框架不能显示;
 4) 可以用setLocation()或setBounds( ) 方法设置内部框架在容器中的位置,缺省值为0,0,即容器的左上角;
 5) 象顶层JFrame一样,对内部框架添加组件也要加在它的内容面板上;
 6) 在内部框架中建立对话框,不能使用JDialog作为顶层窗口,必须用JOptionPane或JInternalF
 7) 内部框架不能监听窗口事件,可以通过监听与窗口事件类似的内部框架(JInternalFrameEvent)处理内部框架窗口的操作。
 JFrame frame=new JFrame("InternalFrameDemo"); //实例化窗口
  JDesktopPane desktop=new JDesktopPane(); //实例化容器JDesktopPane
  MyInternalFrame myframe=new MyInternalFrame(); //实例化内部窗口
  desktop.add(myframe); //把内部窗口添加到容器中
 myframe.setSelected(true); //内部面板是可选择的
 frame.setContentPane(desktop); //把desktop设为frame的内容面板
7.2.3.9 按钮(JButton)
  按钮是一个常用组件,按钮可以带标签或图象。     
  java.lang.Object
     +--java.awt.Component
        |
        +--java.awt.Container
             |
           +--javax.swing.JComponent
                   +--javax.swing.AbstractButton
                        +--javax.swing.JButton
  常用的构造方法有:
  JButton(Icon icon) //按钮上显示图标
  JButton(String text) //按钮上显示字符
 JButton(String text, Icon icon) //按钮上既显示图标又显示字符
例7.2
  public class ButtonDemo extends Jpanel implements ActionListener{
   JButton b1,b2,b3;
    public ButtonDemo() {
      super();
       ImageIcon leftButtonIcon=new ImageIcon("images/right.gif);
                   //显示在左按钮上的图标
      ImageIcon middleButtonIcon=new ImageIcon("images/middle.gif);
                    //显示在中间按钮上的图标
       ImageIcon middleButtonIcon=new ImageIcon("images/left.gif);
                    //显示在右按钮上的图标
       b1=new JButton("Disable middle button",leftButtonIcon);
                   //按钮b1上同时显示文字和图标
      b1.setVerticalTextPosition(AbstractButton.CENTER);
              //按钮b1上的文字在垂直方向上是居中对齐JAVA中文站社区
       b1.setHorizontalTextPosition(AbstractButton.LEFT);
           //按钮b1上的文字在水平居方向上是居左对齐
       b1.setMnemonic('d');  //设置按钮b1的替代的键盘
       b1.setActionCommand("diaable");
复选框提供简单的"on/off"开关,旁边显示文本标签。
7.2.3.11 单选框(JRadioButto
单选框JRadioButton与AWT中的复选框组功能类似。
7.2.3.12 选择框(JComboBox)
JComboBox每次只能选择其中的一项,但是可编辑每项的内容,而且每项的内容可以是任意类,而不再局限于String。如图
7.2.3.13 文件选择器(JFileChooser)
JFileChooser内建有"打开","存储"两种对话框,还可以自己定义其他种类的对话框。
7.2.3.14 标签(JLabel)
提供可带图形的标签&
7.2.3.15 列表(List)
适用于数量较多的选项以列表形式显示,里面的项目可以由任意类型对象构成。支持单选和多选。如图
7.2.3.16 菜单(JMenu)
JMenu与AWT的菜单Menu的不同之处是它可以通过setJMenuBar(menubar)将菜单放置到容器中的任意地方
7.2.3.17 进程条(JProgressBar)
进程条是提供一个直观的图形化的进度描述,从"空"到"满"的过程。
7.2.3.18 滑动条(JSlider)
滑动条使得用户能够通过一个滑块的来回移动来输入数据。如
liujinpan75
浏览: 671716 次
来自: 上海
去掉 UUID字符串中的“-” 直接replaceAll(&q ...
Thinking inJava我读着好像说要建立基类对象啊!请 ...
getFullYear
我觉得楼上的synchronized(this),notify ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'

我要回帖

更多关于 java swing图形界面 的文章

 

随机推荐