震惊!为何这辆坦克......
我们老师丧心病狂惨无人道.....让我们用java写出一个坦克大战游戏
现在做了一共三个函数
主函数中键盘移动有问题{:10_266:} {:10_266:}
TankGameWindow
Tank
TankWindow(主函数)
import java.awt.Color;
import java.awt.Frame;
import java.awt.event.*;
import java.awt.color.*;
import java.awt.Graphics;
public class TankGameWindow extends Frame{
Tank tank;
public void initFrame(){
this.setVisible(true);
this.setLocation(300,300);//实现坦克大战的窗口,且填充了背景颜色
this.setSize(800,500);
this.setTitle("CRAZY TANK");
this.setResizable(false);
this.setBackground(Color.green);
this.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
tank=new Tank(300,300,Color.red);
Thread t;
t=new Thread(new PaintThread());
t.start();
}
//坦克反复擦掉重画
private class PaintThread implements Runnable
{
public void run()
{
while(true)
{
repaint();
try{
Thread.sleep(50);//间隔50mm画
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public void paint(Graphics g){
tank.draw(g);
}
}
import java.awt.Color;
import java.awt.Graphics;
public class Tank {
int x,y;
byte state=1;//状态
public final int WIDTH=20;
public final int HIGHT=20;
Color tankColor;
public Tank(int ax,int ay,Color ac){
x=ax;
y=ay;
tankColor=ac;
}
//move坦克
public void move(){
state--;
if(state<1)
state=3;
}
public void draw(Graphics g){
move();
Color c=g.getColor();
drawBody(g,x,y,Color.RED);
drawTrack(state,g,x,y,Color.RED);
g.setColor(c);
}
public void drawTrack(int a,Graphics g,int x,int y,Color c){
g.setColor(c);
for(int i=a;i<=28;i=i+3)
{
g.drawLine(x-13,y-14+i,x-11,y-14+i);//画出履带上的直线
g.drawLine(x+11,y-14+i,x+13,y-14+i);
}
}
public void drawBody(Graphics g,int x,int y,Color c){
g.setColor(c);
g.drawRect(x-10,y-10,20,20);
g.drawOval(x-8,y-8,16,16);
g.drawRect(x-1,y-24,2,24);//坦克的身体
g.drawRect(x-14,y-14,4,28);
g.drawRect(x+10,y-14,4,28);
}
}
import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class TankWindow {
TankMove Movea = null;
public static void main(String args[]){
TankGameWindow window=new TankGameWindow();
window.initFrame();
Movea = new TankMove();//这里new的时候报错
}
//通过键盘控制坦克移动但无法实现
class TankMove implements KeyListener{
int x =300;
int y = 300;
Tank tank = new Tank(x,y,Color.red);
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_DOWN){
x-=3;
}else if(e.getKeyCode()== KeyEvent.VK_UP){
y-=3;
}else if(e.getKeyCode()== KeyEvent.VK_LEFT){
x-=3;
}else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
x+=3;
}
//调用repain函数,来重画界面
Tank tank = new Tank(x,y,Color.red);
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
}
......................我复制了
Movea是TankWindow的实例属性,怎么能访问到,错误提示已经说的很清楚了
还是别的错?你把错误讲清楚{:10_277:} Direction
package tank;
public enum Direction {
UP(0),
DOWN(2),
LEFT(3),
RIGHT(1);
private int value;
private Direction(int value){
this.value = value;
}
public int getValue(){
return this.value;
}
}
Point
package tank;
import java.util.Random;
public class Point {
int x;
int y;
public Point(int x, int y) {
super();
this.x = x;
this.y = y;
}
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 void rotation(Direction direction,Point center){
int h = center.getY() - y;
int w = center.getX() - x;
switch(direction){
case UP:
//向上不用变化
break;
case RIGHT:
//翻转90°
x += h + w;
y = center.getY() - w;
break;
case DOWN:
//翻转180°,x不变,y变化
//其实,这边也是不用变的,反正上下都看不出
x = center.getX() + w;
y = center.getY() + h;
break;
case LEFT:
//翻转270°
x += h + w;
y = center.getY() - w;
break;
}
}
@Override
public String toString() {
return "Point ";
}
}
Tank
package tank;
import java.awt.Color;
import java.awt.Graphics;
public class Tank {
int x,y;
byte state=1;//状态
Direction direction = Direction.UP;//默认的是向上的方向
public final int WIDTH=20;
public final int HIGHT=20;
Color tankColor;
public Direction getDirection() {
return direction;
}
public void setDirection(Direction direction) {
this.direction = direction;
}
public Tank(int ax,int ay,Color ac){
x=ax;
y=ay;
tankColor=ac;
}
//move坦克
public void move(){
state--;
if(state<1)
state=3;
}
public void draw(Graphics g){
move();
Color c=g.getColor();
drawBody(g,x,y,Color.RED);
drawTrack(state,g,x,y,Color.RED);
g.setColor(c);
}
public void drawTrack(int a,Graphics g,int x,int y,Color c){
g.setColor(c);
for(int i=a;i<=28;i=i+3)
{
drawLine(g,x-13,y-14+i,x-11,y-14+i);//画出履带上的直线
drawLine(g,x+11,y-14+i,x+13,y-14+i);
}
}
public void drawBody(Graphics g,int x,int y,Color c){
g.setColor(c);
g.drawRect(x-10,y-10,20,20);
g.drawOval(x-8,y-8,16,16);
drawRect_body(g,x-1,y-24,2,24);//坦克的身体
drawRect_left(g,x-14,y-14,4,28);
drawRect_right(g,x+10,y-14,4,28);
}
private void drawLine(Graphics g, int x1, int y1, int x2, int y2){
//绘制之前首先翻转坐标
Point p1 = new Point(x1,y1);
Point p2 = new Point(x2,y2);
p1.rotation(direction, getCenterPoint());
p2.rotation(direction, getCenterPoint());
g.drawLine(p1.getX(),p1.getY(), p2.getX(),p2.getY());
}
private void drawRect_left(Graphics g,int x, int y, int width, int height){
int temp;
switch (direction) {
case UP:
break;
case RIGHT:
temp = width;
width = height;
height = temp;
break;
case DOWN:
break;
case LEFT:
temp = width;
width = height;
height = temp;
break;
}
g.drawRect(x,y,width,height);//坦克的身体
}
private void drawRect_right(Graphics g,int x, int y, int width, int height){
int temp;
switch (direction) {
case UP:
break;
case RIGHT:
x -= 24;
y += height-width;
temp = width;
width = height;
height = temp;
break;
case DOWN:
break;
case LEFT:
x -= 24;
y += height-width;
temp = width;
width = height;
height = temp;
break;
}
g.drawRect(x,y,width,height);//坦克的身体
}
private void drawRect_body(Graphics g,int x, int y, int width, int height){
int temp;
switch (direction) {
case UP:
break;
case RIGHT:
y += height;
temp = width;
width = height;
height = temp;
break;
case DOWN:
y += height;
break;
case LEFT:
y += height;
x -= height;
temp = width;
width = height;
height = temp;
break;
}
g.drawRect(x,y,width,height);//坦克的身体
}
/**
* 返回当前tank 的中点坐标
* @return
*/
public Point getCenterPoint(){
return new Point(x, y);
}
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;
}
}
TankGameWindow
package tank;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
@SuppressWarnings("serial")
public class TankGameWindow extends Frame{
Tank tank;
public void initFrame(){
this.setVisible(true);
this.setLocation(300,300);//实现坦克大战的窗口,且填充了背景颜色
this.setSize(800,500);
this.setTitle("CRAZY TANK");
this.setResizable(false);
this.setBackground(Color.green);
this.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_DOWN){
tank.setY(tank.getY() + 3);
tank.setDirection(Direction.DOWN);
}else if(e.getKeyCode()== KeyEvent.VK_UP){
tank.setY(tank.getY() - 3);
tank.setDirection(Direction.UP);
}else if(e.getKeyCode()== KeyEvent.VK_LEFT){
tank.setX(tank.getX() - 3);
tank.setDirection(Direction.LEFT);
}else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
tank.setX(tank.getX() + 3);
tank.setDirection(Direction.RIGHT);
}
}
});
this.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
tank=new Tank(300,300,Color.red);
Thread t;
t=new Thread(new PaintThread());
t.start();
}
//坦克反复擦掉重画
private class PaintThread implements Runnable
{
public void run()
{
while(true)
{
repaint();
try{
Thread.sleep(50);//间隔50mm画
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public void paint(Graphics g){
tank.draw(g);
}
}
TankWindow
package tank;
public class TankWindow {
public static void main(String args[]){
TankGameWindow window=new TankGameWindow();
window.initFrame();
}
}
稍微修改了下,可以运行 zlj19931010 发表于 2017-3-28 09:31
......................我复制了
Movea是TankWindow的实例属性,怎么能访问到,错误提示已经说的很清楚了
...
恩.....就是这个问题,我现在修改了下,我把这个函数重新封装了下 zlj19931010 发表于 2017-3-28 09:31
......................我复制了
Movea是TankWindow的实例属性,怎么能访问到,错误提示已经说的很清楚了
...
import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class TankWindow {
public static void main(String args[]){
TankGameWindow window=new TankGameWindow();
window.initFrame();
}
}//主函数这样
import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class TankMove implements KeyListener{
int x =300;
int y = 300;
Tank tank = new Tank(x,y,Color.red);
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_DOWN){
x-=3;
}else if(e.getKeyCode()== KeyEvent.VK_UP){
y-=3;
}else if(e.getKeyCode()== KeyEvent.VK_LEFT){
x-=3;
}else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
x+=3;
}
//调用repain函数,来重画界面
Tank tank = new Tank(x,y,Color.red);
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}//新建的这个Move类
import java.awt.Color;
import java.awt.Frame;
import java.awt.event.*;
import java.awt.color.*;
import java.awt.Graphics;
public class TankGameWindow extends Frame{
Tank tank;
TankMove area;
public void initFrame(){
this.setVisible(true);
this.setLocation(300,300);//实现坦克大战的窗口,且填充了背景颜色
this.setSize(800,500);
this.setTitle("CRAZY TANK");
this.setResizable(false);
this.setBackground(Color.green);
this.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
tank=new Tank(300,300,Color.red);
Thread t;
t=new Thread(new PaintThread());
t.start();
area = new TankMove();//将move在这里调用
}
//坦克反复擦掉重画
private class PaintThread implements Runnable
{
public void run()
{
while(true)
{
repaint();
try{
Thread.sleep(50);//间隔50mm画
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public void paint(Graphics g){
tank.draw(g);
zlj19931010 发表于 2017-3-28 09:31
......................我复制了
Movea是TankWindow的实例属性,怎么能访问到,错误提示已经说的很清楚了
...
我想知道,可以按我这个思路修改吗..... 本帖最后由 zlj19931010 于 2017-3-29 10:17 编辑
求解在监听里面每次new个tank实例是为了什么 zlj19931010 发表于 2017-3-29 10:11
求解在监听里面每次new个tank实例是为了什么
public class TankGameWindow extends Frame{
Tank tank;
TankMove area;
public void initFrame(){
this.setVisible(true);
this.setLocation(300,300);//实现坦克大战的窗口,且填充了背景颜色
this.setSize(800,500);
this.setTitle("CRAZY TANK");
this.setResizable(false);
this.setBackground(Color.green);
this.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
tank=new Tank(300,300,Color.red);
Thread t;
t=new Thread(new PaintThread());
t.start();
area = new TankMove();
this.addKeyListener(area);
}
我把监听放到下面了......
public class TankMove extends JPanel implements KeyListener{
Tank tank;
int x =300;
int y = 300;
// Tank tank = new Tank(x,y,Color.red);
// public void paint(Graphics g){
// tank.draw(g);
// }
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_DOWN){
x-=3;
}else if(e.getKeyCode()== KeyEvent.VK_UP){
y-=3;
}else if(e.getKeyCode()== KeyEvent.VK_LEFT){
x-=3;
}else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
x+=3;
}
//调用repain函数,来重画界面
// Tank tank = new Tank(x,y,Color.red);
this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
move函数也改了下, 继承了Jpanel,但还是移动不了 zlj19931010 发表于 2017-3-29 10:11
求解在监听里面每次new个tank实例是为了什么
package cn.Make;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
/*
* 功能:加深对事件机制理解
* 1.通过上下左右键来控制小球移动
* 2.
*/
public class MakeBallMove extends JFrame{
Mypanel mp = null;
public static void main(String[] args) {
MakeBallMove me = new MakeBallMove();
}
//构造函数
public MakeBallMove(){
mp = new Mypanel();
//MP加入到JFram中
this.add(mp);
this.setSize(400,300);
this.setVisible(true);
this.addKeyListener(mp);
}
}
//定义自己的面板
class Mypanel extends JPanel implements KeyListener{
int x = 10;
int y = 10;
public void paint(Graphics g){
super.paint(g);
g.fillOval(x, y, 10, 10);
}
//仅仅被压下去
@Override
public void keyPressed(KeyEvent e) {
// System.out.println("啦啦啦阿拉"+(char)e.getKeyCode());
if(e.getKeyCode()==KeyEvent.VK_DOWN){
y+=3;
}else if(e.getKeyCode()== KeyEvent.VK_UP){
y-=3;
}else if(e.getKeyCode()== KeyEvent.VK_LEFT){
x-=3;
}else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
x+=3;
}
//调用repain函数,来重画界面
this.repaint();
}
//被松开
@Override
public void keyReleased(KeyEvent e) {
}
//输入具体信息
@Override
public void keyTyped(KeyEvent e) {
}
}
我是模仿这个写的让他动起来
本帖最后由 zlj19931010 于 2017-3-29 14:40 编辑
...........你这个监听的 this.repaint();是重新绘制的panel,不是你tank,你要重写Jpanel里面的paint函数,然后在paint函数里绘制tank实例
1、这段放开:
// public void paint(Graphics g){
// tank.draw(g);
// }
2、下面的x,y改成tank.x,tank.y(当然要在x,y是public属性),这里是要修改游戏中tank 的位置,不是panel的位置:
if(e.getKeyCode()==KeyEvent.VK_DOWN){
x-=3;
}else if(e.getKeyCode()== KeyEvent.VK_UP){
y-=3;
}else if(e.getKeyCode()== KeyEvent.VK_LEFT){
x-=3;
}else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
x+=3;
}
你可以看我给你的代码,可以运行的,而且坦克的朝向也会根据方向变化。。 zlj19931010 发表于 2017-3-29 14:38
...........你这个监听的 this.repaint();是重新绘制的panel,不是你tank,你要重写Jpanel里面的paint函数 ...
谢谢大佬= =我就想知道我的这个可以改成功不,因为这是老师的作业在他原有基础上改让坦克动起来...... 本帖最后由 zlj19931010 于 2017-3-29 17:45 编辑
十六是只仙 发表于 2017-3-29 16:59
谢谢大佬= =我就想知道我的这个可以改成功不,因为这是老师的作业在他原有基础上改让坦克动起来......
可以的,你把游戏中的tank实例传递到TankMove实例中
比如构造传入:
public TankMove (Tank tank){
this.tank = tank;
}
然后
public void paint(Graphics g){
tank.draw(g);
}
然后监听器里面:
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_DOWN){
tank.y += 3;
}else if(e.getKeyCode()== KeyEvent.VK_UP){
tank.y -= 3;
}else if(e.getKeyCode()== KeyEvent.VK_LEFT){
tank.x-=3;
}else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
tank.x+=3;
}
//调用repain函数,来重画界面
this.repaint();
}
逻辑这样是通的,你自己调试下,我就知道以前上学的时候碰到过一个repaint的坑,你已经开了一个线程在一直repaint,这里不知道会不会阻塞,忘记了 zlj19931010 发表于 2017-3-29 17:38
可以的,你把游戏中的tank实例传递到TankMove实例中
比如构造传入:
public TankMove (Tank tank){
感动世界!!!谢谢我总算弄出来了.....但是,想再请教一个小问题,我想加一个按钮....
public class TankGameWindow extends Frame implements ActionListener{
Tank tank;
TankMove area;
public void initFrame(){
this.setVisible(true);
this.setLocation(300,300);//实现坦克大战的窗口,且填充了背景颜色
this.setSize(800,500);
this.setTitle("CRAZY TANK");
this.setResizable(false);
this.setBackground(Color.green);
this.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
tank=new Tank(300,300,Color.red);
Thread t;
t=new Thread(new PaintThread());
t.start();
area = new TankMove(tank);
this.addKeyListener(area);
JButton jb = new JButton("变色");
jb =new JButton("变色");
jb.add(jb, BorderLayout.NORTH);
}方法应该没有弄错.....但是为什么运行出来没有按钮{:10_266:} 十六是只仙 发表于 2017-3-29 18:10
感动世界!!!谢谢我总算弄出来了.....但是,想再请教一个小问题,我想加一个按钮....
public class Ta ...
你把 jb.add(jb, BorderLayout.NORTH);
改成
this.add(jb, BorderLayout.NORTH);
this:指的是当前Frame zlj19931010 发表于 2017-3-30 09:41
你把 jb.add(jb, BorderLayout.NORTH);
改成
this.add(jb, BorderLayout.NORTH);
JButton jb = new JButton("变色");
jb =new JButton("变色");
this.add(jb, BorderLayout.NORTH);
这样改了,还是没有变化{:10_266:} 本帖最后由 zlj19931010 于 2017-3-31 13:36 编辑
十六是只仙 发表于 2017-3-30 20:21
JButton jb = new JButton("变色");
jb =new JButton("变色");
this.add(jb, BorderLayout.NORT ...
因为你开了个绘画线程,你这个按钮一直在被覆盖绘制,你把鼠标移动到最上面会闪出来button按钮
我想想怎么解决,最近开发中有点忙......
我中午研究下,有问题。。。。
你把继承的Frame改成JFrame,你需要自定义面板,应该用JFrame 我现在改了下,一个frame,上面放操作按钮toppanel
下面是游戏界面 gamepanel 过来膜拜
页:
[1]