HI..I made a little game.But this game works on every computer with different speed.I think it is about resolution.I used every thing in paintcomponent.and If I change screen size the game goes slower or faster.And if i run this game on another computer wich has different resolution it also works different. This is my game
http://rapidshare.com/files/364597095/ShooterGame.2.6.0.jarand here code
public class Shooter extends JFrame implements KeyListener, Runnable {
JFrame frame = new JFrame();
String player;
Font startFont, startSubFont, timerFont,healthFont;
Image img;
Image backGround;
Graphics dbi;
URL url1 = this.getClass().getResource("Images/p2.gif");
URL url2 = this.getClass().getResource("Images/p3.gif");
URL url3 = this.getClass().getResource("Images/p1.gif");
URL url4 = this.getClass().getResource("Images/p4.gif");
URL urlMap = this.getClass().getResource("Images/zemin.jpg");
Player p1 = new Player(5, 150, 10, 40, Color.GREEN, url3);
Computer p2 = new Computer(750, 150, 10, 40, Color.BLUE, url1);
Computer p3 = new Computer(0, 0, 10, 40, Color.BLUE, url2);
Computer p4 = new Computer(0, 0, 10, 40, Color.BLUE, url4);
ArrayList<Bullets> b = new ArrayList<Bullets>();
ArrayList<CBullets> cb = new ArrayList<CBullets>();
Thread sheap;
boolean a, d, w, s;
boolean toUp, toDown;
boolean GameOver;
boolean Level2;
boolean newGame, resart, pause;
int S, E;
int random;
int cbSpeed = 0;
long timeStart, timeEnd;
int timeElapsed;
long GameStart, GameEnd;
int GameScore;
int Timer = 0;
int timerStart, timerEnd;
public Shooter() {
sheap = new Thread(this);
sheap.start();
startFont = new Font("Tiresias PCFont Z", Font.BOLD + Font.ITALIC, 32);
startSubFont = new Font("Tiresias PCFont Z", Font.BOLD + Font.ITALIC, 25);
timerFont = new Font("Tiresias PCFont Z", Font.BOLD + Font.ITALIC, 16);
healthFont = new Font("Tiresias PCFont Z", Font.BOLD + Font.ITALIC, 16);
setTitle("Shooter 2.5.1");
setBounds(350, 250, 800, 600);
// setResizable(false);
setBackground(Color.black);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(this);
a = d = w = s = false;
toUp = toDown = true;
GameOver = true;
newGame = true;
Level2 = false;
S = E = 0;
setVisible(true);
}
public void paint(Graphics g) {
img = createImage(getWidth(), getHeight());
dbi = img.getGraphics();
paintComponent(dbi);
g.drawImage(img, 0, 0, this);
}
public void paintComponent(Graphics g) {
repaint();
timeStart = System.currentTimeMillis();
backGround = Toolkit.getDefaultToolkit().getImage(urlMap);
g.drawImage(backGround, 0, 0, null);
g.setColor(Color.red);
g.setFont(healthFont);
g.drawString("" + player + " Health : " + p1.health, 30, 50);
g.setColor(Color.red);
g.drawString("Computer Health : " + (p2.health + p3.health + p4.health), 600, 50);
g.setColor(Color.BLUE);
g.setFont(timerFont);
g.drawString("Time : " + Timer, 330, 50);
if (newGame) {
g.setColor(Color.LIGHT_GRAY);
g.setFont(startFont);
g.drawString("Well Come To Shoot Game", 200, 190);
g.drawString("Press ENTER To Start", 250, 220);
g.setColor(Color.LIGHT_GRAY);
g.setFont(startSubFont);
g.drawString("Use W,A,S,D and Space For Fire", 200, 250);
g.drawString("GOOD LUCK", 250, 280);
newGame();
}
if (!GameOver) {
for (Bullets b1 : b) {
b1.draw(g);
}
for (CBullets b2 : cb) {
b2.draw(g);
}
update(); // Here MOvements for Player and For Fires
}
if (p1.health <= 0) {
g.setColor(p2.col);
g.setFont(startFont);
g.drawString("Computer Wins ", 200, 190);
g.drawString("Press Key R to Restart ", 200, 220);
GameOver = true;
} else if (p2.health <= 0 && p3.health <= 0 && p4.health <= 0) {
g.setColor(p1.col);
g.setFont(startFont);
g.drawString(""+player+" Wins ", 200, 190);
g.drawString("Press Key R to Resart ", 200, 220);
GameOver = true;
g.setColor(Color.MAGENTA);
g.drawString(""+player+"`s Score is " + Timer, 200, 120);
}
if (Level2) {
if (p3.health >= 0) {
p3.draw(g);
for (CBullets b3 : cb) {
b3.draw(g);
}
} else {
开发者_如何学Python p3.x = 1000;
}
if (p4.health >= 0) {
p4.draw(g);
for (CBullets b4 : cb) {
b4.draw(g);
}
} else {
p4.x = 1000;
}
}
if (p1.health >= 0) {
p1.draw(g);
}
if (p2.health >= 0) {
p2.draw(g);
} else {
p2.x = 1000;
}
}
public void update() {
if (w && p1.y > 54) {
p1.moveUp();
}
if (s && p1.y < 547) {
p1.moveDown();
}
if (a && p1.x > 0) {
p1.moveLeft();
}
if (d && p1.x < 200) {
p1.moveRight();
}
random = 1 * (int) (Math.random() * 100);
if (random > 96) {
if (p2.health >= 0) {
CBullets bo = p2.getCBull();
bo.xVel =-1-cbSpeed;
cb.add(bo);
}
if (Level2) {
if (p3.health >= 0) {
CBullets bo1 = p3.getCBull();
bo1.xVel = -2-cbSpeed;
cb.add(bo1);
}
if (p4.health >= 0) {
CBullets bo2 = p4.getCBull();
bo2.xVel = -4-cbSpeed;
cb.add(bo2);
}
}
}
if (S == 1) {
if (p1.health >= 0) {
Bullets bu = p1.getBull();
bu.xVel = 5;
b.add(bu);
S += 1;
}
}
//Here Also Problem .. When COmputer have More fire then it gaves Array Exeption . Or Player have More Fire
for (int i = cb.size() -1; i >= 0 ; i--) {
boolean bremoved = false;
for (int j = b.size() -1 ; j >=0 ; j--) {
if (b.get(j).rect.intersects(cb.get(i).rect) ||
cb.get(i).rect.intersects(b.get(j).rect)) {
bremoved = true;
b.remove(j);
}
}
if(bremoved)
cb.remove(i);
}
for (int i = 0; i < b.size(); i++) {
b.get(i).move();
if (b.get(i).rect.intersects(p2.rect)) {
if (p2.health >= 0) {
p2.health--;
b.remove(i);
// System.out.println("Hited P2");
i--;
continue;
}
}
if (b.get(i).rect.intersects(p3.rect)) {
if (p3.health >= 0) {
p3.health--;
b.remove(i);
// System.out.println("Hited P3");
i--;
continue;
}
}
if (b.get(i).rect.intersects(p4.rect)) {
if (p4.health >= 0) {
p4.health--;
b.remove(i);
// System.out.println("Hited P4");
i--;
continue;
}
}
if (b.get(i).rect.x > 790) {
b.remove(i);
}
}
for (int j = 0; j < cb.size(); j++) {
cb.get(j).move();
if (cb.get(j).rect.intersects(p1.rect) && cb.get(j).xVel < 0) {
p1.health--;
cb.remove(j);
j--;
continue;
}
}
timeEnd = System.currentTimeMillis();
timeElapsed = (int) (timeEnd - timeStart);
}
public void level2() {
if (p2.health <= 10) {
Level2 = true;
cbSpeed = 4;
p3.x = 750;
p4.x = 750;
p2.speed = 10;
p3.speed = 20;
p4.speed = 30;
}
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_ENTER:
newGame = false;
break;
case KeyEvent.VK_P:
pause = true;
break;
case KeyEvent.VK_R:
resart = true;
break;
case KeyEvent.VK_A:
a = true;
break;
case KeyEvent.VK_D:
d = true;
break;
case KeyEvent.VK_W:
w = true;
break;
case KeyEvent.VK_S:
s = true;
break;
case KeyEvent.VK_SPACE:
S += 1;
break;
}
}
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_A:
a = false;
break;
case KeyEvent.VK_D:
d = false;
break;
case KeyEvent.VK_W:
w = false;
break;
case KeyEvent.VK_S:
s = false;
break;
case KeyEvent.VK_SPACE:
S = 0;
break;
}
}
public void newGame() {
p1.health = 20;
p2.health = 20;
p3.health = 20;
p4.health = 20;
p3.x = 0;
p4.x = 0;
p2.x = 750;
Level2 = false;
cbSpeed = 0;
p2.speed = 9;
b.removeAll(b);
cb.removeAll(cb);
timerStart = (int) System.currentTimeMillis();
GameOver = false;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
KeyListener k = new Shooter();
}
});
}
@Override
public void run() {
player = JOptionPane.showInputDialog(frame, "Enter Player Name", "New Player", JOptionPane.DEFAULT_OPTION);
while (true) {
timerEnd = (int) System.currentTimeMillis();
if (resart) {
newGame();
resart = false;
}
if (pause) {
Thread.currentThread().notify();
}
try {
if (!GameOver) {
Timer = timerEnd - timerStart;
level2();
if (p1.y < p2.y && p2.y>60) {
p2.moveUp();
}
if (p1.y < p3.y && p3.y>43) {
p3.moveUp();
}
if (p1.y < p4.y && p4.y>43) {
p4.moveUp();
}
if (p1.y > p2.y && p2.y<535) {
p2.moveDown();
}
if (p1.y > p3.y && p3.y<535) {
p3.moveDown();
}
if (p1.y > p4.y && p4.y<530) {
p4.moveDown();
}
}
if (timeElapsed < 125) {
Thread.currentThread().sleep(125);
}
} catch (InterruptedException ex) {
System.out.print("FInished");
}
}
}
}
It's hard to tell from your splurge, but I'm going to go right ahead and answer anyway: The problem seems to be that you don't drop frames; only stall them. basically, you need to separate your game logic from your drawing logic, and draw however many frames you can. The two should probably be on different threads, but then again, threads are evil.
The topic you are looking for is "Time based movement". I did not read your source code, but the behavior you described looks like frame based movement is the problem.
Here is a short tutorial which covers Time based movement: http://jerome.jouvie.free.fr/OpenGl/Tutorials/Tutorial10.php
This post also covers the problem in greater detail and focuses at physics but also apply to rather simple games: http://gafferongames.com/game-physics/fix-your-timestep/
Edit: As the other answer states, separating rendering and game logic greatly helps.
You need to keep track of the number of millisecs since the last "tick" (screen redraw probably) and only update your world state (positions for instance) when a certain amount of time has passed. Otherwise your game will run at the speed of screen redraws which is not consistent.
Lets say you want to run at 25 fps, that means you should update the game state 25 times per second at most, ie every 40th millisecond.
HI again..I made some modıfıcation to my game like drawing and moving objects in thread..Now it workы on every сomputer same speed.Also if I change size.But problem is I used J3DTimer.getValue() .For this library I donwnloaded Java3d. Problem is If on machine there is no this library or installation my game doesnot working .How can I solw this problem? I should say every one to setup Java#d? :)) ALso I used standart System.currentTimeMillis(); but now my game works very slow...Any idea?
精彩评论