- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为 2D 方 block 游戏编写一个闪电引擎。与大多数游戏一样,我在 map 上有一个 map [][]和一个光照贴图[][]。没什么特别的。从一个光点,我在灯光范围内画一个圆圈,并尝试将布雷森纳姆线绘制到圆圈上的点。由于某种原因,我的 Bresenham 算法并不完美,我添加了一张图像 它的。为什么布雷森汉姆线算法会跳过一些对角坐标(例如从点 20,20 到 13,14 和 14,13 跳过。)我认为误差计算是错误的。我使用 set 来避免数组中的重复。圆形算法工作正常,在数组中我得到了正确的值。图中还有一个问题:在某些情况下,水平线和有时垂直线也错误。我认为这也是布雷森汉姆的错误。我正在尝试一些调试 ,它显示了布雷森汉姆的错误。白色立方体是圆周上的点,红色通过布雷森汉姆线算法添加到光照贴图中,有一座山阻挡了光线(它工作完美)并且我的小 map 已启用。我添加了更多图像:
import java.awt.geom.Point2D;
import java.util.HashSet;
public class PointLight {
Handler handler;
public float x,y;
private int plx,ply;
public int radius,intensity;
public static Point2D.Double pnt;
public static HashSet<Point2D> circpoints;
public static HashSet<Point2D> bline;
public PointLight(float x,float y,int radius,int intensity,Handler handler) {
super();
this.x=x;
this.y=y;
this.radius=radius;
this.intensity=intensity;
this.handler=handler;
circpoints = new HashSet<Point2D>();
bline = new HashSet<Point2D>();
pnt=new Point2D.Double();
}
public void tick() {
//visibility for rendering process (1000 is for range, to avoid sudden light emitting)
if (x > Game.camera.getX()-1000 && x < Game.camera.getX()+Game.Windoww+1000 && y > Game.camera.getY()-1000 && y < Game.camera.getY()+Game.Windowh+1000) {
if (!Game.visiblepointlight.contains(this)) Game.visiblepointlight.add(this);
} else {
if (Game.visiblepointlight.contains(this)) Game.visiblepointlight.remove(this);
}
//reset visible lightmap
for (int i=(int)((Game.camera.getX()-1000)/Game.tilesize);i < (int)((Game.camera.getX()+1000+Game.Windoww)/Game.tilesize);i++) {
for (int j=(int)((Game.camera.getY()-1000)/Game.tilesize);j < (int)((Game.camera.getY()+1000+Game.Windowh)/Game.tilesize);j++) {
if (i > 0 && i < Game.tiles && j > 0 && j < Game.tiles) Game.lightMap[i][j]=0;
}
}
//set lights
for (PointLight pli : Game.visiblepointlight) {
bline.clear();
circpoints.clear();
Lightcalculate(pli);
}
}
public void Lightcalculate(PointLight pl) {
plx=(int)(pl.x)/Game.tilesize;
ply=(int)(pl.y)/Game.tilesize;
PointsOnCircumference(plx,ply,pl.radius);
for (Point2D circp : circpoints) {
bresenhamsLine(plx,ply,(int)circp.getX(),(int)circp.getY());
for (Point2D plotl :bline) {
double mult = Game.AmbientLight+(pl.intensity / PointDistance(plx,ply,plotl.getX(),plotl.getY()))/(Game.tilesize*2);
//working but no brightness addition:
//if (mult >1) mult=1;
//Game.lightMap[(int) plotl.getX()][(int) plotl.getY()] = mult;
Game.lightMap[(int) plotl.getX()][(int) plotl.getY()] += mult;
if (Game.lightMap[(int) plotl.getX()][(int) plotl.getY()] > 1) Game.lightMap[(int) plotl.getX()][(int) plotl.getY()]= 1;
}
}
}
private double PointDistance(double x1, double y1, double x2, double y2) {
return Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
}
private void PointsOnCircumference(int x0, int y0, int radius)
{
int x = radius-1;
int y = 0;
int dx = 1;
int dy = 1;
int err = dx - (radius << 1);
while (x >= y) {
pnt.setLocation(x0 + x, y0 + y);
circpoints.add((Point2D) pnt.clone());
pnt.setLocation(x0 + y, y0 + x);
circpoints.add((Point2D) pnt.clone());
pnt.setLocation(x0 - y, y0 + x);
circpoints.add((Point2D) pnt.clone());
pnt.setLocation(x0 - x, y0 + y);
circpoints.add((Point2D) pnt.clone());
pnt.setLocation(x0 - x, y0 - y);
circpoints.add((Point2D) pnt.clone());
pnt.setLocation(x0 - y, y0 - x);
circpoints.add((Point2D) pnt.clone());
pnt.setLocation(x0 + y, y0 - x);
circpoints.add((Point2D) pnt.clone());
pnt.setLocation(x0 + x, y0 - y);
circpoints.add((Point2D) pnt.clone());
if (err <= 0) {
y++;
err += dy;
dy += 2;
}
if (err > 0) {
x--;
dx += 2;
err += dx - (radius << 1);
}
}
}
private void bresenhamsLine(double x1,double y1,double x2,double y2) {
double dx = Math.abs(x2 - x1);
double dy = Math.abs(y2 - y1);
double sx = (x1 < x2 ? 1 : -1);
double sy = (y1 < y2 ? 1 : -1);
double error = dx - dy;
double x = x1, y = y1;
while(1==1)
{
if ((int)x < 0 || (int)y < 0 ) break;
if ((int)x >= Game.tiles || (int)y >= Game.tiles ) break;
pnt.setLocation(x,y);
bline.add((Point2D) pnt.clone());
if (Game.map[(int)x][(int)y] >= 0.8) break; //light blocker
if(x==x2 && y==y2) { break; }
double e2 = 2 * error;
if(e2 >= -dy) { error-= dy; x+= sx; }
if(e2 <= dx) { error+= dx; y+= sy; }
}
}
}
最佳答案
我想出了如何以其他方式生成阴影灯。它更简单并且 100% 有效。这是点光源瓷砖闪电的代码:
import java.awt.Point;
import java.util.HashSet;
import java.util.Random;
public class PointLight {
Handler handler;
public int x,y;
private int plx,ply;
public int radius,intensity;
public static Point pnt;
public static HashSet<Point> circpoints;
public static HashSet<Point> bline;
public GameObject BoundToObject;
public PointLight(int x,int y,int radius,int intensity,Handler handler) {
super();
this.x=x;
this.y=y;
this.radius=radius;
this.intensity=intensity;
this.handler=handler;
circpoints = new HashSet<Point>();
bline = new HashSet<Point>();
pnt=new Point();
}
public PointLight(GameObject GamObj,int radius,int intensity,Handler handler) {
super();
this.BoundToObject=GamObj;
this.x=(int) GamObj.getX();
this.y=(int) GamObj.getY();
this.radius=radius;
this.intensity=intensity;
this.handler=handler;
circpoints = new HashSet<Point>();
bline = new HashSet<Point>();
pnt=new Point();
}
public void tick() {
Random rnd;
rnd=new Random();
x+=rnd.nextDouble()*4;
y+=rnd.nextDouble()*4;
if (BoundToObject != null) {
x=(int) BoundToObject.getX();
y=(int) BoundToObject.getY();
}
//visibility for rendering process (200 is for range, to avoid sudden light emitting)
if (x > (int)Game.camera.getX()-200 && x < (int)Game.camera.getX()+Game.Windoww+200 && y > (int)Game.camera.getY()-200 && y < (int)Game.camera.getY()+Game.Windowh+200) {
if (!Game.visiblepointlight.contains(this)) Game.visiblepointlight.add(this);
} else {
if (Game.visiblepointlight.contains(this)) Game.visiblepointlight.remove(this);
}
//reset visible lightmap
for (int i=(int)((Game.camera.getX()-200)/Game.tilesize);i < (int)((Game.camera.getX()+200+Game.Windoww)/Game.tilesize);i++) {
for (int j=(int)((Game.camera.getY()-200)/Game.tilesize);j < (int)((Game.camera.getY()+200+Game.Windowh)/Game.tilesize);j++) {
if (i > 0 && i < Game.tiles && j > 0 && j < Game.tiles) Game.lightMap[i][j]=Game.AmbientLight;
}
}
//set lights
for (PointLight pli : Game.visiblepointlight) {
bline.clear();
circpoints.clear();
Lightcalculate(pli);
}
}
public void Lightcalculate(PointLight pl) {
plx=pl.x/Game.tilesize;
ply=pl.y/Game.tilesize;
RayCast(plx,ply,pl.radius);
for (Point bln :bline) {
double mult = (pl.intensity / PointDistance(plx,ply,bln.x,bln.y))/(Game.tilesize*3);
if (Game.lightMap[bln.x][bln.y] < mult) Game.lightMap[bln.x][bln.y] = mult;
if (Game.lightMap[bln.x][bln.y] > 1) Game.lightMap[bln.x][bln.y]= 1;
}
}
private void RayCast(int xcord,int ycord,int range) {
double angle = 0;
int rays=range*10+1;
for (int i=0; i<rays; i++) {
angle += 2 * Math.PI / rays;
for (int j=0;j<range;j++) {
double xx = xcord+Math.sin(angle)*j;
double yy = ycord+Math.cos(angle)*j;
if ((int) xx <= 0 || (int) yy <= 0 || (int) xx >= Game.tiles-1 || (int) yy >= Game.tiles-1 ) continue;
if (Game.map[(int) xx][(int)yy] >= 0.8) break;
Point dir = new Point((int) Math.round(xx),(int)Math.round(yy));
bline.add(dir);
}
}
}
private double PointDistance(int x1, int y1, int x2, int y2) {
return Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
}
}
关于Java Bresenham 线到圆周上的点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55265605/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!