Как сделать Tron как след в Slick2D

Я работаю над Tron-подобной игрой для своего проекта для 11-го класса Computer Science с использованием Slick2D. Я застрял на след. Как я могу создать след? Если я создаю прямоугольник, как мне его покрасить? Вот мой код для класса Game.

package bmtron;

import java.awt.Rectangle;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.state.transition.FadeInTransition;
import org.newdawn.slick.state.transition.FadeOutTransition;

class Game extends BasicGameState {

int stateID = -1;

// Getting the width, height and the scale from Tron.java 
int w = Tron.WIDTH;
int h = Tron.HEIGHT;
float s  = Tron.SCALE;

// Variable declaration and initialization
float player1x = (480*s), player1y = (540*s);
float player2x = (1440*s), player2y = (540*s);
int direction1x = 5, direction1y = 0;
int direction2x = -5, direction2y = 0;
boolean isDead1 = false, isDead2 = false;
boolean right1 = true, left1 = false, up1 = false, down1 = false;
boolean right2 = false, left2 = true, up2 = false, down2 = false;

// Images that are going to be used in this state
static Image gameBackground = null;
static Image player1 = null;
static Image player2 = null;

// Bounding boxes
Rectangle p1 = new Rectangle((int)(player1x),(int)(player1y),(int)(20*s),(int)(20*s));
Rectangle p2 = new Rectangle((int)(player2x),(int)(player2y),(int)(20*s),(int)(20*s));

public Game(int stateID) {
    this.stateID = stateID;
}

@Override
public int getID() {
    return stateID;
}

@Override
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException { 
    gameBackground = new Image("/resources/background/gamebackground.jpg");
    player1 = new Image("/resources/images/player1.png");
    player2 = new Image("/resources/images/player2.png");
}

@Override
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws         SlickException {
    gameBackground.draw(0, 0, w, h);

    // Drawing the players to the screen
    if (isDead1 == false){
        player1.draw(player1x,player1y,s);
    }else{
        player1.destroy();
    }

    if (isDead2 == false){
        player2.draw(player2x,player2y,s);
    }else{
        player2.destroy();
    }
}

@Override
public void update(GameContainer gc, StateBasedGame sbg, int i) throws SlickException {
    // Updating the location of the bounding boxes
    p1.setLocation((int)(player1x),(int)player1y);
    p2.setLocation((int)(player2x),(int)player2y);

    Input input = gc.getInput();

    getMovement(gc);
    // Checking to see if the players went out of bounds
    if (player1x>(1920*s)||player1x<1){
        isDead1 = true;
        player1.destroy();
    }else{
        player1x +=direction1x;
    }
    if (player1y>(1080*s)||player1y<1){
        isDead1 = true;
        player1.destroy();
    }else{
        player1y +=direction1y;
    }


    if (player2x>(1920*s)||player2x<1){
        isDead2 = true;
        player2.destroy();
    }else{
        player2x +=direction2x;
    }
    if (player2y>(1080*s)||player2y<1){
        isDead2 = true;
        player2.destroy();
    }else{
        player2y +=direction2y;
    }

    // Exit using escape
    if (input.isKeyPressed(Input.KEY_ESCAPE)) {
        System.exit(0);
    }

    // Checking if the two players collide with each other
    if (p1.intersects(p2)) {
        isDead1 = true;
        isDead2 = true;
    }

    // Checking who has won
    if (isDead1 == true && isDead2 == true) {
        sbg.enterState(4, new FadeOutTransition(Color.white, 1000), new FadeInTransition(Color.white, 1000));
        //System.exit(0);
    }
    if (isDead2 == true) {
        System.err.println("Player 1 has won!");
        sbg.enterState(4, new FadeOutTransition(Color.white, 1000), new FadeInTransition(Color.white, 1000));
        //System.exit(0);
    }
    if (isDead1 == true) {
        System.err.println("Player 2 has won!");
        sbg.enterState(4, new FadeOutTransition(Color.white, 1000), new FadeInTransition(Color.white, 1000));
        //System.exit(0);
    }     
}

private void getMovement(GameContainer gc) {
    Input input = gc.getInput();

    // Player 1 controls
    if (input.isKeyDown(Input.KEY_RIGHT)) {
        right1 = true;
        left1 = false;
        up1 = false;
        down1 = false;
    }
    if (input.isKeyDown(Input.KEY_LEFT)) {
        right1 = false;
        left1 = true;
        up1 = false;
        down1 = false;
    }
    if (input.isKeyDown(Input.KEY_UP)) {
        right1 = false;
        left1 = false;
        up1 = true;
        down1 = false;
    }
    if (input.isKeyDown(Input.KEY_DOWN)) {
        right1 = false;
        left1 = false;
        up1 = false;
        down1 = true;
    }

    // Movement of Player 1
    if (right1 == true && player1y % (20*s) == 0){
        direction1x = 5;
        direction1y = 0;
    }else if (left1 == true && player1y % (20*s) == 0){
        direction1x = -5;
        direction1y = 0;          
    }else if (up1 == true && player1x % (20*s) == 0){
        direction1x = 0;
        direction1y = -5;           
    }else if (down1 == true && player1x % (20*s) == 0){
        direction1x = 0;
        direction1y = 5;
    }

    // Player 2 controls
    if (input.isKeyDown(Input.KEY_D)) {
        right2 = true;
        left2 = false;
        up2 = false;
        down2 = false;
    }
    if (input.isKeyDown(Input.KEY_A)) {
        right2 = false;
        left2 = true;
        up2 = false;
        down2 = false;
    }
    if (input.isKeyDown(Input.KEY_W)) {
        right2 = false;
        left2 = false;
        up2 = true;
        down2 = false;
    }
    if (input.isKeyDown(Input.KEY_S)) {
        right2 = false;
        left2 = false;
        up2 = false;
        down2 = true;
    }

    // Movement of Player 2
    if (right2 == true && player2y % (20*s) == 0){
        direction2x = 5;
        direction2y = 0;
    }else if (left2 == true && player2y % (20*s) == 0){
        direction2x = -5;
        direction2y = 0;          
    }else if (up2 == true && player2x % (20*s) == 0){
        direction2x = 0;
        direction2y = -5;           
    }else if (down2 == true && player2x % (20*s) == 0){
        direction2x = 0;
        direction2y = 5;
    }
}

}

