java - 如何在游戏循环中绘制图形上下文?
问题描述
我正在制作水果忍者游戏,我想暂停动画计时器一段时间并将图像设置为切片水果图像“current.getBufferedImages()[1]”,但我得到相同的非切片图像水果“current.getBufferedImages()[0]”即使我更改了要在 graphicsContext.setImage() 中绘制的图像
public void startGame(Stage primaryStage) throws Exception {
ga = GameActions.get();
canvas = new Canvas(1024,683);
gc = canvas.getGraphicsContext2D();
timeline = new Timeline(new KeyFrame(Duration.millis(falling), event -> {
time += falling / 3000;
IGameObject c = ga.createGameObject();
drop.add(c);
}));
timeline.setCycleCount(4000);
timeline.play();
timer = new AnimationTimer() {
@Override
public void handle(long arg0) {
gameUpdate(primaryStage);
}
};
timer.start();
scene = new Scene(root, 1024, 683);
root.getChildren().addAll(ivBackground,lblMissed,canvas,back,reset);
primaryStage.setScene(scene);
primaryStage.show();
}
public void gameUpdate(Stage stage){
Image k;
gc.drawImage(background, 300, 300);
gc.clearRect(0, 0, 1024, 683);
Iterator<IGameObject> itr = drop.iterator();
while(itr.hasNext()) {
IGameObject current = itr.next();
EventHandler<MouseEvent> e = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if(current.insideBounds(event.getX(), event.getY()))
current.slice();
}
};
gc.getCanvas().setOnMousePressed(e);
if(!current.isSliced()) {
k = SwingFXUtils.toFXImage(current.getBufferedImages()[0], null);
}else {
k = SwingFXUtils.toFXImage(current.getBufferedImages()[1], null);
if(current.getObjectType().toString().equalsIgnoreCase("dangerousbomb")) {
for(int i=0;i<150000;i++) {
gc.drawImage(k, current.getXlocation(), current.getYlocation());
timer.stop();
}
timer.start();
itr.remove();
lives--;
lblLives.setText("Lives: " + String.valueOf(lives));
}else if(current.getObjectType().toString().equalsIgnoreCase("fatalbomb")) {
gameOver();
break;
}else if(current.getObjectType().toString().equalsIgnoreCase("specialfruit")) {
for(int i=0;i<150000;i++) {
gc.drawImage(k, current.getXlocation(), current.getYlocation());
timer.stop();
}
timer.start();
itr.remove();
score+=5;
lblScore.setText("Score: " + String.valueOf(score));
if(score >= highestScore) {
highestScore = score;
ga.saveHighScore(highestScore);
lblHighestScore.setText("Highest Score: "+highestScore);
}
}else if(current.getObjectType().toString().equalsIgnoreCase("fruit")) {
for(int i=0;i<150000;i++) {
gc.drawImage(k, current.getXlocation(), current.getYlocation());
timer.stop();
}
timer.start();
itr.remove();
score++;
lblScore.setText("Score: " + String.valueOf(score));
if(score >= highestScore) {
highestScore = score;
ga.saveHighScore(highestScore);
lblHighestScore.setText("Highest Score: "+highestScore);
}
}
}
gc.drawImage(k, current.getXlocation(), current.getYlocation());
ga.updateObjectsLocations(time,current);
}
}
}
解决方案
gameUpdate
在 JavaFX 应用程序线程上执行。这意味着该方法返回的任何延迟只会冻结 GUI,直到该方法返回。为此,那些
for(int i=0;i<150000;i++) {
gc.drawImage(k, current.getXlocation(), current.getYlocation());
timer.stop();
}
循环不起作用。
这里“暂停”的最简单方法是节省AnimationTimer
允许继续的时间。
timer = new AnimationTimer() {
@Override
public void handle(long arg0) {
gameUpdate(arg0);
}
};
private long pauseEnd = 0L;
/**
* Continue updates after a certain number of milliseconds after the current time
*/
private void pauseFor(long currentTime, long durationMillis) {
pauseEnd = currentTime + 1_000_000L * durationMillis;
}
public void gameUpdate(long timestamp) {
if (timestamp >= pauseEnd) { // only redraw, if not paused
...
//for(int i=0;i<150000;i++) {
// gc.drawImage(k, current.getXlocation(), current.getYlocation());
// timer.stop();
//}
//timer.start();
//itr.remove();
//score++;
gc.drawImage(k, current.getXlocation(), current.getYlocation());
itr.remove();
score++;
pauseFor(timestamp, 3000); // start updates again in 3000 ms
...
}
}
EventHandler
此外,您在游戏循环的每次迭代中都替换了for each 游戏对象。这样,只检查一个游戏对象是否与鼠标相交。您需要使用单个事件处理程序检查所有这些。除了从方法中删除事件处理程序注册之外,在gameLoop
方法中添加以下代码以start
检查所有对象的交集:
canvas.setOnMousePressed(event -> {
for (IGameObject current : drop) {
if(current.insideBounds(event.getX(), event.getY())) {
current.slice();
}
}
});
此外,我强烈建议不要BufferedImage
在游戏循环的每次迭代中一遍又一遍地转换 s。最好直接将 s 替换为BufferedImage
JavaFX Image
s 或保留一个Map<BufferedImage, Image>
包含每个转换结果的...
推荐阅读
- android - 无法启动 Appium 设置应用程序:5071 毫秒后未满足条件。超时
- html - 结构指令传递 Html Elements 属性值
- apache-kafka - 使用 SLF4j 为 Apache Beam 和 Kafka 客户端配置日志记录
- rust - link-arg 没有将编译器选项传递给 rustc
- laravel - 尝试从多对多关系 laravel 获取数据时,在字段列表中显示列“user_id”不明确
- reactjs - Reactjs - 我可以在我网站的所有页面中使用来自 AWS Amplify 的 Auth.authenticatedUser 函数吗?
- bash - 多个文件的 Gnuplot 脚本
- tensorflow - 通过 keras 和张量流的 LPR/ANPR
- python - Python 问题在脚本中导入我的文件(不在控制台中)
- powershell - PowerShell:从 API 响应中检索特定单词并编译成 HTML 表