tom*_*ker 4 java swing collision-detection game-physics custom-painting
我一直在尽力解决Pacman与墙壁之间的碰撞检测问题,但是我的实现似乎无法正常工作
任何帮助将不胜感激。提前致谢
GamePanel.java
package pacman;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements Runnable{
private Thread animator;
private boolean isRunning;
private Map map = new Map();
public GamePanel(){
this.setBackground(Color.BLACK);
this.setDoubleBuffered(true);
addKeyListener(new TAdapter());
setFocusable(true);
}
@Override
public void run() {
isRunning = true;
System.out.println("Is running? "+isRunning);
long startTime, timeDiff, sleepTime;
startTime = System.currentTimeMillis();
while(isRunning){
repaint();
gameUpdate();
timeDiff = System.currentTimeMillis() - startTime;
sleepTime = 5 - timeDiff;
try{
Thread.sleep(sleepTime);
}
catch(InterruptedException ex){
System.exit(0);
}
startTime = System.currentTimeMillis();
}
// gameOver(); not implemented yet, will focus on this when I have some basic animation and the game loop working to satisfaction.
}
@Override
public void addNotify(){
super.addNotify();
startGame();
}
public void startGame(){
if(animator == null || !isRunning){
animator = new Thread(this);
animator.start();
}
} //end of StartGame method
public void gameUpdate(){
map.getPlayer().move();
checkCollision();
} //implementation of ingame updates such as pacman getting killed.
public void checkCollision(){ //this is where I officially set collision up
for(int i = 0; i < map.tiles.length; i++){
for(int j = 0; j < map.tiles.length; j++){
if(map.tiles[i][j] != null){
if(map.getPlayer().getPlayerBox().intersects(map.tiles[i][j].getR())){
map.getPlayer().setColliding(true);
System.out.println("OWW"+map.tiles[i][j].getR().getLocation());
}
}
}
}
}
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D) g;
super.paintComponent(g);
if(isRunning){
drawDot(g2d);
drawPlayer(g2d);
map.drawMap(g2d);
}
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
public void drawDot(Graphics2D g){
g.setColor(Color.GREEN);
for(int x= 0; x < 400; x++){
for(int y = 0; y < 400; y++){
g.drawRect(x * 20, y * 20, 1, 1);
}
}
}
public void drawPlayer(Graphics2D g){
g.drawImage(map.getPlayer().getImage(), map.getPlayer().getX(),map.getPlayer().getY(), this);
}
private class TAdapter extends KeyAdapter{
@Override
public void keyPressed(KeyEvent e) {
map.getPlayer().keyPressed(e);
}
@Override
public void keyReleased(KeyEvent e) {
map.getPlayer().keyReleased(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
播放器
package pacman;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
public class Player extends Commons{
private int dx, dy;
private int speed = 1;
private static int playerWidth = 52; //these figures seem off, but that is because the image is not designed correctly or the pacman image is not obeying the logic of not going passed the frame size.
private static int playerHeight = 82;
private Rectangle playerBox;
private Image playerImg = new ImageIcon(Player.class.getResource("Pacman.png")).getImage();
private Image playerImgUp = new ImageIcon(Player.class.getResource("PacmanUp.png")).getImage();
private Image playerImgLeft = new ImageIcon(Player.class.getResource("PacmanLeft.png")).getImage();
private Image playerImgDown = new ImageIcon(Player.class.getResource("PacmanDown.png")).getImage();
private boolean isColliding = false;
public Player(){
this.setX(320);
this.setY(280);
playerBox = new Rectangle(this.getX(), this.getY(),40,40);
}
public void setSpeed(int sp){
speed = sp;
}
public Image getImage(){
if(dy == 1){
return playerImgDown;
}
else if(dy == -1){
return playerImgUp;
}
else if(dx == -1){
return playerImgLeft;
}
else
return playerImg;
}//Responsible for displaying pacman image based on direction of pacman's movement.
void move(){
int x = this.getX();
int y = this.getY();
/*
* This is the part where I am trying to implement some degree of logic to stop it from moving
*/
if(isColliding == false){
this.setX(x += dx);
playerBox.setLocation(x, y);
this.setY(y += dy);
}else if(isColliding == true){
this.setColliding(false);
this.setX(this.getX());
this.setY(this.getY());
}
if (this.getX() <= 1) {
this.setX(1);
}
if (this.getX() >= 400 - playerWidth) {
this.setX(400 - playerWidth);
}
if (this.getY() <= 2) {
this.setY(2);
}
if (this.getY() >= 400 - playerHeight ) {
this.setY(400 - playerHeight);
}
}//Most simplist form of collision detection, stops pacman from leaving the JFrame
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_LEFT ){
dx = -speed;
dy = 0;
}
if(key == KeyEvent.VK_RIGHT){
dx = speed;
dy = 0;
}
if(key == KeyEvent.VK_UP){
dx = 0;
dy = -speed;
}
if(key == KeyEvent.VK_DOWN){
dx = 0;
dy = speed;
}
if(key == KeyEvent.VK_ESCAPE){
System.exit(0);
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_LEFT){
dy = 0;
}
if(key == KeyEvent.VK_RIGHT){
dy = 0;
}
if(key == KeyEvent.VK_UP){
dx = 0;
}
if(key == KeyEvent.VK_DOWN){
dx = 0;
}
}//end of key release
public Rectangle getPlayerBox() {
return playerBox;
}
public void setPlayerBox(Rectangle playerBox) {
this.playerBox = playerBox;
}
public boolean isColliding() {
return isColliding;
}
public void setColliding(boolean isColliding) {
this.isColliding = isColliding;
}
}// end of class
Run Code Online (Sandbox Code Playgroud)
小智 5
好像玩家进入会导致碰撞并isColliding设置为true 的图块时发生的情况。游戏更新的下一个迭代调用移动代码,该代码检查玩家的isColliding布尔值。该条件为真,并且不会发生移动。接下来,检查碰撞,并且我们没有移出引起碰撞的图块,因此我们被卡在该图块中。
我建议在发生碰撞时将玩家移出碰撞瓷砖。
| 归档时间: |
|
| 查看次数: |
51 次 |
| 最近记录: |