桌面弹球游戏制作总结

1 创建游戏对象

本人在做这个游戏时,没有完全按照书上的做法来做,相反的是我根据以前做过的坦克大战游戏思路对类的具体实现及其设计做了很大的改动并纠正书上明显的错误之处,有幸的是游戏可以运行,不免小小激动了一下,但当挡板吃掉道具时还有一部分小问题,就是当吃了道具以后变长,当在吃另一个变长的道具是就没有反应,问题是由于在处理道具的时候增加了一条if判断语句,但是本人改了半天仍然没有的到完好的实现,所以就到此作罢。当然,除了书上所说

用时间控制器来控制画板的重画之外,在这里我个人又用了多线程的方法,让线程睡眠100ms绘画一次,同样实现了游戏的功能

在这个游戏中,有挡板(Stick),小球(Ball),砖块(Brick)(障碍物),道具(Magic)等物品,把这些物品都抽象成具体的类,类名见括号里的红体字,这些物品都有自己的属性,但是它们也都有公共属性:有属于自己的位置(横坐标x和纵坐标y),有图片image属性,还有运动速度speed属性。所以可以设计一个基类BallComponent包含些共有的属性和相关的方法,让其子类继承。其中道具类Magic的作用就是让挡板变长或者变短。它是一个抽象类,该类中有一个用于道具功能实现的抽象方法,供其子类LongMagic(让道具变长的道具类)和ShortMagic(让道具变短的道具类)实现

。同时游戏中还有一个画板(BallFrame),用于绘制图片,此类还负责完成界面的初始化,监听用户的键盘,而游戏的相关的业务逻辑,比如判断输赢,或者弹球的运动,挡板的运动等,都放在BallService中去处理。最后提供一个单独的类(Main),里面只有main方法,这是个人的习惯问题,当然也可以把它放在BallFrame中去

     注意,在平时的开发中,如果发现多个对象之间一些共有的特性或者行为,并且觉得可以使用这些特性或者行为构造一个对象,那么可以考虑建立一个新的对象作为这些对象的父类

 

2 编辑各个类

               BallComponent(父类)

      前面说了,这个类是Stick, Ball, Brick 和Magic的父类,拥有自己的位置坐标x,y,还有图片image,速度speed属性,所以该类的代码到目前为止暂且如下(后面还有具体的添加代码的操作)

      public class BallComponent {

//imagePath为图片文件路径

    public BallComponent(String imagePath,int x,int y) throws IOException{

//     读取图片

       this.image = ImageIO.read(new File(imagePath));

//     设置x y 坐标

       this.x = x;

       this.y = y;

      

    }

   

    //得到图片

    public Image getImage() {

       return image;

    }

   

//  得到横坐标

    public int getX() {

       return x;

    }

//  设置横坐标

    public void setX(int x) {

       this.x = x;

    }

//  得到纵坐标

    public int getY() {

       return y;

    }

//  设置纵坐标

    public void setY(int y) {

       this.y = y;

    }

//  获得运动的速度

    public int getSpeed() {

       return speed;

    }

    private Image image = null;

    private int speed = 5;

    private int x = -1;

private int y = -1;

}

 

   

 

                 弹球类(Ball)

Ball是BallComponent的子类,由于小球在运动的时候除了横竖方向上的运动,还有各个角度的斜方向,所以在此把小球的速度分解成横向速度SpeedX和竖向速度SpeedY。也就是说Ball类提供了SpeedX和SpeedY属性,此外游戏开始时,小球处于静止状态(也可以说是死亡状态),所以用一个布尔变量started来表示小球是否开始运动,初始值为false(当然在做游戏时,我沿用的坦克大战里面的思路定义的是isLife,来判断是否活着)。游戏结束后,小球也是处于静止状态,但是不能移动,同样再定义一个布尔变量stop属性来标识小球能否在移动。当然仍然为这些属性定义了相应的getter,setter方法

同时为该类提供一个构造器,所以其代码如下:

public class BallComponent {

//  public BallComponent(int panelWidth,int panelHeight,String imagePath) throws IOException {

//     this.image = ImageIO.read(new File(imagePath));//读取图片

//     //设置x坐标,在这里是把图片设置到画板中间的位置

//     this.x =(int)( panelWidth - image.getWidth(null))/2;

//  }

//  //用图片来构造一个BallComponent

//  public BallComponent(String imagePath) throws IOException{

////       读取图片

//     image = ImageIO.read(new File(imagePath));

//  }

   

    public BallComponent(String imagePath,int x,int y) throws IOException{

//     读取图片

       this.image = ImageIO.read(new File(imagePath));

//     设置x y 坐标

       this.x = x;

       this.y = y;

      

    }

   

    //得到图片

    public Image getImage() {

       return image;

    }

   

//  得到横坐标

    public int getX() {

       return x;

    }

//  设置横坐标

    public void setX(int x) {

       this.x = x;

    }

//  得到纵坐标

    public int getY() {

       return y;

    }

//  设置纵坐标

    public void setY(int y) {

       this.y = y;

    }

//  获得运动的速度

    public int getSpeed() {

       return speed;

    }

    /**

     * 获得包围图片的矩形

     * @return Rectangle 矩形

     */

    public Rectangle getRect() {

       return new Rectangle(this.getX(),this.getY(),this.getImage().getWidth(null),this.getImage().getHeight(null));

    }

    private Image image = null;

    private int speed = 5;

    private int x = -1;

