精灵跳跃练习

1 import java.awt.Color;
2  import java.awt.Dimension;
3 import java.awt.Graphics;
4 import java.awt.event.KeyEvent;
5 import java.awt.event.KeyListener;
6
7 import javax.swing.JFrame;
8 import javax.swing.JPanel;
9 /**
10 * 游戏人物的跳跃练习
11 * @author tiger
12 */
13 public class Screen extends JPanel implements Runnable, KeyListener{
14
15 private static final long serialVersionUID = 1L;
16
17 public static int width = 500;
18 public static int height = 400;
19
20 public static Map map;
21 public static Player player;
22
23
24 public Screen() {
25 map = new Map();
26 player = new Player();
27 player.x = width / 2;
28 player.y = height / 2;
29 this.setPreferredSize(new Dimension(width, height));
30 this.addKeyListener(this);
31 this.setFocusable(true);
32 new Thread(this).start();
33 }
34
35 @Override
36 public void paint(Graphics g) {
37 super.paint(g);
38
39 g.setColor(Color.white);
40 g.fillRect(0, 0, width, height);
41
42 map.draw(g);
43 player.draw(g);
44 }
45
46
47 /**
48 * @param args
49 */
50 public static void main(String[] args) {
51 JFrame frame = new JFrame("act tiger");
52 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
53 frame.add(new Screen());
54 frame.pack();
55 frame.setLocationRelativeTo(null);
56 frame.setVisible(true);
57 }
58
59 public static final int FPS = 20;
60 public static final int FPC = 1000/FPS;
61
62
63 private boolean LEFT = false;
64 private boolean RIGHT = false;
65 private boolean UP = false;
66
67 @Override
68 public void run() {
69 while(true)
70 {
71 try {
72 long time1 = System.currentTimeMillis();
73
74
75 // 改变方向
76 if (LEFT) {
77 player.left();
78 } else if (RIGHT) {
79 player.right();
80 }
81 if (UP) {
82 player.jump();
83 }
84 player.update();
85
86 map.update(player);
87 this.repaint();
88 long time2 = System.currentTimeMillis();
89
90 long sleepTime = Math.max(20, FPC - (time2 - time1)) ;
91 Thread.sleep(sleepTime);
92 } catch (Exception e) {
93 e.printStackTrace();
94 }
95 }
96 }
97
98
99
100 @Override
101 public void keyPressed(KeyEvent e) {
102 int key = e.getKeyCode();
103 switch(key)
104 {
105 case KeyEvent.VK_LEFT:
106 LEFT = true;
107 break;
108 case KeyEvent.VK_RIGHT:
109 RIGHT = true;
110 break;
111 case KeyEvent.VK_UP:
112
113 //只有新按键后,才触发跳跃。
114 //j2se按下键后,会不断的触发按键事件一直到松开按键,即不断的调用到本方法,所以才要这样处理。j2me应该不需要。
115 if(isNewUpEvent == true)
116 {
117 isNewUpEvent = false;
118 UP = true;
119 player.isJump = false; //使得在人物的jump()方法中不受isJump的限制。
120 }
121 break;
122 }
123 }
124
125 private boolean isNewUpEvent = true;
126
127 @Override
128 public void keyReleased(KeyEvent e) {
129 int key = e.getKeyCode();
130 switch(key)
131 {
132 case KeyEvent.VK_LEFT:
133 LEFT = false;
134 break;
135 case KeyEvent.VK_RIGHT:
136 RIGHT = false;
137 break;
138 case KeyEvent.VK_UP:
139 UP = false;
140 isNewUpEvent = true;
141 break;
142 }
143 }
144
145 @Override
146 public void keyTyped(KeyEvent e) {
147
148 }
149 }
150
151
152
153 import java.awt.Color;
154 import java.awt.Graphics;
155
156 public class Player {
157
158 public double x;
159 public double y;
160
161 private int head_size = 8;
162 private int neck_length = 6;
163 private int body_size = 10;
164 private int leg_length = 4;
165
166 public boolean isJump = false; //用来支持连续跳跃
167
168 /**
169 * x,y 为脖子底部坐标
170 */
171 public void draw(Graphics g) {
172
173 int x = (int) (this.x - Screen.map.offsetX);
174 int y = (int) (this.y - Screen.map.offsetY);
175
176 g.setColor(Color.green);
177
178 //draw head
179 g.fillArc(x - head_size / 2, y - neck_length - head_size, head_size, head_size, 0, 360);
180 //draw neck
181 g.drawLine(x, y, x, y - neck_length);
182 //draw body
183 g.fillRect(x - body_size / 2, y, body_size, body_size);
184 //draw leg
185 g.drawLine(x - 5, y + body_size, x - 7, y + body_size + leg_length);
186 g.drawLine(x + 5, y + body_size, x + 7, y + body_size + leg_length);
187
188 //draw test
189 g.setColor(Color.red);
190 g.drawLine(x, y, x + 6, y);
191 }
192
193 /**变化速度*/
194 private double vx, vy;
195
196 /**y轴加速度*/
197 private double y_jiasudu = 0.6;
198
199 private int x_speed = 6;
200 private int y_speed = 8;
201
202 private int jump_counter = 0; //当前连续跳了几次
203 private int jump_max = 3; //连续跳跃最多次数
204
205 public void left()
206 {
207 vx -= x_speed;
208 }
209 public void right()
210 {
211 vx += x_speed;
212 }
213
214 public void jump()
215 {
216 if(isJump || jump_counter >= jump_max)
217 {
218 return;
219 }
220 isJump = true;
221 vy = -y_speed;
222 jump_counter ++;
223 }
224
225 public void update()
226 {
227 x += vx;
228 vx = 0;
229 vy += y_jiasudu;
230 y += vy;
231
232 if(this.isTopCollision()) //头碰到了砖块
233 {
234 vy = 0;
235 }
236 if(this.isBottomCollision()) //脚碰到了砖块
237 {
238 vy = 0;
239 isJump = false;
240 this.y = (((int)y + body_size + leg_length) / Map.tile_size) * Map.tile_size - (body_size + leg_length);
241 jump_counter = 0;
242 return;
243 }
244
245 }
246
247
248 private double getTopY() {
249 return y - neck_length - head_size;
250 }
251
252 private double getBottomY()
253 {
254 return y + body_size + leg_length;
255 }
256
257
258 /**
259 * 是否头部撞到砖块
260 * @return
261 */
262 public boolean isTopCollision()
263 {
264 return this.isCollisionTile(x - head_size / 2, getTopY())
265 || this.isCollisionTile(x + head_size / 2, getTopY());
266 }
267
268 /**
269 * 是否脚底撞到砖块
270 * @return
271 */
272 public boolean isBottomCollision()
273 {
274 return this.isCollisionTile(x - 7, getBottomY())
275 || this.isCollisionTile(x + 7, getBottomY());
276 }
277
278 /**
279 * 判断某坐标处是否有砖块
280 * @param x
281 * @param y
282 * @return
283 */
284 public boolean isCollisionTile(double x, double y)
285 {
286 int row = (int) (y / Map.tile_size);
287 int column = (int) (x / Map.tile_size);
288 return Screen.map.isTile(row, column);
289
290 }
291 }

