【面向对象程序设计】侩子手游戏(Java、JavaFX)

目录

版本1:

版本2:

版本3:


版本1:

  随机产生一个单词,提示用户每次猜一个字母。单词中的每个字母以星号显示。当用户猜对一个字母时,显示实际字母。当用户完成一个单词时,显示猜错的次数,同时询问用户是否继续下一单词。单词存储使用数组形式,如:String[] words = {write,that,};

满足上述要求的控制台程序运行示例:

 

package version1;
import java.util.Scanner;

public class game {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String[] words = {"write", "this", "love", "for"};//添加单词到数组之中

        for (int i = 0; i < words.length; i++) {
            int n = (int) (Math.random() * words.length);//用于随机产生一个单词
            int miss = 0;//将失误次数设置为
            char[] guess = new char[words[n].length()];

            for (int j = 0; j < words[n].length(); j++)
                guess[j] = '*';//将还没有猜出来的的单词设置为*

            boolean m = true;

            a:
            while (m) {
                System.out.print("<Guess>Enter a letter in word ");

                for (int j = 0; j < guess.length; j++)
                    System.out.print(guess[j]);//输出单词

                System.out.print(">");

                char letter = input.next().charAt(0);//输入你所猜测的字母

                //如果输入的单词重复则有以下情况
                for (int z=0;z<guess.length;z++)
                    if (letter==guess[z]){
                        System.out.println(letter+" is already in the word");
                        continue a;
                    }

                //如果猜出的字母属于单词,则将其添加到guess之中
                int count = 0;
                for (int k = 0; k < words[n].length(); k++) {
                    if (letter == words[n].charAt(k)) {
                        count = 1;
                        guess[k] = letter;
                    }
                }
                //如果count==0则说明没有猜正确单词
                if (count == 0) {
                    miss++;
                    System.out.println(letter + " is not a letter in word");
                }
              //弱国guess之中还存在‘*’则说明还没有猜完,游戏继续,反之结束本轮游戏
                for (int l = 0; l < words[n].length(); l++) {
                    if (guess[l] == '*')
                        continue a;
                }
                m = false;//退出本轮游戏
                System.out.println("yes! this word is " + words[n] + ", you missed " + miss + " times");
            }
            //询问是否进行下一轮游戏,y继续游戏 n结束本轮游戏
            System.out.print("Do you want to guess for another word? Enter y or n ");
            char choice = input.next().charAt(0);
            if (choice=='n')
                break;


        }


    }

}

版本2:

实现画出以下图形界面的程序。

 

package version2;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Arc;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

public class game2 extends Application{
    @Override
    public void start(Stage primaryStage){

    Pane pane = new Pane();//创建一个面板
    //创建一个人的小人,包括头,身体
    Circle circle = new Circle();
        circle.setCenterX(270);
        circle.setCenterY(150);//设置圆心坐标
        circle.setRadius(40);//设置半径
        circle.setStroke(Color.BLACK);//边框颜色
        circle.setFill(Color.WHITE);//填充颜色
    Line body = new Line(270,190,270,300);//设置躯干的长度
    Line leg0 = new Line(270,300,245,350);
    Line leg1 = new Line(270,300,295,350);//设置两条腿的长度
    Line arm0 = new Line(270-25*Math.sqrt(2),150+25*Math.sqrt(2),270-25*Math.sqrt(2)-40,150+25*Math.sqrt(2)+40);
    Line arm1 = new Line(270+25*Math.sqrt(2),150+25*Math.sqrt(2),270+25*Math.sqrt(2)+40,150+25*Math.sqrt(2)+40);
    //设置两条胳膊的长度

    /* 创造支架,设置线条颜色和填充颜色 */
    Line line0 = new Line(270,110,270,50);//连接小人头的部分
    Line line1 = new Line(270,50,100,50);//平行于地面的部分
    Line line2 = new Line(100,50,100,375);//垂直于地面的部分
    Arc base = new Arc(100,400,75,25,0,180);//设置地基部分
        base.setFill(Color.WHITE);
        base.setStroke(Color.BLACK);//填充颜色以及线条颜色
    /* 将支架和小人加入面板中 */
        pane.getChildren().add(circle);
        pane.getChildren().add(line0);
        pane.getChildren().add(line1);
        pane.getChildren().add(line2);
        pane.getChildren().add(body);
        pane.getChildren().add(leg1);
        pane.getChildren().add(leg0);
        pane.getChildren().add(arm0);
        pane.getChildren().add(arm1);
        pane.getChildren().add(base);
    /* 设置场景和舞台大小 */
    Scene scene = new Scene(pane,400,400);
        primaryStage.setTitle("Hangman game");//设置主舞台标题为Hangman game
        primaryStage.setScene(scene);
        primaryStage.show();
}
}