    private int y = -1;

   

}

                      道具类Magic

道具类Magic是一个抽象类,它是BallComponent的子类,又是LongMagic和ShortMagic的父类,此类之提供一个方法magicDo.道具是来出来挡板Stick的,所以magicDo方法里传一个Stick 类型的参数用来完成道具的功能,使得挡板在吃了道具之后变长或者变短,变长变短的处理当然首先需要获得挡板的原有宽度preWidth,在进行处理,这也是在Stick里提供getPreWidth的原因之一。在此游戏中,道具图片随机地隐藏在砖块中,当弹球和砖块撞击时砖块消失,如果该砖块有道具,那么就在画板中画出来并且随即向下运动。

 

这个类提供了一个使用图片路径和x y坐标的参数的构造器使其子类继承,代码如下

public abstract class Magic extends BallComponent{

   /**

    * 提供子类调用的构造器

    * @param imagePath图片路径

    * @param x 横坐标

    * @param y纵坐标

    * @throws IOException

    */

     public Magic(String imagePath, int x,int y) throws IOException{

        super(imagePath,x,y);

     }

    

     /**

      * 道具的功能

      * @param stick

      *     Stick

      * @return void

      */

     public abstract void magicDo(Stick stick);

        

    

}

 

 

 

 LongMagic 代码

主要是使得挡板的宽度变成原来的二倍

public class LongMagic extends Magic{

    /**

     * 让挡板变长的道具

     * @param imagePath图片路径

     * @param x 横坐标

     * @param y 纵坐标

     * @throws IOException

     */

    public LongMagic(String imagePath, int x, int y) throws IOException{

       super(imagePath, x,y);

    }

 

    @Override

    public void magicDo(Stick stick) {

       double sticklength = stick.getImage().getWidth(null);

      

       //如果挡板没变长过

       if(stick.getPreWidth() <= sticklength)

           stick.setPreWidth((int)stick.getPreWidth()*2);

    }

   

   

}

 ShortMagic 代码

使得挡板变为原来的一半

public class ShortMagic extends Magic {

   /**

    * 让挡板变短的道具

    * @param imagePath图片路径

    * @param x 横坐标

    * @param y纵坐标

    * @throws IOException

    */

    public ShortMagic(String imagePath, int x, int y) throws IOException {

       super(imagePath, x, y);

       // TODO Auto-generated constructor stub

    }

 

    @Override

    public void magicDo(Stick stick) {

       double stickImageLength = stick.getImage().getWidth(null);

       //如果挡板没有变短过

       if(stick.getPreWidth()>=stickImageLength)

           stick.setPreWidth((int)(stick.getPreWidth()*0.5));

    }

   

   

 

}

                砖块类 Brick

Brick类是BallComponent的一个子类,在游戏中当小球和挡板碰撞时砖块就被消灭不在画板上显示,变成无效的,所以在本类中用一个布尔变量disable属性来标志对象是否有效的效果,其中还包含一个Magic类型的属性magic,

其代码如下

  public class Brick extends BallComponent{

    public Brick(String imagePath,int magicType, int x, int y) throws IOException{

       super(imagePath,x,y);

       if(magicType==MAGIC_LONG_TYPE){

       //长道具

  magic = new LongMagic("img/long.gif",x,y);

       }else if(magicType == MAGIC_SHORT_TYPE){

//短道具

           magic = new ShortMagic("img/short.gif",x,y);

       }

    }

   

    /**

     * 判断砖块是否有生命

     * @return booelean 是否有生命

     */

    public boolean isDisable() {

       return disable;

    }

   

    /**

     * 设置砖块的生命状态

     * @param isLive

     */

    public void setDisable(boolean disable) {

       this.disable = disable;

    }

   

    /**

     * 获得道具

     * @return Magic

     */

    public Magic getMagic() {

       return magic;

    }

   

    /**

     * 设置砖块要用到的道具

     * @param magic

     */

    public void setMagic(Magic magic) {

       this.magic = magic;

    }

 

    private boolean disable = false;

    private static final int MAGIC_LONG_TYPE = 1;

    private static final int MAGIC_SHORT_TYPE = 2;

    private Magic magic = null;

}

 

 

挡板类Stick

此类提供了一个以画板的宽,高,和挡板的图片路径为参数的构造器,首先调用父类的构造器,初始化位置并用javax.ImageIO.的read方法读取磁盘中的图片,然后把y坐标设置到画板的底部和中部。

     由于挡板在游戏中吃了道具(Magic)会改变,所以该类有个int类型的preWidth属性,代表挡板的长度,并提供了gettet和setter方法,并定义一个final int 类型的SPEED的属性,代表挡板移动的速度

 

public class Stick extends BallComponent {

    public Stick(int panelWidth,int panelHeight,String imagePath) throws IOException{

       super(imagePath,panelWidth,panelHeight);

//把挡板设置到画板中央

       this.setX((int)( panelWidth - this.getImage().getWidth(null))/2);

       //把挡板设置到画板底部

       this.setY(panelHeight - super.getImage().getHeight(null));//设置y坐标

//     获得挡板原本的宽度,也就是挡板图片的宽度,把挡板的宽度设置为第一次调用图片的宽度

       this.preWidth = super.getImage().getWidth(null);

      

    }

   

//  得到挡板的宽度

   public int getPreWidth() {

       return preWidth;

    }

   //设置挡板的宽度

