1.技能点
- 循环,分支
- 方法的抽取
- 数组的使用
- 面向对象
- 继承,子类方法的重写
- 接口,接口的实现
2.游戏图形化界面编程
GUI图形化界面编程(GUI技术不流行了)
GUI中的组件:
- 窗口
- 弹窗
- 面板
- 文本框
- 列表框
- 按钮
- 图片
- 交互事件:监听事件(鼠标事件,键盘事件)
3.小蛇移动原理图
4.制作流程
-
把所需要的图片封装
package com.msb.game; import javax.swing.*; import java.net.URL; //获取图片 public class Images { //封装图片 public static URL bodyURL=Images.class.getResource("/images/身体.png"); public static ImageIcon bodyimg=new ImageIcon(bodyURL); public static URL downURL=Images.class.getResource("/images/头下.png"); public static ImageIcon downimg=new ImageIcon(downURL); public static URL foodURL=Images.class.getResource("/images/圆点.png"); public static ImageIcon foodimg=new ImageIcon(foodURL); public static URL leftURL=Images.class.getResource("/images/头左.png"); public static ImageIcon leftimg=new ImageIcon(leftURL); public static URL rightURL=Images.class.getResource("/images/头右.png"); public static ImageIcon rightimg=new ImageIcon(rightURL); public static URL upURL=Images.class.getResource("/images/头上.png"); public static ImageIcon upimg=new ImageIcon(upURL); public static URL headerURL=Images.class.getResource("/images/头部.png"); public static ImageIcon headerimg=new ImageIcon(headerURL); }
-
创建窗体、面板
package com.msb.game; import javax.swing.*; import java.awt.*; public class StartG { public static void main(String[] args) { //创建窗体 JFrame jf=new JFrame(); //给窗体设置标题 jf.setTitle("小游戏啊,不值一提!"); //获取屏幕大小 int width= Toolkit.getDefaultToolkit().getScreenSize().width; int height= Toolkit.getDefaultToolkit().getScreenSize().height; //设置窗口弹出位置坐标,对应窗口的大小 jf.setBounds((width-800)/2,(height-750)/2,800,700); //设置窗口大小不可调节 jf.setResizable(false); //关闭窗口时,程序关闭 jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //创建面板 GPanel g=new GPanel(); //将面板放入窗体 jf.add(g); //默认窗口隐藏,将窗体显现 jf.setVisible(true); } }
-
静态小蛇 → 小蛇的头按照行走的方向改变 → 加入监听器控制游戏开始、暂停、小蛇的移动 → 小蛇吃食物 ,蛇身加长 → 吃食物加积分 → 游戏结束的判定
package com.msb.game; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; //创建面板 public class GPanel extends JPanel { //蛇的长度 int length; //定义两个数组 //存x坐标 int snakex[]=new int[200]; int snakey[]=new int[200]; //游戏的开始与暂停 boolean isStart=false;//默认暂停 //加入定时器 Timer timer; //蛇的行走方向 String direction; //定义食物坐标 int foodx; int foody; //定义一个积分 int score; //死亡判定 boolean isdie=false; public void init(){ //初始化蛇的长度为3 length=3; //初始化蛇头坐标 snakex[0]=175; snakey[0]=275; //初始化第一节身子坐标 snakex[1]=150; snakey[1]=275; //初始化第二节身子坐标 snakex[2]=125; snakey[2]=275; //初始化蛇头的方向 direction="R"; //初始化食物坐标 foodx=300; foody=200; //积分初始化为0 score=0; } public GPanel(){ init(); //把焦点定位在游戏窗口上 this.setFocusable(true); //加入监听 this.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) {//监听按键的按下操作 super.keyPressed(e); int keyCode = e.getKeyCode(); System.out.println(keyCode); if (keyCode==KeyEvent.VK_SPACE){//监听空格 if (isdie){ //恢复初始状态 init(); isdie=false; }else {//没死情况 isStart=!isStart; repaint();//重绘动作 } } //监听向上箭头 if (keyCode==KeyEvent.VK_UP||keyCode==87){ direction="U"; } //监听向下箭头 if (keyCode==KeyEvent.VK_DOWN||keyCode==83){ direction="D"; } //监听向左箭头 if (keyCode==KeyEvent.VK_LEFT||keyCode==65){ direction="L"; } //监听向右箭头 if (keyCode==KeyEvent.VK_RIGHT||keyCode==68){ direction="R"; } } }); //定时器初始化 timer=new Timer(100, new ActionListener() {//ActionListener 事件监听,监听是否发生了动作 @Override public void actionPerformed(ActionEvent e) {//从蛇尾到蛇头一次向某个方向移动 if (isStart&&isdie==false){ //身子动 for (int i=length-1;i>0;i--){ snakex[i]=snakex[i-1]; snakey[i]=snakey[i-1]; } //头动 if ("R".equals(direction)){ snakex[0]+=25; } if ("L".equals(direction)){ snakex[0]-=25; } if ("U".equals(direction)){ snakey[0]-=25; } if ("D".equals(direction)){ snakey[0]+=25; } //死亡判定 for (int i=1;i<length;i++){ if (snakex[0]==snakex[i]&&snakey[0]==snakey[i]){ isdie=true; } } repaint();//重绘,刷新页面 //防止出界 if (snakex[0]>750){ snakex[0]=25; } if (snakex[0]<25){ snakex[0]=750; } if (snakey[0]>650){ snakey[0]=75; } if (snakey[0]<75){ snakey[0]=650; } //检测吃到食物 if (snakex[0]==foodx&&snakey[0]==foody){ length++; //随机产生食物 foodx=(int) (Math.random()*30+1)*25;//[25,750] foody=(int) (Math.random()*24+3)*25;//[75,650] //吃上食物,积分加10 score+=10; } } } }); //定时器启动 timer.start(); } //图形版的main方法 @Override protected void paintComponent(Graphics g) {//画笔 super.paintComponent(g); //填充背景颜色 this.setBackground(new Color(193, 241, 240)); //画头部图片,this指当前面板,g指画笔,x,y对应坐标 Images.headerimg.paintIcon(this,g,20,15); //调节画笔颜色 g.setColor(new Color(142, 237, 166)); //画一个矩形 g.fillRect(10,70,770,650); //画小蛇 //画蛇头 if ("R".equals(direction)){ Images.rightimg.paintIcon(this,g,snakex[0],snakey[0] ); } if ("L".equals(direction)){ Images.leftimg.paintIcon(this,g,snakex[0],snakey[0] ); } if ("U".equals(direction)){ Images.upimg.paintIcon(this,g,snakex[0],snakey[0] ); } if ("D".equals(direction)){ Images.downimg.paintIcon(this,g,snakex[0],snakey[0] ); } //画蛇身子 for(int i=1;i<length;i++){ Images.bodyimg.paintIcon(this,g,snakex[i],snakey[i]); } //如果游戏暂停提示 if (isStart==false){ //画文字 g.setColor(new Color(1,1,1)); //文字类型参数大小 g.setFont(new Font("微软雅黑",Font.BOLD,40)); //画文字 g.drawString("点击空格开始游戏",250,330); } //画食物 Images.foodimg.paintIcon(this,g,foodx,foody); //画积分 g.setColor(new Color(217, 137, 87)); g.setFont(new Font("微软雅黑",Font.BOLD,20)); g.drawString("积分:"+score,600,40); //画入死亡状态 if (isdie) { g.setColor(new Color(254, 0, 14)); g.setFont(new Font("微软雅黑", Font.BOLD, 20)); g.drawString("GAME OVER,按空格继续", 300, 300); } } }