I'm new to programming and I have some issues on how to control my animation's speed. And I hope that you can give me some tips for this code.
public class Maze extends Canvas {
Map map;
Mario mario;
private Timer time;
private BufferStrategy strategy;
private int move;
boolean gameRunning = true;
public Maze(){
map = new Map();
mario = new Mario();
JFrame frame = new JFrame();
frame.setTitle("SuperMario2D");
JPanel panel = (JPanel) frame.getContentPane();
panel.setPreferredSize(new Dimension(438, 438));
panel.setLayout(null);
setBounds(0, 0, 454, 476);
panel.add(this);
setIgnoreRepaint(true);
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
addKeyListener(new KeyHandler());
requestFocus();
createBufferStrategy(2);
strategy = getBufferStrategy();
}
public void gameLoop() {
long lastLoopTime = System.currentTimeMillis();
while (gameRunning) {
// work out how long its been since the last update, this
// will be used to calculate how far the entities should
// move this loop
long delta = System.currentTimeMillis() - lastLoopTime;
lastLoopTime = System.currentTimeMillis();
Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0,0,800,600);
map.draw(g);
mario.draw(g, move);
g.dispose();
strategy.show();
}
try {
Thread.sleep(10);
} catch (Exception e) {}
}
public class KeyHandler extends KeyAdapter{
public void keyPressed(KeyEvent e){
int keycode = e.getKeyCode();
if(keycode == KeyEvent.VK_UP){
mario.move(0, -1); //if it's not equal this will not execute because Y-1 will equal to w
move = 1;
System.out.println("You press up");
}
if(keycode == KeyEvent.VK_DOWN){
mario.move(0, 1);
move = 2;
System.out.println("You press down");
}
if(keycode == KeyEvent.VK_LEFT){
mario.move(-1, 0);
move = 3;
System.out.println("You press left");
}
if(keycode == KeyEvent.VK_RIGHT){
mario.move(1, 0);
move = 4;
System.out.println("You press right");
}
}
public void keyReleased(KeyEvent e){
int keycode = e.getKeyCode();
if(keycode == KeyEvent.VK_UP){
move = 5;
System.out.println("You released up");
}
if(keycode == KeyEvent.VK_DOWN){
move = 6;
System.out.println("You released down");
}
if(keycode == KeyEvent.VK_LEFT){
move = 7;
System.out.println("You released down");
}
if(keycode == KeyEvent.VK_RIGHT){
move = 8;
System.out.println("You released down");
}
}
public void keyTyped(KeyEvent e){
}
}
public static void main(String[] args){
Maze maze = new Maze();
maze.gameLoop();
}
}
here is the code that loads my animated images
public class Mario {
private int x, y;
private int tileX, tileY; //for collision
//private Image player;
private Image[] playerDown = new Image[3];
private Image[] playerUp = new Image[3];
private Image[] playerLeft = new Image[3];
private Image[] playerRight = new Image[3];
private Image[] playerJumpD = new Image[3];
private Image[] playerJumpU = new Image[3];
private Image[] playerJumpL = new Image[3];
private Image[] playerJumpR = new Image[3];
private int cycle = 0;
private long scene1 = 0;
private long scene2 = 500;
public Mario(){
moveDown();
moveUp();
moveLeft();
moveRight();
/*
//jump
jumpDown();
jumpUp();
jumpLeft();
jumpRight();
*/
tileX = 1;
tileY = 1;
}
public void moveDown(){
playerDown[0] = new ImageIcon("images/marioFW1.png").getImage();
playerDown[1] = new ImageIcon("images/marioFW2.png").getImage();
playerDown[2] = new ImageIcon("images/marioFW3.png").getImage();
}
public void moveUp(){
playerUp[0] = new ImageIcon("images/marioB1.png").getImage();
playerUp[1] = new ImageIcon("images/marioB2.png").getImage();
playerUp[2] = new ImageIcon("images/marioB3.png").getImage();
}
public void moveLeft(){
playerLeft[0] = new ImageIcon("images/marioJW1.png").getImage();
playerLeft[1] = new ImageIcon("images/marioJW2.png").getImage();
playerLeft[2] = new ImageIcon("images/marioJW3.png").getImage();
}
public void moveRight(){
playerRight[0] = new ImageIcon("images/marioR1.png").getImage();
playerRight[1] = new ImageIcon("images/marioR2.png").getImage();
playerRight[2] = new ImageIcon("images/marioR3.png").getImage();
}
/*
//jump
public void jumpDown(){
playerJumpD[0] = new ImageIcon("images/marioFJ1.png").getImage();
playerJumpD[1] = new ImageIcon("images/marioFJ2.png").getImage();
playerJumpD[2] = new ImageIcon("images/marioFJ3.png").getImage();
}
public void jumpUp(){
playerJumpU[0] = new ImageIcon("images/marioBJ1.png").getImage();
playerJumpU[1] = new ImageIcon("images/marioBJ2.png").getImage();
playerJumpU[2] = new ImageIcon("images/marioBJ3.png").getImage();
}
public void jumpLeft(){
playerJumpL[0] = new ImageIcon("images/marioJL1.png").getImage();
playerJumpL[1] = new ImageIcon("images/marioJL2.png").getImage();
playerJumpL[2] = new ImageIcon("images/marioJL3.png").getImage();
}
public void jumpRight(){
playerJumpR[0] = new ImageIcon("images/marioRJ1.png").getImage();
playerJumpR[1] = new ImageIcon("images/marioRJ2.png").getImage();
playerJumpR[2] = new ImageIcon("images/marioRJ3.png").getImage();
}
*/
public void move(int dx, int dy){
// x += dx;
// y += dy;
tileX += dx;
tileY += dy;
}
public Image getMoveDown(){
if(cycle == playerDown.length){
cycle = 0;
}
return playerDown[cycle++];
}
public Image getMoveUp(){
if(cycle == playerUp.length){
cycle = 0;
}
return playerUp[cycle++];
}
public Image getMoveLeft(){
if(cycle == playerLeft.length){
cycle = 0;
}
return playerLeft[cycle++];
}
public Image getMoveRight(){
if(cycle == playerRight.length){
cycle = 0;
}
return playerRight[cycle++];
}
/*
//jump
public Image getJumpD(){
if(cycle == playerJumpR.length){
cycle = 0;
}
return playerJumpR[cycle++];
}
public Image getJumpU(){
if(cycle == playerJumpU.length){
cycle = 0;
}
return playerJumpU[cycle++];
}
public Image getJumpL(){
if(cycle == playerJumpL.length){
cycle = 0;
}
return playerJumpL[cycle++];
}
public Image getJumpR(){
if(cycle == playerJumpR.length){
cycle = 0;
}
return playerJumpR[cycle++];
}
*/
/*
public void checkMove(){
if (System.currentTimeMillis() - scene1 < scene2) {
return;
}
scene1 = System.currentTimeMillis();
}
*/
public int getTileX(){
return tileX;
}
public int getTileY(){
return tileY;
}
public void draw(Graphics g, int move) {
if(move == 0)
g.drawImage(playerDown[1], getTileX(), getTileY(), null );
if(move == 1)
g.drawImage(getMoveUp(), getTileX(), getTileY(), null );
if(move == 2)
g.drawImage(getMoveDown(), getTileX(), getTileY(), null );
if(move == 3)
g.drawImage(getMoveLeft(), getTileX(), getTileY(), null );
if(move == 4)
g.drawImage(getMoveRight(), getTileX(), getTileY(), null );
if(move == 5)
g.drawImage(playerUp[1], getTileX(), getTileY(), null );
if(move == 6)
g.drawImage(playerDown[1], getTileX(), getTileY(), null );
if(move == 7)
g.drawImage(playerLeft[1], getTileX(), getTileY(), null );
if(move == 8)
g.drawImage(playerRight[1], getTileX(), getTileY(), null );
}
}
This is where the map was successfully loaded. I'm not sure how i was able to make i run in accelerated graphics mode.
public class Map {
private Scanner m;
private String[] Map = new String[14]; //how many tiles in the map
private Image tiles, grass2, grass3, grass3b;
private Image wall, sand1;
private Image finish;
public Map(){
tiles = new ImageIcon("images/grass2.png").getImage();
wall = new ImageIcon("images/grass1.png").getImage();
grass2 = new ImageIcon("images/grass2.png").getImage();
grass3 = new ImageIcon("images/grass3.png").getImage();
grass3b = new ImageIcon("images/grass3b.png").getImage();
sand1 = new ImageIcon("images/sand1.png").getImage();
finish = new ImageIcon("images/tile.png").getImage();
openFile();
readFile();
closeFile();
}
public void openFile(){
try{
m = new Scanner(new File("images/Map.txt"));
}catch(Exception e){
System.out.println("Can't open the file: "+e);
}
}
public void readFile(){
while(m.hasNext()){ // read through the file
for(int i = 0; i < 14; i++){
Map[i] = m.next();
}
}
}
public void closeFile(){
m.close();
}
public String getMap(int x, int y){
String index = Map[y].substring(x, x + 1);
return index;
}
public Image getTiles(){
return tiles;
}
public Image getWall(){
return wall;
}
public Image getFinish(){
return finish;
}
public Image getImageGrass2(){
return grass2;
}
public Image getImageGrass3(){
return grass3;
}
public Image getImageGrass3b(){
return grass3b;
}
public Image getImageSand1(){
return sand1;
}
//added
public void draw(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
for(int y = 0; y < 14; y++){
for(int x = 0; x < 14; x++){
/**draw the finish line**/
if(getMap(x, y).equals("f")){
g2.drawImage(getFinish(), x*32,y*32, null);
}
/**-----------------------)*/
if(getMap(x, y).equals("g")){
//the size of the image is X 20 by Y20
g2.drawImage(getTiles(), x*32, y*32, null);
}
if(getMap(x, y).equals("w")){
//the size of the image is X 20 by Y20
g2.drawImage(getWall(), x*32, y*32, null);
}
if(getMap(x, y).equals("d")){
//the size of the image is X 20 by Y20
g2.drawImage(getImageGrass3(), x*32, y*32, null);
}
if(getMap(x, y).equals("b")){
//the size of the image is X 20 by Y20
g2.drawImage(getImageGrass3b(), x*32, y*32, null);
}
if(getMap(x, y).equals("s")){
//the size of the image is X 20 by Y20
g2.drawImage(getImageSand1(), x*32, y*32, null);
}
}
}
}
}
Related
I am currently working on my first jump'n Run game. The initial part is already working decent, but i still get a "bug" which appears when my "colums" are moving. This only happens when "MOVE_SPEED" is 1<. I tryed it with a Timer too, same thing.
This is how it looks like:
Please have a look at the code:
...
public class Board implements Runnable, KeyListener {
JFrame frame;
ArrayList<Column> cList;
Player p;
private boolean ingame = false;
public final static int INIT_WIDTH = 600;
public final static int INIT_HEIGHT = 400;
public static int WIDTH;
public static int HEIGHT;
private final int MOVE_SPEED = 10;
//When this is 1 the problem doesnt appear!
private final int GRAVITY = -3;
private int cPlayerStayingOn;
private double playerBottom;
private double floorTop;
private boolean mR = false;
private boolean mL = false;
private boolean jump = false;
long lastLoopTime = System.nanoTime();
final int TARGET_FPS = 100;
final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;
private int fps;
private int lastFpsTime;
public static double delta = 1;
public Board() {
initBoard();
initPlayer();
initColumns();
}
private void initBoard() {
frame = new JFrame("Jump'nRun");
frame.setSize(INIT_WIDTH, INIT_HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.addKeyListener(this);
cList = new ArrayList<Column>();
frame.setVisible(true);
Board.WIDTH = frame.getContentPane().getWidth();
Board.HEIGHT = frame.getContentPane().getHeight();
}
private void initColumns() {
for (int i = 0; i < 8; i++) {
cList.add(new Column(i + 1, true));
frame.add(cList.get(i));
}
}
private void initPlayer() {
p = new Player();
frame.add(p);
}
private void moveColums() {
for (Column col : cList) {
col.setLocation((int) (col.getLocation().getX() - MOVE_SPEED), 0);
}
}
private int playerStanding(double pX) {
for (int i = 0; i < 8; i++) {
if (cList.get(i).getX() <= pX
&& (cList.get(i).getX() + cList.get(i).getWidth()) >= pX) {
return i;
}
}
return -1;
}
private void movePlayer() {
// gravity
if (playerBottom < floorTop) {
p.setLocation((int) p.getLocation().getX(), (int) p.getLocation()
.getY() - GRAVITY);
}
if (mR) {
p.moveRight();
}
if (mL) {
p.moveLeft();
}
if (jump) {
p.jump();
jump = false;
}
}
private void collectData() {
this.cPlayerStayingOn = playerStanding(p.getBounds().getX()
+ p.getBounds().getWidth());
this.playerBottom = p.getBounds().getMaxY();
this.floorTop = cList.get(cPlayerStayingOn).floor.getY();
}
private void recycleColums() {
if (cList.get(0).getX() + cList.get(0).getWidth() <= 0) {
cList.remove(0);
cList.add(7, new Column(7 + 1, false));
frame.add(cList.get(7));
}
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE
|| e.getKeyCode() == KeyEvent.VK_W
|| e.getKeyCode() == KeyEvent.VK_UP) {
if (playerBottom >= floorTop) {
jump = true;
}
}
if (e.getKeyCode() == KeyEvent.VK_D
|| e.getKeyCode() == KeyEvent.VK_RIGHT) {
mR = true;
}
if (e.getKeyCode() == KeyEvent.VK_A
|| e.getKeyCode() == KeyEvent.VK_LEFT) {
mL = true;
}
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_D
|| e.getKeyCode() == KeyEvent.VK_RIGHT) {
mR = false;
}
if (e.getKeyCode() == KeyEvent.VK_A
|| e.getKeyCode() == KeyEvent.VK_LEFT) {
mL = false;
}
}
private int getFps() {
return fps;
}
private void setFps(int fps) {
this.fps = fps;
}
#Override
public void run() {
while (true) {
if (!ingame) {
ingame = true;
} else {
long now = System.nanoTime();
long updateLength = now - lastLoopTime;
lastLoopTime = now;
delta = updateLength / ((double) OPTIMAL_TIME);
lastFpsTime += updateLength;
setFps(getFps() + 1);
if (lastFpsTime >= 1000000000) {
lastFpsTime = 0;
setFps(0);
}
recycleColums();
collectData();
moveColums();
movePlayer();
try {
Thread.sleep((lastLoopTime - System.nanoTime() + OPTIMAL_TIME) / 1000000);
} catch (Exception e) {
}
}
}
}
}
and the Column Class:
...
public class Column extends JPanel {
JPanel floor;
JPanel grass;
Random rand = new Random();
private static final long serialVersionUID = 1L;
public final static int WIDTH = Board.WIDTH / 6;
public final int HEIGHT = Board.HEIGHT;
private int position;
public final static int FLOOR_H = WIDTH;
public Column(int pos, boolean init) {
this.position = pos;
setBounds((WIDTH * position) - WIDTH, 0, WIDTH, HEIGHT);
setLayout(null);
setBackground(Color.WHITE);
floor = new JPanel();
floor.setLayout(null);
floor.setBackground(Color.BLACK);
if (init) {
floor.setBounds(0, HEIGHT - FLOOR_H, WIDTH, FLOOR_H);
} else {
floor.setBounds(0,
(HEIGHT - (FLOOR_H + (FLOOR_H * rand.nextInt(2) / 2))),
WIDTH, FLOOR_H * 2);
}
grass = new JPanel();
grass.setBounds(0, 0, WIDTH, 10);
grass.setBackground(Color.GREEN);
floor.add(grass);
add(floor);
}
}
Any hints are appreciatet!
(Sorry for the bad english)
i fixed it by changing the following:
private void recycleColums() {
if (cList.get(0).getX() + cList.get(0).getWidth() <= 0) {
cList.remove(0);
cList.add(7, new Column(7 + 1, false, cList.get(6).getX()));
frame.add(cList.get(7));
}
}
...
public Column(int pos, boolean init, int lastX) {
this.position = pos;
setLayout(null);
setBackground(Color.WHITE);
floor = new JPanel();
floor.setLayout(null);
floor.setBackground(Color.BLACK);
if (init) {
setBounds((WIDTH * position) - WIDTH, 0, WIDTH, HEIGHT);
floor.setBounds(0, HEIGHT - FLOOR_H, WIDTH, FLOOR_H);
} else {
setBounds(lastX + WIDTH, 0, WIDTH, HEIGHT);
floor.setBounds(0,
(HEIGHT - (FLOOR_H + (FLOOR_H * rand.nextInt(2) / 2))),
WIDTH, FLOOR_H * 2);
}
I have make a Simple program using Java Swing.
If you start, the missiles across canvas from left to right, when you click canvas the balloon is made.
I make crush event between two labels. But, It doesn't work well.
Sometime It's worked well, But some Balloon doesn't cognize missile.
(..sorry i'm little the south korean boy. I don't know english grammar well..)
This is my source file
Game2.java
public class Game2 {
public Game2(){
JFrame jF = new JFrame();
jF.setTitle("게임");
jF.setDefaultCloseOperation(jF.EXIT_ON_CLOSE);
jF.setSize(500, 500);
jF.setVisible(true);
MyPanel myPanel = new MyPanel();
jF.setContentPane(myPanel);
}
public static void main(String[] args) {
new Game2();
}
}
MyPanel.java
public class MyPanel extends JPanel implements Runnable {
private ArrayList<Balloon> ballList = new ArrayList<Balloon>();
private ArrayList<Missile> misList = new ArrayList<Missile>();
public MyPanel() {
setLayout(null);
Thread setMissileThread = new Thread(this);
setMissileThread.start();
}
#Override
public void run() {
// 마우스 클릭 이벤트 처리(풍선)
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
ballList.add(new Balloon(e.getX(), e.getY()));
// System.out.println("풍선 생성");
}
});
// 자동 처리(미사일)
while (true) {
// synchronized(ballList){
Missile mis;
misList.add(mis = new Missile());
mis.start();
// System.out.println("미사일생성");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
return;
}
// 미사일 충돌
if (!misList.isEmpty() && !ballList.isEmpty()) {
for (Missile misArr : misList) {
for (Balloon ballArr : ballList) {
Point ballPos = ballArr.getPosition();
Point misPos = misArr.getPosition();
if(ballArr.visible){System.out.println("살아있더"+ballPos.x+", "+ballPos.y);}
if (ballPos.x - 10 <= misPos.x + 60
&& misPos.x + 60 <= ballPos.x + 40
&& ballPos.y - 20 <= misPos.y + 15
&& misPos.y + 25 <= ballPos.y + 50) {
//visible을 따져서 충돌 파괴모션을 설정한다.
if (ballArr.visible == true) {
ballArr.visible = false;
// 라벨 삭제
remove(misArr.missile);
remove(ballArr.ball);
repaint();
System.out.println("Bomb!");
}
/*
* //ArrayList 인덱스 삭제 misList.remove(misArr);
* ballList.remove(ballArr);
*/
}
}
//}
}
}
}
}
public boolean intersects(JLabel testa, JLabel testb)
{
boolean b3 = false;
if(testa.contains(testb.getX(), testb.getY()))
{
b3 = true;
}
return b3;
}
class Missile extends Thread {
JLabel missile;
int xPos, yPos;
Random r = new Random();
public Missile() {
imgSetting();
setLoc();
repaint();
}
void imgSetting() {
ImageIcon img = new ImageIcon(
"C:/Users/JS_UbSE/Desktop/missile.png");
Image reImg = img.getImage();
Image changedImg = reImg.getScaledInstance(60, 30,
java.awt.Image.SCALE_SMOOTH);
ImageIcon IMG = new ImageIcon(changedImg);
missile = new JLabel(IMG);
missile.setSize(IMG.getIconWidth(), IMG.getIconHeight());
}
void setLoc() {
int xPos = 0;
int yPos = r.nextInt(500);
missile.setLocation(xPos, yPos);
add(missile);
this.xPos = xPos;
this.yPos = yPos;
repaint();
}
public Point getPosition() {
Point p = new Point();
p.x = xPos;
p.y = yPos;
return p;
}
public void run() {
while (xPos < 500) {
int nextXPos = xPos + 5;
missile.setLocation(nextXPos, yPos);
xPos = nextXPos;
repaint();
try {
Thread.sleep(25);
} catch (InterruptedException e) {
return;
}
}
remove(missile);
return;
}
}
class Balloon extends Thread {
JLabel ball;
int xPos, yPos;
private boolean visible;
public Balloon(int x, int y) {
visible = true;
imgSetting();
setLoc(x, y);
repaint();
}
void imgSetting() {
ImageIcon img = new ImageIcon(
"C:/Users/JS_UbSE/Desktop/balloon.png");
Image reImg = img.getImage();
Image changedImg = reImg.getScaledInstance(30, 40,
java.awt.Image.SCALE_SMOOTH);
ImageIcon IMG = new ImageIcon(changedImg);
ball = new JLabel(IMG);
}
void setLoc(int mouseX, int mouseY) {
ball.setSize(30, 40);
ball.setLocation(mouseX, mouseY);
xPos = mouseX;
yPos = mouseY;
add(ball);
}
public Point getPosition() {
Point p = new Point();
p.x = xPos;
p.y = yPos;
//System.out.println(xPos + ", " + yPos);
return p;
}
}
}
You should be detecting for collision on every move of a missile not on a different thread. Since your collision detection thread runs every 500ms, some missiles just pass right through balloons as collision detection thread is sleeping during that time.
Also make your lists synchronized using
private volatile List<Balloon> ballList = Collections
.synchronizedList(new ArrayList<Balloon>());
private volatile List<Missile> misList = Collections
.synchronizedList(new ArrayList<Missile>());
Also user iterator to remove as list can throw ConcurrentModificatoinException.
Balloon class doesn't need to be a thread.
*Edit
Working code
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MyPanel extends JPanel implements Runnable {
private List<Balloon> ballList = Collections
.synchronizedList(new ArrayList<Balloon>());
private List<Missile> misList = Collections
.synchronizedList(new ArrayList<Missile>());
private ReentrantLock listLock = new ReentrantLock();
private static final String MISSILE_IMAGE_PATH = "C:/Users/JS_UbSE/Desktop/missile.png";
private static final String BALOON_IMAGE_PATH = "C:/Users/JS_UbSE/Desktop/balloon.png";
public static void main(String[] args) {
Game2.main(null);
}
public MyPanel() {
setLayout(null);
Thread setMissileThread = new Thread(this);
setMissileThread.start();
}
#Override
public void run() {
// 마우스 클릭 이벤트 처리(풍선)
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
ballList.add(new Balloon(e.getX(), e.getY()));
// System.out.println("풍선 생성");
}
});
// 자동 처리(미사일)
while (true) {
// synchronized(ballList){
Missile mis;
listLock.lock();
try {
misList.add(mis = new Missile());
} finally {
listLock.unlock();
}
mis.start();
// System.out.println("미사일생성");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
return;
}
// 미사일 충돌
}
}
public boolean intersects(JLabel testa, JLabel testb) {
boolean b3 = false;
if (testa.contains(testb.getX(), testb.getY())) {
b3 = true;
}
return b3;
}
class Missile extends Thread {
JLabel missile;
int xPos, yPos;
Random r = new Random();
public Missile() {
imgSetting();
setLoc();
repaint();
}
void imgSetting() {
ImageIcon img = new ImageIcon(MISSILE_IMAGE_PATH);
Image reImg = img.getImage();
Image changedImg = reImg.getScaledInstance(60, 30,
java.awt.Image.SCALE_SMOOTH);
ImageIcon IMG = new ImageIcon(changedImg);
missile = new JLabel(IMG);
missile.setSize(IMG.getIconWidth(), IMG.getIconHeight());
}
void setLoc() {
int xPos = 0;
int yPos = r.nextInt(500);
missile.setLocation(xPos, yPos);
add(missile);
this.xPos = xPos;
this.yPos = yPos;
repaint();
}
public Point getPosition() {
Point p = new Point();
p.x = xPos;
p.y = yPos;
return p;
}
public void run() {
repaint();
while (xPos < 500) {
int nextXPos = xPos + 5;
missile.setLocation(nextXPos, yPos);
xPos = nextXPos;
repaint();
listLock.lock();
try {
detectCollision();
} finally {
listLock.unlock();
}
try {
Thread.sleep(25);
} catch (InterruptedException e) {
return;
}
}
remove(missile);
listLock.lock();
try {
misList.remove(missile);
} finally {
listLock.unlock();
}
return;
}
}
class Balloon extends Thread {
JLabel ball;
int xPos, yPos;
private boolean visible;
public Balloon(int x, int y) {
visible = true;
imgSetting();
setLoc(x, y);
repaint();
}
void imgSetting() {
ImageIcon img = new ImageIcon(BALOON_IMAGE_PATH);
Image reImg = img.getImage();
Image changedImg = reImg.getScaledInstance(30, 40,
java.awt.Image.SCALE_SMOOTH);
ImageIcon IMG = new ImageIcon(changedImg);
ball = new JLabel(IMG);
}
void setLoc(int mouseX, int mouseY) {
ball.setSize(30, 40);
ball.setLocation(mouseX, mouseY);
xPos = mouseX;
yPos = mouseY;
add(ball);
}
public Point getPosition() {
Point p = new Point();
p.x = xPos;
p.y = yPos;
// System.out.println(xPos + ", " + yPos);
return p;
}
}
public void detectCollision() {
if (!misList.isEmpty() && !ballList.isEmpty()) {
Iterator<Missile> missileIterator = misList.iterator();
while (missileIterator.hasNext()) {
Missile misArr = missileIterator.next();
Iterator<Balloon> ballIterator = ballList.iterator();
while (ballIterator.hasNext()) {
Balloon ballArr = ballIterator.next();
Point ballPos = ballArr.getPosition();
Point misPos = misArr.getPosition();
if (ballPos.x - 10 <= misPos.x + 60
&& misPos.x + 60 <= ballPos.x + 40
&& ballPos.y - 20 <= misPos.y + 15
&& misPos.y + 25 <= ballPos.y + 50) {
if (ballArr.visible == true) {
ballArr.visible = false;
// 라벨 삭제
remove(misArr.missile);
missileIterator.remove();
remove(ballArr.ball);
ballIterator.remove();
repaint();
System.out.println("Bomb!");
}
}
}
}
}
}
}
I'm creating a game like zType
and I have a problem in validating the input. As you can see in the picture below it select two words. How can I fix this problem, please help.
This is My Game class
import java.awt.Canvas;
import java.awt.event.KeyListener;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.LinkedList;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable, KeyListener
{
public static final int WIDTH = 640;
public static final int HEIGHT = 680;
public final String TITLE = "Game";
private boolean running = false;
private Thread thread;
private BufferedImage spriteSheet = null;
private BufferedImage background = null;
public int level = 1;
public int fps = 0;
public int score = 0;
private int enemy_count = 15;
private int enemy_killed = 0;
private int enemy_notkilled = 0;
private boolean target = false;
public String t = "";
private Controller c;
private Textures tex;
private LinkedList<Enemy> e = new LinkedList<Enemy>();
private Enemy enemy;
public void init()
{
requestFocus();
try
{
spriteSheet = ImageIO.read(getClass().getResource("/sprite_sheet.png"));
background = ImageIO.read(getClass().getResource("/background.png"));
}
catch(IOException e)
{
e.printStackTrace();
}
tex = new Textures(this);
c = new Controller(tex, this);
addKeyListener(this);
c.createEnemy(enemy_count);
e = c.getEnemy();
}
private synchronized void start()
{
if(running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
private synchronized void stop()
{
if(!running)
return;
running = false;
try
{
thread.join();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.exit(1);
}
public void run()
{
init();
long lastTime = System.nanoTime();
final double amountOfTicks= 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
int frames = 0;
long timer = System.currentTimeMillis();
while(running)
{
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if(delta >= 1)
{
update();
delta--;
}
render();
frames++;
if(System.currentTimeMillis() - timer > 1000)
{
timer += 1000;
fps = frames;
frames = 0;
}
}
stop();
}
private void update()
{
c.update();
if(enemy_killed + enemy_notkilled >= enemy_count)
{
e.clear();
t = "";
level++;
enemy_killed = 0;
enemy_notkilled = 0;
c.createEnemy(enemy_count);
}
}
private void render()
{
BufferStrategy bs = this.getBufferStrategy();
if(bs == null)
{
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.drawImage(background, 0, 0, null);
c.render(g);
g.dispose();
bs.show();
}
public void keyPressed(KeyEvent ek)
{
int key = ek.getKeyCode();
char character = Character.toLowerCase(ek.getKeyChar());
boolean result = isValid(key);
if(result && !target)
{
for(int i = 0; i < e.size(); i++)
if(e.get(i).getFirstLetter() == character && e.get(i).getOnScreen())
{
enemy = e.get(i);
t = enemy.getText();
if(enemy.getCurrentIndex() == 0)
enemy.addCurrentIndex();
target = true;
System.out.println("---"+enemy.text);
break;
}
}
else if(result && t.charAt(enemy.getCurrentIndex()) == character)
enemy.addCurrentIndex();
}
public void keyReleased(KeyEvent ek){ }
public void keyTyped(KeyEvent ek){ }
public static void main(String[] args)
{
Game game = new Game();
game.setPreferredSize(new Dimension(WIDTH, HEIGHT));
game.setMaximumSize(new Dimension(WIDTH, HEIGHT));
game.setMinimumSize(new Dimension(WIDTH, HEIGHT));
JFrame frame = new JFrame(game.TITLE);
frame.add(game);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
game.start();
}
public boolean isValid(int key)
{
return key >= 65 && key <= 90 ? true : false;
}
public BufferedImage getSpriteSheet()
{
return spriteSheet;
}
public int getEnemy_count()
{
return enemy_count;
}
public void setEnemy_count(int enemy_count)
{
this.enemy_count = enemy_count;
}
public int getEnemy_killed()
{
return enemy_killed;
}
public void setEnemy_killed(int enemy_killed)
{
this.enemy_killed = enemy_killed;
}
public int getEnemy_notkilled()
{
return enemy_notkilled;
}
public void setEnemy_notkilled(int enemy_notkilled)
{
this.enemy_notkilled = enemy_notkilled;
}
public void addScore(int k)
{
score += k;
}
public void falseTarget()
{
target = false;
}
public String getT()
{
return t;
}
public void setT(String k)
{
t = k;
}
}
This is my Enemy Class
import java.awt.*;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
public class Enemy
{
private double x ,y;
public String text;
private char firstLetter;
private AttributedString as;
private Controller c;
private Textures tex;
private Game game;
private int currentIndex = 0;
private int textLength = 0;
private double speed = 0.0;
private int stringWidth = 0;
private boolean onScreen = false;
public Enemy(double x, double y, double speed, Textures tex, Controller c, Game game, String text, int stringWidth)
{
this.x = x;
this.y = y;
this.tex = tex;
this.text = text;
this.game = game;
this.c = c;
this.speed = speed;
firstLetter = this.text.charAt(0);
textLength = this.text.length();
this.stringWidth = stringWidth;
}
public void update()
{
y += speed;
if(y >= 0)
onScreen = true;
if(currentIndex >= textLength)
{
game.addScore(5);
game.setT("");
c.removeEnemy(this);
game.setEnemy_killed(game.getEnemy_killed() + 1);
game.falseTarget();
}
if(y >= Game.HEIGHT - 50)
{
//game.decreaseHealth();
game.setT("");
c.removeEnemy(this);
game.setEnemy_notkilled(game.getEnemy_notkilled() + 1);
game.falseTarget();
game.t ="";
}
}
public void render(Graphics g)
{
g.drawImage(tex.enemy, (int)x, (int)y, null);
as = new AttributedString(text);
if(currentIndex >= 1)
as.addAttribute(TextAttribute.FOREGROUND, Color.WHITE, 0, currentIndex);
as.addAttribute(TextAttribute.FONT, new Font("Consolas", Font.BOLD, 12), 0, text.length());
g.drawString(as.getIterator(), (int)x + getAdd(stringWidth), (int)y + 13);
}
public double getX()
{
return x;
}
public double getY()
{
return y;
}
public String getText()
{
return text;
}
public char getFirstLetter()
{
return firstLetter;
}
public void addCurrentIndex()
{
currentIndex++;
}
public int getCurrentIndex()
{
return currentIndex;
}
public int getTextLength()
{
return textLength;
}
public int getAdd(int width)
{
return (96 / 2) - (width / 2);
}
public boolean getOnScreen()
{
return onScreen;
}
}
The problem is that you're calling falseTarget() whenever an enemy moves out of the screen. In your example, you assigned target = true when you pressed the 'o' (for the enemy named "owe"), but then a different enemy (maybe "jet", maybe an enemy that is no longer visible) finished "dropping" out of the screen (y >= Game.HEIGHT - 50), so you called falseTarget() - and thus, when you pressed 'i' you started a new enemy ("ice").
What you want to do is call falseTarget() in this case only if the enemy that dropped out of the screen is the one that's currently being targeted:
if(y >= Game.HEIGHT - 50)
{
//game.decreaseHealth();
//game.setT(""); // <-- Commented this line out
c.removeEnemy(this);
game.setEnemy_notkilled(game.getEnemy_notkilled() + 1);
if(game.getT().equals(text)) // <-- Added this if before calling falseTarget()
{ // and clearing the game's current enemy text
game.falseTarget();
game.t ="";
}
}
I am making a JFrame holding several images that refresh using repaint(). The problem, however, was that the more images I added (or as the area that was being rendered increased) the framerate drastically decreased.
I was initially attempting to reduce the lag that Swing's unpredictable Timer experiences, but was unsuccessful. This time, I tried to call
repaint()
every 10 milliseconds based on system time. (To bypass the timer, desktop.screenPaint.drawWindow(); is called instead of repaint())
while(true)
{
long starttime = System.currentTimeMillis();
while(System.currentTimeMillis()-starttime < 10)
{
}
desktop.screenPaint.drawWindow();
desktop2.screenPaint.drawWindow();
}
Each "desktop" is just one of the draggable windows that you see if you run the code below. I noticed that when only "desktop" is added to "frame," there is no flickering. However, when "desktop2" is also added, flickering does not go away until the time until each refresh is set to 20 or more milliseconds. It is extremely strange, because when I was still using the timer, even thought the wait was set to 10 milliseconds, the framerate would lower to a frame every 20 milliseconds! I tested a little and noticed a trend: you will get flickering until the wait time to the amount of time that the 10 millisecond timer lagged behind. My question: Why is this happening? And is there any way to prevent the flickering, other than going back to the timer?
import javax.swing.JFrame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.SwingUtilities.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
import java.io.File;
import java.io.IOException;
public class Display extends JPanel
{
public static int width, height;
public static JFrame frame = new JFrame("");
private static int rh = 10;
public static Display desktop = new Display();
public static Display desktop2 = new Display();
public static void main(String[] args)
{
Dimension screen = new Dimension();
screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
width = (int)screen.getWidth();
height = (int)screen.getHeight();
frame.setLayout(null);
frame.setLocation(0, 0);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
desktop.setBounds(0, 0, 620, 500+rh);
desktop2.setBounds(1000, 200, 620, 500+rh);
frame.add(desktop);
frame.add(desktop2);
frame.setUndecorated(true);
frame.setSize(width, height);
frame.setVisible(true);
while(true)
{
long starttime = System.currentTimeMillis();
while(System.currentTimeMillis()-starttime < 10)
{
}
desktop.screenPaint.drawWindow();
//desktop2.screenPaint.drawWindow();
}
}
private BufferedImage image;
private Graphics2D g;
public Listener screenPaint = new Listener();
private Display identify;
public Display()
{
identify = this;
image = new BufferedImage(620, 500+rh, BufferedImage.TYPE_INT_RGB);
g = (Graphics2D)image.getGraphics();
Timer timer = new Timer(1, screenPaint);
timer.start();
addMouseListener(new mMouse());
addMouseWheelListener(new wWheel());
setFocusable(true);
}
private BufferedImage toCompatibleImage(BufferedImage image)
{
GraphicsConfiguration gfx_config = GraphicsEnvironment.
getLocalGraphicsEnvironment().getDefaultScreenDevice().
getDefaultConfiguration();
if (image.getColorModel().equals(gfx_config.getColorModel()))
return image;
BufferedImage new_image = gfx_config.createCompatibleImage(
image.getWidth(), image.getHeight(), image.getTransparency());
}
public void paint(Graphics view)
{
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
view.drawImage(toCompatibleImage(image), 0, 0, 620, 500+rh, null);
view.dispose();
}
private class Listener implements ActionListener
{
int y = 0;
int wy = 0;
int b = 500;
int c = 1500;
int iy = (int)(wy/(c/(double)b));
int a = -1;
int i = -1;
int j = -1;
boolean d = false;
boolean u = false;
int f = 0;
public void moveY(int sy)
{
f += sy;
}
public void actionPerformed(ActionEvent e)
{
//drawWindow();
}
public void drawWindow()
{
int lx = (int)(identify.getLocation().getX());
int ly = (int)(identify.getLocation().getY());
g.setColor(Color.white);
g.fillRect(0, 0, 620, 500+rh);
g.drawImage(new ImageIcon("image.png").getImage(), 0, wy+rh, 610, c, null);
if(c > b)
{
if(d || Mouse.withinRect(610+lx, (int)(-wy/(c/(double)b))+rh+ly, 10, (int)Math.ceil(Math.pow(b, 2)/(double)c)))
{
if(Mouse.pressLeft())
{
if(!d)d = true;
if(a == -1)a = Mouse.y()-(int)(-wy/(c/(double)b));
y = (int)((Mouse.y()-a)*(c/(double)b));
f = y;
g.setColor(Color.black);
}
else
{
if(d)d = false;
if(a != -1)a = -1;
g.setColor(new Color(60, 60, 60));
}
}
else
{
g.setColor(Color.gray);
if(a != -1)a = -1;
}
if(y == f){}
else if(y < f)
{
y += (int)((f-y)*0.1);
if(y < f)y++;
}
else
{
y -= (int)((y-f)*0.1);
if(y > f)y--;
}
if(y < 0)
{
y = 0;
f = 0;
}
else if(y > c-b)
{
y = c-b;
f = y;
}
wy = -y;
if(u || Mouse.withinRect(lx, ly, 620, 10))
{
if(Mouse.pressLeft())
{
if(!u)u = true;
if(i == -1)i = Mouse.x()-lx;
if(j == -1)j = Mouse.y()-ly;
identify.setLocation(Mouse.x()-i, Mouse.y()-j);
}
else
{
if(u)u = false;
if(i != -1)i = -1;
if(j != -1)j = -1;
}
}
else
{
if(u)u = false;
if(i != -1)i = -1;
if(j != -1)j = -1;
}
int scrollBarLength = (int)Math.ceil(Math.pow(b, 2)/(double)c);
g.fillRect(610, (int)(-wy/(c/(double)b))+rh, 10, scrollBarLength);
}
else
{
g.setColor(new Color(200, 200, 200));
g.fillRect(610, rh, 10, b);
}
g.setColor(new Color(50, 50, 50));
g.fillRect(0, 0, 620, rh);
if(identify == desktop)
repaint();
else if(false)
{}
}
}
}
public static boolean LMPress, LMRelease = false;
public static boolean LMRight, LMLeft = false;
private class mMouse extends MouseAdapter
{
public void mousePressed(MouseEvent e)
{
LMPress = true; LMRelease = false;
if(SwingUtilities.isRightMouseButton(e))
{
LMRight = true;
LMLeft = false;
}
else if(SwingUtilities.isLeftMouseButton(e))
{
LMLeft = true;
LMRight = false;
}
}
public void mouseReleased(MouseEvent e)
{
LMRelease = true; LMPress = false;
if(SwingUtilities.isRightMouseButton(e))
{
LMRight = true;
LMLeft = false;
}
else if(SwingUtilities.isLeftMouseButton(e))
{
LMLeft = true;
LMRight = false;
}
}
}
private class wWheel implements MouseWheelListener
{
public void mouseWheelMoved(MouseWheelEvent e)
{
int notches = e.getWheelRotation();
if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {}
e.getScrollAmount();
screenPaint.moveY(e.getUnitsToScroll()*60); //desired pixel jump: 120
}
}
}
Mouse class:
import java.awt.*;
import java.awt.event.*;
public class Mouse {
public static int x() {
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
return (int) b.getX();
}
public static int y() {
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
return (int) b.getY();
}
public static boolean withinRect(int x, int y, int w, int h) {
if (x() >= x && x() < x + w && y() >= y && y() < y + h) return true;
else return false;
}
public static boolean press() {
return Display.LMPress;
}
public static boolean release() {
return Display.LMRelease;
}
public static boolean pressLeft() {
if (Display.LMPress && Display.LMLeft)
return true;
else return false;
}
public static boolean releaseLeft() {
if (Display.LMRelease && Display.LMLeft)
return true;
else return false;
}
public static boolean pressRight() {
if (Display.LMPress && Display.LMRight)
return true;
else return false;
}
public static boolean releaseRight() {
if (Display.LMRelease && Display.LMRight)
return true;
else return false;
}
}
Updating the view at 1 kHz is unrealistic; instead, consider the alternatives cited here. See this AnimationTest for an example of self-timing to determine your animation budget.
Addendum: The while(true) loop at the top is running at 100 Hz.
The available resolution of System.currentTimeMillis() may vary by platform.
Addendum: I am reopening this question because I was not able to fix it. Any more help?
Absent a Minimal, Complete, Tested and Readable Example, it's hard to say. You appear to be overriding paint(); was noted in Painting in AWT and Swing: The Paint Methods, "Swing programs should override paintComponent()." Moreover, you need to invoke super.paintComponent(), as shown here, to avoid visual artifacts.
I'm trying to make the game "Snake," but I'm getting stuck on the tail. Right
now, I'm just trying to make the first tail block have the same coordinates as the
head. Here's what I have. For the main class:
public class Game extends JPanel implements ActionListener {
Snake p;
RandomDot r;
Trail trail;
Point w;
Image img;
Timer time;
int t=75;
int score = 0;
int count = 0;
int x, y;
boolean lost = false;
public Game(){
p = new Snake();
r = new RandomDot();
trail = new Trail();
w = new Point();
addKeyListener(new AL());
setFocusable(true);
ImageIcon i = new ImageIcon("C:/Matt's stuff/background.png");
img = i.getImage();
time = new Timer(t, this);
time.start();
}
#Override
public void actionPerformed(ActionEvent e)
{
p.move();
p.moveup();
w.points();
trail.getFirstDot();
trail.findCoords();
if (score>=1)
{
trail.getFirstDot();
}
if (lost==true)
{
score++;
r.getRandom();
lost = false;
}
repaint();
checkCollisions();
}
public int score()
{
return score;
}
public boolean getLost()
{
return lost;
}
public void checkCollisions()
{
Rectangle r1 = r.getBounds();
Rectangle r2 = p.getBounds();
if (r1.intersects(r2))
{
lost = true;
}
}
#Override
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(img, 0, 0, null);
g2d.drawImage(p.getImage(), p.getX(), p.getY(), null);
g2d.drawImage(r.getImage2(), r.getX2(), r.getY2(), null);
if (score>=1)
{
g2d.drawImage(trail.getImage(), trail.getX(), trail.getY(), null);
}
System.out.println(score + "00");
}
private class AL extends KeyAdapter{
#Override
public void keyReleased(KeyEvent e)
{
p.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e)
{
p.keyPressed(e);
}
}
}
For the Snake's head's class:
public class Snake {
Integer x = 480, y = 280, dx = 0, dy = 0, h, m;
boolean dead = false;
boolean didmove = false;
Image still;
RandomDot r;
Game g;
Trail t;
public Snake(){
ImageIcon i = new ImageIcon("C:/Matt's Stuff/snake.png");
still = i.getImage();
}
public Rectangle getBounds(){
return new Rectangle(x,y, 10, 10);
}
public void move(){
x = x + dx;
h = x;
didmove = true;
if (x>=990||x<=5){
dead = true;
x = 480;
y = 280;
dx = 0;
dy = 0;
didmove = false;
}
}
public void moveup(){
y = y + dy;
m = y;
didmove = true;
if (y>=590||y<=0){
dead = true;
x = 480;
y = 280;
dx = 0;
dy = 0;
didmove = false;
}
}
public Integer getX(){
return x;
}
public Integer getY(){
return y;
}
public Image getImage(){
return still;
}
public boolean getBoolean(){
return dead;
}
public boolean didmove(){
return didmove;
}
public void keyPressed(KeyEvent e){
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT){
if (dead == false){
dx = -10;
dy = 0;
} else {
x = 480;
y = 280;
dx = 0;
dy = 0;
}
}
if (key == KeyEvent.VK_RIGHT){
if (dead == false){
dx = 10;
dy = 0;
} else {
x = 480;
y = 280;
dx = 0;
dy = 0;
}
}
if (key == KeyEvent.VK_UP){
if (dead == false){
dy = -10;
dx = 0;
}else {
x = 480;
y = 280;
dx = 0;
dy = 0;
}
}
if (key == KeyEvent.VK_DOWN){
if (dead == false){
dy = 10;
dx = 0;
}else {
x = 480;
y = 280;
dx = 0;
dy = 0;
}
}
}
public void keyReleased(KeyEvent e){
int key = e.getKeyCode();
}
}
And lastly, the tail:
public class Trail {
Image still;
Integer x = 500, y = 500, dx, dy, dx2, dy2;
Game g;
Snake p;
Point d;
int count=0;
boolean visible = false;
public Trail(){
ImageIcon i = new ImageIcon("C:/Matt's Stuff/Dot.png");
still = i.getImage();
p = new Snake();
d = new Point();
}
public void getFirstDot(){
visible = true;
}
public void findCoords(){
if (visible == true)
{
x = p.getX();
y = p.getY();
}
}
public Integer getX(){
return x;
}
public Integer getY(){
return y;
}
public Image getImage(){
return still;
}
}
Now my problem is this: The p.getX() and p.getY() in the tail class do not work! The tail block just sits there where the snake's head initially started! I don't know what is going on, none of my research seems to help! Please help me out? Why is it that p.getX() and p.getY() will work in the main Game class, but not the Tail's? Thank you in advance!
You're creating a new Snake() inside your Trail constructor, and then referring to that Snake instead of the one the Game knows about. Instead of creating a new Snake, you should pass in a reference to the constructor, so that you call the methods of the object that is actually being updated:
// In the Trail class
public Trail(Snake s) {
p = s;
// other stuff
}
// In the Game class:
trail = new Trail(p);
// ...
Now when you call p.getX() and so on, you'll actually be pointing at the correct Snake, so you should see your position update correctly.
You should pass the reference of existing Snake object to Trail constructor to make it work. For example in Game class your code should be like this:
public Game(){
p = new Snake();
r = new RandomDot();
trail = new Trail(p);//Pass the reference of Snake so that you get all information w.r.t the current Snake in consideration
w = new Point();
addKeyListener(new AL());
setFocusable(true);
ImageIcon i = new ImageIcon("C:/Matt's stuff/background.png");
img = i.getImage();
time = new Timer(t, this);
time.start();
}
And change the Trail constructor as follows:
public Trail(Snake p){
ImageIcon i = new ImageIcon("C:/Matt's Stuff/Dot.png");
still = i.getImage();
this.p = p;
d = new Point();
}