    public void setPreWidth(int preWidth) {

       this.preWidth = preWidth;

    }

   

public static final int SPEED = 20;//设置挡板的运动速度

   private int preWidth = 0;//挡板的宽度

}

 

 

 

 

到此位置,游戏需要用到的角色(对象类)都已经全部设计完成,现在该是处理游戏功能(逻辑业务)的时候了,包括游戏的开始,游戏的结束,处理小球的运动,挡板的移动,初始化砖块和道具,判断游戏中的图片元素是否有碰撞以及把图片绘制到画板等功能,在这里单独设计一个类BallService来完成这个工作。

由于该类需要维护界面中所有的组件:小球对象,挡板对像。砖块的二维数组等下面重点将将这个工作。

根据面向对象的思维方式,既然是处理小球和挡板还有砖块的功能,该类中显然有Ball Stick 和Brick属性。这些属性在该类的构造器里进行初始化

代码如下

//  提供一个挡板

   private Stick stick = null;

//   提供一个弹球

   private Ball ball = null;

//   定义一个砖块数组

   private Brick[][] brick = null;

   private int panelWidth ;//游戏界面的宽度

private int panelHeight;//游戏界面的高度

 

注意:确定一个砖块对象以后,在界面中由于要画出许多的砖块,在这里提供一个Brick的二维数组,来表示界面中所有的砖块,二维数组的所有元素都是每个Birck对象,在画障碍物砖块的时候就可以遍历这个二维数组来进行绘制。

 

游戏中主要实现的是是否发生撞击,包括弹球和砖块的撞击,弹球和挡板的撞击,挡板和道具的撞击,为了判断是否发生撞击。在这里分别提供isHitBrick,isHitStick,和stickEatMagic三个布尔类型的方法,仔细分析一下,“弹球”撞击“砖块”,当然该方法得提供一个砖块的对象作为参数,不然撞谁去呢,所以同理isHitStick也要提供一个挡板对象作为参数,stiickEatMagic要提供一个Magic作为参数;

到这里先停一下。按照以前我做的坦克大战的游戏的思路,发生撞击时是两个图片所包围的矩形进行碰撞,所以仿照坦克大战的游戏的方法,需要”获得”所有这些对象的图片所包围的矩形Rectangle, 就需要为Ball Stick 和Brick Magic 提供一Rectangle类型的getRect()方法,很明显,因为都得发生碰撞,所以可以看出每个类里都需要这个方法,因此可以把这个方法放在这些类的父类BallComponent里面去,所以在这里在BallComponent类里添加了下面代码

/**

     * 获得包围图片的矩形

     * @return Rectangle 矩形

     */

    public Rectangle getRect() {

       return new Rectangle(this.getX(),this.getY(),this.getImage().getWidth(null),this.getImage().getHeight(null));

}

 

 

当然需要注意的是,如果球和砖块撞击,那么砖块就变得无效了,所以在处理砖块和弹球转机的同时需要判断和设置一下砖块的disable属性。因此判断撞击的方法可以写成如下所示

 

 

/**

     * 判断是否和砖块相撞,既然是和砖块相撞,必须提供砖块,所以参数里面传了一个Brick

     * @param brick 判断要撞的砖块,这里判断是否相撞,我采取了坦克大战里面的方法

     * @return 如果撞击了,返回true 否则返回false

     */

    public boolean isHitBrick(Brick brick){

//     如果砖块无效,由前面知道界面中就不会画出砖块来了,所以肯定撞不住,所以返回false

       if(brick.isDisable()){

           return false;

       }

//     判断小球是否开始运动

       if(ball.isStarted()&&ball.getRect().intersects(brick.getRect())){

//         设置砖块的生命状态为false,也就是砖块死了

           brick.setDisable(true);//如果撞击了就设置砖块为无效状态

           return true;

       }

      

       return false;

    }

    /**

     * 判断是否和格挡板相撞,同理得参数提供一个Stick

     * @param stick Stick挡板

     * @return 如果撞击了返回true否则返回false

     */

    public boolean isHitStick(Stick stick){

       if(ball.isStarted()&&ball.getRect().intersects(stick.getRect())){

           return true;

       }

      

       return false;

    }

 

    /**

     * 判断挡板是否吃了道具,同理需提供一个道具Magic

     * @param magic 道具

     * @return 如果吃了返回true 否则返回false

     */

    public boolean stickEatMagic(Magic magic){

       if(stick.getRect().intersects(magic.getRect())){

           return true;

       }

          

       return false;

    }

    注:查一下api intersects(Retangle r)方法就是判断当前的矩形和另一个矩形是否相交,如果相交说明发生了撞击

 

 

下面来设置挡板的左右移动的位置setStickPos。这个位置的处理是用键盘上的左右键来处理的。在本类中提供了一个KeyEvent ke作为此方法的参数用来监听键盘的动作。当然当挡板运动的时候还得把小球的运动状态设置为true

 Ball.setStarted(true);

同时在这里如果按下F2时需要重新开始,重新开始的处理很简单,只要重新绘制一下画板Frame即可,所以我们要为该类在提供一个BallFrame,并且在该类的构造器里初始化,然后就可以调用该类的init()方法得到开始时的画面

所以此时完成的该类构造器的操作