1 ответ

Я не так много работал с LWJGL или Slick 2d, но вот как покрасить:

    glBegin(GL_QUADS);
    Color.white(or the color of choice).bind();
    glVertex2f(x, y);
    glVertex2f(x2, y2);
    glVertex2f(x3, y3);
    glVertex2f(x4, y4);
    glEnd();

И в данный момент у меня нет компьютера для тестирования, но для эффекта затухания попробуйте:

    //call when the effect is to begin
    //If you don't have a set update rate
    counter++
    //If you lock logic update rate
    counter += 1.0f * delta

    private float r, b, g //I think opengl uses RBG, but the name doesn't matter

    public setFade(){
          //the 5 can be changed to however long you want the ribbon to stay visible 
         if(counter > 5); r-- (or r -= 1.0f * delta);
         if(counter > 5); b-- (or b -= 1.0f * delta);
         if(counter > 5); g-- (or g -= 1.0f * delta);
     }

где вы рисуете прямоугольник должен выглядеть так:

    glClearColor(r, b, g, 0.0f);
    glBegin(GL_QUADS);
    Color.white(or the color of choice).bind();
    glVertex2f(x, y);
    glVertex2f(x2, y2);
    glVertex2f(x3, y3);
    glVertex2f(x4, y4);
    glEnd();

И вы просто рисуете это как кусочки для ленты.

Вы также можете технически добиться этого эффекта, просто никогда вообще не вызывая glClearColor, но единственная проблема в том, что цвет никогда не очищается, и через некоторое время возникают проблемы с производительностью, и эффекта затухания нет, он только отстает

Опять же, в данный момент у меня нет компьютера, чтобы проверить это, но логика кажется правильной, и если она не работает, то она должна, по крайней мере, установить основу для типа логики, которую вы ищете.

Другие вопросы по тегам