版本3:

结合以上两个功能,实现动画方式的侩子手游戏,当用户猜错7次,绞刑架上的人摆动。当一个单词完成后,用户使用回车键继续猜下一个单词。

初始状态如下:

 

猜错一次:

 

猜错2次:

 

猜错7次:

 

完成一个单词:

 

package version3;
import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Arc;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;


import java.util.Arrays;
import java.util.Random;

public class KillerGame extends Application {


    String[] words = {"write", "this", "love", "for"};//添加单词到数组之中
    int n=(int)(Math.random()*words.length);
    String result=words[n];//随机生成一个单词  String result = words[new Random().nextInt(words.length)];
    char[] guess = new char[words[n].length()];//储存猜测的结果 char[] theResult = new char[result.length()];
    private int miss=0;//用来计数猜测失败的次数 failCount
    String guess0;//储存猜测结果(String)String word2;
    private Label label = new Label("<Guess>Enter a letter in word ");
    // 坐标位于0,0的label
    private Label judgeLine = new Label();
    // 坐标位于0,1的label
    private Label /*failCountLine*/ missCount = new Label("Your enter is not a letter in word.");
    // 坐标位于1,1的label
    TextField tf= new TextField(); // 初始输入框
    RotateTransition rt = new RotateTransition();//实现动画旋转的

    Button ybt = new Button("Yes");// // Yes按钮和No按钮
    Button nbt = new Button("No");//用于设置yes和no按钮 借此来选择是否继续游戏

    Pane pane = new Pane();// 用于储存所有形状的Pane
    GridPane gridPane = new GridPane();// 用于储存前三行的Pane 网格类
    GridPane newGame = new GridPane();// 用于询问是否重新开始的GridPane
    Group guideGroup = new Group();// 用于储存辅助线并设置为透明的Group
    Group people = new Group();// 看作一个装人形的容器

    //创建一个人的小人,包括头,身体
    Line guideLine = new Line();//设置辅助线
    Circle circle = new Circle(270,150,40);//设置小人的头,即设置一个圆形的圆心和半径
    Line body = new Line(270,190,270,300);//设置躯干的长度
    Line leg0 = new Line(270,300,245,350);
    Line leg1 = new Line(270,300,295,350);//设置两条腿的长度
    Line arm0 = new Line(270-25*Math.sqrt(2),150+25*Math.sqrt(2),270-25*Math.sqrt(2)-40,150+25*Math.sqrt(2)+40);
    Line arm1 = new Line(270+25*Math.sqrt(2),150+25*Math.sqrt(2),270+25*Math.sqrt(2)+40,150+25*Math.sqrt(2)+40);
    //设置两条胳膊的长度
    Line rope = new Line(270,75,270,50);//连接小人头的部分

    //此部分用于绘制游戏中支架部分
    public static Pane fixedPart(Stage stage)  {
        Pane p1 = new Pane();
        Line line1 = new Line(310,85,100,85);// 平行于地面的直线,第一条
        Line line2 = new Line(100,85,100,375);// 垂直于地面的直线,第二条
        Arc arc1 = new Arc(100,400,75,25,0,180);//设置底座
        arc1.setStyle("-fx-stroke: BLACK;-fx-fill: WHITE");//令地基的边框为黑色 填充为白色
        p1.getChildren().addAll(line1, line2, arc1);
        return p1;
    }

