- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有人可以解释一下为什么我会收到此错误以及如何解决它吗?还要尽量保持简单。我是编码新手。 (我也知道问题的答案存在,但我不知道如何将其实现到我的代码中)
删除行时会出现 NullPointerException 错误。此外,当 block 向下移动时, block 仍然被计为 0,因此新 block 会通过它们。 (我猜它只是顶行,其他行按预期工作)但实际错误更重要:(但如果您也帮助解决这个问题,我会很高兴)
package application;
import java.util.*;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.input.*;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Tetris extends Application {
public static final int MOVE_AMOUNT = 25;
public static final int SIZE = 25;
public static int XLIMIT = SIZE * 10;
public static int YLIMIT = SIZE * 24;
public static int[][] GRID = new int[XLIMIT/SIZE][YLIMIT/SIZE];
private static Pane group = new Pane();
private static Shape object;
private static Scene scene = new Scene(group, XLIMIT, YLIMIT);
public static void main(String[] args) { launch(args); }
@Override public void start(Stage stage) throws Exception {
for(int[] a: GRID){
Arrays.fill(a, 0);
}
for(int i = 0; i <= XLIMIT; i+= SIZE){
Line a = new Line(i, 0, i, YLIMIT);
group.getChildren().add(a);
}
for(int i = 0; i <= YLIMIT; i+= SIZE){
Line a = new Line(0, i, XLIMIT, i);
group.getChildren().add(a);
}
for(int i = 0; i <= YLIMIT; i+= SIZE){
Text a = new Text("" + i);
a.setY(i);
group.getChildren().add(a);
}
for(int i = SIZE; i < XLIMIT; i+= SIZE){
Text a = new Text("" + i);
a.setY(10);
a.setX(i);
group.getChildren().add(a);
}
Shape a = TetrisHolder.createRect();
group.getChildren().addAll(a.a, a.b, a.c, a.d);
moveOnKeyPress(scene, a.a, a.b, a.c, a.d);
object = a;
stage.setScene(scene);
stage.show();
Timer myTimer=new Timer();
TimerTask task =new TimerTask() {
@Override
public void run() {
Platform.runLater(new Runnable(){
public void run(){
CheckDown(object);
}
});
}
};
myTimer.schedule(task,0,300);
}
private void moveOnKeyPress(Scene scene, Rectangle rect, Rectangle rect2, Rectangle rect3, Rectangle rect4) {
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override public void handle(KeyEvent event) {
Shape shape = new Shape(rect, rect2, rect3, rect4);
switch (event.getCode()) {
case RIGHT:
TetrisHolder.CheckRight(shape);
break;
case DOWN:
CheckDown(shape);
break;
case LEFT:
TetrisHolder.CheckLeft(shape);
break;
case UP:
//TetrisHolder.CheckTurn(shape);
break;
}
}
});
}
private void CheckTurn(Shape shape){
}
private void DeleteRows(Pane pane){
ArrayList<Node> rects = new ArrayList<Node>();
ArrayList<Integer> lines = new ArrayList<Integer>();
int full = 0;
for(int i = 0; i < GRID[0].length; i++){
for(int j = 0; j < GRID.length; j++){
if(GRID[j][i] == 1)
full++;
}
if(full == GRID.length)
lines.add(i/*+lines.size()*/);
full = 0;
}
for(Node node: pane.getChildren()) {
if(node instanceof Rectangle) {
rects.add(node);
}
}
if(lines.size() > 0)
do{
for(Node node: rects){
Rectangle a = (Rectangle)node;
if(a.getY() == lines.get(0)*SIZE){
GRID[(int)a.getX()/SIZE][(int)a.getY()/SIZE] = 0;
pane.getChildren().remove(node);
}
if(a.getY() < lines.get(0)*SIZE){
GRID[(int)a.getX()/SIZE][(int)a.getY()/SIZE] = 0;
a.setY(a.getY() + SIZE);
GRID[(int)a.getX()/SIZE][(int)a.getY()/SIZE] = 1;
}
}
lines.remove(0);
rects.clear();
for(Node node: pane.getChildren()) {
if(node instanceof Rectangle) {
rects.add(node);
}
}
} while(lines.size() > 0);
}
private void CheckDown(Shape shape){
if((shape.c.getY() == YLIMIT - SIZE) || checkA(shape) || checkB(shape) || checkC(shape) || checkD(shape)){
GRID[(int)shape.a.getX()/SIZE][(int)shape.a.getY()/SIZE] = 1;
GRID[(int)shape.b.getX()/SIZE][(int)shape.b.getY()/SIZE] = 1;
GRID[(int)shape.c.getX()/SIZE][(int)shape.c.getY()/SIZE] = 1;
GRID[(int)shape.d.getX()/SIZE][(int)shape.d.getY()/SIZE] = 1;
DeleteRows(group);
Shape a = TetrisHolder.createRect();
object = a;
group.getChildren().addAll(a.a, a.b, a.c, a.d);
moveOnKeyPress(shape.a.getScene(), a.a, a.b, a.c, a.d);
}
if(shape.c.getY() + MOVE_AMOUNT < YLIMIT){
int checka = GRID[(int)shape.a.getX()/SIZE][((int)shape.a.getY()/SIZE) + 1];
int checkb = GRID[(int)shape.b.getX()/SIZE][((int)shape.b.getY()/SIZE) + 1];
int checkc = GRID[(int)shape.c.getX()/SIZE][((int)shape.c.getY()/SIZE) + 1];
int checkd = GRID[(int)shape.d.getX()/SIZE][((int)shape.d.getY()/SIZE) + 1];
if(checka == 0 && checka == checkb && checkb == checkc && checkc == checkd){
shape.a.setY(shape.a.getY() + MOVE_AMOUNT);
shape.b.setY(shape.b.getY() + MOVE_AMOUNT);
shape.c.setY(shape.c.getY() + MOVE_AMOUNT);
shape.d.setY(shape.d.getY() + MOVE_AMOUNT);
}
}
}
private boolean checkA(Shape shape){
return (GRID[(int)shape.a.getX()/SIZE][((int)shape.a.getY()/SIZE) + 1] == 1);
}
private boolean checkB(Shape shape){
return (GRID[(int)shape.b.getX()/SIZE][((int)shape.b.getY()/SIZE) + 1] == 1);
}
private boolean checkC(Shape shape){
return (GRID[(int)shape.c.getX()/SIZE][((int)shape.c.getY()/SIZE) + 1] == 1);
}
private boolean checkD(Shape shape){
return (GRID[(int)shape.d.getX()/SIZE][((int)shape.d.getY()/SIZE) + 1] == 1);
}
}
错误:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at application.Tetris.moveOnKeyPress(Tetris.java:70)
at application.Tetris.CheckDown(Tetris.java:147)
at application.Tetris.access$1(Tetris.java:137)
at application.Tetris$1$1.run(Tetris.java:60)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
最佳答案
如果您仍然引用顶部的静态场景,为什么还要从形状获取场景?
我想说尝试在第 70 行切换以下内容:
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
对此:
this.scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
关于JavaFX 空指针异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47091357/
我刚接触 C 语言几周,所以对它还很陌生。 我见过这样的事情 * (variable-name) = -* (variable-name) 在讲义中,但它到底会做什么?它会否定所指向的值吗? 最佳答案
我有一个指向内存地址的void 指针。然后,我做 int 指针 = void 指针 float 指针 = void 指针 然后,取消引用它们以获取值。 { int x = 25; vo
我正在与计算机控制的泵进行一些串行端口通信,我用来通信的 createfile 函数需要将 com 端口名称解析为 wchar_t 指针。 我也在使用 QT 创建一个表单并获取 com 端口名称作为
#include "stdio.h" #include "malloc.h" int main() { char*x=(char*)malloc(1024); *(x+2)=3; --
#include #include main() { int an_int; void *void_pointer = &an_int; double *double_ptr = void
对于每个时间步长,我都有一个二维矩阵 a[ix][iz],ix 从 0 到 nx-1 和 iz 从 0 到 nz-1。 为了组装所有时间步长的矩阵,我定义了一个长度为 nx*nz*nt 的 3D 指针
我有一个函数,它接受一个指向 char ** 的指针并用字符串填充它(我猜是一个字符串数组)。 *list_of_strings* 在函数内部分配内存。 char * *list_of_strings
我试图了解当涉及到字符和字符串时,内存分配是如何工作的。 我知道声明的数组的名称就像指向数组第一个元素的指针,但该数组将驻留在内存的堆栈中。 另一方面,当我们想要使用内存堆时,我们使用 malloc,
我有一个 C 语言的 .DLL 文件。该 DLL 中所有函数所需的主要结构具有以下形式。 typedef struct { char *snsAccessID; char *
指针, C语言的精髓 莫队先咕几天, 容我先讲完树剖 (因为后面树上的东西好多都要用树剖求 LCA). 什么是指针 保存变量地址的变量叫做指针. 这是大概的定义, 但是Defad认为
我得到了以下数组: let arr = [ { children: [ { children: [], current: tru
#include int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0;
我正在编写一个程序,它接受一个三位数整数并将其分成两个整数。 224 将变为 220 和 4。 114 将变为 110 和 4。 基本上,您可以使用模数来完成。我写了我认为应该工作的东西,编译器一直说
好吧,我对 C++ 很陌生,我确定这个问题已经在某个地方得到了回答,而且也很简单,但我似乎找不到答案.... 我有一个自定义数组类,我将其用作练习来尝试了解其工作原理,其定义如下: 标题: class
1) this 指针与其他指针有何不同?据我了解,指针指向堆中的内存。如果有指向它们的指针,这是否意味着对象总是在堆中构造? 2)我们可以在 move 构造函数或 move 赋值中窃取this指针吗?
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C : pointer to struct in the struct definition 在我的初学者类
我有两个指向指针的结构指针 typedef struct Square { ... ... }Square; Square **s1; //Representing 2D array of say,
变量在内存中是如何定位的?我有这个代码 int w=1; int x=1; int y=1; int z=1; int main(int argc, char** argv) { printf
#include #include main() { char *q[]={"black","white","red"}; printf("%s",*q+3); getch()
我在“C”类中有以下函数 class C { template void Func1(int x); template void Func2(int x); }; template void
我是一名优秀的程序员,十分优秀!