JavaFX横幅类游戏开发 教训 游戏贴图

JavaFX横幅类游戏开发 教训 游戏贴图

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

  上一节课,我们即将完成战旗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坐标和绘制的宽度和高度。

 单元图片例如以下:

  JavaFX横幅类游戏开发 教训 游戏贴图

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

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

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);
	}
}


以下看看执行效果:

JavaFX横幅类游戏开发 教训 游戏贴图

  这样,游戏地图就绘制成功了。有兴趣的朋友也能够自行改动地图索引。来绘制不同的地图。

当然在实际开发中,我们还是会用地图编辑器来编辑的。

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

  本文章为个人原创。版权全部,转载请注明出处:http://blog.csdn.net/ml3947。另外我的个人博客:http://www.wjfxgame.com.


版权声明:本文博客原创文章,博客,未经同意,不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/117573.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 漏洞知识库

    漏洞知识库

  • System.err.println()和System.out.println()区别

    System.err.println()和System.out.println()区别看了些资料总结下:1.JDK文档对两者的解释:out:“标准”输出流。此流已打开并准备接受输出数据。通常,此流对应于显示器输出或者由主机环境或用户指定的另一个输出目标。err:“标准”错误输出流。此流已打开并准备接受输出数据。通常,此流对应于显示器输出或者由主机环境或用户指定的另一个输出目标。按照惯例,此输出流用于显示错误消息,或者显示那些即使用户输出流(变量 out 的值)已经重定向…

  • 40篇英语短文搞定高考3500个单词[通俗易懂]

    40篇英语短文搞定高考3500个单词[通俗易懂]40篇英语短文搞定高考3500个单词1.FallinLovewithEnglish爱上英语Hidingbehindtheloosedustycurtain,ateenagerpackeduphisovercoatintothesuitcase.Heplannedtoleavehomeatduskthoughtherewasthun…

  • RAID 小结

    RAID 小结

  • linux命令手册 apk_linux命令全集

    linux命令手册 apk_linux命令全集linux手册app是一款学习教育应用,是个能让你快速查询linux命令的手机软件。此外在linux手册app中还有学习手册,让你可随时查询不清楚的知识点。基本简介linux手册包app含linux命令速查以及一个linux简易学习教程,是学习linux必备宝典,命令速查可以快速知道linux命令使用方法,并且配有学习手册,方便及时查阅不懂知识。功能介绍1,linux简易教程方便随时阅读2,命令搜…

  • Mysql中用SQL增加、删除字段,修改字段名、字段类型、注释,调整字段顺序总结

    Mysql中用SQL增加、删除字段,修改字段名、字段类型、注释,调整字段顺序总结1.增加一个字段 代码如下 复制代码 //增加一个字段,默认为空altertableuseraddCOLUMNnew1VARCHAR(20)DEFAULTNULL; //增加一个字段,默认不能为空altertableuseraddCOLUMNnew2VARCHAR(20)NOTNULL; 2….

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号