public BallService(int panelWidth, int panelHeight, BallFrame frame) throws IOException {

       super();

       this.panelWidth = panelWidth;

       this.panelHeight = panelHeight;

       this.frame = frame;

//     初始化挡板

       stick = new Stick(panelWidth,panelHeight,"img/stick.jpg");

//     初始化弹球

       ball = new Ball(panelWidth,panelHeight,stick.getImage().getHeight(null),"img/ball.gif");

//     初始化砖块数组

       brick = this.creatBricks("img/brick.gif", 11, 6);

       // 游戏结束图片

       gameOver = new BallComponent("img/over.gif",0,0);

       // 赢图片

       won = new BallComponent("img/win.gif",0,0);

    }

 

 

 

 

 

/**

     * 控制挡板的移动方向

     * @param ke KeyEvent

     * @return void

     * @throws IOException

     */

    public void setStickPos(KeyEvent ke) throws IOException{

       // 把弹球的运动状态设为true

       ball.setStarted(true);

//     如果是按的左键,

       if(ke.getKeyCode() == KeyEvent.VK_LEFT){

//         判断是否到达游戏界面的最左边,当二者之差大于零时说明还没有到达最左边,如果按下left建,仍然向左运动

           if(stick.getX() - Stick.SPEED >=0)

//            挡板向左运动

              stick.setX(stick.getX()-Stick.SPEED);

//         如果按的是右键

       }

      

       if(ke.getKeyCode()==KeyEvent.VK_RIGHT){

//         判断挡板是否到达游戏界面的最右边,同理如果if语句里面成立,说明还没有到达最右边,可以继续向右运动

           if(stick.getX()+ Stick.SPEED<=panelWidth)

//            挡板向右运动

              stick.setX(stick.getX()+Stick.SPEED);    

       }

//     如果按的是F2就重新开始

       if(ke.getKeyCode()==KeyEvent.VK_F2){

//         重新初始化游戏界面

           frame.init();

       }

      

      

    }

 

由于挡板吃了道具以后,它的长度会随着改变,所以需要提供一个setStickWidth的方法。来设置其宽度。

 

}

   

    /**

     * 设计挡板的宽度,注意多态性的应用

     * @param magic道具

     * @return void

     */

    public void setStickWidth(Magic magic){

////       如果挡板吃了道具

       if(this.stickEatMagic(magic)){

////          改变挡板的长度

           magic.magicDo(stick);

       }

    }

 

需要注意的是,挡板的长度是增加了,怎么在游戏的过程之中,小球可以从挡板之中穿过呢?而没有发生撞击,看了getRect()类的处理方式我知道了原因的所在。看一下getRect()的代码

public Rectangle getRect() {

       return new Rectangle(this.getX(),this.getY(),this.getImage().getWidth(null),this.getImage().getHeight(null));

    }

黑体部分是包围图片的矩形的宽度,由于getImage()得到的只是stick.gif的宽度,所以在preWidth已经改变的情况下,得到的矩形的宽度应该随之改变才对,但是其恰恰没有改变,所以我在Stick里重写了这个方法,把黑体部分改成this.getPreWidth()或者preWidth得到完美解决。

 

 

 

处理完了挡板,现在处理砖块,如下代码,注在画砖块的时候并不是每一个二维数组的元素都有砖块,。另外道具里也随机包含有道具,这一点要注意

* 创建一个数组类型为Brick的数组,用来存储砖块图片

     * @param imagePath 图片路径

     *

     * @param xSize二维数组的横向宽度

     * @param ySize二维数组的纵向宽度

     * @return Brick[][] 砖块的二维数组

     * @throws IOException

     */

    public Brick[][] creatBricks(String imagePath, int xSize,int ySize) throws IOException{

       Brick[][] bricks = new Brick[xSize][ySize];

       int x = 0;//砖块的横坐标

       int y = 0;//砖块的纵坐标

       int randomType = 0;//随机产生道具的类型

       int imageSize = 28;

        boolean isDisable = false;

       

        for(int i=0;i<xSize;i++){

        for(int j = 0;j<ySize;j++){

            randomType = (int)(Math.random()*3);//随机生成道具类型

            x = i*imageSize;//第i个砖块的横坐标位置

            y = j * imageSize;//第i个砖块的纵坐标位置

            isDisable = Math.random()>0.8? true:false;//随机为砖块产生道具说

//       如果界面数组中某一位置没有砖块,即isDisable为true没有砖块。则不提供道具,具体见运行时的结果

            if(isDisable){

                randomType = 0;//不提供道具

            }

           

            Brick brick = new Brick(imagePath,randomType,x,y);

//          随机设置砖块的是否有生命,如果没有生命则不在游戏界面上面显示,或者画出来,如果不设置会出现每一个二维数组中都有brick元素

            brick.setDisable(isDisable);

            bricks[i][j] = brick;

        }      

        }

        return bricks;

    }

 

当砖块被消灭的时候,里面如果有道具的话,道具就会下降,所以要设计一下怎么下降,只需设计一下它的纵坐标即可,在这里需要遍历砖块的二维数组,并且判断每一个元素位置的magic道具是否为空。间下面代码

    /**

     * 设置道具位置,因为道具是向下运动的,所以只需要设置道具的纵坐标即可

     *

     */

    public void setMagicPos(){

       for(int i=0;i<brick.length;i++){

           for(int j=0;j<brick[i].length;j++){

//            获得道具

              Magic magic = brick[i][j].getMagic();

//            如果道具不为空

              if(magic != null){

                  if(brick[i][j].isDisable()&&magic.getY()<panelHeight){

                     magic.setY(magic.getY()+ magic.getSpeed());

//                   //如果挡板吃了砖块

                     this.setStickWidth(magic);                   

                  }

              }

           }

       }

    }

   

 