    public void  initialization() {
        //初始化
        n = (int) (Math.random() * words.length);//用于随机产生一个单词
        result = words[n];
        guess = new char[result.length()];
        Arrays.fill(guess, '*');//初始化猜测数组 使之全部为‘*’
        miss = 0;//重置了错误的次数

        StringBuilder str = new StringBuilder();
        for (char c : guess) {
            str.append(c);
        }
        guess0 = str.toString();//将char类型转化成String类型

        label = new Label(" <Guess>e=Enter a letter in a word: " + guess0);
        gridPane.add(label, 0, 0);//将label放在(0,0)处
        // 将judgeLine(提示行)初始化并放置在(0,1)
        judgeLine = new Label();
        gridPane.add(judgeLine, 0, 1);
        missCount = new Label("Your enter is not a letter in word");

    }

    /*判断字母是否在单词之中*/
    public static boolean letterInWord(char x, char[] list) {
        for (char m : list) {
            if (x == m) {
                return true;
            }
        }
        return false;
    }

    // 判断字母是否在字符数组中并替换对应的Label语句
    public void labelFixed(char x, char[] list, Stage stage) {
        gridPane.getChildren().remove(label);
        gridPane.getChildren().remove(judgeLine);
        if (letterInWord(x, list)) {
            //字母在对应的数组之中{
            if (letterInWord(x, guess)){
                //字母是否在单词之中
                // 此步骤是为了防止重复输入已正确的字母
                judgeLine = new Label(" " + x + " is already in the word");
                gridPane.add(judgeLine, 0, 1);
            }
            else {
                // x不在guess中,即给出的答案之中
                for (int i = 0; i<guess.length; i++) {
                    if (x == list[i]) {
                        guess[i] = x;
                    }
                }
            }
        }
        else {
            // 当猜错的时候才对missCount进行更新
            gridPane.getChildren().remove(missCount);
            judgeLine = new Label(" " + x + " is not in the word");
            missCount = new Label(missCount.getText() + x);
            miss++;//错误次数加1
            gridPane.add(missCount, 1, 1);
            gridPane.add(judgeLine, 0, 1);
            peopleShape(miss, stage);//根据猜错的次数设置小人的样式
        }
        StringBuilder str = new StringBuilder();
        for (char c : guess) {
            str.append(c);
        }
        guess0 = str.toString();//将char类型转化成String类型


        label = new Label("Guess a word:" +guess0 );
        gridPane.add(label, 0, 0);
        if ((guess0.equals(result)) || (miss== 7)) {
            peopleGuideLine(miss);//生成辅助线
            if (miss == 7) {//游戏失败 询问玩家是否开始新游戏
                newGame.add(new Label("You lose. Game again?"), 0, 0);
            }
            else {
                // 游胜利,同时询问是否重新开始
                newGame.add(new Label("You win. Game again?"), 0, 0);
            }
            gridPane.add(newGame, 0, 3);
            gridPane.add(ybt, 1, 3);
            gridPane.add(nbt, 2, 3);//yes和no按钮
            ybt.setOnAction(e -> yesRefreshGame());
            nbt.setOnAction(e -> noRefreshGame());//注册事件驱动处理器,功能是选择是否继续游戏
        }
    }

    public void peopleShape(int i, Stage stage) {
        people.getChildren().removeAll(rope,circle/*头*/, body, arm0, arm1, leg0, leg1);
        switch (i) {
            //属性绑定
            case 7:
                leg1.startXProperty().bind(body.endXProperty());
                leg1.startYProperty().bind(body.endYProperty());
                leg1.endXProperty().bind(leg1.startXProperty().subtract(48));
                leg1.endYProperty().bind(leg1.startYProperty().add(64));
                people.getChildren().add(leg1);
            case 6:
                leg0.startXProperty().bind(body.endXProperty());
                leg0.startYProperty().bind(body.endYProperty());
                leg0.endXProperty().bind(leg0.startXProperty().add(48));
                leg0.endYProperty().bind(leg0.startYProperty().add(64));
                people.getChildren().add(leg0);
            case 5:
                arm1.startXProperty().bind(circle.centerXProperty().subtract(24));
                arm1.startYProperty().bind(circle.centerYProperty().add(32));
                arm1.endXProperty().bind(arm1.startXProperty().subtract(48));
                arm1.endYProperty().bind(arm1.startYProperty().add(64));
                people.getChildren().add(arm1);
            case 4:
                arm0.startXProperty().bind(circle.centerXProperty().add(24));
                arm0.startYProperty().bind(circle.centerYProperty().add(32));
                arm0.endXProperty().bind(arm0.startXProperty().add(48));
                arm0.endYProperty().bind(arm0.startYProperty().add(64));
                people.getChildren().add(arm0);
            case 3:
                body.startXProperty().bind(circle.centerXProperty());
                body.startYProperty().bind(circle.centerYProperty().add(40));
                body.endXProperty().bind(body.startXProperty());
                body.endYProperty().bind(body.startYProperty().add(100));
                people.getChildren().add(body);
            case 2:
                circle.centerXProperty().bind(rope.endXProperty());
                circle.centerYProperty().bind(rope.endYProperty().add(40));
                circle.setStyle("-fx-stroke: BLACK;-fx-fill: WHITE");
                people.getChildren().add(circle);
            case 1:
                rope.startXProperty().bind(stage.widthProperty().multiply(0.6));
                rope.startYProperty().bind(stage.heightProperty().divide(6));
                rope.endXProperty().bind(rope.startXProperty());
                rope.endYProperty().bind(rope.startYProperty().add(50));
                people.getChildren().add(rope);
                break;
        }
    }

