Java语言程序设计基础篇_编程练习题***18.33 (游戏:骑士旅途的动画)

目录

***18.33 (游戏:骑士旅途的动画)

习题思路

代码示例

动画演示


***18.33 (游戏:骑士旅途的动画)

  为骑士旅途的问题编写一个程序,该程序应该允许用户将骑士放到任何一个起始正方形,并单击Solve按钮,用动画展示骑士沿着路径的移动,如图18-16所示

  • 习题思路

  1. 初始化棋盘和骑士位置

    1. Board类:这个内部类继承自Pane,用于绘制棋盘和骑士。棋盘通过绘制水平和垂直线来创建,而骑士则通过红色圆圈表示。
    2. draw方法:此方法用于绘制棋盘和骑士。首先清除所有子节点,然后绘制棋盘网格和初始骑士位置(红色圆圈)。骑士有两个圆圈表示:theKnight(静态位置)和movingKnight(用于动画的移动位置)。
    3. startX和startY:这两个变量用于记录骑士的起始位置。初始时,它们被设置为(0, 0),即棋盘的左上角。但用户可以通过点击棋盘上的任意格子来改变这些值。
  2. 点击事件处理

    1. 当用户在棋盘上点击时,Board类中的setOnMouseClicked事件处理器会被触发。
    2. 事件处理器计算点击位置对应的格子索引(startXstartY),这是通过将鼠标点击的坐标除以每个格子的大小(棋盘宽度/SIZE或棋盘高度/SIZE)并取整来实现的。
    3. 随后,重置moves列表,即骑士的移动历史,为新的求解过程做准备。
  3. 求解按钮点击事件

    1. 当用户点击“Solve”按钮时,会触发一个事件处理器,该处理器执行以下步骤:
    2. 初始化棋盘状态:创建一个boolean[][] moves数组来跟踪哪些格子已被访问。将起始位置标记为已访问。
    3. 重置和添加起始移动:调用resetMoves()addMove(startX, startY)来重置移动历史并添加起始位置到历史中。
    4. 递归求解:调用solvePuzzle(moves, 1, startX, startY)开始递归求解过程。该方法尝试从当前位置出发,找到所有可能的下一步,并评估哪一步能导致最少的未访问格子数(通过lookAheadCount方法)。然后,它选择最优的下一步,并递归地尝试解决剩余的问题。
    5. 动画展示:如果找到解决方案,draw方法会被再次调用以更新棋盘上的骑士位置(尽管在这个实现中,movingKnight并未在动画中实际移动),然后调用playAnimation方法来展示骑士的移动路径。
  4. 动画展示

    1. playAnimation方法:此方法使用SequentialTransitionPathTransition来创建动画,展示骑士沿着求解路径移动的过程。对于moves列表中的每一对相邻点,它创建一个PathTransition,该过渡使一个红色圆圈沿着两点之间的直线移动。所有这些过渡被添加到一个SequentialTransition中,以便按顺序播放。
  • 代码示例

编程练习题18_33TheKnightJourney.java