现在来判断是否输赢,如果在小球死亡的情况下界面中只有有一个砖块,那么就没有赢,直到砖块都没有的情况下才能赢,这就需要遍历砖块数组判断每一个砖块的有效性

 

    public boolean isWon(){

       for(int i=0;i<brick.length;i++){

           for(int j=0;j<brick[i].length;j++){

              if(!brick[i][j].isDisable())//如果有一个砖块还活着,说明你没有胜利

                  return false;           

           }

       }

       return true;     

    }

 

 

下面设置小球的运动,由于小球的运动是自动了,是不受玩家控制的,在整个游戏中玩家能控制的只有挡板的作用移动,在小球运动的时候需要判断是否碰到边界,包括左边界,右边界,上边界,下边界。这都要进行相应的处理。

 

public void setBallPos(){

       int absSpeedX = Math.abs(ball.getSpeedX());

       int absSpeedY = Math.abs(ball.getSpeedY());

//     如果小球开始运动并且游戏还没有结束

       if(ball.isStarted()){

//         如果碰到左边界,即是球的横坐标小于0

           if(ball.getX()-absSpeedX<0){

//            重新设定弹球的位置,注意画图分析一下怎么设置,很有技巧

              ball.setX(ball.getImage().getWidth(null));

//            让弹球反方向弹回

              ball.setSpeedX(-ball.getSpeedX());

           }

//         如果碰到右边界,即是球的的横坐标大于panelWidth-ball.getImage().getWidth(null),画图分析之

           if(ball.getX() + absSpeedX>panelWidth-ball.getImage().getWidth(null)){

//            重新设置弹球的位置,注意画图分析一下怎么设置,很有技巧

              ball.setX(panelWidth - ball.getImage().getWidth(null));

//            让弹球放方向弹回

              ball.setSpeedX(-ball.getSpeedX());

           }

//         如果碰到上边界

           if(ball.getY() - absSpeedY<0){

//            重新设置弹球的Y位置

              ball.setY(ball.getImage().getWidth(null));

//            让弹球放方向弹回

              ball.setSpeedY(-ball.getSpeedY());

           }

          

//         如果碰到下边界

           if(ball.getY() + absSpeedY>panelHeight - stick.getImage().getHeight(null)){

              if(this.isHitStick(stick)){//如果和挡板有碰撞;只需把纵坐标速度改成相反即可,横坐标速度不变,根据速度的合成,即可得到合速度

                  ball.setSpeedY(-ball.getSpeedY());

              }

           }

          

           // 与砖块碰撞后的运动

           for (int i = brick.length - 1; i > -1; i--) {

              for (int j = brick[i].length - 1; j > -1; j--) {

                  // 如果小球与砖块有碰撞

                  if (isHitBrick(brick[i][j])) {

                     if (ball.getSpeedY() > 0) {

                         //反方向弹回

                         ball.setSpeedY(-ball.getSpeedY());

                     }

                  }

              }

           }

           // 如果小球碰到底部结束游戏

           if (ball.getY() > panelHeight) {

              ball.setStop(true);

           }

 

           // 设置x坐标,让小球子自动运动.开始时是让小球横坐标向左运动的。注意

           ball.setX(ball.getX() - (int) (Math.random() * 2)

                  -ball.getSpeedX());

           // 设置y坐标

           ball.setY(ball.getY() - (int) (Math.random() * 2)

                  - ball.getSpeedY());

          

       }

    }

 

 

下面定义了一个让游戏开始的方法,run

 

    public void run(){

       // 弹球坐标改变

       setBallPos();

       // 道具坐标改改变

       setMagicPos();

    }

 

下面提供一个方法,把游戏的组件化的界面上去

public void draw(Graphics g){

       if(this.isWon()){

           // 绘制赢的图片

           g.drawImage(won.getImage(), won.getX(), won.getY(), panelWidth,

                  panelHeight - 10, null);

       } else if (ball.isStop()) {

           // 绘制游戏结束图像

           g.drawImage(gameOver.getImage(), gameOver.getX(), gameOver.getY(),

                  panelWidth, panelHeight - 10, null);

       }else{

//         清除所有图像

           g.clearRect(0, 0, panelWidth,panelHeight);

           // 绘制档板图像

           g.drawImage(stick.getImage(), stick.getX(), stick.getY(), stick

                  .getPreWidth(), stick.getImage().getHeight(null), null);

           // 绘制弹球图像

           g.drawImage(ball.getImage(), ball.getX(), ball.getY(), null);

           // 迭代绘制砖块图像

           for (int i = 0; i < brick.length; i++) {

              for (int j = 0; j < brick[i].length; j++) {

                  BallComponent magic = brick[i][j].getMagic();

                  // 如果这个砖块图像对像是有效的

                  if (!brick[i][j].isDisable()) {

                     // 里面的数字1为砖块图像间的间隙

                     g.drawImage(brick[i][j].getImage(), brick[i][j]

                            .getX(), brick[i][j].getY(), brick[i][j]

                            .getImage().getWidth(null) - 1, brick[i][j]

                            .getImage().getHeight(null) - 1, null);

                  } else if (magic != null && magic.getY() < panelHeight) {

                     g.drawImage(magic.getImage(), magic.getX(), magic

                             .getY(), null);

                  }

              }

           }

       }

    }

 

              游戏面板BallFrame

 

