Я только начинаю делать игры, и я сделал апплет HelloWorld, затем проверил свою идею прокрутки на нем, и в конце концов он начал превращаться в игру в стиле «вертолета». Теперь все работало нормально, пока я не решил добавить несколько операторов switch для обработки состояний (титульный экран, запуск и окончание игры). Код, который работал раньше, не изменился, и мой новый «вводный экран» работает нормально, но когда вы переключаетесь в состояние игры, двойная буферизация, кажется, выходит из строя. Передний план игры быстро включается и выключается, из него вырезаются треугольники, а фон практически не отображается. Я просто изучаю основные принципы кодирования игр, так что это не элегантно, не модульно или что-то в этом роде, но должно работать...
[EDIT] Я знаю, что апплеты и AWT в целом, вероятно, плохой путь, но я начал это так, и я просто хочу узнать, как это работает и что я делаю неправильно, чтобы я мог быть удовлетворен и двигаться дальше.
package testStuff;
import java.awt.*;
import java.applet.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class HelloWorld extends Applet implements Runnable{
//game time counter
int count = 0;
//controller object
Controller control;
//accesses images and creates image variables
File wavesource = new File("C:\\sourceimages\\waves.jpg");
File playerSource = new File("C:\\sourceimages\\plane3.png");
Image player = null;
Image waves = null;
//font for score
Font myFont;
//double buffer objects
Graphics bground;
Image bgImage = null;
private int bgx = 0;
//player position
private int xPos=0;
private int yPos=50;
//arrays for tunnel locations
private int[] topTunnel = new int[200];
private int[] botTunnel = new int[200];
//size of tunnel
private int tunnelSize;
//boolean determines direction of tunnel movement
private boolean tunUp;
//state
private int state;
//"constructor"
public void init(){
//set state
state = 0;
//instantiates controller adds it to the applet
control = new Controller();
this.addKeyListener(control);
//instantiates images
try {
waves = ImageIO.read(wavesource);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
player = ImageIO.read(playerSource);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//instantiates arrays and tunnel size
for(int i=0;i<199;i++){
topTunnel[i]=-1;
botTunnel[i]=-1;
}
topTunnel[199]=20;
botTunnel[199]=179;
tunnelSize = botTunnel[199]-topTunnel[199];
tunUp = false;
}
public void paint(Graphics g){
switch(state){
case 0:
g.setColor(Color.black);
myFont = new Font("Courier", Font.BOLD+Font.ITALIC, 12);
g.setFont(myFont);
g.drawString("DON'T CRASH THE PLANE BRO", 10, 100);
myFont = new Font("Courier", Font.PLAIN, 8);
g.setFont(myFont);
g.drawString("Press Spacebar to Play", 40, 150);
break;
case 1:
g.drawImage(player, xPos, yPos, null);
g.setColor(Color.red);
for(int i=0;i<200;i++){
g.fillRect(i, 0, 1, topTunnel[i]);
g.fillRect(i, botTunnel[i], 1, botTunnel[i]);
}
g.setColor(Color.cyan);
myFont = new Font("Helvetica", Font.PLAIN, 12);
setFont(myFont);
if(count<170)
g.drawString("SCORE: " + 0, 0, 12);
else
g.drawString("SCORE: " + (this.count-170), 0, 12);
break;
}
}
public void start(){
Thread thread = new Thread(this);
thread.start();
}
@Override
public void run(){
while(true){
switch(state){
case 0:
//increases count
count++;
//paints
this.repaint();
try {
Thread.sleep(1000/30);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if(control.spaceDown()){
state = 1;
count = 0;
}
break;
case 1:
//increases count
count++;
//handles scrolling
if(xPos<75){
xPos++;
}
else{
if(bgx>-600){
bgx--;
}
else{
bgx=0;
}
}
//handles input
if(control.spaceDown()==true&&yPos>=0){
yPos--;
}
else if(yPos<180){
yPos++;
}
//repositions tunnel
if(xPos>=75){
for(int i=1;i<200;i++){
topTunnel[i-1]=topTunnel[i];
botTunnel[i-1]=botTunnel[i];
}
}
//defines new tunnel space
if(topTunnel[199]<=0 || !tunUp)
topTunnel[199]++;
if(botTunnel[199]>=200 || tunUp)
topTunnel[199]--;
botTunnel[199] = topTunnel[199]+tunnelSize;
//randomly chooses direction to move tunnel
double randomNum = Math.random();
if(randomNum>.5)
tunUp = true;
else
tunUp = false;
//narrows tunnel
if(count%20 == 0)
tunnelSize--;
//calls update
this.repaint();
//handles framerate
try {
Thread.sleep(1000/30);
} catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
public void update(Graphics g){
//instantiates image and graphics on first tick
if(bgImage == null){
bgImage = createImage(this.getSize().width, this.getSize().height);
bground = bgImage.getGraphics();
}
//create background based on state
switch(state){
case 0:
//flashing colors!
if(count%20<10){
bground.setColor(Color.yellow);
bground.fillRect(0, 0, 200, 200);
}
else{
bground.setColor(Color.orange);
bground.fillRect(0, 0, 200, 200);
}
break;
case 1:
//draws background image(s)
bground.drawImage(waves,bgx,0,this);
if(bgx<-399)
bground.drawImage(waves,bgx+600,0,this);
break;
}
//paint over the background then draw it to screen
paint(bground);
g.drawImage(bgImage, 0, 0, this);
}
}
JFrame
- по многим причинам, включая песочницу апплета при загрузке изображений и тенденцию компонентов Swing иметь встроенную двойную буферизацию. Кроме того, этот код сломается во время выполненияFile wavesource = new File("C:\\sourceimages\\waves.jpg");
Доступ к ресурсам в апплетах должен осуществляться по URL-адресу. - person Andrew Thompson   schedule 24.01.2013