一,图片
要将图片(泥巴,钢铁墙,坦克等一系列块状图形)的大小设置为30*30,最好是png的格式,透明的图片可以适应不同的背景图。
二,画布
首先,我既然把所有的对象图片都弄成30*30了,那么当我对他们进行初始化定位的时候也要是30的倍数,这样的话整个世界就清晰多了。如下图:
but,后来我发现O点的坐标不是(0,0),原因是因为上面的菜单条占了一些空间,然后我就通过调试,知道了菜单条的高度大概在58左右
gps.setColor(Color.PINK);
gps.fillRect(30, 60, WIDTH, HEIGHT);
哇,强迫症啦,所有东东必须是30的倍数,所以我决定修改菜单条的高度。
经过不断的搜索,我发现Java的菜单没有高这与属性,也没有设置高的方法,C#才有。百度碰壁,我就想去星球上提问,想到我的问题比较二,我就想把问题阐述的清晰一点,这样就不会被骂了。然后在阐述问题的时候我就对画布这一块的知识非常清晰了,自己就把问题解决了。看下面的解决思路:
先看代码,和运行结果
// 创建背景图
screanImage = this.createImage(WIDTH, HEIGHT);
// 获取能在背景图上作画的画笔
Graphics gps = screanImage.getGraphics();gps.setColor(Color.PINK);
gps.fillRect(100, 100, WIDTH, HEIGHT);
g.drawImage(screanImage, 0, 0, null);
// 创建背景图
screanImage = this.createImage(WIDTH, HEIGHT);
// 获取能在背景图上作画的画笔
Graphics gps = screanImage.getGraphics();gps.setColor(Color.PINK);
gps.fillRect(0, 0, WIDTH, HEIGHT);
g.drawImage(screanImage, 100, 100, null);
这样就会发现, 修改两个不同位置的x,y都会影响粉色背景的位置。其实g.drawImage(screanImage, 100, 100, null)设置的是画布g(我觉得这个g画布应该是调用repaint()方法自动生成的系统画布)的位置,而gps.fillRect(100, 100, WIDTH, HEIGHT)设置的是我们自己创建在g上的gps画布的位置,而gps的位置是相对g的。我们可以通过下面代码来验证:
@Override
public void update(Graphics g) {
// 创建背景图
screanImage = this.createImage(WIDTH, HEIGHT);
// 获取能在背景图上作画的画笔
Graphics gps = screanImage.getGraphics();
gps.setColor(Color.PINK);
gps.fillRect(100, 100, WIDTH, HEIGHT);
g.drawImage(screanImage, 100, 100, null);
}
经过上面的代码测试,我们就知道了画布的关系,以及定位了,所以我们就可以通过设置画布g的位置,将其下移58个像素,—g.drawImage(screanImage, 100, 100, null)— 就可以把画布gps(gps的位置是相对于g的)对其了。
但是,虽然老壳(顶部)对整齐了,最下面的坐标却有问题。大家都知道,我们的home老王都是放在最底部的,但在刚刚的图片上最底部的y坐标不是600,而是542
这又违背了我们的初心,全部以30为倍数
最终方案:
我们不移动画布g和gps的坐标,它们都放在<0,0>处,然后因为有一个菜单条在那里,所以我们的y轴的起始坐标应该是60,以后都以<0,60>为原点。
问题是小问题,但是我们在研究这一细节时,可以加强对画布这一块知识的理解。并且在解决问题时,有点山不过来,我就过去的感觉。
三,全部代码:
package cn.tedu.tankwar.game;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;
public class Client extends Frame {
// 定义游戏窗口的宽和高
public static final int WIDTH = 900, HEIGHT = 600;
// 定义顶部菜单栏
MenuBar menuBar = null;
// 定义顶部四个菜单按钮
Menu m1 = null, m2 = null, m3 = null, m4 = null;
// 定义下拉框按钮
MenuItem newGame = null, quit = null, pause = null,
goon = null, lv1 = null, lv2 = null, lv3 = null,
lv4 = null, explain = null;
//背景
Image screanImage = null;
@Override
public void update(Graphics g) {
// 创建背景图
screanImage = this.createImage(WIDTH, HEIGHT);
// 获取能在背景图上作画的画笔
Graphics gps = screanImage.getGraphics();
//先保留当前画笔颜色,再设置画笔颜色为粉色并填充,再恢复画笔原来的颜色
Color c = gps.getColor();
gps.setColor(Color.PINK);
gps.fillRect(0, 0, WIDTH, HEIGHT);
gps.setColor(c);
//画画布的这个操作必须在最后面 @@
//要先把其他东西画在画布上 @@
//再添加画布 @@
g.drawImage(screanImage, 0, 0, null);
}
public Client(){
// 创建菜单栏
menuBar = new MenuBar();//如何设置菜单栏的高度
// 创建菜单按钮
m1 = new Menu("游戏");
m2 = new Menu("暂停or继续");
m3 = new Menu("游戏难度");
m4 = new Menu("帮助");
// 给菜单设置字体样式
m1.setFont(new Font("幼圆", Font.BOLD, 15));
m2.setFont(new Font("幼圆", Font.BOLD, 15));
m3.setFont(new Font("幼圆", Font.BOLD, 15));
m4.setFont(new Font("幼圆", Font.BOLD, 15));
// 创建下拉框按钮
newGame = new MenuItem("新游戏");
quit = new MenuItem("退出");
pause = new MenuItem("暂停");
goon = new MenuItem("继续");
lv1 = new MenuItem("级别一");
lv2 = new MenuItem("级别二");
lv3 = new MenuItem("级别三");
lv4 = new MenuItem("级别四");
explain = new MenuItem("说明");
// 向菜单按钮中添加下拉框
m1.add(newGame);
m1.add(quit);
m2.add(pause);
m2.add(goon);
m3.add(lv1);
m3.add(lv2);
m3.add(lv3);
m3.add(lv4);
m4.add(explain);
// 把菜单按钮添加到菜单栏
menuBar.add(m1);
menuBar.add(m2);
menuBar.add(m3);
menuBar.add(m4);
// 把菜单栏添加到窗口对象中
this.setMenuBar(menuBar);
// 设置窗口的位置
this.setLocation(150, 80);
// 设置游戏标题
this.setTitle("坦克大战");
// 设置窗口大小
this.setSize(WIDTH, HEIGHT);
// 设置大小不可更改
this.setResizable(false);
// 添加窗口关闭监听(匿名内部类)?????
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
// 设置背景颜色
this.setBackground(Color.GREEN);
// 窗口可视
this.setVisible(true);
//repaint();??????
for (int i = 0; i < 1; ) {
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
public static void main(String[] args) {
new Client();
}
}