我们在BallService里面已经处理过了小球,挡板,砖块,和挡板,面板的作用就是所以把处理的结果显示出来让我们看即可,所以,只需为该类提供了一个BallService即可,当然还需要对面板添加键盘监听器,用来监听挡板的运动方向。还有一个时间控制器

ublic class BallFrame extends JFrame {

     /**

     *

     */

    private static final long serialVersionUID = 1L;

    public class BallPanel extends JPanel{

 

       /**

        *

        */

       private static final long serialVersionUID = 1L;

 

       @Override

       public void paint(Graphics g) {

           service.draw(g);//在面板上画图

       }

        

     }

     

    /**

     * 得到有一个BallPanel

     * @return BallPanel

     */

     public  BallPanel getBallPanel(){

        if(ballPanel == null){

            ballPanel = new BallPanel();

//         设置ballPanel的大小,使得其大小和frame一样

            ballPanel.setPreferredSize(new Dimension(WITDH,HEIGHT));

       }

 

       return ballPanel;

        

     }

/**

 * 初始化界面

 * @throws IOException

 */

     public void init() throws IOException{

        this.setTitle("ballGame");

        this.setResizable(false); 

        this.setBackground(Color.black);

        ballPanel = this.getBallPanel();

//     初始化service

        service = new BallService(WITDH,HEIGHT,this);

      

        /**

         * 添加一个事件监听器

         */

        ActionListener task = new ActionListener(){

 

           @Override

           public void actionPerformed(ActionEvent e) {

//            游戏开始

              service.run();

//            刷新游戏面板

              ballPanel.repaint();

             

           }

            

        };

        

//     提供时间控制器

        if(timer!=null){

            timer.restart();

        }else{

//         每100ms控制一次事件监听器

            timer = new Timer(100,task);

            timer.start();

        }

        this.add(ballPanel);

//     添加键盘监听器,用来控制挡板的移动

        KeyListener[] klarr = this.getKeyListeners();

        if(klarr.length==0){

//         定义一个键盘监听适配器

            KeyListener keyAdapter = new KeyAdapter(){

 

              @Override

              public void keyPressed(KeyEvent ke) {

                  try {

                     service.setStickPos(ke);

                  } catch (IOException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

                  }

              }

               

            };

            

            this.addKeyListener(keyAdapter);

        }

        this.setVisible(true);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.pack();

        

     }

     

     /**

        * 默认构造器

        */

       public BallFrame() throws IOException {

           super();

           // 初始化

           init();

       }

     private BallPanel ballPanel = null;

     private final int WITDH = 307;

     private final int HEIGHT = 400;

     private BallService service = null;

     private Timer timer = null;

}

 

 

注意一下这个paint方法,查询api可知:由 Swing 调用,以绘制组件。应用程序不应直接调用 paint,而是应该使用 repaint 方法来安排重绘组件。

为了使弹球达到运动的效果,用来Timer这个时间控制器,设置每隔0.1秒监听一下任务,下面是一些关于Timer的api说明

 

设置计时器的过程包括创建一个 Timer 对象,在该对象上注册一个或多个动作侦听器,以及使用 start 方法启动该计时器。例如,以下代码创建并启动一个每秒(该时间由 Timer 构造方法的第一个参数指定)触发一次动作事件的计时器。Timer 构造方法的第二个参数指定接收计时器动作事件的侦听器。

int delay = 1000; //milliseconds

  ActionListener taskPerformer = new ActionListener() {

      public void actionPerformed(ActionEvent evt) {

          //...Perform a task...

      }

  };

  new Timer(delay, taskPerformer).start();

构造 Timer 时要指定一个延迟参数和一个 ActionListener。延迟参数用于设置初始延迟和事件触发之间的延迟(以毫秒为单位)。启动了计时器后,它将在向已注册侦听器触发第一个 ActionEvent 之前等待初始延迟。第一个事件之后,每次超过事件间延迟时它都继续触发事件,直到被停止。

构造之后,可以单独更改初始延迟和事件间延迟,并且可以添加其他 ActionListener。

如果希望计时器只在第一次时触发然后停止,可以对计时器调用 setRepeats(false)。

 

其实,也可以不用事件监听器,直接用多线程的知识的知识,直接让现成睡眠100ms然后继续刷新画板,然后代码就可以改成如下所示情况

为BallFrame类里面添加一个线程内部类

private class PaintThread implements Runnable {

 

           public void run() {

              while(true) {

                  service.run();

                  ballPanel.repaint();

                  try {

                     Thread.sleep(100);

                  } catch (InterruptedException e) {

                     e.printStackTrace();

                  }

              }

           }

}

这样在init里面添加一个线程对象然后启动线程即可

