我得到了这个非常烦人的错误。这很难解释,但基本上每当我的蛇牌(我对游戏进行编码" Snake")离开屏幕时,我都会将其设置为返回相同的y,但是x为0,因为x = 0是屏幕的最左边部分......
所以是的,很难解释。这是完整的代码:
主类:
package com.Code0.Snake.Main;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.util.LinkedList;
import java.util.Random;
import com.Code0.Snake.Listeners.KeyListenerS;
import com.Code0.Snake.Threads.EventS;
public class MainS extends Applet{
//Defining vars.
public final int BOX_HEIGHT = 15;
public final int BOX_WIDTH = 15;
public final int GRID_HEIGHT = 30;
public final int GRID_WIDTH = 30;
public static final int NORTH = 1;
public static final int SOUTH = 2;
public static final int EAST = 3;
public static final int WEST = 4;
public static final int NONE = 0;
public static int direction;
public LinkedList<Point> snakeParts = new LinkedList<Point>();
public Point itemLocation = new Point();
public Graphics graphics;
int randomX;
int randomY;
int runCount = 0;
EventS events = new EventS(this);
KeyListenerS keylistener = new KeyListenerS(this);
//On Initialization
public void init(){
//Adding "Snakeparts" to the linked list.
snakeParts.add(new Point(10, 10));
snakeParts.add(new Point(10, 11));
snakeParts.add(new Point(10, 12));
this.addKeyListener(keylistener);
}
//Startup paint method.
public void paint(Graphics paramGraphics){
graphics = paramGraphics.create();
this.customInit();
this.setBackground(Color.WHITE);
this.drawAll();
}
public void customInit(){
this.runCount++;
this.setSize(new Dimension(451,451));
if(this.runCount == 2){
Thread eventThread = new Thread(events);
eventThread.start();
}
}
//Used to call all draw methods.
public void drawAll(){
Random random = new Random();
//Calling all draw methods.
this.drawGrid(graphics);
this.drawFruit(graphics,random.nextInt(GRID_WIDTH),random.nextInt(GRID_HEIGHT));
this.drawSnake(graphics);
}
public void drawGrid(Graphics paramGraphics){
paramGraphics.drawRect(0,0,BOX_WIDTH * GRID_WIDTH,BOX_HEIGHT * GRID_HEIGHT);
//Drawing horizontal lines.
for(int x = BOX_WIDTH; x < BOX_WIDTH * GRID_WIDTH; x+=BOX_WIDTH){
paramGraphics.drawLine(x,0,x,BOX_HEIGHT * GRID_HEIGHT);
}
//Drawing vertical lines.
for(int y = BOX_HEIGHT; y < BOX_HEIGHT * GRID_HEIGHT; y+=BOX_HEIGHT){
paramGraphics.drawLine(0, y, GRID_WIDTH * BOX_WIDTH,y);
}
}
public void drawSnake(Graphics paramGraphics){
paramGraphics.setColor(Color.GREEN);
for(Point point : this.snakeParts){
paramGraphics.fillRect(point.x * 15, point.y * 15, BOX_WIDTH, BOX_HEIGHT);
}
paramGraphics.setColor(Color.BLACK);
}
public void drawFruit(Graphics paramGraphics, int paramX, int paramY){
paramGraphics.setColor(Color.RED);
int tempX = paramX * 15;
int tempY = paramY * 15;
paramGraphics.fillOval(tempX, tempY, BOX_WIDTH,BOX_HEIGHT);
paramGraphics.setColor(Color.BLACK);
}
public void drawEmpty(Graphics paramGraphics, int x, int y){
paramGraphics.clearRect(x * 15, y * 15, 15, 15);
this.drawGrid(graphics);
}
}
事件类(在单独的线程上运行):
package com.Code0.Snake.Threads;
import java.awt.Point;
import com.Code0.Snake.Main.MainS;
public class EventS implements Runnable{
MainS main;
int CURRENT_DIRECTION;
public EventS(MainS paramMain){
this.main = paramMain;
}
@Override
public void run() {
//Infinite loop checking the game and updating it.
while(true){
main.drawGrid(main.graphics);
Point head;
Point tail;
Point finalPoint = new Point();
switch(MainS.direction){
//If direction = north
case(MainS.NORTH):
head = main.snakeParts.getFirst();
finalPoint = new Point(head.x, head.y - 1);
main.snakeParts.push(finalPoint);
tail = main.snakeParts.getLast();
main.snakeParts.remove(tail);
main.drawSnake(main.graphics);
main.drawEmpty(main.graphics, tail.x, tail.y);
break;
//If direction = south
case(MainS.SOUTH):
head = main.snakeParts.getFirst();
finalPoint = new Point(head.x, head.y + 1);
main.snakeParts.push(finalPoint);
tail = main.snakeParts.getLast();
main.snakeParts.remove(tail);
main.drawSnake(main.graphics);
main.drawEmpty(main.graphics, tail.x , tail.y);
break;
case(MainS.WEST):
head = main.snakeParts.getFirst();
finalPoint = new Point(head.x - 1, head.y);
main.snakeParts.push(finalPoint);
tail = main.snakeParts.getLast();
main.snakeParts.remove(tail);
main.drawSnake(main.graphics);
main.drawEmpty(main.graphics, tail.x , tail.y);
break;
case(MainS.EAST):
head = main.snakeParts.getFirst();
finalPoint = new Point(head.x + 1, head.y);
main.snakeParts.push(finalPoint);
tail = main.snakeParts.getLast();
main.snakeParts.remove(tail);
main.drawSnake(main.graphics);
main.drawEmpty(main.graphics, tail.x , tail.y);
break;
case(MainS.NONE):
break;
}
if(finalPoint.x > main.GRID_WIDTH){
int totalSnakeParts = main.snakeParts.size();
main.snakeParts.clear();
for(int i = totalSnakeParts; i > 0; i--){
Point tempPoint = new Point(i - 2, finalPoint.y);
main.snakeParts.add(tempPoint);
main.drawGrid(main.graphics);
System.out.println(tempPoint);
}
main.drawSnake(main.graphics);
}
try {
Thread.currentThread().sleep((long)100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
KeyListener类:
package com.Code0.Snake.Listeners;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import com.Code0.Snake.Main.MainS;
public class KeyListenerS implements KeyListener{
MainS main;
public KeyListenerS(MainS paramMain){
this.main = paramMain;
}
@Override
public void keyPressed(KeyEvent event) {
if(event.getKeyCode() == KeyEvent.VK_UP){
if(main.direction == main.SOUTH){
return;
}
main.direction = main.NORTH;
}
if(event.getKeyCode() == KeyEvent.VK_DOWN){
if(main.direction == main.NORTH){
return;
}
main.direction = main.SOUTH;
}
if(event.getKeyCode() == KeyEvent.VK_LEFT){
if(main.direction == main.EAST){
return;
}
main.direction = main.WEST;
}
if(event.getKeyCode() == KeyEvent.VK_RIGHT){
if(main.direction == main.WEST){
return;
}
main.direction = main.EAST;
}
}
@Override
public void keyReleased(KeyEvent arg0) {
}
@Override
public void keyTyped(KeyEvent arg0) {
}
}
修改
这里是它的外观链接(错误):
http://s15.postimg.org/8z62dy7az/Bildschirmfoto_2014_06_03_um_16_47_48.png
答案 0 :(得分:0)
Thread
调用绘图。现在,我不确定applet和AWT,但在Swing中这是一个巨大的禁止 - 否。有一种方便的repaint()
方法... direction
上没有任何同步。这意味着模型可以忽略用户命令,如果它感觉像。试试volatile
。实际上,将所有变量和绘图代码都放在一个类中是相当糟糕的。 MVC是要走的路。finalPoint.x > main.GRID_WIDTH
因为网格以0开头而导致一个单元格触发太迟,for(int i = totalSnakeParts; i > 0; i--){Point tempPoint = new Point(i - 2, finalPoint.y);
表示第一个点位于负坐标(当i == 1时)