小程序图形Bug?

时间:2014-06-03 14:43:32

标签: java multithreading applet graphic

我得到了这个非常烦人的错误。这很难解释,但基本上每当我的蛇牌(我对游戏进行编码" 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

1 个答案:

答案 0 :(得分:0)

好的,我会尝试逐个解决你的错误,但实际上,这是一个巨大的混乱。

  1. 您可以保存图形状态并从单独的Thread调用绘图。现在,我不确定applet和AWT,但在Swing中这是一个巨大的禁止 - 否。有一种方便的repaint()方法...
  2. direction上没有任何同步。这意味着模型可以忽略用户命令,如果它感觉像。试试volatile。实际上,将所有变量和绘图代码都放在一个类中是相当糟糕的。 MVC是要走的路。
  3. 您遭受了大量的1分之一错误。如果你不知道它是什么 - 谷歌会帮助你。只是举几个你拥有它们的地方:finalPoint.x > main.GRID_WIDTH因为网格以0开头而导致一个单元格触发太迟,for(int i = totalSnakeParts; i > 0; i--){Point tempPoint = new Point(i - 2, finalPoint.y);表示第一个点位于负坐标(当i == 1时)
  4. 在边框检查逻辑中,您可以重置所有蛇点的位置,但是您不会在之前的位置上绘制空方块。你在处理搬家时这样做,你为什么不现在这样做?这是你在右边留下的剩余方块。
  5. 你的边境检查无论如何都在做一些奇怪的事情。他们所做的是将蛇拉直并将其传送到左边缘完全而不是仅仅将头部移动到那里。 看起来相同,而蛇只有3个方格长,因为3号中的错误组合,但是较长的一个会很明显(试试吧!)。一种经典的方法是简单地将头部的x坐标设置为0,而不是重置所有内容。这也将使第4号过时,因为你根本不需要重新绘制余数(不会有任何,蛇不会传送)。