package chapter_18;  import java.util.ArrayList;
import javafx.animation.PathTransition;
import javafx.animation.SequentialTransition;
import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;  
import javafx.scene.Scene;  
import javafx.scene.control.Button;  
import javafx.scene.layout.BorderPane;  
import javafx.scene.layout.Pane;  
import javafx.scene.paint.Color;  
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
import javafx.util.Duration;  public class 编程练习题18_33TheKnightJourney extends Application {private static final int SIZE = 8;private int startX = 0;private int startY = 0;private ArrayList<Point2D> moves = null;private ArrayList<Line> pathList;public static void main(String[] args) {  Application.launch(args);  }  @Override  public void start(Stage primaryStage) throws Exception {pathList = new ArrayList<Line>();BorderPane pane = new BorderPane();Board board = new Board();pane.setCenter(board);Button btSolve = new Button("Solve");pane.setBottom(btSolve);BorderPane.setAlignment(btSolve, Pos.CENTER);Scene scene = new Scene(pane,400,400);primaryStage.setTitle("编程练习题18_33TheKnightJourney");primaryStage.setScene(scene);primaryStage.show();board.draw();btSolve.setOnAction(e -> {boolean[][] moves = new boolean[SIZE][SIZE];moves[startX][startY] = true;resetMoves();addMove(startX,startY);solvePuzzle(moves,1,startX,startY);board.draw();board.playAnimation(pathList);});}private boolean solvePuzzle(boolean[][] moves,int numberMoves,int x,int y) {int nextX = 0;int nextY = 0;int bestMoveX = 0;int bestMoveY = 0;int bestMoveX2 = 0;int bestMoveY2 = 0;int minMoveCount = SIZE;int moveCount = 0;for(int i = 2;i >= -2;i += -4) {for(int j = 1;j >= -1;j += -2) {nextX = x + i;nextY = y + j;if(nextX >= 0&&nextX <= SIZE-1&&nextY >= 0&&nextY <= SIZE-1&&!moves[nextX][nextY]) {moveCount = lookAheadCount(moves,nextX,nextY);if(moveCount <= minMoveCount) {minMoveCount = moveCount;bestMoveX2 = bestMoveX;bestMoveY2 = bestMoveY;bestMoveX = nextX;bestMoveY = nextY;}}nextX = x + j;nextY = y + i;if(nextX >= 0&&nextX <= SIZE-1&&nextY >= 0&&nextY <= SIZE-1&&!moves[nextX][nextY]) {moveCount = lookAheadCount(moves,nextX,nextY);if(moveCount <= minMoveCount) {minMoveCount = moveCount;bestMoveX2 = bestMoveX;bestMoveY2 = bestMoveY;bestMoveX = nextX;bestMoveY = nextY;}}}}moves[bestMoveX][bestMoveY] = true;addMove(bestMoveX,bestMoveY);numberMoves++;if(numberMoves == (SIZE * SIZE))return true;if(moveCount > 0&&solvePuzzle(moves, numberMoves, bestMoveX, bestMoveY))return true;moves[bestMoveX][bestMoveY] = false;moves[bestMoveX2][bestMoveY2] = true;removeLastMoveHistory();addMove(bestMoveX2,bestMoveY2);if(moveCount > 1&&solvePuzzle(moves, numberMoves, bestMoveX2, bestMoveY2)) {return true;}moves[bestMoveX2][bestMoveY2] = false;removeLastMoveHistory();numberMoves--;return false;}private int lookAheadCount(boolean[][] moves,int x,int y) {int maxCount = 0;for(int i = -2;i<=2;i+=4) {for(int j = -1;j <= 1;j += 2) {int nextX = x + i;int nextY = y + j;if(nextX >= 0&&nextX <= SIZE-1&&nextY >=0 && nextY <= SIZE-1&&!moves[nextX][nextY]) {maxCount++;}nextX = x + j;nextY = y + i;if(nextX >= 0&&nextX <= SIZE-1&&nextY >= 0&&nextY <= SIZE-1&&!moves[nextX][nextY])maxCount++;}}return maxCount;}public void resetMoves() {moves = new ArrayList(63);}public void addMove(int x,int y) {moves.add(new Point2D(x, y));}public void removeLastMoveHistory() {moves.remove(moves.size()-1);}private class Board extends Pane{Circle theKnight = new Circle();Circle movingKnight = new Circle();Board(){this.setOnMouseClicked(e ->{startX = (int)(e.getX()/(getWidth()/SIZE));startY = (int)(e.getY()/(getHeight()/SIZE));resetMoves();draw();});}protected void draw() {this.getChildren().clear();this.getChildren().add(theKnight);theKnight.setCenterX(startX * getWidth()/SIZE +15);theKnight.setCenterY(startY * getHeight()/SIZE + 15);theKnight.setRadius(5);theKnight.setFill(Color.RED);movingKnight.setCenterX(startX * getWidth()/SIZE +15);movingKnight.setCenterY(startY * getHeight()/SIZE + 15);movingKnight.setRadius(5);movingKnight.setFill(Color.RED);this.getChildren().add(movingKnight);for(int i = 1;i <= SIZE;i++) {this.getChildren().add(new Line(0,i*getHeight()/SIZE,getWidth(),i*getHeight()/SIZE));			                     this.getChildren().add(new Line(i*getWidth()/SIZE,0,i*getWidth()/SIZE,getHeight()));}if(moves != null) {for(int i = 1;i < moves.size();i++) {Point2D p1 = moves.get(i - 1);Point2D p2 = moves.get(i);Line line = new Line(p1.getX()*(getWidth()/SIZE)+(getWidth()/SIZE/2),p1.getY()*(getHeight()/SIZE)+(getHeight()/SIZE/2),p2.getX()*(getWidth()/SIZE)+(getWidth()/SIZE/2),p2.getY()*(getHeight()/SIZE)+(getHeight()/SIZE/2));pathList.add(line);}}}private void playAnimation(ArrayList<Line> lines) {int i = 0;SequentialTransition sequentialTransition = new  SequentialTransition();Circle c;c = new Circle(5);c.setFill(Color.RED);getChildren().add(c);for(Line l: lines) {PathTransition transition = new PathTransition(Duration.seconds(1), l, c);transition.setOnFinished(e->{if(i<lines.size()-2) {getChildren().add(l);}});sequentialTransition.getChildren().add(transition);}sequentialTransition.play();}}
}
  • 动画演示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/149232.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

