Как сделать 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, но единственная проблема в том, что цвет никогда не очищается, и через некоторое время возникают проблемы с производительностью, и эффекта затухания нет, он только отстает
Опять же, в данный момент у меня нет компьютера, чтобы проверить это, но логика кажется правильной, и если она не работает, то она должна, по крайней мере, установить основу для типа логики, которую вы ищете.