public void init() throws IOException{

        this.setTitle("ballGame");

        this.setResizable(false); 

        this.setBackground(Color.black);

        ballPanel = this.getBallPanel();

//     初始化service

        service = new BallService(WITDH,HEIGHT,this);

               

        this.add(ballPanel);

//     添加键盘监听器,用来控制挡板的移动

//         定义一个键盘监听适配器

            KeyListener keyAdapter = new KeyAdapter(){

 

              @Override

              public void keyPressed(KeyEvent ke) {

                  try {

                     service.setStickPos(ke);

                  } catch (IOException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

                  }

              }

               

            };

            

            this.addKeyListener(keyAdapter);

        

        

        new Thread(new PaintThread()).start();

        this.setVisible(true);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.pack();

        

        

     }

     

   

     至于图片文件,要是想要的话,请联系feixiangdebaiyun@yeah.net

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. CKeditor自定义上传图片功能

    原文出自: "http://cmsblogs.com" 在 方法中做了两件事情,一是调用 获取 XML 的验证模式,二是调用 获取 Document 对象。上篇博客已经分析了获取 XML 验证模式( "【死磕Spring】 IOC 之 获取验证模型" ),这篇我们分析获取 Document 对象。 虐铰99Jf叶…...

    2024/5/4 20:46:37
  2. centos7 mysql 数据库备份与还原

    数据库备份1showdatabases; #先查看一下数据库现在我要备份word数据库退出mysql输入1mysqldump-u root -p word > word.sql #我把它备份在了当前目录下查看一下备份完成还原数据库mysqldump -u root -p word < word.sql...

    2024/4/30 14:10:41
  3. 开发简化版NgFor

    开发简化版NgFor 下面是自定义实现一个简化版本的NgFor指令,一般来说使用Angular默认的即可,但是在追求高性能的时候,或许你需要这样一个简化版本的指令,让你的程序运行流畅、纵享丝滑。 直接贴出代码。 import {Directive, EmbeddedViewRef, Input, DoCheck, OnChanges, S…...

    2024/4/29 12:46:16
  4. stm32实现秒表及万年历

    秒表 /普通按键初始化函数****通用定时器中断初始化这里时钟选择为APB1的2倍,而APB1为36Marr:自动重装值。psc:时钟预分频数这里使用的是定时器3! ******************************************************/ void TimerxInit(u16 arr, u16 psc) { RCC->APB1ENR |= 1<&…...

    2024/5/4 21:59:48
  5. 《图书管理系统——需求分析》

    图书借阅管理系统-阶段项目3 第一部分 案例描述案例目的 学习Java语言中的文件读写、集合框架的使用、异常处理和输入输出等。 案例难度 ★★★★ 案例覆盖技能点 1、 I/O流 2、 ArrayList的使用 3、 HashMap的使用 4、 异常的处理 5、 scanner的使用 推荐案例完成时间3天 适用…...

    2024/4/29 14:50:01
  6. 漫游Kafka设计篇之性能优化

    分享mysql客户端50与55的一个小区别分享mysql客户端50与55的一个小区别 分享mysql客户端50与55的一个小区别分享mysql客户端50与55的一个小区别 分享mysql客户端50与55的一个小区别分享mysql客户端50与55的一个小区别匪治菜泊靖潜渤腹http://baobao.baidu.com/article/64782e26…...

    2024/5/6 15:45:02
  7. h5的canvas小游戏实例

    最近看了一些canvas的小游戏例子,参照写了个实例。 原理大致讲一下:主要是通过requestAnimationFrame无间断刷新canvas实现动画,监听一些事件,实现操作。 流程大致是,准备容器,准备相关角色,事件绑定,更新数据,初始化画布,主流程函数(这里循环调用requestAnimationF…...

    2024/4/24 5:41:10
  8. sqlserver 2005 数据库还原是出现“备份集中的数据库备份与现有的X数据库不同”的解决办法

    当我们从备份集(带.bak后缀名或者无后缀)还原数据库时,由于搞不清原备份集中的数据库名和确切的数据库文件和log文件名和路径,直接创建一个新数据库,然后选择从备份集中还原,由于和原数据库的名号和路径不匹配就是出现“备份集中的数据库备份与现有的X数据库不同”的问题…...

    2024/5/5 11:38:27
  9. Spring 根据条件注入对应的Bean

    业务场景:做一个统一的Healcheck通用包,做一个通用的jar包,需要提供一个接口给依赖项目拓展,如果对依赖项目没有实现此接口,就使用Healthcheck默认的接口,如果对方有实现此接口,则实例化依赖项目的实现。HealthCheck接口public interface HealthCheck {Message doCheck(…...

    2024/4/26 22:27:39
  10. 网页万年历

    一个万年历的源代码,网页中实现的,上学期做电子商务大作业的时候写的,里面有各个时区的时间,以及节日的提示等,发上来一下,如果有不足的地方望指出.综合应用了HTML.Javascript等方便的技术,实现比较容易,不做过多解释.. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 T…...

    2024/4/16 23:40:14
  11. Angular 笔记(day1)

    1,生命周期日志信息的日志和所规定的钩子调用顺序是一致的:constructor()OnChangesOnInit //表示组件指令加载完成DoCheck (3x)AfterContentInitAfterContentChecked (3x)AfterViewInitAfterViewChecked (3x)OnDestroy构造函数中除了使用简单的值对局部变量进行初始化之外,…...

    2024/4/28 15:34:30
  12. 0x00D83DDA 处有未经处理的异常(在 DXFont.exe 中): 0xC000041D: 用户回调期间遇到未经处理的异常

    本文只针对于《逐梦之旅windows 游戏编程从零开始》之中D3D框架篇遇到的问题,不是本问题的请绕行,以免耽误您的时间!在浅墨的框架中从创建窗口到消息循环中是这样一段代码: HWND hwnd = CreateWindow(wndClass.lpszClassName,WINDOW_TITLE,WS_POPUP|WS_THICKFRAME, CW_USED…...

    2024/4/30 1:26:27
  13. Java编写 万年历

    在GitHub上看到的一个很有意思的一个小程序:万年历 import java.util.Scanner; import java.util.GregorianCalendar; import java.util.Calendar;public class Test {final static String blank=" ";final static String border=" | ";public st…...

    2024/5/1 4:02:28
  14. SQL总结之数据库备份与还原(MSSQL)

    数据库备份与还原常用,但通常是通过数据库管理器界面配置即可,用不着以下列出的sql命令。但是如果你的应用系统中存在相关的数据库还原备份的功能,就需要掌握这些基本的SQL语法了。 此外,在实际的生产环境,需要一些简单的自动化脚本实现数据库的备份,可能还需要了解数据…...

    2024/4/16 23:41:14
  15. JS按Enter进行查询操作

    JS按Enter进行查询操作document.onkeydown = function (e) {if (!e) e = window.event; //火狐中是window.eventif ((e.keyCode || e.which) == 13) {doCheck();}};转载于:https://www.cnblogs.com/xiaxixue/archive/2013/05/08/3066301.html...

    2024/4/27 2:22:13
  16. PowerShell_零基础自学课程_6_PS中获取帮助信息详解、管道、格式化输

    前些文章陆续的说了一些关于这些主题,但是讨论的都不够深入,今天我们深入的了解一下获取帮助信息、管道以及格式化输出的内容。 一、获取帮助信息在PS中获取帮助信息,最常用的有: -? 、get-command和get-help。这三者获取的信息不是完全一致的,并且由于get-command和get-…...

    2024/4/18 23:57:58
  17. 用java的robot类以及Gui 制作一个游戏(阴阳师)脚本

    ** 用java的robot类以及Gui 制作一个游戏(阴阳师)脚本 **由于阴阳师这个游戏肝度太大,就决定写一个脚本来模拟玩家的重复性操作.所以我就决定用java中的robot类中的一些方法来模拟鼠标点击,移动等功能,具体方法见下图.因为一个好看的界面能让人看着更加的舒服,所以就决定用java…...

    2024/5/4 5:10:24
  18. 小型仓库管理系统——毕业论文

    大家好,我是程序员爱酸奶,希望您能喜欢我的文章。可以专注我个人公众号获取更多内容。有什么问题可以通过公众号加我微信交流~~ 手动比心 ♥ 关于毕业论文,还需要大家自行编写,这里是提供给大家一些参考,如果大家想要一些毕业设计的项目,可以关注公众号,回复 "毕设…...

    2024/4/19 8:23:57
  19. ★Navicat For Mysql 数据库备份与还原

    一.首先设置, 备份保存路径工具 -> 选项 点开其他 -> 日志文件保存路径二. 开始备份备份分两种, 一种是以sql保存, 一种是保存为备份1.SQL保存右键点击你要备份的数据库, -> 转储SQL文件选择位置和文件名点击保存,开始转储导入建议 删除所有表 或 重新建数据库 右键数…...

    2024/5/1 15:46:04
  20. angular生命点接口 生命周期钩子

    生命点接口周期钩子调用方式OnChangesngOnChanges()简单输入变量本值发生变化时调用,第一次调用在OnInit之前OnInitngOnInit()初始化时调用DoCheckngDoCheck()周期更改检测,每次变更周期都会调用AfterContentInitngAfterContentInit()内容完成初始化投影后调用AfterCon…...

    2024/4/29 0:02:12

最新文章

  1. 3d中如何对模型粉碎处理?---模大狮模型网

    在3D建模和动画设计中&#xff0c;模型粉碎处理是一种引人注目的效果&#xff0c;可以为场景增添动态和震撼的视觉效果。无论是用于电影特效、游戏设计还是虚拟现实项目&#xff0c;都可以通过模型粉碎处理来创造出引人入胜的场景。本文将介绍如何在3D中轻松实现模型粉碎处理&a…...

    2024/5/9 5:03:22
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/7 10:36:02
  3. C# 构建可定时关闭的异步提示弹窗

    C# 构建可定时关闭的异步提示弹窗 引言1、调用接口的实现2、自动定时窗口的实现 引言 我们在最常用最简单的提示弹框莫过于MessageBox.Show( )的方法了&#xff0c;但是使用久了之后&#xff0c;你会发现这个MessageBox并不是万能的&#xff0c;有事后并不想客户去点击&#x…...

    2024/5/7 15:39:44
  4. 自我介绍的HTML 页面(入门)

    一.前情提要 1.主要是代码示例&#xff0c;具体内容需自己填充 2.代码后是详解 二.代码实例和解析 代码 <!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8"> <title>自我介绍页面</title>…...

    2024/5/5 7:22:10
  5. 【嵌入式开发 Linux 常用命令系列 4.3 -- git add 不 add untracked file】

    请阅读【嵌入式开发学习必备专栏 】 文章目录 git add 不add untracked file git add 不add untracked file 如果你想要Git在执行git add .时不添加未跟踪的文件&#xff08;untracked files&#xff09;&#xff0c;你可以使用以下命令&#xff1a; git add -u这个命令只会加…...

    2024/5/5 8:53:25
  6. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/8 6:01:22
  7. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/7 9:45:25
  8. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  9. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/9 4:20:59
  10. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  11. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  12. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  13. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/7 11:36:39
  14. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  15. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/6 1:40:42
  16. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  17. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/8 20:48:49
  18. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/7 9:26:26
  19. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  20. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/8 19:33:07
  21. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  22. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/8 20:38:49
  23. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  24. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/6 21:42:42
  25. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57