所以,基本上我正在做的是,我试图让我的角色在我正在制作的游戏中行走,但是图像不是双重缓冲,因为对于一个,我不完全确定在什么地方加倍缓冲(即什么类,游戏类或播放器类),或者甚至是如何做到这一点;我不知道如何实现它。谁能帮我?这只是HS的一个项目,没什么大不了的,我真的很想学习如何去做/实现它。
package castlevania;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Game extends JFrame implements Runnable, KeyListener {
private final int WIDTH = 800, HEIGHT = 600;
private boolean running = false;
private Player p;
private Graphics g;
private GUI gui;
private boolean aIsDown = false, wIsDown = false, sIsDown = false,
dIsDown = false;
private Level[] levels = {
new Level("levels/level1.png", new Audio("music/vampirekiller.wav"))
};
private int oldHealth, loop = 0;
private Image dbImage;
private Graphics dbg;
public Game() {
p = new Player(0, HEIGHT - 128);
oldHealth = p.getHealth();
gui = new GUI();
setSize(new Dimension(800, 600));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setMinimumSize(new Dimension(WIDTH, HEIGHT));
setMaximumSize(new Dimension(WIDTH, HEIGHT));
add(gui);
setLocationRelativeTo(null);
setFocusable(true);
setResizable(false);
pack();
setVisible(true);
addKeyListener(this);
}
public void start() {
run();
}
public void run() {
running = true;
while (running) {
try {
Thread.sleep(17);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void stop() {
running = false;
}
public void keyPressed(KeyEvent e) {
p.isRunning = false;
int keyCode = e.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_W:
wIsDown = true;
if(p.clearBelow() && !p.isJumping)
p.resetTime(); //Using v = v_i + a*t for velocity, so need to reset time.
p.jump();
break;
/*case KeyEvent.VK_S:
sIsDown = true;
p.setY(p.getY() + 10);
break;
*
* This is commented out because we don't need 'S' to do anything yet.
*/
case KeyEvent.VK_A:
aIsDown = true;
p.isStanding = false;
p.setDirection(-1);
break;
case KeyEvent.VK_D:
dIsDown = true;
p.isStanding = false;
p.setDirection(1);
break;
case KeyEvent.VK_SPACE:
Audio whip1 = new Audio("soundeffects/whip1.wav");
whip1.play();
break;
}
if (aIsDown || dIsDown) {
p.isRunning = true;
}
}
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
int i = e.getKeyCode();
switch (i) {
case KeyEvent.VK_A:
aIsDown = false;
break;
case KeyEvent.VK_D:
dIsDown = false;
break;
case KeyEvent.VK_W:
wIsDown = false;
break;
case KeyEvent.VK_S:
sIsDown = false;
break;
}
if (!aIsDown && !dIsDown) //This is where I have to fix things. Along with the below if statement.
{
if (!p.isJumping)
{
p.isRunning = false;
p.isStanding = true;
}
}
if ((aIsDown || dIsDown) && !p.isJumping)
{
System.out.println("This is happening");
p.isRunning = true;
//p.setVelx(p.);
p.isStanding = false; //Changed this.
}
}
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void paint(Graphics g) {
int newHealth = p.getHealth();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedImage image = p.changeImages();
g.drawImage(image, p.getX(), p.getY(), null);
if (newHealth != oldHealth || loop == 0)
{
gui.paintComponent(g);
}
loop++;
repaint();
}
public int getWIDTH() {
return WIDTH;
}
public int getHEIGHT() {
return HEIGHT;
}
}
玩家等级如下:
package castlevania;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
public class Player extends Entity {
private static final long serialVersionUID = -5471880502989465049L;
private static int counter = 0;
private int xSprite = 0, ySprite = 0;
private int x, velx;
private BufferedImage currentImage;
private int y, vely, velyInit = 15, accel = -20, t = 0, direction = 1; //Should be 1
private Graphics dbg;
private Image dbImage;
private final int SPRITEROWS = 4, SPRITECOLS = 6, WIDTH = 128, HEIGHT = 128, RUNSPEED = 10; //RUNSPEED = 10;
private SpriteSheet sheet;
private int health;
private ArrayList<Item> items;
public boolean isRunning = false, isAttacking = false, isStanding = true, isJumping = false;
public Player(int x, int y) {
super();
sheet = new SpriteSheet("spritesheets/belmont_sprite_sheet_without_bg.png", WIDTH, HEIGHT, SPRITEROWS, SPRITECOLS);
currentImage = sheet.getImage(0, 0);
this.x = x;
this.y = y;
health = 10;
items = new ArrayList<Item>(); // for items gathered in game
setFocusable(true);
setDoubleBuffered(true);
}
public void resetTime() {
this.t = 0;
}
public BufferedImage changeImages() // CHANGE THIS
// METHOD!-----------------------------------------------------------
{
counter++;
if (isJumping) { //This probably needs to go in the counter.
if (clearBelow()) {
jump();
} else {
vely = 0;
isJumping = false;
xSprite = 0;
ySprite = 0;
}
}
//Just sets Sprites and running Speeds.
if (counter >= 5) { //Should be 5
System.out.println("Is running " + isRunning + " is Standing: " + isStanding);
if (isJumping) {
xSprite = 0;
ySprite = 5;
}
else if (isRunning) // I'm going to have images be returned
// differently
// depending on what the player is doing. This part
// is if it's running.
{
xSprite = 0;
setVelx(RUNSPEED * direction);
if (ySprite != SPRITECOLS - 1 && velx != 0) {
ySprite++;
} else {
ySprite = 0;
}
}
else if (isStanding)
{
setVelx(0);
xSprite = 0;
ySprite = 0;
}
else if (isAttacking) // This sprite is for when he's attacking.
{
xSprite = 1; // Both of the attacks are in the same row.
if (isStanding) {
for (int i = 0; i < 2; i++) { // Also modified this to
// appropriately change
// xSprite
// And ySprite instead of
// returning
// The image
if (ySprite == 0) {
ySprite = 1;
} else { //This will not work
ySprite = 0;
}
}
} else {
for (int i = 2; i < 4; i++) {
return sheet.getImage(1, i); //This will not work
}
}
}
//System.out.println(direction);
if (direction == 1)
{
//System.out.println("Going right");
currentImage = sheet.getImage(xSprite, ySprite);
}
else //if (direction == -1)
{
//System.out.println("This should print");
currentImage = sheet.getFlippedImage(xSprite, ySprite);
}
counter = 0;
}
this.x += velx;
this.y += vely;
return currentImage;
}
public boolean clearBelow() // Modify later to make it check below for
// platforms.
{
if (this.y + HEIGHT > 600) {
this.y = 600 - HEIGHT;
return false;
}
return true;
}
public boolean clearAbove() {
return true;
}
public void jump() { // Needs to get fixed.
// v = vi + at ---- Physics ----
isJumping = true;
t++;
if (t % 4 == 0) {
vely = (int) ((velyInit + accel * ((double) (t / 30.0))) * -1);
System.out.println(vely);
}
}
public void setDirection(int dir) {
direction = dir;
}
public boolean onGround() {
return true;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getWIDTH() {
return WIDTH;
}
public int getHEIGHT() {
return HEIGHT;
}
public void setHealth(int x) {
this.health = x;
}
public int getHealth() {
return health;
}
public void addItem(Item item) {
items.add(item);
}
public void removeItem(Item item) {
items.remove(item);
}
public static int getCounter() {
return counter;
}
public static void setCounter(int counter) {
Player.counter = counter;
}
public int getxSprite() {
return xSprite;
}
public void setxSprite(int xSprite) {
this.xSprite = xSprite;
}
public int getySprite() {
return ySprite;
}
public void setySprite(int ySprite) {
this.ySprite = ySprite;
}
public int getSpriteRows() {
return SPRITEROWS;
}
public int getSpriteCols() {
return SPRITECOLS;
}
@Override
public SpriteSheet getSheet() {
return sheet;
}
@Override
public void setSheet(SpriteSheet sheet) {
this.sheet = sheet;
}
public ArrayList<Item> getItems() {
return items;
}
public void setItems(ArrayList<Item> items) {
this.items = items;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setVelx(int x) {
this.velx = x;
}
public int getVelx() {
return this.velx;
}
}