引言
开挂
每个人或多或少的都玩过游戏,有些人天生是打游戏的料,而有些人则是手残。于是想着当个程序员,开发一款属于自己的游戏,不高兴了就随意修改游戏的属性,反正你说了算!任性!
理想与现实的距离
理想:局局吃鸡MVP
现实:落地成盒MMP
你自己写游戏也是这样,一上手就想写个某农药的小游戏是不可能滴,不如先写个贪吃蛇?连连看?亦或是俄罗斯方块!反正就是最基本的贴图游戏。
正文
编贴图游戏的基本步骤:
概念:所谓贴图游戏也就是把图片一张一张画到窗体中(包括背景、敌人、障碍物)
绘制的时候要用到双缓冲技术,首先创建一张缓冲图片,然后将游戏所需要绘制的图片全部画到缓冲图片中,最后将缓冲图片画到窗体。
目的是为了避免图片闪烁,因为这样每次都是将一张完整的图片绘制到窗体,如果将背景、敌人、障碍物等元素逐一绘制到窗体的话,由于不同元素绘制不是同时的(有先后顺序),所以会产生图片闪烁的现象。
小例子
1. import java.awt.Color;
2. import java.awt.Graphics;
3. import java.awt.image.BufferedImage;
4. import javax.swing.JFrame;
5.
6. public class BaseFrame extends JFrame {
7.
8. /**
9. * 构造函数
10. */
11. public BaseFrame() {
12. this.setBounds(100, 100, 500, 500); // 设置窗体的位置、大小
13. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置窗体右上角那个叉关闭程序
14. this.setVisible(true); // 设置窗体可见
15. }
16.
17. /**
18. * 绘制方法
19. */
20. public void paint(Graphics gr) {
21. BufferedImage image = new BufferedImage(500, 500,
22. BufferedImage.TYPE_3BYTE_BGR); // 创建一张500*500的缓冲图片
23. Graphics g2 = image.getGraphics(); // 获取缓冲图片的画笔
24.
25. /*
26. *
27. * 这里面就可以画东西了,而且时候到image缓冲图片上,想画什么查阅java API里的Graphics 例如
28. * g2.drawRect(50, 50, 100, 100);
29. */
30.
31. g2.setColor(Color.WHITE); // 设置画笔颜色
32. g2.drawRect(50, 50, 100, 100);
33. g2.fillRect(200, 200, 100, 100);
34.
35. gr.drawImage(image, 0, 0, this); // 将缓冲图片画到窗体上
36. }
37.
38. public static void main(String[] args) {
39. new BaseFrame();
40. }
41.
42. }
编写游戏的基本架构:
创建一个窗体,绘制一张缓冲图片到窗体,而且获取到了缓冲图片的画笔,这样你就可以用画笔画你需要的形状或是图片了。如果想让绘制的东西动起来,可以通过加入线程来实现,改变绘制物体的坐标,最重要一点不要忘记repaint。
1. import java.awt.Color;
2. import java.awt.Graphics;
3. import java.awt.image.BufferedImage;
4.
5. import javax.swing.JFrame;
6.
7. public class BaseFrame extends JFrame implements Runnable {
8.
9. /**
10. * 绘制方块x坐标
11. */
12. private int x = 30;
13.
14. /**
15. * 绘制方块y坐标
16. */
17. private int y = 30;
18.
19. /**
20. * 构造函数
21. */
22. public BaseFrame() {
23. this.setBounds(100, 100, 500, 500); // 设置窗体的位置、大小
24. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置窗体右上角那个叉关闭程序
25. this.setVisible(true); // 设置窗体可见
26.
27. Thread thread = new Thread(this); //创建线程
28. thread.start(); //启动线程
29. }
30.
31. /**
32. * 绘制方法
33. */
34. public void paint(Graphics gr) {
35. BufferedImage image = new BufferedImage(500, 500,
36. BufferedImage.TYPE_3BYTE_BGR); // 创建一张500*500的缓冲图片
37. Graphics g2 = image.getGraphics(); // 获取缓冲图片的画笔
38.
39. /*
40. *
41. * 这里面就可以画东西了,而且时候到image缓冲图片上,想画什么查阅java API里的Graphics 例如
42. * g2.drawRect(50, 50, 100, 100);
43. */
44.
45. g2.setColor(Color.WHITE); // 设置画笔颜色
46. g2.fillRect(x, y, 100, 100);
47.
48. gr.drawImage(image, 0, 0, this); // 将缓冲图片画到窗体上
49. }
50.
51. /**
52. * 线程执行方法
53. */
54. public void run() {
55. try {
56. while (true) {
57. x++;
58. y++;
59. if (x > 400 || y > 400) {
60. x = 0;
61. y = 0;
62. }
63. this.repaint();
64. Thread.sleep(50); //while(true)的循环里一点要记得sleep一会,要不然太可怕了。。。
65. }
66. } catch (InterruptedException e) {
67. e.printStackTrace();
68. }
69. }
70.
71. public static void main(String[] args) {
72. new BaseFrame();
73. }
74.
75. }
实现了让图片动起来,但是这顶多算是一个动画,因为没有交互性,游戏是人来玩的嘛,这个可以通过加入事件来完成,下面加入一个键盘事件:
1. import java.awt.Color;
2. import java.awt.Graphics;
3. import java.awt.event.KeyEvent;
4. import java.awt.event.KeyListener;
5. import java.awt.image.BufferedImage;
6.
7. import javax.swing.JFrame;
8.
9. public class BaseFrame extends JFrame implements Runnable, KeyListener {
10.
11. /**
12. * 绘制方块x坐标
13. */
14. private int x = 200;
15.
16. /**
17. * 绘制方块y坐标
18. */
19. private int y = 200;
20.
21. /**
22. * 构造函数
23. */
24. public BaseFrame() {
25. this.setBounds(100, 100, 500, 500); // 设置窗体的位置、大小
26. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置窗体右上角那个叉关闭程序
27. this.setVisible(true); // 设置窗体可见
28.
29. this.addKeyListener(this); // 添加键盘监听器
30.
31. Thread thread = new Thread(this); // 创建线程
32. thread.start(); // 启动线程
33. }
34.
35. /**
36. * 绘制方法
37. */
38. public void paint(Graphics gr) {
39. BufferedImage image = new BufferedImage(500, 500,
40. BufferedImage.TYPE_3BYTE_BGR); // 创建一张500*500的缓冲图片
41. Graphics g2 = image.getGraphics(); // 获取缓冲图片的画笔
42.
43. g2.setColor(Color.WHITE); // 设置画笔颜色
44. g2.fillRect(x, y, 100, 100);
45.
46. gr.drawImage(image, 0, 0, this); // 将缓冲图片画到窗体上
47. }
48.
49. /**
50. * 线程执行方法
51. */
52. public void run() {
53. try {
54. while (true) {
55. this.repaint();
56. Thread.sleep(50);
57. }
58. } catch (InterruptedException e) {
59. e.printStackTrace();
60. }
61. }
62.
63. /**
64. * 按下时调用
65. */
66. public void keyPressed(KeyEvent e) {
67. int keyCode = e.getKeyCode();
68. // System.out.println(keyCode); // 打印按键的keyCode
69. if (keyCode == 38) { // 上按键
70. y--;
71. }
72. if (keyCode == 40) { // 下按键
73. y++;
74. }
75. if (keyCode == 37) { // 左按键
76. x--;
77. }
78. if (keyCode == 39) { // 右按键
79. x++;
80. }
81. }
82.
83. /**
84. * 释放按键时调用
85. */
86. public void keyReleased(KeyEvent e) {
87.
88. }
89. public void keyTyped(KeyEvent e) {
90.
91. }
92.
93. public static void main(String[] args) {
94. new BaseFrame();
95. }
96.
97. }
现在这个程序可以用上下左右按键控制方块移动了,运用这些知识基本可以搞定贪吃蛇、俄罗斯方块了。
学习是个逐步递进的过程,祝你成功。
ps:本人开通了个人的微信公众号,希望大家能关注一下,
我会将资源、文章优先推送到公众号上。
推送自己的一些学习笔记,实验源代码等,
欢迎大家互相交流学习。