对话框是很多游戏都有的内容,当我们观察游戏的对话框,会发现其主要内容有:人物头像,对话内容以及对话框背景贴图,这篇文章就主要对对话框进行绘制。
对话框实体类
除了上面我们提到的主要内容以外,我们还需要模拟对话框中文字延时展示的效果,也就是每隔一段时间多显示几个字这样的效果。我们采用延时计数的形式进行实现,每当计数器到了某个值的时候才让字符串指针前进,并且当字符串指针已经到达字符串的尾部的时候,将不再前进。
@Data
@NoArgsConstructor
@AllArgsConstructor
// 文字动画类,主要实现的功能是一个字一个字浮现一段话
public class TextAnimEntity {
// 这个属性是说话的人
private String name;
// 这个属性是说的话
private String text;
// 人物的头像
private Image image;
// 背景图片
private Image bgImage;
private int width = 100;
private int height = 100;
// 指针,指向下一个要显示的字
private int textIdx;
// 定义一个延时计数器,只有计数器到达一定值的时候才将指针前移
private int clock;
private int clock_max;
// 是否完全显示标志位
private boolean finish;
public TextAnimEntity(String image, String bg_img,String name, String text){
this.image = new Image(image, width, height, true, true);
this.bgImage = new Image(bg_img);
this.name = name;
this.text = text;
this.textIdx = 0;
this.finish = false;
this.clock = 0;
this.clock_max = 5;
}
private String getsub(){
if (textIdx == 0) {
return "";
}
char[] c = new char[textIdx+1];
for(int i=0; i<textIdx; i++){
c[i] = text.charAt(i);
}
return new String(c);
}
// 获取要显示的字
public synchronized String getnext(){
if(finish){
return name + ":" + text;
}
if(clock < clock_max){
//System.out.println(textIdx);
clock++;
return name + ":" + getsub();
} else {
clock = 0;
String rst = name + ":" + getsub();
textIdx++;
if (textIdx == text.length()) {
finish = true;
}
return rst;
}
}
}
绘制类
绘制类在之前的基础上需要再加上对画框的绘制,由于对话框是显示在最上面的,所以应该最后绘制。
public class AnimDrawer {
private Canvas canvas;
private GraphicsContext gc;
// 动画集合
private List<AnimEntity> animlist;
// 对话集合
private List<TextAnimEntity> textlist;
public AnimDrawer(Canvas canvas, GraphicsContext gc){
this.canvas = canvas;
this.gc = gc;
animlist = new ArrayList<>();
textlist = new ArrayList<>();
}
// 添加对话实体
public void addText(TextAnimEntity textEntity){
textlist.add(textEntity);
}
// 移除对话实体
public void removeText(TextAnimEntity textEntity){
textlist.add(textEntity);
}
// 添加动画实体
public void addAnim(AnimEntity animEntity){
this.animlist.add(animEntity);
}
// 移除动画实体
public void removeAnim(AnimEntity animEntity){
this.animlist.remove(animEntity);
}
// 开始不停画动画
public void start(int timeout){
new Thread(()->{
while (true) {
draw();
try {
Thread.sleep(timeout);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
// 在画布上画动画
public void draw(){
if(animlist.size() == 0){
throw new RuntimeException("没有动画呀");
}
gc.clearRect(0,0,canvas.getWidth(), canvas.getHeight());
for(int i=0; i<animlist.size(); i++){
//System.out.println("aaa");
gc.drawImage(animlist.get(i).getnext(),
animlist.get(i).getPosx(), animlist.get(i).getPosy(),
animlist.get(i).getWidth(), animlist.get(i).getHeight());
}
// 绘制对话
// 首先在屏幕下半区绘制一个黑色矩形
//gc.strokeRect(0, 350, canvas.getWidth(), canvas.getHeight()-350);
TextAnimEntity entity = textlist.get(0);
// 绘制对话框
gc.drawImage(entity.getBgImage(), 0, 350,canvas.getWidth(), canvas.getHeight()-350);
// 绘制头像
gc.drawImage(entity.getImage(), 35,380, 50,50);
// 绘制说的话
gc.setFont(Font.getDefault());
//System.out.println(entity.getnext());
//gc.setFill(Color.BLACK);
gc.strokeText(entity.getnext(), 100, 400);
}
}
主启动类
主启动类主要是添加了加载对话框的内容的代码
public class MainStage extends Application {
public static void main(String[] args) {
launch(args);
}
// 读取文件夹下面的所有图片
public List<String> getnamelist(String sufix){
String path = "/workspace/JAVAFXGame/target/classes/image/" + sufix;
File file = new File(path);
String[] filelist = file.list();
List<String> namelist = new ArrayList<>();
for(int i=0; i<filelist.length; i++){
namelist.add("/image/" + sufix + "/" + filelist[i]);
}
return namelist;
}
@Override
public void start(Stage primaryStage) throws Exception {
Canvas canvas = new Canvas(500,500);
GraphicsContext gc = canvas.getGraphicsContext2D();
AnimDrawer animDrawer = new AnimDrawer(canvas, gc);
// 创建动画
List<String> namelist = getnamelist("role");
List<String> namelist1 = getnamelist("role1");
AnimEntity animEntity = new AnimEntity(namelist, 150, 150, 50, 100);
AnimEntity animEntity1 = new AnimEntity(namelist1, 150,150, 150,100);
animDrawer.addAnim(animEntity);
animDrawer.addAnim(animEntity1);
// 添加对话实体类
TextAnimEntity textAnimEntity = new TextAnimEntity("/image/刻晴111.png", "/image/对话框2.png","刻晴", "你们是谁,来这里干什么");
animDrawer.addText(textAnimEntity);
animDrawer.start(50);
Pane pane = new Pane();
Scene scene = new Scene(pane, 500,500);
pane.getChildren().add(canvas);
primaryStage.setScene(scene);
primaryStage.show();
}
}
效果展示
?图片素材
本文素材较为简单,就是刻晴的头像以及背景图
?
|