2017-03-18 7 views
0

두 색상과 타이머 사이에 페이딩/트랜지션 색상 알고리즘을 만들려고합니다. 타이머는 색상이 서로 얼마나 빨리 바뀌는지를 결정합니다. 유일한 문제는 내가 추가하는 페이딩 전환 개체가 많을수록 빠를수록 빠릅니다. 예를 들면 : 하나의 StandardFade (클래스) 객체를 추가하면 타이머 (알파의 코드)에서 실행됩니다. 그러나 '페이드'가 더 많은 물체를 화면에 표시하는 경우 타이머는 더 이상 적합하지 않으며 모든 물체에 대해 동일한 속도, 더 빠르 고 빠릅니다. 왜 그 이유를 설명 할 수 있습니까? 다음은 색상 변색 알고리즘이 작동하지 않습니까?

//Test Game Class, Implements the StandardFades 
import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.image.BufferStrategy; 

public class TestGame extends Canvas implements Runnable{ 

private static final long serialVersionUID = -7267473597604645224L; 

private Thread thread; 
private boolean running = false; 
private boolean consoleFPS = true; 
private boolean titleFPS = true; 

private TestWindow window; 

//Fade objects, two is for a really long timer to test to see if they would transition at different times 
StandardFade one = new StandardFade(Color.RED,Color.BLUE,.005); 
StandardFade two = new StandardFade(Color.RED,Color.GREEN,.00000000000000001); 
StandardFade three = new StandardFade(Color.RED,Color.YELLOW,.000005); 

private int currentFPS; 
private int frames; 

public int levelNum; 

public TestGame(int width, int height, String title){ 
    this.window = new TestWindow(width,height, title, this); 

    this.initFades(); 
    this.start(); 
} 

private synchronized void start(){ 
    if(running) 
     return; 
    else{ 
     this.thread = new Thread(this); 
     this.thread.start(); 
     this.running = true; 
    } 
} 

private synchronized void stop(){ 
    if(!this.running) 
     return; 
    else{ 
     try{ 
      this.thread.join(); 
     }catch(InterruptedException e){ 
      e.printStackTrace(); 
     } 
     this.running = false; 
     System.exit(0); 
    } 
} 
/** 
* This game loop was provided by online sources, though there are many examples 
* of a game loop online. 
* 
* @author RealTutsGML 
*/ 
public void run() { 
    requestFocus(); //Focuses the click/input on the frame/canvas. 
    long lastTime = System.nanoTime(); //The current system's nanotime. 
    double ns = 1000000000.0/60.0; //Retrieves how many nano-seconds are currently in one tick/update. 
    double delta = 0; //How many unprocessed nanoseconds have gone by so far. 
    long timer = System.currentTimeMillis(); 
    int frames = 0; //The frames per second. 
    int updates = 0; //The updates per second. 
    while (running) { 

     boolean renderable = false; //Determines if the game should render the actual graphics. 

     long now = System.nanoTime();//At this point, the current system's nanotime once again. 
     delta += (now - lastTime)/ns; 
     lastTime = now; 
     //If the amount of unprocessed ticks is or goes above one... 
     //Also determines if the game should update or not/render. Approximately sixty frames per second. 
     while (delta >= 1) { 
      tick(); 

      delta--; 
      updates++; 

      renderable = true; 
     } 

     if(renderable){ 
      frames++; 
      render(); 
     } 

     if (System.currentTimeMillis() - timer > 1000) { 
      timer += 1000; 
      System.out.println(frames); 
      updates = 0; 
      frames = 0; 
     } 
    } 

    this.stop(); 
} 

/** 
* This method should tick everything that needs to be updated via positioning, 
* mouse input, etc. 
*/ 
private void tick(){ 
    /********************PUT ALL TICKABLE METHODS IN THIS METHOD; ALL CALCULATIONS, EVERYTHING*********************/ 
    //this.stdFadeHandler.get(0).tick(); 

    //this.stdFadeHandler.tick(); 

    one.tick(); 
    two.tick(); 
    three.tick(); 
    /**********************************END OF TICK METHOD INFORMATION AND METHODS******************************/ 
} 

private void render(){ 
    BufferStrategy bs = this.getBufferStrategy(); 

    if(bs == null){ 
     createBufferStrategy(3); 
     return; 
    } 

    Graphics g = bs.getDrawGraphics(); 
    Graphics2D g2 = (Graphics2D) g; 

    g2.setColor(Color.BLACK);  
    g2.fillRect(0, 0, window.getWidth(), window.getHeight()); 
    /*******************PLACE ALL DRAWING INSTRUCTIONS WITHIN THIS SECTION OF THE RENDER METHOD*************************/ 

    g2.setColor(one.getColor()); 
    g2.fillRect(20, 20, 200, 200); 
    g2.setColor(two.getColor()); 
    g2.fillRect(20, 300, 200, 200); 
    g2.setColor(three.getColor()); 
    g2.fillRect(20, 540, 200, 200); 

    //this.stdFadeHandler 


    /*******************DO NOT PLACE ANY MORE DRAWING INSTRUCTIONS WITHIN THIS SECTION OF THE RENDER METHOD***************/ 

    g.dispose(); 
    g2.dispose(); 

    bs.show(); 
} 

private void initFades(){ 


} 

public static void main(String[] args){ 

    TestGame stdGame = new TestGame(800,800,"Test Standard Game"); 
} 

는 프레임을 만드는 실제 클래스 : StandardFade

import java.awt.Color; 
import java.awt.Graphics2D; 

public class StandardFade { 

private static float time = 0; 
private static boolean firstColor = true; 

private Color color1; 
private Color color2; 
private double alpha; 

private Color fadeColor; 

/** 
* Lines that implement the 
* r,g and b values come from Princeton University; I will author 
* them in at the bottom. 
* 
* Method takes two parameters and fades them into one another according to a 
* timer/clock value: alpha. 
* @param c1 First color to be used. 
* @param c2 Second color to be used. 
* @param alpha How fast colors should shift. 0 <= n <= 1. 
* Closer value is to zero, the longer it will take to shift. 
* ***Important note about alpha: for non-seizure inducing colors, alpha <= .0005*** 
* 
* The issue that is occurring is that, no matter what I do, no matter if I make 
* different StandardFade objects and assign them, they will always render at the 
* same rate, and faster and faster, depending on how many objects are fading. 
* 
* @return new Color based on r, g, and b values calculated. 
* 
* @author (Only code utilized was lines 58-60): 
* http://introcs.cs.princeton.edu/java/31datatype/Fade.java.html 
*/ 
public StandardFade(Color c1, Color c2, double alpha){ 
    this.color1 = c1; 
    this.color2 = c2; 

    this.alpha = alpha; 
} 

public void tick() { 

    if(time <= 1f && firstColor){ 
     time += alpha; 
    } 

    else{ 
     firstColor = false; 
    } 
    if(time >= 0f && !firstColor) 
     time -= alpha; 
    else{ 
     firstColor = true; 
    } 

    //System.out.println(time); 

    short r = (short) (time * color2.getRed() + (1 - time) * color1.getRed()); 
    short g = (short) (time * color2.getGreen() + (1 - time) * color1.getGreen()); 
    short b = (short) (time * color2.getBlue() + (1 - time) * color1.getBlue()); 

    if(r > 255) r = 255; 
    if(g > 255) g = 255; 
    if(b > 255) b = 255; 

    if(r < 0) r = 0; 
    if(g < 0) g = 0; 
    if(b < 0) b = 0; 


    this.fadeColor = new Color(r, g, b); 
} 

public Color getColor(){ 
    return this.fadeColor; 
} 

답변

1

유일한 문제는 : 나는에 추가 더 페이딩 전환 개체, 빨리 그들 모두가

이동

시간에 정적 변수를 사용하고 있습니다. 이 변수는 ColorFade 클래스의 모든 인스턴스에서 공유됩니다. 따라서 각 페이딩 객체는 동일한 변수를 업데이트합니다.

정적 변수를 사용하지 마십시오 (static 키워드를 제거하십시오). 각 페이딩 객체는 자체 "시간"변수가 ​​필요합니다.

private float time = 0; 

나는 또한 firstColor 변수가 정적이어야하는지 질문합니다.

+0

감사합니다! 이로 인해 문제가 해결되었습니다. firstColor는 정적이 아니어야합니다. 왜냐하면 여러 색상의 오브젝트가 변했을 때 색상이 완전히 바뀌지 않기 때문입니다. 정말 고맙습니다. –

0

상당히 많은 코드가 있습니다. 문제를 가능한 한 줄일 수는 있지만 문제점에 대한 설명을 기반으로하면 더 많은 오브젝트를 빠르게 얻을 수 있습니다. 문제는 다음과 같습니다.

private static float time = 0; 

정적 입력란이 클래스 인스턴스간에 공유되어 있다는 것을 알고 있다고 생각합니다. 그들은 각각 자신의 별도의 가치를 저장하지 않습니다.

tick 메서드가 호출 될 때마다 각 인스턴스가 시간 값을 증가시키기 때문에 이로 인해 문제가 발생합니다. 인스턴스가 하나 뿐이라면 문제가 없지만 더 많은 인스턴스가있을 때는 문제가됩니다.

는 단순히 static 키워드를 제거하고이 제대로 작동해야합니다

private float time = 0;