教你使用JAVA制作羊了个羊消除小游戏

下面通过一个代码案例来制作一个这样的小游戏。游戏的GUI部分使用了JAVAFX来编写,下面是代码部分和效果图展示,话不多说直接上代码,供参考和学习。

二、代码部分


public class FXController extends Application implements Serializable{

    private static final long serialVersionUID = 1L;
    private double x=0,y=0,width = 500,height = 800,jianju=18;
    private volatile int img_x = -1,img_y = -1,
            end_x = 50,end_y = 625,
            count = 0,status = 0,
            guanqia = 4,qiehuan_x = (int) (width*2);
    private volatile boolean qiehuan = false,setting_show = false,play_muisc = false,
            last = false;
    private Canvas canvas = new Canvas(width,height);
    private GraphicsContext context = canvas.getGraphicsContext2D();
    private Random random = new Random();
    private ExecutorService service = new ThreadPoolExecutor(10, 100, 0, TimeUnit.SECONDS,
            new ArrayBlockingQueue<Runnable>(100));
    private Font font = Font.font("微软雅黑",FontWeight.BOLD,60);
    //private Font wei = Font.font("微软雅黑",FontWeight.BOLD,40);
    private AudioClip clip = play_music("D:\\桌面\\imagess\\button.mp3",1,false),clip2,
            clip3 = play_music("D:\\桌面\\imagess\\xiaochu2.mp3",1,false);
    
    private static List<Image> back,yuansu,buttons,icon,huiyuansu,bu,jie,setting;
    private static Map<String,String> muisc;
    private List<ImageInfo> info1 = new ArrayList<ImageInfo>(8);
    private ImageInfo[][] images = new ImageInfo[guanqia][guanqia];
    private ImageInfo[][] images2 = new ImageInfo[guanqia][guanqia];
    private boolean[] muisc_is = new boolean[3];
    
    @AllArgsConstructor
    //@ToString
    private static final class ImageInfo{
        private double x,y,value,index;
        private boolean show;
    }
    
    static{
        try {
            Path[] paths=Files.list(Paths.get("D:\\桌面\\imagess")).toArray(Path[]::new);
            Map<String, List<Image>> maps =Stream.of(paths)
            .filter(image->image.getFileName().toString().matches(".+\\.(?i)(jpg|png)"))
            .sorted(Comparator.comparing(path->{
                String filename = path.getFileName().toString();
                return filename.startsWith("bu_")?
                        Integer.parseInt(filename.replaceAll("[^\\d+]","")):0;
            })).collect(Collectors.groupingBy(path->{
                String string = path.getFileName().toString();
                return string.startsWith("1_")?"yuansu":string.matches("\\d+\\.png")?"buttons":
                    string.matches("(01|02)\\.jpg")?"back":string.startsWith("setting")?"setting":
                    string.startsWith("jie_")?"jie":string.startsWith("bu_")?"bu":"icon";
            },Collectors.mapping(path->new Image(path.toUri().toString()),Collectors.toList())));
            muisc = Stream.of(paths).filter(path->path.getFileName().toString().matches(".+\\.(?i)(mp3|wav)"))
            .collect(Collectors.toMap(k->k.getFileName().toString().split("\\.")[0],v->v.toString()));
            back = maps.get("back");
            yuansu =  maps.get("yuansu");
            huiyuansu = yuansu.stream().map(m->pixWithImage(3,m)).collect(Collectors.toList());
            buttons =  maps.get("buttons");
            icon =  maps.get("icon");
            bu =  maps.get("bu");
            jie =  maps.get("jie");
            setting =  maps.get("setting");
        } catch (IOException e) {
            e.printStackTrace();
            throw new Error("ERR");
        }
    }
    