9.5HSV体系进行颜色分割

基本概念 inRange() 函数是 OpenCV 中用于图像处理的一个非常有用的函数&#xff0c;即从图像中提取出介于指定范围内的像素值。这个函数在图像处理中特别有用&#xff0c;比如颜色检测、背景去除等应用。它主要用于图像的阈值处理&#xff0c;但与其他阈值方法&#xff08;如…

前端——浮动+定位样式

一、浮动float——浮动是会使盒子脱离文档流 添加了浮动的元素 1.原本的位置不占用 脱离文档流 2.设置了浮动 就不支持auto自适应居中 3.文字会感受到浮动 跟着进行文字环绕效果 而不是浮动元素覆盖文字 文字和浮动处于同一层的关系 4.可以使行内元素支持 高…

苍穹外卖——day3

1.公共字段自动填充 我们在添加功能的时候常常要重复执行一些重复的操作 如下图 我们在执行update或者insert数据库操作的时候&#xff0c;总是要给下面的一些属性赋值 这样如果代码功能一多&#xff0c;这会显得代码很冗长 所以我们引入了公共字段自动填充这个功能的实现…

从入门到精通:SQL 100个关键技术关键词

无论你是刚刚接触数据库管理的新手&#xff0c;还是希望提升技能水平的数据分析师&#xff0c;掌握SQL都是至关重要的一步。SQL是一种强大的工具&#xff0c;用于管理和操作关系型数据库。从简单的数据检索到复杂的事务处理&#xff0c;SQL提供了广泛的功能来满足各种需求。为了…

软件设计师:01计算机组成与结构

文章目录 一、校验码1.奇偶校验码2.海明码3.循环冗余检验码 二、原码反码补码移码三、浮点数表示法1.浮点数相加时 四、寻址方式五、CPU1.访问速度2.cpu的组成 六、RISC和CISC&#xff08;<font color red>只用记住不同就可以&#xff09;七、冗余技术1.结构冗余2.信息冗…

unix中的vfork函数

一、前言 本文介绍unix中的vfork函数&#xff0c;vfork函数功能和fork函数类似&#xff0c;也是用于创建新的进程&#xff0c;只不过调用vfork函数创建的子进程将共享父进程的进程空间&#xff0c;且只有当子进程调用exec()或者exit()函数后&#xff0c;父进程才会继续运行。 …

统信服务器操作系统【Cron定时任务服务】

Cron定时任务服务服务介绍、服务管理、服务配置 文章目录 一、功能概述二、功能介绍1. Cron 服务管理2.Cron 服务管理3.Cron 服务配置run-parts一、功能概述 cron是一个可以用来根据时间、日期、月份、星期的组合来 调度对周期性任务执行的守护进程。利用 cron 所提供的功能,可…

苹果电脑系统重磅更新——macOS Sequoia 15 系统 新功能一 览

有了 macoS Sequoia&#xff0c;你的工作效率将再次提升&#xff1a;快速调整桌面布局&#xff0c;一目了然地浏览网页重点&#xff0c;还可以通过无线镜像功能操控你的iPhone。 下面就来看看几项出色新功能&#xff0c;还有能够全面发挥这些功能的 App 和游戏。 macOS Sequo…

Vue 中 watch 的使用方法及注意事项

前言 Vue 的 Watch 是一个非常有用的功能&#xff0c;它能够监听 Vue 实例数据的变化并执行相应的操作。本篇文章将详细介绍 Vue Watch 的使用方法和注意事项&#xff0c;让你能够充分利用 Watch 来解决 Vue 开发中的各种问题。 1. Watch 是什么&#xff1f; 1.1 Watch 的作…

