在上一节课中,我们对即将要完成的战旗Demo有了一个大概的了解,本节课当中,我们将会学习绘制游戏地图。

自从在JavaFX 2.2中增加了Canvas相关的功能,我们就可以使用Canvas来实现游戏绘制了。

游戏地图绘制主要用到GraphicsContext.drawImage方法。

drawImage(Image image,double sx,double sy,double sw,double sh,double dx,double dy,double dw,double dh);

其中image 表示源图片。

sx,sy,sw,sh表示相对于源图片的x,y坐标和截取的宽度和高度。

dx,dy,dw,dy表示绘制到画布上的x, y坐标和绘制的宽度和高度。

单元图片如下:

地图绘制就是将单元格进行拼接。

通常使用一个二维数组来表示地图数据如下:

int[][] mapIndex = { 
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, };

下面来看看我们的游戏地图类:

import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
public class GameMap {
	private int[][] mapIndex = { 
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, };
	private int tileWidth;
	private int tileHeight;
	private int cols;
	private Image image;
	public GameMap(int tileWidth,int tileHeight, Image map){
		this.tileWidth = tileWidth;
		this.tileHeight = tileHeight;
		this.image = map;
		cols = (int) (map.getWidth() / tileWidth);
	public void drawMap(GraphicsContext gc) {
		int mapWidth = mapIndex[0].length;
		int mapHeight = mapIndex.length;
		for (int y = 0; y < mapHeight; y++) {
			for (int x = 0; x < mapWidth; x++) {
				int px = mapIndex[y][x] % cols;
				int py = mapIndex[y][x] / cols;
				gc.drawImage(image, px * tileWidth, py * tileHeight, tileWidth, tileHeight, x * tileWidth, y
						* tileHeight, tileWidth, tileHeight);
	public int[][] getMapIndex() {
		return mapIndex;
	public void setMapIndex(int[][] mapIndex) {
		this.mapIndex = mapIndex;
  在实际游戏开发中,游戏地图数据通常存储在文件中,从文件读取,由于我这只是个Demo,写进来方便大家直观的了解。 

  首先,我们通过地图贴图的宽度和单元格的宽度来计算地图贴图单元格的列数,然后在绘制的时候,就可以通过地图索引和单元格列数,计算当前绘制的贴图的行和列,通过drawImage绘制出来。

接下来,创建我们的Canvas类:

import javafx.application.Platform;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
public class MainCanvas extends Canvas {
	// 游戏地图
	private GameMap gameMap;
	private GraphicsContext gContext;
	private Image map;
	private int tileWidth = 32;
	private int tileHeight = 32;
	private boolean isRunning = true;
	private long sleep = 100;
	// 主线程
	private Thread thread = new Thread(new Runnable() {
		@Override
		public void run() {
			while (isRunning) {
				Platform.runLater(new Runnable() {
					@Override
					public void run() {
						draw();
						update();
				try {
					Thread.sleep(sleep);
				} catch (InterruptedException e) {
					e.printStackTrace();
	public MainCanvas(double width, double height) {
		super(width, height);
		map = new Image(getClass().getResourceAsStream("map0.png"));
		gContext = getGraphicsContext2D();
		// 初始化游戏地图
		gameMap = new GameMap(tileWidth, tileHeight, map);
		thread.start();
	public void draw() {
		gameMap.drawMap(gContext);		
	public void update() {

  MainCanvas类比较简单,创建一个线程,用于执行draw和update方法。然后载入地图贴图,初始化GameMap,并完成绘制工作。

最后,在Main类中,将我们的Canvas加入到布局中。

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
public class Main extends Application {
	@Override
	public void start(Stage primaryStage) {
		try {
			AnchorPane root = new AnchorPane();
			Scene scene = new Scene(root,640,480);
			MainCanvas mainCanvas = new MainCanvas(640, 480);
			root.getChildren().add(mainCanvas);
			scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
			primaryStage.setScene(scene);
			primaryStage.show();
		} catch(Exception e) {
			e.printStackTrace();
	public static void main(String[] args) {
		launch(args);
下面看看运行效果: 

  这样,游戏地图就绘制成功了。有兴趣的朋友也可以自行修改地图索引,来绘制不同的地图。当然在实际开发中,我们还是会用地图编辑器来编辑的。

  这一节课就到此结束了,下一节再见。

在上一节课中,我们对即将要完成的战旗Demo有了一个大概的了解,本节课当中,我们将会学习绘制游戏地图。 自从在JavaFX 2.2中增加了Canvas相关的功能,我们就可以使用Canvas来实现游戏绘制了。 游戏地图绘制主要用到GraphicsContext.drawImage方法。 java8开始,对java fx进行大力支持,弥补了fx对图形编程方面的缺失,重要的java终于支持硬件加速。 相信有兴趣的都已经看过fx3D编程推广视频,场面非常震撼。 学习过程中遇到很多问题,有一些个人的新的,拿出来同大家分享,本文原创,请支持。 相信对桌面端有编程经验的都知道WPF了,javaFx似WPF的MVVM开发模式,将逐渐取代Swi
其实早在几年前就有开发一个自己的游戏地图编辑器的想法,当时使用JavaSE开发的,纯属练手。结果后来笔记本出问题了,数据丢失,代码都找不回来了。    于是便准备重新开发一个游戏地图编辑器的,因为自己偶尔会研究JavaFX,而且论GUI技术,JavaFX也确实还是不错,所以就使用JavaFX做了。   GitHub地址:javafx-TKMapEditor。   JavaFX相关个人博客
在进行2d游戏制作的时候,通常都会绘制瓦片地图,所谓的瓦片地图,实际上就是一小块一小块的图片绘制成一张大地图,这篇文章就简单介绍一下瓦片地图绘制的思路 地图元素 地图元素存储了待绘制的图片,以及图片的长宽信息。 @Data @NoArgsConstructor @AllArgsConstructor // 瓦片地图上的瓦片 public class MapComponent { // 长度和宽度 private int height; private int width; 根据Apache许可证2.0版(“许可证”)获得许可; 除非遵守许可,否则您不得使用此文件。 您可以在以下位置获得许可证的副本: 除非适用法律要求或以书面形式同意,否则根据“许可”分发的软件将按“原样”分发,没有任何形式的明示或暗示担保或条件。 有关许可下特定的语言管理权限和限制,请参见许可。 建立图书馆 该项目是使用mvn构建的。 库jar是通过运行mvn package创建的 Java版本和分支 分支3.x使用Java 15 分支2.x使用Java 11 分支1.x使用Java 8(未进一步开发) 引入请求应基于1.
在上一节课程中,我们学习了在JavaFX绘制游戏地图。这一节课,我们将会创建我们的游戏角色。   首先,同样的,我们创建一个简单的基。   import javafx.scene.canvas.GraphicsContext; * 游戏物体基 * @author Wing Mei public abstract class BaseObject { protec
  由于只是Demo,我创建的是最简单的形式,如下图所示:   基于游戏开发中的UI控件通常需要有事件(比如图中的移动,攻击,待机,是有事件处理的),我们应该首先创建自己的文字控件。   文字控件代码如下:   import com.sun.javafx.tk.FontMetrics; import com. 1.地图设定 战棋游戏地图游戏的基础设定之一,它决定了游戏的规则和过程。在Java编程中,可以使用数组来存储地图信息。例如,可以使用二维数组来表示一个地图,其中每个元素代表地图上的一个格子,存储格子的型和状态等信息。 2.角色设定 战棋游戏的角色是游戏中最重要的元素之一,游戏的进程和玩法都与角色密切相关。在Java编程中,应该定义角色的属性和行为。例如,可以定义一个角色,包含角色的基本属性(如生命值、攻击力)和行为(如移动、攻击),然后通过继承该创建不同型的角色。 3.胜负判断 战棋游戏即使在所有角色都打完之后,胜负判断是非常重要的。在Java编程中,可以使用条件判断语句来检查游戏是否已结束。例如,通过检查每个角色是否死亡来确定哪个队伍获胜。 4.图形界面 大多数战棋游戏都具有精美的图形界面,这需要Java编程者使用GUI库创建相应的图形界面。例如,可以使用Swing或JavaFX库创建游戏窗口、按钮、文本框等组件,并将其与游戏逻辑和显示相结合。 综合以上要素,Java语言可以实现具有丰富玩法和精美图形界面的战棋游戏。但需要提醒的是,在编写代码的过程中,需要考虑游戏的逻辑和流程,确保游戏的平衡性和可玩性。 * What went wrong: Could not transfer artifact org.javafxports:dalvik-sdk:zip:8u40-b5 from/to maven-central (http://repo1.maven.org/maven2/): Failed to transfer file: http://repo1.maven.org/maven2/org/javafxports/dalvik-sdk/8u40-b5/dalvik-sdk-8u40-b5.zip. Return code is: 501 , ReasonPhrase:HTTPS Required. > Could not transfer artifact org.javafxports:dalvik-sdk:zip:8u40-b5 from/to maven-central (http://repo1.maven.org/maven2/): Failed to transfer file: http://repo1.maven.org/maven2/org/javafxports/dalvik-sdk/8u40-b5/dalvik-sdk-8u40-b5.zip. Return code is: 501 , ReasonPhrase:HTTPS Required. * Try: Run with --stacktrace option to get the stack trace. Run with --debug option to get more log output. BUILD FAILED Total time: 7.806 secs Stopped 0 compiler daemon(s). JavaFX打包到Android上 quan_ming: 楼主,这个配置环境是什么样的吗?我这边尝试没有成功。 关于philips Spark2刷机失败的问题 m0_73344251: 谁还有这个工具,共享一个嘛nine1999@qq.com 关于philips Spark2刷机失败的问题 m0_73344251: 你找到了吗 EnumProcessModules失败的问题 有解决办法吗?