1 import java.awt.Color;
2 import java.awt.Graphics;
3
4
5 public class Map {
6
7 public static int tile_size = 25;
8
9 public int offsetX = 0;
10 public int offsetY = 0;
11
12 /**
13 * 地图数据。为0表示活动空间,为1表示阻挡活动的砖块。
14 */
15 public int[][] data = {
16 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
17 {1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
18 {1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1},
19 {1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1},
20 {1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1},
21 {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
22 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1},
23 {1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
24 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
25 {1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1},
26 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
27 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1},
28 {1,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
29 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
30 {1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1},
31 {1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1},
32 {1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1},
33 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
34 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
35 };
36
37 /**
38 * 判断某处是否砖块
39 * @param row
40 * @param column
41 * @return
42 */
43 public boolean isTile(int row, int column)
44 {
45 if(row >= data.length || column >= data[row].length )
46 {
47 return false;
48 }
49 return data[row][column] == 1;
50 }
51
52
53 public int getMapWidth()
54 {
55 return data[0].length * tile_size;
56 }
57
58 public int getMapHeight()
59 {
60 return data.length * tile_size;
61 }
62
63 public void draw(Graphics g)
64 {
65 int row = offsetY / tile_size;
66 int column = offsetX / tile_size;
67 for (int i = row; i < data.length; i++) {
68 for (int j = column; j < data[i].length; j++) {
69 if(data[i][j] == 1)
70 {
71 g.setColor(Color.black);
72 g.fillRect(j * tile_size - offsetX, i * tile_size - offsetY, tile_size, tile_size);
73 }
74 }
75
76 }
77 }
78
79 // public void left(int distance)
80 // {
81 // if(this.getMapWidth() <= Screen.width)
82 // {
83 // return;
84 // }
85 // offsetX -= distance;
86 // checkOffsetX();
87 // }
88 //
89 // public void right(int distance)
90 // {
91 // if(this.getMapWidth() <= Screen.width)
92 // {
93 // return;
94 // }
95 //
96 // offsetX += distance;
97 // checkOffsetX();
98 // }
99 //
100 // public void up(int distance)
101 // {
102 // if(this.getMapHeight() <= Screen.height)
103 // {
104 // return;
105 // }
106 // offsetY -= distance;
107 // checkOffsetY();
108 // }
109 //
110 // public void down(int distance)
111 // {
112 // if(this.getMapHeight() <= Screen.height)
113 // {
114 // return;
115 // }
116 // checkOffsetY();
117 // }
118 //
119
120 public void update(Player player)
121 {
122 this.offsetX = (int) (player.x - Screen.width / 2);
123 this.offsetY = (int) (player.y - Screen.height / 2);
124 checkOffsetX();
125 checkOffsetY();
126 }
127
128 public void checkOffsetX()
129 {
130 if(offsetX > this.getMapWidth() - Screen.width)
131 {
132 offsetX = this.getMapWidth() - Screen.width;
133 }
134 if(offsetX < 0)
135 {
136 offsetX = 0;
137 }
138 }
139
140 public void checkOffsetY()
141 {
142 if(offsetY > this.getMapHeight() - Screen.height)
143 {
144 offsetY = this.getMapHeight() - Screen.height;
145 }
146 if(offsetY < 0)
147 {
148 offsetY = 0;
149 }
150 }
151 }

posted on 2011-06-20 11:48 千山万水_ 阅读(...) 评论(...) 编辑 收藏

导航

公告