I am programming my first actually 2D game(Pac-Man). I think game looks good,but I have one big problem - Collision. Object still going through the wall.I'm stuck with it so I decided to ask for help real programmers with great experience. (Of course I did some research, but I don't want to do things like COPY and Paste, because I didn't understand). As I said, game is almost done, just all I need to do is keep pacman from going through. Like example I draw large white rectangle as platform. I hope somebody is able to help me. Throughout this project I've learned much and collision is something which I understand, but don't know how correctly program it. I think I am close to figure it out, but something is missing.
PS: I've created window in WindowBuilder, so compiling might be a problem :(
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
public class Main extends JFrame implements ActionListener{
JPanel contentPane;
Rectangle packman ;
Rectangle platform;
Rectangle secondPlat;
private int count = 0;
private int x = 170, y = 50;
private int xVel = 1, yVel = 1;
Timer timer;
public static void main(String[] args) {
// TODO Auto-generated method stub
Main frame = new Main();
frame.setVisible(true);
}
public Main() {
// TODO Auto-generated constructor stub
this.setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
getContentPane().setBackground(Color.gray);
packman = new Rectangle(x,y,50,50);
platform = new Rectangle(100,70,50,100);
secondPlat = new Rectangle(220,50,50,100);
timer = new Timer(0,this);
timer.start();
this.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
switch(e.getKeyCode()) {
case 37: //doleva
count = 1;
repaint();
break;
case 38: //nahorů
count = 2;
repaint();
break;
case 39://doprava
count = 3;
repaint();
break;
case 40://dolů
count =4;
repaint();
break;
}
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
System.out.println("Char" + e.getKeyCode());
System.out.println("Hod" + e.getKeyCode());
}
});
}
#Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
g.drawRect(x,y,packman.width,packman.height);
g.setColor(Color.blue);
g.fillRect(x,y,packman.width,packman.height);
g.drawRect(platform.x,platform.y,platform.width,platform.height);
g.setColor(Color.blue);
g.drawRect(secondPlat.x,secondPlat.y,secondPlat.width,secondPlat.height);
g.setColor(Color.blue);
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
if (count == 1) {
x = x - xVel;
repaint();
zkontrolujKolizi();
}
if (count ==2) {
y = y - yVel;
repaint();
zkontrolujKolizi();
}
if (count ==3) {
x = x + xVel;
repaint();
zkontrolujKolizi();
}
if (count ==4) {
y = y+yVel;
repaint();
zkontrolujKolizi();
}
}
public void zkontrolujKolizi() {
// TODO Auto-generated method stub
if (packman.intersects(platform) || packman.intersects(secondPlat)) {
System.out.println("Got ya!");
}
}
}
In your code you update x and y, but this is not done in the "packman" object, that always sits at its initial position; so when you check intersection with the wall the packman is always at (170,50); I changed both the animation method to reflect the changes in packman and the paint method, so that you use the updated packman coordinates.
Animation:
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
if (count == 1) {
packman.x = packman.x - xVel;
repaint();
zkontrolujKolizi();
}
if (count ==2) {
packman.y = packman.y - yVel;
repaint();
zkontrolujKolizi();
}
if (count ==3) {
packman.x = packman.x + xVel;
repaint();
zkontrolujKolizi();
}
if (count ==4) {
packman.y = packman.y+yVel;
repaint();
zkontrolujKolizi();
}
}
Paint:
#Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
g.drawRect(packman.x,packman.y,packman.width,packman.height);
g.setColor(Color.blue);
g.fillRect(packman.x,packman.y,packman.width,packman.height);
g.drawRect(platform.x,platform.y,platform.width,platform.height);
g.setColor(Color.blue);
g.drawRect(secondPlat.x,secondPlat.y,secondPlat.width,secondPlat.height);
g.setColor(Color.blue);
}
Of course, there is much more to refactor in the code, but this is the reason why the collisions were not detected.
To avoid moving through the walls, calculate new position, check collision, if true, rollback the position changes:
#Override
public void actionPerformed(ActionEvent arg0) {
int rollbackX=packman.x;
int rollbackY=packman.y;
switch (count) {
case 1:
packman.x = packman.x - xVel;
break;
case 2:
packman.y = packman.y - yVel;
break;
case 3:
packman.x = packman.x + xVel;
break;
case 4:
packman.y = packman.y+yVel;
break;
}
//Collision found, rollback
if (zkontrolujKolizi()) {
packman.x=rollbackX;
packman.y=rollbackY;
} else {
repaint();
}
}
public boolean zkontrolujKolizi() {
return packman.intersects(platform) || packman.intersects(secondPlat);
}
before collision
after collision
I've used exactly same,but just with moving object
#Override
public void actionPerformed(ActionEvent e) {
//This is my actually code I've implemented from your answer
int rollbackX = packRect.x;
int rollbackY = packRect.y;
switch (count) {
case 1:
packman.setCoordinatesX(packman.getCoordinatesX() - xVel);
gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
packRect.x = packRect.x - xVel;
collectPoint();
// repaint();
break;
case 2:
packman.setCoordinatesY(packman.getCoordinatesY() - yVel);
gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
packRect.y = packRect.y - yVel;
sbirejBody();
// repaint();
break;
case 3:
packman.setCoordinatesX(packman.getCoordinatesX() + xVel);
gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
packRect.x = packRect.x + xVel;
collectPoint();
// repaint();
break;
case 4:
packman.setCoordinatesY(packman.getCoordinatesY() + yVel);
gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
packRect.y = packRect.y+yVel;
collectPoint();
// repaint();
break;
}
int originX = packRect.x;
int originY = packRect.y;
packRect.setLocation(originX, originY);
packman.setCoordinatesX(originX);
packman.setCoordinatesY(originY);
gifLabel.setLocation(originX, originY);
if (checkCollision) {
rollbackX= originX;
rollbackY = originY;
}else {
repaint();
}
packRect.setLocation(originX, originY);
packman.setCoordinatesX(originX);
packman.setCoordinatesY(originY);
gifLabel.setLocation(originX, originY);
}
public boolean checkCollision() {
return packman.intersects(platform) || packman.intersects(secondPlat);
}
Related
I am programming a Mario game for my project for my computer science class, and so far the Mario character can run left and right, crouch, and I have built the background.
Two questions that I have are
when making the background move, should I make a separate class that has all the background images? This way I can switch out the various backgrounds I intend to create.
My current program has the issue of when I try and jump (press the up arrow key), Mario does not jump normally, he lags a bit and then rises a lot. I am trying to make it so Mario can rise lets say, one pixel every 100th of a second, but that is not working, instead, it waits around 1 or 2 seconds then rises 100 pixels and stops.
Frame Class:
package FirstPlatformer;
import javax.swing.JFrame;
public class PlatformerFrame
{
public static void main(String[] args)
{
//change to match your values for width/height
//these can be changed
int w = 1525;
int h = 830;
//sets up a JFrame object with title "Template"
JFrame frame = new JFrame("Template");
//make sure the jframe closes when you hit the 'x'
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//adds the drawing panel to the frame
frame.getContentPane().add(new Platformer(w,h));
//resizes the frame to fit the panel
frame.pack();
//makes it visible
frame.setVisible(true);
}
}
Platformer Class:
package FirstPlatformer;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
//change to be your packagename
//all imports are necessary
//must 'extend' JPanel
public class Platformer extends JPanel
{
Random test = new Random();
Color aboveground = new Color (99, 158, 169);
private ImageIcon marioStart, ground, mysteryBlock, smallMarioRight, smallMarioLeft, smallMarioCrouchedLeft, smallMarioCrouchedRight;
//variables for the overall width and height
private int w, h;
boolean start = false;
//crouching mechanism
boolean crouchPressed = false;
boolean crouchReleased = false;
boolean youAreCrouching = false;
//facing direction mechanisms
boolean facingRight = true;
boolean facingLeft = false;
//jumping mechanisms
boolean jumpStart = false;
int jumpCountEqual = 0;
private int number = 0;
private int count = 0;
int baseHeight = 770;
int smallMarioGround = 725;
//variable that establishes marios x coord
int marioX = 0;
//sets up the initial panel for drawing with proper size
public Platformer(int w, int h)
{
setFocusable(true);
this.w = w;
this.h = h;
this.setPreferredSize(new Dimension(w,h));
//creating the images
marioStart = new ImageIcon("src/FirstPlatformer/marioStart.JPG");
//building blocks
ground = new ImageIcon("src/FirstPlatformer/ground.JPG");
mysteryBlock = new ImageIcon("src/FirstPlatformer/mysteryBlock.png");
//small mario actions
smallMarioLeft = new ImageIcon("src/FirstPlatformer/smallMarioRight.png");
smallMarioRight = new ImageIcon("src/FirstPlatformer/smallMarioLeft.png");
smallMarioCrouchedLeft = new ImageIcon("src/FirstPlatformer/marioCrouched.png");
smallMarioCrouchedRight= new ImageIcon("src/FirstPlatformer/marioCrouchedRight.png");
this.addMouseListener(new MouseTracker());
this.addKeyListener(new Keyboard());
}
//all graphical components go here
//this.setBackground(Color c) for example will change background color
public void paintComponent(Graphics g)
{
//this line sets up the graphics - always needed
super.paintComponent(g);
g.setColor(Color.RED);
//all drawings below here:
//creating the starting screen
if(start != true) {
setBackground(Color.BLACK);
marioStart.paintIcon(this,g,240,100);
g.setFont(new Font("Arial", Font.BOLD, 50));
g.drawString("Created by Zane Lanski", 515, 625);
g.drawString("Press Space to Start", 525, 725);
}
else {
//setting the overall background for when mario is aboveground
setBackground(aboveground);
//variable for building the bottom of the level
int groundCount = 0;
//for loop creates the base of the level
for(int groundBase = 0; groundBase <30; groundBase++)
{
ground.paintIcon(this, g, groundCount, 770);
groundCount = groundCount + 52;
}
mysteryBlock.paintIcon(this, g, 500, 500);
if(crouchPressed != true && facingRight == true) {
smallMarioRight.paintIcon(this,g,marioX,smallMarioGround);
}
if(crouchPressed != true && facingLeft == true) {
smallMarioLeft.paintIcon(this,g,marioX,smallMarioGround);
}
if(crouchPressed != false) {
smallMarioCrouchedRight.paintIcon(this,g, marioX, smallMarioGround+18);
}
if(jumpStart == true) {
for(int jumpCount = jumpCountEqual;jumpCount < 100; jumpCount++) {
smallMarioGround = smallMarioGround- 1;
// smallMarioRight.paintIcon(this, g, marioX, smallMarioGround);
try
{
Thread.sleep(10);
}
catch(InterruptedException e)
{
System.out.println(e);
}
repaint();
System.out.println(jumpCount);
jumpCountEqual++;
}
}
}
}
private class MouseTracker implements MouseListener, MouseMotionListener
{
#Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
number++;
count++;
number %= 5;
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
private class Keyboard implements KeyListener
{
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
int key = e.getKeyCode();
repaint();
}
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT) {
facingLeft = false;
facingRight = true;
marioX = marioX + 5;
facingRight = true;
facingLeft = false;
}
if(key == KeyEvent.VK_LEFT) {
crouchPressed = false;
marioX = marioX - 5;
facingLeft = true;
facingRight = false;
}
if(key == KeyEvent.VK_DOWN) {
crouchPressed = true;
youAreCrouching = true;
}
if(key == KeyEvent.VK_UP) {
jumpStart = true;
}
if(key == KeyEvent.VK_SPACE) {
start = true;
}
repaint();
}
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
int key = e.getKeyCode();
if(key == KeyEvent.VK_DOWN) {
crouchPressed = false;
}
repaint();
}
}
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I was following a tutorial on some basic game design for Java when I ran across an unusual issue. When I run an applet that simply moves an image based character on the screen, it will not let me use the methods to change position of the image. It raises a NullPointerException in located at my robot.update() method which handles the movement of the image. The odd part is that if I choose the "Restart" option from the drop down list in the Applet frame, it works as normal. Any ideas?
Main Class
package Game;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;
public class First extends Applet implements Runnable, KeyListener {
private Robot robot;
private Image image, character;
private Graphics second;
private URL base;
#Override
public void init() {
setSize(800,480);
setBackground(Color.BLACK);
setFocusable(true);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("First Game");
addKeyListener(this);
try {
base = getDocumentBase();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Image not accessible");
}
character = getImage(base, "data/character.png");
// TODO Auto-generated method stub
super.init();
}
#Override
public void start() {
Thread thread = new Thread(this);
thread.start();
robot = new Robot();
// TODO Auto-generated method stub
super.start();
}
#Override
public void stop() {
// TODO Auto-generated method stub
super.stop();
}
#Override
public void destroy() {
// TODO Auto-generated method stub
super.destroy();
}
#Override
public void run() {
// TODO Auto-generated method stub
while (true) {
robot.update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void update(Graphics g) {
if (image == null) {
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
g.drawImage(character, robot.getCenterX() - 61,
robot.getCenterY() - 63, this);
super.paint(g);
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
System.out.println("Move UP");
break;
case KeyEvent.VK_DOWN:
System.out.println("Move DOWN");
break;
case KeyEvent.VK_LEFT:
robot.moveLeft();
break;
case KeyEvent.VK_RIGHT:
robot.moveRight();
break;
case KeyEvent.VK_SPACE:
robot.jump();
break;
}
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
System.out.println("Stop UP");
break;
case KeyEvent.VK_DOWN:
System.out.println("Stop DOWN");
break;
case KeyEvent.VK_LEFT:
robot.stop();
break;
case KeyEvent.VK_RIGHT:
robot.stop();
break;
case KeyEvent.VK_SPACE:
robot.stop();
break;
// TODO Auto-generated method stub
}
}
}
Robot Class
package Game;
public class Robot {
private int centerX = 100;
private int centerY = 382;
private boolean jumped = false;
private int speedX = 0;
private int speedY = 1;
public void update() {
if (speedX < 0) {
centerX += speedX;
} else if (speedX == 0){
System.out.println("Do not scroll the background");
} else {
if (centerX <= 300) {
centerX += speedX;
} else {
System.out.println("Scroll background here");
}
}
if (centerY + speedY >= 382) {
centerY = 382;
}else{
centerY += speedY;
}
// Handles Jumping
if (jumped == true) {
speedY += 1;
if (centerY + speedY >= 382) {
centerY = 382;
speedY = 0;
jumped = false;
}
}
// Prevents going beyond X coordinate of 0
if (centerX + speedX <= 60) {
centerX = 61;
}
}
public int getCenterX() {
return centerX;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public int getCenterY() {
return centerY;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public boolean isJumped() {
return jumped;
}
public void setJumped(boolean jumped) {
this.jumped = jumped;
}
public int getSpeedX() {
return speedX;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public int getSpeedY() {
return speedY;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
public void moveRight() {
speedX = 6;
}
public void moveLeft() {
speedX = -6;
}
public void stop() {
speedX = 0;
}
public void jump() {
if (jumped == false) {
speedY = -15;
jumped = true;
}
}
}
This is the error message I am gettings
Exception in thread "Thread-3" java.lang.NullPointerException
at Game.First.run(First.java:65)
at java.lang.Thread.run(Thread.java:722)
You should initialize robot object first not after running the thread, try:
robot = new Robot();
Thread thread = new Thread(this);
thread.start();
As when you start the thread's execution it may start with null robot.
when you again reload it works as by then it is initialized.
I was following this tutorial here
and I downloaded its source code and ran but the image is not showing.
here is the result
I was expecting that the result would be like this
same as the result in the tutorial.
Here is the code:
StartingClass.java
package kiloboltgame;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;
public class StartingClass extends Applet implements Runnable, KeyListener {
private Robot robot;
private Image image, character;
private Graphics second;
private URL base;
#Override
public void init() {
setSize(800, 480);
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Q-Bot Alpha");
try {
base = getDocumentBase();
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.toString());
}
// Image Setups
character = getImage(base, "data/character.png");
System.out.println(" "+base);
}
#Override
public void start() {
robot = new Robot();
Thread thread = new Thread(this);
thread.start();
}
#Override
public void stop() {
// TODO Auto-generated method stub
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void run() {
while (true) {
robot.update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void update(Graphics g) {
if (image == null) {
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g) {
g.drawImage(character, robot.getCenterX() - 61, robot.getCenterY() - 63, this);
}
#Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
System.out.println("Move up");
break;
case KeyEvent.VK_DOWN:
System.out.println("Move down");
break;
case KeyEvent.VK_LEFT:
robot.moveLeft();
break;
case KeyEvent.VK_RIGHT:
robot.moveRight();
break;
case KeyEvent.VK_SPACE:
System.out.println("Jump");
robot.jump();
break;
}
}
#Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
System.out.println("Stop moving up");
break;
case KeyEvent.VK_DOWN:
System.out.println("Stop moving down");
break;
case KeyEvent.VK_LEFT:
robot.stop();
break;
case KeyEvent.VK_RIGHT:
robot.stop();
break;
case KeyEvent.VK_SPACE:
System.out.println("Stop jumping");
break;
}
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Robot.java
package kiloboltgame;
import java.awt.Graphics;
public class Robot {
private int centerX = 100;
private int centerY = 382;
private boolean jumped = false;
private int speedX = 0;
private int speedY = 1;
public void update() {
// Moves Character or Scrolls Background accordingly.
if (speedX < 0) {
centerX += speedX;
} else if (speedX == 0) {
//System.out.println("Do not scroll the background.");
} else {
if (centerX <= 150) {
centerX += speedX;
} else {
//System.out.println("Scroll Background Here");
}
}
// Updates Y Position
centerY += speedY;
if (centerY + speedY >= 382) {
centerY = 382;
}
// Handles Jumping
if (jumped == true) {
speedY += 1;
if (centerY + speedY >= 382) {
centerY = 382;
speedY = 0;
jumped = false;
}
}
// Prevents going beyond X coordinate of 0
if (centerX + speedX <= 60) {
centerX = 61;
}
}
public void moveRight() {
speedX = 6;
}
public void moveLeft() {
speedX = -6;
}
public void stop() {
speedX = 0;
}
public void jump() {
if (jumped == false) {
speedY = -15;
jumped = true;
}
}
public int getCenterX() {
return centerX;
}
public int getCenterY() {
return centerY;
}
public boolean isJumped() {
return jumped;
}
public int getSpeedX() {
return speedX;
}
public int getSpeedY() {
return speedY;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public void setJumped(boolean jumped) {
this.jumped = jumped;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
}
and here is my file structure in intelij
Whats wrong with the code?? I tride the "../data/character.png" and "../src/data/character.png" but it didnt work.
applet.html the page loading the applet.
data (directory)
Character.png
If that is the structure of the server, the image will be available by:
getImage(base, "data/character.png");
I stressed server above since that is apparently not how your IDE is set up.
Can you elaborate more?
You opened the src/kilobolt path to show the locations of the source files, but it you expand the bin folder and trace down, you'll probably find the .class files in the bin/kilobolt directory.
An IDE typically won't use an HTML file for loading the applet, but if IntelliJ did, it would probably put it in the bin directory so it has direct access to the class files.
The path from there to the image would be ../data/character.png, but instead of using that path, suggest you get the IDE to copy the image into the bin.
At this stage it has become about IntelliJ so any further questions you have, will need to be about the IDE and the run-time class-path it uses.
This seems to be an image issue. The computer is not able to find the location of the image, or the image is being drawn under the applet.
IF you are using a linux/Mac/unix machine, most of time, I have had to either start from the root folder such as /Users/.....to the source folder, or when using a directory that is closer, just use '/' in front of it. Example is:
You're using a directory named src, with an 'img' folder inside. To get to the 'img' contents, you have two options:
//......src/img
or
/src/img/....
Hope that helped with anything
Copy your data folder into the bin folder.
Clean the project and run.
It will work.
#Luiggi Mendoza I had the same issue and was able to resolve it by right clicking on 'character.png' and selecting properties and then copying the image's location all the way from its root. In my case it was "/Users/macbookpro/NetBeansProjects/Kilobolt/src/data/character.png" and bingo the robot appeared in the applet window.
And yeah, i am learning game from the same website as you were 3 years back
I'm in dire need of help. I've spent 3 hours pulling my hair over the fact that I don't know how to make my collision with one single platform work!
I want the player to be able to jump on the platform and not glitch on it, or fall through it. However, there is also the case that if the player holds up and the left arrow key or right arrow key and comes in contact with the edge of the platform! I really need your help on how I can make the simple aspects of collision with a platform work with my code.
Here is my code:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Form1 extends Applet implements Runnable, KeyListener
{
private Image dbImage;
private Graphics dbg;
Thread t1;
int x = 300;
int y = 300;
boolean jumping = false;
double yVel = 0;
double termVel = 10;
int loop_cnt = 0;
int start_cnt = loop_cnt;
boolean falling = false;
boolean left, right, up, down;
double counter2 = 4;
int counter;
int num = 7;
int prevY = y;
int prevX = x;
int d = 0;
Rectangle player;
Rectangle platform;
public void init()
{
setSize(600, 400);
}
public void start()
{
player = new Rectangle();
platform = new Rectangle();
addKeyListener(this);
t1 = new Thread(this);
t1.start();
}
public void stop()
{
}
public void destroy()
{
}
#Override
public void run()
{
while (true)
{
//this code will be used if the player is on a platform and then walks off it by pressing either right or left
if (y <= 300 && !up)
{
y += 10;
}
if (left)
{
prevX = x;
x -= 2;
}
if (right)
{
prevX = x;
x += 2;
}
if (up)
{
counter2 += 0.05;
prevY = y;
y = y + (int) ((Math.sin(counter2) + Math.cos(counter2)) * 5);
if (counter2 >= 7)
{
counter2 = 4;
up = false;
}
}
if (y >= 300)
{
falling = false;
y = 300;
}
repaint();
try
{
t1.sleep(17);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public Rectangle IntersectPlatform()
{
return platform;
}
public void update(Graphics g)
{
dbImage = createImage (this.getSize().width, this.getSize().height);
dbg = dbImage.getGraphics();
// initialize buffer
if (dbImage == null)
{
}
// clear screen in background
dbg.setColor(getBackground());
dbg.fillRect(0, 0, this.getSize().width, this.getSize().height);
// draw elements in background
dbg.setColor(getForeground());
paint(dbg);
// draw image on the screen
g.drawImage(dbImage, 0, 0, this);
}
public void paint(Graphics g)
{
String string = String.valueOf(y);
g.setColor(Color.RED);
g.fillRect(x, y, 40, 100);
player.setBounds(x, y, 40, 100);
g.setColor(Color.BLUE);
platform.setBounds(180, 300, 100, 40);
g.fillRect(180, 300, 100, 40);
g.drawString(string, 100, 100);
}
#Override
public void keyPressed(KeyEvent e)
{
switch (e.getKeyCode())
{
case KeyEvent.VK_RIGHT:
right = true;
break;
case KeyEvent.VK_LEFT:
left = true;
break;
case KeyEvent.VK_UP:
up = true;
break;
case KeyEvent.VK_DOWN:
down = true;
break;
}
}
#Override
public void keyReleased(KeyEvent e)
{
switch (e.getKeyCode())
{
case KeyEvent.VK_RIGHT:
right = false;
break;
case KeyEvent.VK_LEFT:
left = false;
break;
case KeyEvent.VK_UP:
break;
case KeyEvent.VK_DOWN:
down = false;
break;
}
}
#Override
public void keyTyped(KeyEvent arg0)
{
// TODO Auto-generated method stub
}
}
I'm just starting out trying to make games and I did a HelloWorld Applet, then tested my idea for scrolling on it, and eventually it started turning into a "helicopter" style game. Now everything worked fine until I decided to put a bunch of switch statements in to handle states(title screen, running, and game over). The code that was functioning before is unchanged, and my new "intro screen" works fine, but when you switch into the game state the double buffering seems to go out of whack. The game foreground flashes on and off quickly and has triangles cut out of it, and the background hardly renders at all. This is just me exploring basic principles of game coding, so it's not elegant or modular or anything, but it should work...
[EDIT] I know that Applets and AWT in general is probably a bad way to go, but I started it like this and I just want to learn how this works and what I'm doing wrong so I can be satisfied and move on.
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);
}
}
You need to "clear" the graphics on each frame, otherwise you are painting on what was previously painted...
In the example below, I've filled the graphics context while it's "playing", but left as is when it's paused, you should be able to see the difference...
public class HelloWorld extends Applet implements Runnable {
private int direction = 4;
private int state = 0;
private Image bgImage;
private Graphics bground;
private int count;
private int x = 0;
//"constructor"
public void init() {
addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
if (state == 0) {
state = 1;
} else if (state == 1) {
state = 0;
}
}
}
});
}
public void paint(Graphics g) {
switch (state) {
case 0:
g.setColor(Color.black);
g.drawString("DON'T CRASH THE PLANE BRO", 10, 100);
g.drawString("Press Spacebar to Play", 40, 150);
break;
case 1:
break;
}
}
public void start() {
Thread thread = new Thread(this);
thread.start();
}
#Override
public void run() {
while (true) {
switch (state) {
case 0:
count++;
this.repaint();
break;
case 1:
x += direction;
if (x < 0) {
x = 0;
direction *= -1;
} else if (x > getWidth()) {
x = getWidth();
direction *= -1;
}
//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:
bground.setColor(Color.WHITE);
bground.fillRect(0, 0, getWidth(), getHeight());
bground.setColor(Color.RED);
int y = (getHeight() / 2) - 4;
bground.fillOval(x, y, 8, 8);
break;
}
//paint over the background then draw it to screen
paint(bground);
g.drawImage(bgImage, 0, 0, this);
}
}
I think you should start but adding more braces. I'm a beginner at coding but from what I've been reading, coding lengthy statements without braces on certain statements in your code would result in some errors.
There are a lot of processes going on here and I feel like braces help a
//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();
Correct me if I'm wrong, I just want to learn too!