NVIDIA发布端到端自动驾驶框架Hydra-MDP

自动驾驶是目前人工智能领域的一个主要分支&#xff0c;目前特斯拉的FSD确实是为数不多的大模型框架。与其说特斯拉是一个造车公司&#xff0c;不如说是一个人工智能大数据公司。特斯拉每天靠行驶在道路上的汽车搜集的道路数据不胜其数&#xff0c;而拥有海量的数据是人工智能领…

数据结构——顺序表、链表

目录 前言 一&#xff0c;数据结构 1&#xff0c;什么是数据结构&#xff1f; 2&#xff0c;有什么类型&#xff1f; 二&#xff0c;顺序表 1&#xff0c;线性表 2&#xff0c;顺序表基本结构 3&#xff0c;动态顺序表的功能实现 三&#xff0c;链表 1&#xff0c;链…

乌克兰因安全风险首次禁用Telegram

据BleepingComputer消息&#xff0c;乌克兰国家网络安全协调中心 &#xff08;NCCC&#xff09; 以国家安全为由&#xff0c;已下令限制在政府机构、军事单位和关键基础设施内使用 Telegram 消息应用程序。 这一消息通过NCCC的官方 Facebook 账号对外发布&#xff0c;在公告中乌…

2024icpc(Ⅱ)网络赛补题 L

L、502 Bad Gateway 题意&#xff1a; 给定一个 T T T&#xff0c;每一步可以做以下两个操作&#xff1a; 1、减1 2、随机重置为 [ 1 , T ] [1,T] [1,T]中的某个整数 求在最优策略下&#xff0c;得到 0 0 0的期望步数 思路&#xff1a; 最优策略为选择一个阈值 S S S&…

01.系统IO

文章的函数说明只是简单的说明&#xff0c;具体还得查看man手册 Linux文件说明 linux下一切皆是文件。 Linux 下的文件类型&#xff1a; 1&#xff0c;普通文件&#xff08;regular&#xff09;&#xff1a;存在于外部存储器中&#xff0c;用于存储普通数据。 2&#xff0…

深入理解音视频pts,dts,time_base以及时间数学公式

引入 首先介绍一下基础名词 DTS&#xff08;Decoding Time Stamp&#xff09;&#xff1a;即解码时间戳&#xff0c;这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。当数据没b帧时&#xff0c;dts pts&#xff0c;有兴趣可参阅我前面视频知识类文章。 PTS&a…

统信服务器操作系统【开机自启动】配置方法

开机自启动的四种配置方法,包括systemctl命令、rc.local文件、crontab任务,通过desktop配置开机自动,前三种方法适合后台程序或者脚本启动,最后一种方法适合图形化程序启动。 文章目录 准备环境配置方法一、通过编写service的方法,使用systemctl配置开机自启二、通过rc.lo…

展锐平台的手机camera 系统isptool 架构

展锐平台的isptool 主要用于支持展锐各代芯片isp的各效果模块快速tuning和参数生成打包。 具体需要&#xff1a; 一、工具段能在线实时预览到调试sensor经过isp 处理后的图像&#xff0c;也就是各模块的参数在当下实时生效&#xff0c;通过工具能在PC 上在线观看到修改的效果。…

【企业微信】群机器人自动消息配置

0、群聊机器人 内部企微群聊可以添加一个机器人&#xff0c;这个机器人其实是个消息接口&#xff0c;可以外部脚本来自动定时发送消息到群里&#xff0c;打工人最有用的提醒就是每周提醒发周报了。 1、创建机器人 一般公司都没有人使用&#xff0c;我们可以手动创建一个。 …

小程序开发设计-小程序的宿主环境:宿主环境简介⑥

上一篇文章导航&#xff1a; 小程序开发设计-小程序代码的构成&#xff1a;小程序页面的组成部分详解⑤-CSDN博客https://blog.csdn.net/qq_60872637/article/details/142306902?spm1001.2014.3001.5501 注&#xff1a;不同版本选项有所不同&#xff0c;并无大碍。 目录 上…

OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【用户态内存调测】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 基本概念 Debug版本的musl-libc库为用户提供内存泄漏检测、堆内存…