我正在使用Slick2D库在Java游戏中工作。我刚刚开始构建一个新的机制,它将涉及激光,我将实现稍后重定向的能力。但是现在我在首先渲染基本激光时遇到了麻烦。
以下是处理激光拍摄对象的类的代码。 " updateLaser" method用于basicGame扩展的更新循环," render"渲染循环中的方法。
package assets;
import java.util.ArrayList;
import levelTEST.BoxesTest;
import levelTEST.WallsTest;
import org.newdawn.slick.Color;
import org.newdawn.slick.ShapeFill;
import org.newdawn.slick.fills.GradientFill;
import org.newdawn.slick.geom.Point;
import org.newdawn.slick.geom.Polygon;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.geom.ShapeRenderer;
public class LaserFire {
Polygon hitbox;
ArrayList<Point> laser = new ArrayList<Point>();
String directL;
float xL;
float yL;
boolean isOn;
WallsTest wT;
float startX;
float startY;
boolean laserNew;
float pointX;
float pointY;
BoxesTest bT;
// the wallstest and boxestest variables are just for colision, just ignore
// them
public LaserFire(float x, float y, WallsTest wt, BoxesTest bt, String direct) {
hitbox = new Polygon();
directL = direct;
xL = x;
yL = y;
// this part of the code creates the hitbox of the laser shooter and
// determines where the laser will start
if (direct.equals("top")) {
hitbox.addPoint(x, y + 50);
hitbox.addPoint(x + 50, y + 50);
hitbox.addPoint(x + 25, y);
startX = xL + 25;
startY = yL;
} else if (direct.equals("bottom")) {
hitbox.addPoint(x, y);
hitbox.addPoint(x + 50, y);
hitbox.addPoint(x + 25, y + 50);
startX = xL + 25;
startY = yL + 50;
} else if (direct.equals("left")) {
hitbox.addPoint(x + 50, y + 50);
hitbox.addPoint(x + 50, y);
hitbox.addPoint(x, y + 25);
startX = xL;
startY = yL + 25;
} else if (direct.equals("right")) {
hitbox.addPoint(x, y);
hitbox.addPoint(x, y + 50);
hitbox.addPoint(x + 50, y + 25);
startX = xL + 50;
startY = yL + 25;
}
isOn = true;
wT = wt;
laserNew = true;
pointX = 0;
pointY = 0;
bT = bt;
}
public void updateLaser(int delta) {
// first I wanted the laser to not be instant in how fast it went, so I
// limit the amount of time it takes before a new point in the laser can
// be added
int time = 0;
int timeToBlock = 2;
// second I made sure to start the laser in the correct spot and to have
// a point to start the laser (so there is a point to render at first)
if (laserNew == true) {
laser.add(new Point(startX, startY));
pointX = startX;
pointY = startY;
laserNew = false;
}
// if the laser is on...
if (isOn) {
// this is part of the time limiter
if (time > 0 && time < timeToBlock) {
time += delta;
} else if (time >= timeToBlock) {
time = 0;
}
// here's where each new point of the laser is added, it first
// checks if it would colide with the wall, if so, no new points are
// added
if (bT.allColide(new Point(pointX, pointY)) != true
&& wT.checkColi(new Point(pointX, pointY)) != true
&& time == 0) {
// then it adds a point if there is space for it
laser.add(new Point(pointX, pointY));
// then it checks what direction the laser is going, and plans
// where the next point will be
if (directL.equals("top")) {
pointY -= 1;
} else if (directL.equals("bottom")) {
pointY++;
} else if (directL.equals("left")) {
pointX -= 1;
} else if (directL.equals("right")) {
pointX++;
}
// this part sets of the timer
time += delta;
}
} else if (isOn != true) {
// this resets the laser if it is off
laser.clear();
laserNew = true;
}
}
public void render() {
// first I need the colors for the laser and the ShapeFill to fill it in
Color c = new Color(10, 210, 210);
Color c2 = new Color(10, 210, 210);
Color cL = new Color(255, 10, 10);
ShapeFill fillbox;
// if the laser is on it fills one color for the shooter, if not,
// another
if (isOn) {
fillbox = new GradientFill(0, 0, c, 960, 540, c);
} else {
fillbox = new GradientFill(0, 0, c2, 960, 540, c2);
}
// this renders the shooter
ShapeFill fillLaser = new GradientFill(0, 0, cL, 960, 540, cL);
ShapeRenderer.fill(hitbox, fillbox);
// if the laser is on, this renders each part of the laser beam
if (isOn) {
for (int i = 0; i < laser.size(); i++) {
ShapeRenderer.fill(laser.get(i), fillLaser);
}
}
}
// this part is for character colision, and works fine.
public boolean colision(Shape X) {
boolean check = false;
if (hitbox.intersects(X)) {
check = true;
} else if (hitbox.intersects(X) != true) {
check = false;
}
return check;
}
}
每次我在Eclipse中运行代码时,我都会在以下行获得NullPointerException(至少根据Eclipse):
&& wT.checkColi(new Point(pointX, pointY)) != true
我已经用激光关闭测试了这个类,它工作得很好,但是现在我测试了激光器,我一直得到这个例外。
我认为这与我如何添加到ArrayList&#34; laser&#34;在if语句中,但我真的不知道。万一它与wallTest对象的碰撞检测有关,这里是&#34; checkColi&#34;来自该对象的方法:
public boolean checkColi(Shape jupiter){
boolean colide = false;
if (top.intersects(jupiter)){
colide = true;
}if (bottom.intersects(jupiter)){
colide = true;
}if (left.intersects(jupiter)){
colide = true;
}if (right.intersects(jupiter)){
colide = true;
}if (midtop.intersects(jupiter)){
colide = true;
}if (midbottom.intersects(jupiter)){
colide = true;
}if (spire.intersects(jupiter)){
colide = true;
}
return colide;
}
这是&#34; WallsTest&#34;的初始化激光类中使用的对象:
这是在构造函数中传递的wT
package levelTEST;
public class levelTest{
public WallsTest W;
public void render(){
W = new WallsTest();
W.render();
}
}
这个类(levelTEST)将用于管理处理各种对象的所有其他类,但到目前为止,它只负责wall对象。
这个类本身在以下类Level中初始化(这个类将管理所有级别,但同样,还没有得到那么远):
package assets;
import levelTEST.levelTest;
public class Level{
public levelTest lT = new levelTest();
public void main(){
lT.render();
}
}
最后,它在主游戏类中全部初始化,如下所示:
Level lT = new Level();
下面是对象wT的传递方式:
LaserTest laT = new LaserTest(lT.lT.W , bT);
lT.lT.W正在构造函数中传递,它是&#34; wallstest&#34; &#34; leveltest&#34;中的对象&#34;级别内的对象&#34;对象
这一行来自主要的BasicGame扩展类,它初始化LaserTest类(一个本身初始化LaserFire类的类)&#34; lT.lT.W&#34;通向WallsTest&#34; W&#34;在LaserFire对象中使用。
下面是LaserTest类,它显示了如何将wT传递给&#34; LaserFire&#34;的构造函数。类:
package levelTEST;
import org.newdawn.slick.geom.Shape;
import assets.LaserFire;
public class LaserTest {
LaserFire[] lasers;
public LaserTest(WallsTest wT, BoxesTest bT) {
//this is how the wT variable is passed into the LaserFire object
LaserFire L1 = new LaserFire(300, 300, wT, bT, "top");
lasers = new LaserFire[] { L1 };
}
public void render() {
for (int i = 0; i < lasers.length; i++) {
lasers[i].render();
}
}
public void update(int delta) {
for (int i = 0; i < lasers.length; i++) {
lasers[i].updateLaser(delta);
}
}
public boolean colide(Shape X) {
boolean coli = false;
for (int i = 0; i < lasers.length; i++) {
if (lasers[i].colision(X)) {
coli = true;
}
}
return coli;
}
}