    private void random(){
        try {
            AudioClip clip = play_music(muisc.get("xipai"),-1,true);
            clip.setVolume(1.0);
            int index = 0;
            List<Integer> ints1 = random_next_int(images.length*images[0].length,yuansu.size());
            List<Integer> ints2 = random_next_int(images2.length*images2[0].length,yuansu.size());
            count = ints1.size()+ints2.size();
            for (int i = 0; i < images.length; i++)
                for (int j = 0; j < images[i].length; j++){
                    TimeUnit.MILLISECONDS.sleep(50);
                    double width1 = 50,height1 = 50,x = (width-images.length*width1+i*jianju)/2+width1*i,y = (guanqia>4?100:200)+height1*j+j*jianju;
                    if(index<ints1.size())images[i][j] = new ImageInfo(x,y,ints1.get(index++),1,true);
                }index = 0;
            for (int i = 0; i < images2.length; i++)
                for (int j = 0; j < images2[i].length; j++){
                    TimeUnit.MILLISECONDS.sleep(50);
                    double width1 = 50,height1 = 50,x = (width-images2.length*width1+i*jianju)/2+width1*i,y = (guanqia>4?100:200)+height1*j+j*jianju;
                    if(index<ints2.size())images2[i][j] = new ImageInfo(x,y,ints2.get(index++),2,true);
                }
            clip.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private AudioClip play_music(String path,Integer count,Boolean auto){
        AudioClip clip = new AudioClip(Paths.get(path).toUri().toASCIIString());
        clip.setCycleCount(count);
        if(auto)clip.play();
        return clip;
    }
    
    private Bounds getFontWH(String text,Font font){
        Text texts = new Text(text);texts.setFont(font);
        return texts.getBoundsInLocal();
    }
    
    private void rest(int length){
        guanqia = length>0?length:guanqia+1;
        images = new ImageInfo[guanqia][guanqia];
        images2 = new ImageInfo[guanqia][guanqia];
        service.execute(()->random());
        info1.clear();
        end_x = 50;
    }
    
    private double[] dengbi(Image img,Double new_width){
        boolean is_bili = false;
        double bili = (is_bili = new_width<img.getWidth())?new_width/img.getWidth():img.getWidth()/new_width;
        return new double[]{new_width,is_bili?img.getHeight()*bili:img.getHeight()/bili};
    }
    
    
    
    public FXController(){
        canvas.setCache(true);
        clip2 = play_music(muisc.get("bgm"),-1,true);
        service.execute(()->{
            try {
                while(true){
                    TimeUnit.MICROSECONDS.sleep(100);
                    if(qiehuan && qiehuan_x--<-(width+275)){qiehuan_x = (int) (width*2);qiehuan = false;status = 4;rest(0);}
                    if(img_x ==-1 && img_y ==-1)continue;
                    ImageInfo[][] images = !this.images[img_x][img_y].show?this.images2:this.images;
                    images[img_x][img_y].x=images[img_x][img_y].x>end_x?images[img_x][img_y].x-3:images[img_x][img_y].x+3;
                    images[img_x][img_y].y+=3;
                    if(images[img_x][img_y].y >= end_y){
                        end_x+=50;images[img_x][img_y].show=false;
                        info1.add(new ImageInfo(images[img_x][img_y].x,images[img_x][img_y].y,images[img_x][img_y].value,images[img_x][img_y].index,images[img_x][img_y].show));
                        img_x = img_y = -1;
                        ImageInfo[] info2 = new ImageInfo[3];
                        AtomicInteger integer = new AtomicInteger(0); 
                        boolean falses = IntStream.range(0,info1.size())
                        .anyMatch(index->{
                            if(index<info1.size()-1){
                                ImageInfo info_1 = info1.get(index);
                                ImageInfo info_2 = info1.get(index+1);
                                if(info_1.value==info_2.value){
                                    info2[integer.get()] = info_1;
                                    info2[integer.get()+1] = info_2;
                                    if(integer.incrementAndGet()==2)return true;
                                }else integer.set(0);
                            }
                            return false;
                            });
                        if(falses){
                            count-=3;end_x-=50*3;
                            TimeUnit.MILLISECONDS.sleep(200);
                            if(!play_muisc)clip3.play();
                            info1.removeAll(Arrays.asList(info2));
                            if(count<=0){
                                TimeUnit.MILLISECONDS.sleep(500);
                                status=3;//play_music(muisc.get("success"),1,true);
                            }
                        }if(info1.size()>=8){TimeUnit.MILLISECONDS.sleep(500);
                        play_music(muisc.get("false"),1,true);
                        status=1;}
                            
//                        info1.stream().collect(Collectors.groupingBy(info->info.value))
//                        .entrySet().stream().filter(info->info.getValue().size()==3)
//                        .findFirst().ifPresent(info->{
//                            end_x-=50*3;
//                            try {
//                                TimeUnit.MILLISECONDS.sleep(150);
//                                clip.play();
//                                info1.removeAll(info.getValue());
//                            } catch (Exception e) {
//                                e.printStackTrace();
//                            }
//                        });
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        
        service.execute(()->{
            try {
                int index = 0,index3 = 0,back_image = 0,jie_image = 0;
                while(true){
                TimeUnit.MILLISECONDS.sleep(100);
                context.clearRect(0,0,canvas.getWidth()+1,canvas.getHeight()+1);
                boolean disable = String.valueOf(status).matches("[123]");
                
                
                if(status==0){
                //画首页背景动画
                    
                if(index3++%5==0){
                    if(++jie_image>=back.size())jie_image = 0;
                    context.drawImage(jie.get(jie_image),0,0,width,height);
                    if(index>=10)index = 0;
                }else context.drawImage(jie.get(jie_image),0,0,width,height);
                
                //画顶部按钮
                for (int j = 4; j < 7; j++) {
                    if(!last && j>5)continue;
                    Image image = (last && j>5)?bu.get(7):bu.get(j);
                    double width1 = 50,x = j>4?width-width1-30:30,y = j>5?90:30;
                    if(!setting_show && new Rectangle2D(x,y,width1,width1).intersects(this.x,this.y,1,1)){
                        this.x=this.y=0;width1+=10;
                        if(!play_muisc)clip.play();
                        if(j==4)System.exit(0);
                        else if(j==5)setting_show = true;
                        else status=4;
                    }context.drawImage(image,x,y,width1,width1);
                }

                //画主界面按钮
                for (int j = 0;j < 3;j++) {
                    Image image = bu.get(j);
                    double[] wh = dengbi(image,200D);
                    double x = (width-wh[0])/2,y = 310+wh[1]*j+j*30;
                    if(!setting_show && new Rectangle2D(x, y,wh[0],wh[1]).intersects(this.x,this.y,1,1)){
                        this.x=this.y=0;wh[0]+=10;wh[1]+=10;
                        if(!play_muisc)clip.play();
                        status=4;rest(4+j);
                    }context.drawImage(image,x,y,wh[0],wh[1]);
                    }
                
                
                if(setting_show){
                    
                context.setFill(Color.BLACK);
                context.setGlobalAlpha(0.4);
                context.fillRect(0,0,width,height);
                context.setGlobalAlpha(1.0);
                
                Image image = setting.get(0);
                Image image2 = bu.get(3);
                double[] wh = dengbi(image,300D);
                double[] wh2 = dengbi(image2,140D);
                context.drawImage(image,(width-wh[0])/2,(height-wh[1])/2,wh[0],wh[1]);
                
                if(new Rectangle2D((width-wh2[0])/2,510,wh2[0],wh2[1]).intersects(this.x,this.y,1,1)){
                    this.x=this.y=0;wh2[0]+=10;wh2[1]+=10;
                    if(!play_muisc)clip.play();setting_show = false;
                }context.drawImage(image2,(width-wh2[0])/2,510,wh2[0],wh2[1]);
                
                for (int j = 0;j < 3;j++) {
                    double width1 = 50,x1 = 160,y1 = 290+j*width1+j*30;
                    if(new Rectangle2D(x1,y1,width1,width1).intersects(this.x,this.y,1,1)){
                        this.x=this.y=0;width1+=10;if(!play_muisc)clip.play();
                        if(j==0){
                            muisc_is[j] = !muisc_is[j];
                            if(muisc_is[j])clip2.stop();else clip2.play();
                        }else if(j==1)
                            muisc_is[j] = play_muisc = !muisc_is[j];
                        else muisc_is[j] = play_muisc = !muisc_is[j];
                    }context.drawImage(muisc_is[j]?bu.get(8):bu.get(9),x1,y1,width1,width1);
                }}
                continue;
                }
                
//-------------------------------------------------------------------------------------------------------
                
                //画背景图片
                if(index++%10==0){
                    if(++back_image>=back.size())back_image = 0;
                    context.drawImage(back.get(back_image),0,0,width,height);
                    if(index>=10)index = 0;
                }else context.drawImage(back.get(back_image),0,0,width,height);
                
                    //画顶部按钮
                    Image image0 = bu.get(6);
                    double width0 = 50,x0 = 30,y0 = 30;
                    if(!setting_show && new Rectangle2D(x0,y0,width0,width0).intersects(this.x,this.y,1,1)){
                        this.x=this.y=0;width0+=10;if(!play_muisc)clip.play();
                        status = 0;last = true;
                    }context.drawImage(image0,x0,y0,width0,width0);
                
                //画第二层元素
                for (int i = 0; i < images2.length; i++)
                    for (int j = 0; j < images2[i].length; j++) {
                        ImageInfo imgs = images2[i][j];
                        ImageInfo imgs2 = images[i][j];
                        if(imgs2 == null || imgs==null || !imgs.show)continue;
                        Image image = imgs2.show?huiyuansu.get((int)imgs.value):yuansu.get((int)imgs.value);
                        double width1 = 50,height1 = 50,x = imgs.x-30,y = imgs.y+30;
                        if(!disable && !imgs2.show && new Rectangle2D(x, y, width1, height1).intersects(this.x,this.y,1,1)){
                            this.x=this.y=0;
                            if(!play_muisc)clip.play();
                            //System.out.println("第二层");
                            width1 += 4;height1 +=4;
                            //x = (width-images2.length*width1)/2+width1*i;y = 100+height1*j;
                            if(info1.size()<8){img_x = i;img_y = j;}
                        }context.drawImage(image,x,y,width1,height1);
                    }
                //画第一层元素
                 for (int i = 0; i < images.length; i++)
                    for (int j = 0; j < images[i].length; j++) {
                        ImageInfo imgs = images[i][j];
                        if(imgs==null || !imgs.show)continue;
                        Image image = yuansu.get((int)imgs.value);
                        double width1 = 50,height1 = 50,x = imgs.x,y = imgs.y;
                        if(!disable && new Rectangle2D(x, y, width1, height1).intersects(this.x,this.y,1,1)){
                            this.x=this.y=0;
                            if(!play_muisc)clip.play();
                            //System.out.println("第一层");
                            width1 += 4;height1 +=4;
                            //x = (width-images.length*width1)/2+width1*i;y = 100+height1*j;
                            if(info1.size()<8){img_x = i;img_y = j;}
                        }context.drawImage(image,x,y,width1,height1);
                    }
                
                //画按钮图片
                for (int j = 0; j < info1.size(); j++) {
                    Image image = yuansu.get((int) info1.get(j).value);
                    double width1 = 50,x = 50+width1*j,y = 625;
                    context.drawImage(image,x,y,width1,width1);
                }
                
                //画按钮图片
                for (int j = 0; j < 3; j++) {
                    Image image = buttons.get(j);
                    double width1 = 100,height1 = 65,x = (width-3*width1+j*40)/2+width1*j-20,y = 720;
                    if(!disable && new Rectangle2D(x, y, width1, height1).intersects(this.x,this.y,1,1)){
                        this.x=this.y=0;
                        width1 +=10;height1 +=10;
                        if(!play_muisc)clip.play();
                        //x = (width-buttons.size()*width1+j*40)/2+width1*j-20;y = 715;
                        switch (j) {
                        case 0:
                            System.exit(0);
                            break;
                        case 1:
                            rest(guanqia);
                            break;
                        case 2:
                            break;
                        }
                    }
                    context.drawImage(image,x,y,width1,height1);
                }
                
                if(status==3){
                    Image image = buttons.get(buttons.size()-1);
                    double[] wh = dengbi(image,width+40);
                    if(qiehuan_x == width*2){qiehuan_x = (int)(wh[0]/2+width);qiehuan = true;}
                    context.drawImage(image,qiehuan_x,(height-wh[1])/2,wh[0],wh[1]);
                }else if(status==1){
                    context.setFill(Color.BLACK);
                    context.setGlobalAlpha(0.4);
                    context.fillRect(0,0,width,height);
                    context.setGlobalAlpha(1.0);
                    for (int j = 3,i=0; j < buttons.size()-1; j++,i++) {
                    Image image = buttons.get(j);
                    double[] wh = dengbi(image,220D);
                    double x = (width-wh[0])/2,y = 350+wh[1]*i+i*40;
                    if(new Rectangle2D(x, y,wh[0],wh[1]).intersects(this.x,this.y,1,1)){
                        this.x=this.y=0;wh[0]+=20;wh[1]+=20;
                        if(!play_muisc)clip.play();
                        if(j==3){status = 4;rest(4);}
                        else{status = 4;info1.clear();end_x = 50;}
                    }context.drawImage(image,x,y,wh[0],wh[1]);
                    }
                    Bounds bounds = getFontWH("游戏结束",font);
                    context.setFont(font);
                    context.setFill(Color.WHITE);
                    context.fillText("游戏结束",(width-bounds.getWidth())/2,300);
                }
                
                
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        canvas.setOnMousePressed(event->{   
            x=event.getX();y=event.getY();
        });
    }
    
    private List<Integer> random_next_int(int count,int images){
        while(true)if(count--%3==0)break;
        List<Integer> list = new ArrayList<Integer>(count);
        AtomicInteger integer = new AtomicInteger(0);
        while(list.size()<count){
            IntStream.range(0,3).forEach(m->list.add(integer.get()));
            integer.incrementAndGet();
            integer.set(integer.get()>images-1?random.nextInt(images):integer.get());
        }
        Collections.shuffle(list);
        return list;
    }
    
    private static Image pixWithImage(int type,Image image){
        PixelReader pixelReader = image.getPixelReader();
        if(image.getWidth()>0 && image.getHeight() >0){
            WritableImage wImage;
            wImage = new WritableImage(
                    (int)image.getWidth(),
                    (int)image.getHeight());
            PixelWriter pixelWriter = wImage.getPixelWriter();
            for(int y = 0; y < image.getHeight(); y++){
                for(int x = 0; x < image.getWidth(); x++){
                    Color color = pixelReader.getColor(x, y);
                    switch (type) {
                        case 1:
                            // 颜色变轻
                            color = color.brighter();
                            break;
                        case 2:
                            // 颜色变深
                            color = color.darker();
                            break;
                        case 3:
                            // 灰度化
                            Color colors = color.grayscale();
                            color = Color.color(colors.getRed(),colors.getGreen(),colors.getBlue(),0.6);
                            break;
                        case 4:
                            // 颜色反转
                            color = color.invert();
                            break;
                        case 5:
                            // 颜色饱和
                            color = color.saturate();
                            break;
                        case 6:
                            // 颜色不饱和
                            color = color.desaturate();
                            break;
                        case 7:
                            // 颜色灰度化后反转(字黑体,背景鲜亮,可用于强字弱景)
                            color = color.grayscale();
                            color = color.invert();
                            break;
                        default:
                            break;
                    }
                    pixelWriter.setColor(x, y, color);
                }
            }
            return wImage;
        }
        return null;
    }
    @Override
    public void start(Stage stage) throws Exception {
        AnchorPane pane = new AnchorPane(canvas);
        pane.setPadding(new Insets(0));
        Scene scene = new Scene(pane,width-15,height-10);
        stage.getIcons().add(icon.get(0));
        stage.setTitle("羊了个羊"); 
        stage.setScene(scene);
        stage.setAlwaysOnTop(true);
        stage.setResizable(false);
        stage.show();
    }
}

public abstract class GameStarting {
    public static void main(String[] args) throws Exception {
        Application.launch(FXController.class,args);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值