Skip to content Skip to footer

绘制山脉

最近在绘制山脉,先来看看效果:

虽然不是很好看,但至少从远方望去,山脉的那种感觉出来了,下面来看看是怎么做的:

绘制画图板很简单,这里就不多作叙述了。我们直接来看看山脉是怎么画的。

首先,我们需要确定一条长直线的起点和终点坐标,然后取这条直线的中点坐标,横坐标直接起点和终点的横坐标相加再除以二即可。至于纵坐标,为了实现山脉的效果,我们需要先确定某个值,然后以这个值为中心确定一个范围,纵坐标应该在这个范围内随机取值。然后,再分别取起点和这一点的中点以及这一点和终点的中点,再分别用递归来完成。

然后要注意,这个范围每次递归的时候都要按照一定的比例减小。

等到递归结束的时候,再画直线,同时填充颜色。这样一来,绘制山脉的方法基本思路就确定了。

下面是绘制山脉的方法:

1 public void drawMountains(int x1,int y1,int x2,int y2,double k,int times,Graphics g,Color c){

2 Random rand = new Random();

3 int range=0;

4 if(times > 0){

5 range = (int)((rand.nextInt(400)-200)*k); //纵坐标取值的范围

6 k*=0.5; //缩小的比例

7 int middleX = (x1+x2)/2; //中点横坐标

8 int middleY = (y1+y2)/2 + range; //中点纵坐标

9 drawMountains(x1,y1,middleX,middleY,k,times-1,g,c); //这里开始就是递归

10 drawMountains(middleX,middleY,x2,y2,k,times-1,g,c);

11 }else{

12 g.drawLine(x1,y1,x2,y2); //递归结束,画直线

13 g.setColor(c); //同时设置颜色

14 Polygon p1 = new Polygon(); //使用这个类来填充颜色

15 p1.addPoint(x1, 800);

16 p1.addPoint(x1, y1);

17 p1.addPoint(x2, y2);

18 p1.addPoint(x2, 800);

19 Graphics2D g2 = (Graphics2D)g;

20 g2.fillPolygon(p1);

21 }

22 }

至于天空的颜色,我们可以在绘制画图板的时候就设置背景颜色。

下面来看完整代码:

Board.java:

1 package Practice;

2

3 import java.awt.Graphics;

4 import javax.swing.JFrame;

5

6 public class Board extends JFrame{

7 public void paint(Graphics g){

8 super.paint(g);

9 }

10 }

Mountains.java:

1 package Practice;

2

3 import java.awt.Color;

4 import java.awt.Graphics;

5 import java.awt.Graphics2D;

6 import java.awt.Polygon;

7 import java.util.Random;

8 import javax.swing.JFrame;

9

10 public class Mountains{

11

12 public static void main(String[] args) {

13 Mountains m = new Mountains();

14 m.show();

15 }

16

17 public void show(){

18 Board board = new Board();

19 board.setTitle("绘制山脉");

20 board.setSize(1200,800);

21 board.setLocationRelativeTo(null);

22 board.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

23 board.setVisible(true);

24 try {

25 Thread.sleep(100); //画图板也是绘制的,这里是为了等画图板全部绘制完成后再画山脉

26 } catch (InterruptedException e) {

27 // TODO Auto-generated catch block

28 e.printStackTrace();

29 }

30 Graphics g = board.getGraphics();

31 Color c1 = new Color(12,62,88);

32 Color c2 = new Color(14,70,101);

33 Color c3 = new Color(7,38,54);

34 g.setColor(new Color(109,191,235));

35 g.fillRect(0, 0, 1200, 800);

36 g.drawArc(100,40,90,50,0,180); //这里画个太阳

37 g.setColor(Color.yellow); g.fillArc(100,100,40,40,0,-360);

38 drawMountains(0, 580, 1200, 580, 2,10,g,c3);

39 drawMountains(0, 580, 1200, 580, 2,10,g,c2);

40 drawMountains(0, 580, 1200, 580, 2,10,g,c1);

41 }

42

43 public void drawMountains(int x1,int y1,int x2,int y2,double k,int times,Graphics g,Color c){

44 Random rand = new Random();

45 int range=0;

46 if(times > 0){

47 range = (int)((rand.nextInt(400)-200)*k); //纵坐标取值的范围

48 k*=0.5; //缩小的比例

49 int middleX = (x1+x2)/2; //中点横坐标

50 int middleY = (y1+y2)/2 + range; //中点纵坐标

51 drawMountains(x1,y1,middleX,middleY,k,times-1,g,c); //这里开始就是递归

52 drawMountains(middleX,middleY,x2,y2,k,times-1,g,c);

53 }else{

54 g.drawLine(x1,y1,x2,y2); //递归结束,画直线

55 g.setColor(c); //同时设置颜色

56 Polygon p1 = new Polygon(); //使用这个类来填充颜色

57 p1.addPoint(x1, 800);

58 p1.addPoint(x1, y1);

59 p1.addPoint(x2, y2);

60 p1.addPoint(x2, 800);

61 Graphics2D g2 = (Graphics2D)g;

62 g2.fillPolygon(p1);

63 }

64 }

65 }

这样就可以啦!

关于遇到的Bug:

首先,就是范围缩小的问题,特别注意这里k值一定要是double型!一开始我定义的k是整型的,但是这样一来,每次k×0.5的话,取整就变成0了,这样一来画出来不是山脉的效果,而是一条直线。

其次,是关于颜色的问题。因为这里在show方法里面调用了三次绘制山脉的方法,因此画出来有三条山脉,这里没有问题,但是天空的颜色,我刚开始是想画山脉的时候顺便就把天空颜色给画了。这样的话绘制山脉的方法里面我又添加了一个Color类型的参数,代表画天空的颜色。在画山脉颜色的时候,同时也利用Polygon这个类把山脉上方填充为天空的天蓝色。但是,因为有三座山,高度又是随机取值,一旦有一座山在横坐标相同情况下纵坐标取值比另一座山低,那么它的上面就会被填充成天蓝色,这样一来,上面那座山脉的颜色就被覆盖了,所以画出来只有一座山。然鹅解决方法很简单,只需要在最开始给整个绘图板画上天蓝色即可。

最后是一个不怎么算bug的bug,就是range取值,不要太大了。-400到400的范围就很好。

Copyright © 2088 天剑神弩网络游戏活动平台 All Rights Reserved.
友情链接