    // 根据失败的次数生成辅助线,并将其添加到group当中,同时播放动画效果
    public void peopleGuideLine(int i) {
        guideLine = new Line(300, 50, 300, 51);
        guideLine.startXProperty().bind(rope.startXProperty());
        guideLine.startYProperty().bind(rope.startYProperty());
        guideLine.endXProperty().bind(guideLine.startXProperty());
        if (i==1)//失败一次
            guideLine.endYProperty().bind(rope.startYProperty().subtract(rope.endYProperty().subtract(rope.startYProperty())));
        if (i==2)//失败两次
            guideLine.endYProperty().bind(rope.startYProperty().subtract(circle.centerXProperty().add(circle.radiusProperty()).subtract(rope.startYProperty())));
        if (i==3||i==4||i==5)//失败3、4、5次
            guideLine.endYProperty().bind(rope.startYProperty().subtract(body.endYProperty().subtract(rope.startYProperty())));
        if (i==6||i==7)//失败6、7次
            guideLine.endYProperty().bind(rope.startYProperty().subtract(leg0.endYProperty().subtract(rope.startYProperty())));
        guideGroup.setOpacity(0);
        guideGroup.getChildren().add(guideLine);
        people.getChildren().add(guideGroup);
        rt.setNode(people);//此动画应用到person上
        rt.setFromAngle(30);//从30度开始
        rt.setByAngle(-60);//设置动画摇摆的角度
        rt.setAutoReverse(true);//
        rt.setInterpolator(Interpolator.LINEAR);//匀速
        rt.setRate(0.5);//定义速度大小
        rt.setCycleCount(Timeline.INDEFINITE);//循环
        rt.play();//播放
    }

    // 重新开始游戏的方法
    public void yesRefreshGame() {
        people.getChildren().removeAll(rope, circle, body, arm0, arm1, leg0, leg1, guideGroup);
        gridPane.getChildren().removeAll(label, missCount, judgeLine, newGame, ybt, nbt);
        initialization();//初始化
        rt.stop();
    }
    // 不重新开始游戏的方法
    public void noRefreshGame() {
        pane.getChildren().remove(gridPane);
        pane.getChildren().add(new Label("End"));//如果选择不继续游戏则游戏结束
    }


    @Override
    public void start(Stage stage) {
        pane = fixedPart(stage);// 画出固定不动的架子
        initialization();// 用初始化方法将面板初始化
        gridPane.setHgap(8);
        gridPane.setVgap(8);//设置结点间距离
        tf = new TextField();// 设置输入框
        gridPane.add(tf, 1, 0);
        gridPane.add(new Label("Enter"), 2, 0);
        //将char字符与结果单词进行比较
        tf.setOnAction(e -> labelFixed(tf.getText().charAt(0), result.toCharArray(), stage));
        pane.getChildren().add(gridPane);
        pane.getChildren().add(people);
        Scene scene = new Scene(pane, 500, 500);
        stage.setTitle("KillerGame");
        stage.setScene(scene);
        stage.setResizable(false);//不可设置大小
        stage.setMaximized(false);//不最大化
        stage.show();
    }
}

  • 9
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天的命名词

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值