I observe one thing.
If I performed some of the operations on the bufferImage, like Loading image, drawing some graphics with the help of createGraphics() method,on restoring the same buffer image variable with the same JPEG image it is also showing the drawing performed by me on the previous buffer image.
class Controller {
static Thread second;
static Thread minutes;
static Thread hour;
static Logic l;
static Design d;
static SecondNiddle s;
static MinutNiddle m;
static HourNiddle h;
static BufferedImage img1 ;
Controller(){
Niddle n=new Niddle();
l=new Logic();
s=new SecondNiddle(l);
m=new MinutNiddle(l);
h=new HourNiddle(l);
d=new Design(l,n,s,m,h);
try {
img1 = ImageIO.read(new File("back1.jpg"));
} catch (IOException e) {
}
}
public static void main(String... args) throws Exception{
Controller c=new Controller();
c.myThread();
while(true){
second.start();
second.join();
Temp.setClockBackGround(img1);
minutes.start();
minutes.join();
hour.start();
hour.join();
c.myThread();
}
}
public void myThread(){
second=new Thread(s,"second");
minutes=new Thread(m,"minutes");
hour=new Thread(h,"hour");
}
After performing the second thread operation if I reset the image and perform the following operations in minut thread.
public void run(){
l.minutAngle+=6;
create(Temp.getClockBackGround().createGraphics());
}
public void create(Graphics2D g){
System.out.println(l.minutAngle);
g.setStroke(new BasicStroke(3));
g.drawLine(175,175,getX(115,l.minutAngle),getY(115,l.minutAngle));
g.dispose();
}
the same is happening in the hour thread and getx and logic will provide time and coordinates.Here is the Temp class
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
class Temp{
private static BufferedImage background;
public static void setClockBackGround(BufferedImage bg){
background=bg;
}
public static BufferedImage getClockBackGround(){
BufferedImage b=background;
return b;
}
}
second thread
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;
class SecondNiddle extends JPanel implements Runnable{
public Graphics g;
public Logic l;
BufferedImage bg;
Image img1 = Toolkit.getDefaultToolkit().getImage("yourFile.gif");
SecondNiddle(Logic l){
this.l=l;
setLayout( new BorderLayout() );
setSize(358,380);
img1 = Toolkit.getDefaultToolkit().getImage("back.jpg");
}
public void run(){
for(int i=0;i<60;i++){
try{
Thread.sleep(1000);
}catch(Exception e){}
l.secondAngle+=6;
repaint();
}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(Temp.getClockBackGround(),0,0,null);
System.out.println("running the paintComonent...");
g.drawLine(175,175,getX(155,l.secondAngle),getY(155,l.secondAngle));
g.dispose();
}
public int getX(int r,float angle){
return (int)(175+(r*Math.sin(3.1416*angle/180)));
}
public int getY(int r,float angle){
return (int)(175-(r*Math.cos(3.1416*angle/180)));
}
}
and the output is as below
Ok, now I can see what you're trying to do. There are several issues here, but with a change in implementation a number of them will go away.
If you intend to have more than this graphic updating (like if this is part of a game) then you should really create a game loop that does the game logic and then the graphical updates at a fixed rate.
Barring that, if you want a clock background and just move the hands, the best way to do it is to create another empty buffered image with transparency, draw the hands on that, then create a composite of both the background buffered image and the hands buffered image. This requires you only loading the background once, and then reusing it for every update. Psuedo code:
public void init()
{
...
BufferedImage background = ImageIO.read();
BufferedImage foreground = new BufferedImage(background.width,
background.height, BufferedImage.TYPE_ARGB);
BufferedImage composite = new BufferedImage(background.width,
background.height, BufferedImage.TYPE_ARGB);
....
}
....
public void paint()
{
...
Gragphics2d g = (Graphics2d)composite.createGraphics();
g2d.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0));
g.drawImage(background,0,0,null);
g.drawImage(foreground,0,0,null);
...
}
Or something along these lines.
Related
trying to create a rectangle using paint but repaint method's not calling paint method.
even tried replacing paint with paintComponent, but still not working.
So what changes to make to make it work.
is there a problem with calling repaint method in run.
is there a problem with the instance.
trying to create a rectangle using paint but repaint method's not calling paint method.
even tried replacing paint with paintComponent, but still not working.
So what changes to make to make it work.
is there a problem with calling repaint method in run.
is there a problem with the instance.
package src;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
public class main extends JFrame implements Runnable{
private final int Height = 480;
private final int Width = 640;
Thread gameloop;
public static main instance = null;
private main(){
JFrame frame = new JFrame();
frame.setSize(this.Width,this.Height);
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static main getInstance(){
if (instance == null){
instance = new main();}
return instance;
}
private void start(){
gameloop = new Thread(this);
gameloop.start();
}
#Override
public void paint(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(g2d.getBackground());
g2d.fillRect(0, 0, instance.Width, instance.Height);
g2d.setColor(Color.red);
g2d.fillRect(0, 0, 50, 50);
}
#Override
public void run() {
Thread current = Thread.currentThread();
while (gameloop == current){
try{
Thread.sleep(5);
}
catch (InterruptedException e){
e.printStackTrace();
}
repaint();
}
}
public static void main(String[] args){
main.getInstance();
main.getInstance().start();
}
}
The original problem was that you created a new JFrame in your constructor and then made that visible, instead of using the main instance you just created, so nothing in your main class was actually being displayed in your app, just a blank JFrame that does nothing. Also your run loop made no sense.
However, your code has a lot of other problems, both in logic and style. I'd advise you to just refactor everything. Here's a cleaner version that also solves your problem.
package src;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
public final class Main extends JFrame implements Runnable {
private volatile boolean running;
private Main(int width, int height) {
setSize(width, height);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void start() {
running = true;
new Thread(this).start();
}
private void stop() {
running = false;
}
#Override
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(g2d.getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(Color.red);
g2d.fillRect(0, 0, 50, 50);
}
#Override
public void run() {
while (running) {
try {
Thread.sleep(40);
}
catch (InterruptedException e){
e.printStackTrace();
}
repaint();
}
}
public static void main(String[] args) {
new Main(640, 480).start();
}
}
I have worked with the school assignment for quite some time now. But I can not really understand what I should do. The assignment is due tomorrow and I feel quite stressed.
The task is, I'll get some pictures, have them in a window, then be able to move around them and also be able to rotate.
The big problem is that I do not know how I'll manage paintComponent().
What I read is that it should be called automatic "when needed" and when you call repaint(). I find it hard to get it to work.
The main class
import java.awt.*;
import javax.swing.*;
import java.util.*;
public class JFrameC extends JFrame{
JPanel panel;
ArrayList <ThePhoto> oneArray = new <ThePhoto> ArrayList();
public JFrameC(){
super("This window");
setLayout(new BorderLayout());
panel = new JPanel();
panel.setBackground(Color.GREEN);
panel.setLayout(null);
add(panel);
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void addPicture(String name){
oneArray.add(new ThePhoto(name, this));
panel.add(oneArray.get(oneArray.size()-1).getJPanel());
}
public void draw(JPanel p){
//One of the tasks is that the image is pressed to end up on top.
//I thought that if I sort of an ArrayList so I can keep track of which one
//is on top. Then be able to paint them in order.
for(ThePhoto x : oneArray){
if(x.getJPanel() == p && oneArray.indexOf(x) != 0){
int i = oneArray.indexOf(x);
for(;i > 0; i--){
ThePhoto temp = oneArray.get(i);
oneArray.set(i, oneArray.get(i-1));
oneArray.set(i-1, temp);
}
break;
}
}
panel.validate();//I can not get this to work
panel.repaint();
getContentPane().validate();//Or this.
getContentPane().repaint();
}
public void paintComponent(Graphics g){
//Is this right?
//What should I write here?
}
public static void main(String[] args) {
JFrameC j = new JFrameC();
j.addPicture("one.gif");
j.addPicture("two.gif");
j.addPicture("three.gif");
j.addPicture("four.gif");
}
}
Class
import javax.swing.*;
import java.awt.*;
public class ThePhoto{
ImageIcon onePicture;
JLabel l;
JPanel p;
JFrameC k;
int posX = 10;
int posY = 10;
public ThePhoto(String name, JFrameC k){
this.k = k;
onePicture = new ImageIcon(name);
l = new JLabel(onePicture);
p = new JPanel();
p.setLayout(new CardLayout());
p.setBorder(null);
p.setBackground(null);
p.add(l);
p.setBounds(posX, posY, 100, 100);
p.addMouseListener(new HandleMouse(k, this));
p.addMouseMotionListener(new HandleMouse(k, this));
}
public void setX(int x){posX = x;}
public void setY(int y){posY = y;}
public JPanel getJPanel(){return p;}
public void paintComponent(Graphics g){
//Is this right?
//What should I write here?
}
}
MouseEvent Class
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.*;
import javax.swing.*;
public class HandleMouse extends MouseAdapter implements MouseMotionListener{
JFrame k;
ThePhoto b;
public HandleMouse(JFrameC k, ThePhoto b){
this.k = k;
this.b = b;
}
public void mouseClicked (MouseEvent e) {
k.draw((JPanel)e.getComponent());
}
public void mouseDragged (MouseEvent e) {
e.translatePoint(e.getComponent().getLocation().x, e.getComponent().getLocation().y);
e.getComponent().setLocation(e.getX(), e.getY());
b.setX(e.getX());
b.setY(e.getY());
}
public void mouseReleased(MouseEvent e) {
k.draw((JPanel)e.getComponent());
}
}
To summarize the issues clearer:
1.Is it best to call repaint() to Frame or Panel? As, I understand it is in both cases everything 'in' the container that will be repainted. And if so, should JFrame be preferable?
2.Is there any routine/usual/rule on what should be in the paintComponent()?
3.What advice and criticism whatsoever is very welcome. But please write so that a beginner understands and no unnecessary insults.
I understand that nobody wants to do my homework. But I only ask for some advice so that I can get better. I also want to write that I am a novice and therefore looks like my code to be written by a novice.
Solve the problem for a single image before trying for multiple images. Starting from this example, use ImageIO.read() to initialize an image and use drawImage() to render it in paintComponent().
private final BufferedImage image = getImage();
private BufferedImage getImage() {
try {
return ImageIO.read(new URL(
"http://i.imgur.com/kxXhIH1.jpg"));
} catch (IOException e) {
e.printStackTrace(System.err);
}
return null;
}
…
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image,
textPt.x - image.getWidth() / 2,
textPt.y - image.getHeight() / 2, this);
}
You can rotate the graphics context as shown here.
Graphics2D animation, cant understand why paintComponent only draws the shape one time and then stops. I Also can't understand why my timer counter variable isn't incrementing. I've been banging my head against this for over an hour, can anyone nudge me in the right direction?
Tetri
package Tetris;
import javax.swing.JLabel;
import java.util.ArrayList;
public class Tetri {
private int xCoords= (int)(Math.random()*10);
private int yCoords=0;
private int shapeType;
private int orientation=0;
public Tetri(int shapeT){
shapeType = shapeT;
}
public int getOrient(){
return orientation;
}
public void setOrient(int orient){
orientation = orient;
}
public void setXCoords(int coords){
xCoords = coords;
}
public int getXCoords(){
return xCoords;
}
public void setYCoords(int coords){
yCoords = coords;
}
public int getYCoords(){
return yCoords;
}
public int getShape(){
return shapeType;
}
}
MovingRectangle
package Tetris;
import javax.swing.JFrame;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JPanel;
import java.awt.Color;
import javax.swing.Timer;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
public class MovingRectangle {
public static void main(String[] args){
new MovingRectangle();
}
public MovingRectangle() {
EventQueue.invokeLater(new Runnable(){
#Override
public void run(){
JFrame frame = new JFrame("Tetris");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0,1));
frame.add(new TestPane(Color.RED));
frame.setSize(1000,800);
frame.setVisible(true);
}
});
}
TestPane
public class TestPane extends JPanel {
private Graphics g0;
private int unit = 50;
private ArrayList<Tetri> shapeList = new ArrayList<Tetri>();
int timercount =1;
public TestPane(Color foreground){
setForeground(foreground);
this.setBackground(Color.BLUE);
Timer timer = new Timer(2000,new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
System.out.println("timercount :"+timercount);
timercount = timercount++;
shapeList.add(new Tetri((int)(Math.random()*2)));
System.out.println("shapeList size : "+shapeList.size());
repaint();
}
});
timer.start();
}
#Override
public void paintComponent(Graphics g){
g0 = g;
super.paintComponent(g);
if(shapeList.size()>0){
Tetri current = shapeList.get(0);
if(current.getShape()==0){
createShape0(current.getXCoords(),current.getYCoords(),current.getOrient());
}
if(current.getShape()==1){
createShape1(current.getXCoords(),current.getYCoords(),current.getOrient());
}
current.setYCoords(current.getYCoords()+50);
}
else{shapeList.add(new Tetri((int)(Math.random()*2)));}
}
public void createShape0(int xc,int yc,int orien){
int yPixel= yc*50;
int xPixel= xc*50;
Graphics2D g2d = (Graphics2D) g0.create();
g2d.setColor(Color.RED);
if(orien==0){
g2d.drawRect(xPixel, yPixel, unit*4, unit);
}
if(orien==1){
g2d.drawRect(xPixel, yPixel, unit, unit*4);
}
}
public void createShape1(int xc,int yc, int orien){
int yPixel= yc*50;
int xPixel= xc*50;
Graphics2D g2d = (Graphics2D) g0.create();
g2d.setColor(Color.GREEN);
if(orien==0){
g2d.drawRect(xPixel, yPixel, unit*3, unit);
g2d.drawRect(xPixel+50, yPixel+50,unit,unit);
}
if(orien==1){
g2d.drawRect(xPixel+50, yPixel-50, unit, unit*3);
g2d.drawRect(xPixel, yPixel,unit,unit);
}
if(orien==2){
g2d.drawRect(xPixel, yPixel, unit*3, unit);
g2d.drawRect(xPixel+50, yPixel-50,unit,unit);
}
if(orien==3){
g2d.drawRect(xPixel+50, yPixel-50, unit, unit*3);
g2d.drawRect(xPixel+100, yPixel,unit,unit);
}
}
}
}
I have a list of things, but lets start with the most obvious.
You "movement" calculations are way off.
int yPixel = yc * 50;
int xPixel = xc * 50;
This is causing your shape to "jump" expectational larger distances...in fact, I can't find any reason for you to "modify" these values at all. Simply making them read as...
int yPixel = yc;
int xPixel = xc;
Got the shape moving just fine...
Code Review
Don't maintain any references to any graphics context you didn't create. These references can be shared amongst the other UI components and there is no guarantee that the reference is in one paint cycle, will be the same on the next. If you want to paint to a graphics context, pass it as parameter to the method that needs to do the painting.
If you create a graphics context (Graphics2D g2d = (Graphics2D) g.create();) then you are responsible for disposing of it (g2d.dispose()) when you are done with it. Otherwise you will slowly consume system resources until your application crashes (talking from experience - it's a hard bug to find ;))
You seem to be going about the process the hard way. You should create a class for each Shape, based off the Tetri that knows how to "draw" itself. That way you would simple pass the graphics context to it in your paint loop and not care. This makes is significantly easier to add new pieces over time.
If you base each of these pieces off a java.awt.Shape, it becomes significantly easier to transform the shape and rotate them.
Take a look at 2D Graphics, in particular, Working with Geometry
I have a Java project that's about traffic network simulation in a random city, I've managed to figure out a way to implement this project, so I divided each intersection into a section which is basically an extended JPanel class (named Carrefour)...everything works well until I got stuck with how to draw vehicles and make them pass through roads.
So my problem is how to draw an image (vehicle image) over an another image (road)?
Another approach that does not require extending components.
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Random;
import java.net.URL;
import javax.imageio.ImageIO;
public class ImageOnImage {
ImageOnImage(final BufferedImage bg, BufferedImage fg) {
final BufferedImage scaled = new BufferedImage(
fg.getWidth()/2,fg.getHeight()/2,BufferedImage.TYPE_INT_RGB);
Graphics g = scaled.getGraphics();
g.drawImage(fg,0,0,scaled.getWidth(),scaled.getHeight(),null);
g.dispose();
final int xMax = bg.getWidth()-scaled.getWidth();
final int yMax = bg.getHeight()-scaled.getHeight();
final JLabel label = new JLabel(new ImageIcon(bg));
ActionListener listener = new ActionListener() {
Random random = new Random();
public void actionPerformed(ActionEvent ae) {
Graphics g = bg.getGraphics();
int x = random.nextInt(xMax);
int y = random.nextInt(yMax);
g.drawImage( scaled, x, y, null );
g.dispose();
label.repaint();
}
};
Timer timer = new Timer(1200, listener);
timer.start();
JOptionPane.showMessageDialog(null, label);
}
public static void main(String[] args) throws Exception {
URL url1 = new URL("http://i.stack.imgur.com/lxthA.jpg");
final BufferedImage image1 = ImageIO.read(url1);
URL url2 = new URL("http://i.stack.imgur.com/OVOg3.jpg");
final BufferedImage image2 = ImageIO.read(url2);
//Create the frame on the event dispatching thread
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
new ImageOnImage(image2, image1);
}
});
}
}
If this is Swing, then draw the background image in a BufferedImage. Display this BufferedImage in a JComponent's (such as a JPanel's) paintComponent method using Graphic's drawImage(...) method, and then draw the changing images over this in the same paintComponent method. Don't forget to call the super.paintComponent(...) method first though.
Please note that this question has been asked quite a bit here and elsewhere, and as you would expect, there are lots of examples of this sort of thing that you can find here with a bit of searching.
Edit
You ask:
Thanks, this is how I draw the firt image (road)
Again, you would create a BufferedImage for this, likely by using ImageIO.read(...). Then you'd draw this in your JPanel's paintComponent(Graphics g) method override using g.drawImage(...).
For example...
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class IntersectionImagePanel extends JPanel {
private static final String INTERSECTION_LINK = "http://www.weinerlawoffice.com/" +
"accident-diagram.jpg";
private BufferedImage intersectionImage;
public IntersectionImagePanel() {
URL imageUrl;
try {
imageUrl = new URL(INTERSECTION_LINK);
intersectionImage = ImageIO.read(imageUrl );
} catch (MalformedURLException e) {
e.printStackTrace();
System.exit(-1);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (intersectionImage != null) {
g.drawImage(intersectionImage, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
if (intersectionImage != null) {
int width = intersectionImage.getWidth();
int height = intersectionImage.getHeight();
return new Dimension(width , height );
}
return super.getPreferredSize();
}
private static void createAndShowGui() {
IntersectionImagePanel mainPanel = new IntersectionImagePanel();
JFrame frame = new JFrame("IntersectionImage");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
im making a side scroller and i dont know how to side scroll and im trying to scroll on the x and y axis
this is for a school project so i would like help as soon as possable
heres some of my code if you have question just ask. any advice is welcome.
source code http://www.mediafire.com/?fi1f9lv6qc2t5d7
gameCanvas.java
package Game;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
#SuppressWarnings("serial")
public abstract class GameCanvas extends Canvas implements Runnable,KeyListener{
public static final long ONE_SECOND_MILI = 1000;
protected int frameW;
protected int frameH;
protected long fps;
private long period = 15;
private BufferStrategy buff;
private Graphics graph;
private Color bckGround=(Color.GRAY);
private Image bckGround_img;
private Thread t;
boolean left;
boolean right;
boolean up;
boolean down;
int lastpressed;
int newlastpressed;
private String drawFps = "0";
public GameCanvas(int w,int h){
this.frameW=w;
this.frameH=h;
this.setIgnoreRepaint(true);
this.setBounds(0,0,frameW,frameH);
this.setBackground(Color.GREEN);
this.setVisible(true);
}
public GameCanvas(int w,int h,Color bck){
this.frameW=w;
this.frameH=h;
this.bckGround=bck;
this.setIgnoreRepaint(true);
this.setBounds(0,0,frameW,frameH);
this.setBackground(bckGround);
this.setVisible(true);
}
public void addNotify(){
super.addNotify();
this.createBufferStrategy(2);
this.buff=this.getBufferStrategy();
requestFocus();
startGame();
}
public void startGame(){
if (t==null){
t=new Thread(this);
t.start();
}
}
public void run(){
while(true){
long beginTime=System.currentTimeMillis();
// try {
// Thread.sleep(25);
// } catch (InterruptedException e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// }
Update();
Render();
Draw();
fps=System.currentTimeMillis() - beginTime ;
long sleepTime=period-fps;
if (sleepTime == 30) sleepTime = -1;
fps= ONE_SECOND_MILI / ((period * 2) - sleepTime);
try{
if (sleepTime > 0){
Thread.sleep(sleepTime);
}
}
catch(Exception e){
}
}
}
public void Render(){
graph = buff.getDrawGraphics();
if (!HasImgBackground()){
graph.setColor(bckGround);
graph.fillRect(0, 0, frameW, frameH);
}else{
graph.drawImage(bckGround_img, 0, 0, frameW, frameH,null);
}
graph.setColor(new Color(255,255,255));
graph.drawString("FPS: " + fps , 10, 15);
Paint(graph);
}
private void Draw(){
if(!buff.contentsLost()){
buff.show();
if(graph != null){
graph.dispose();
}
}
}
private boolean HasImgBackground(){
if (bckGround_img==null){
return false;
}
return true;
}
public void setBackgroundImg(Image image){
this.bckGround_img=image;
}
public void deleteBackground(){
this.bckGround_img=null;
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_LEFT){
left=true;
if(lastpressed!=4)
newlastpressed=lastpressed;
lastpressed=4;
}
if(e.getKeyCode()==KeyEvent.VK_UP){
up=true;
if(lastpressed!=1)
newlastpressed=lastpressed;
lastpressed=1;
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
right=true;
if(lastpressed!=2)
newlastpressed=lastpressed;
lastpressed=2;
}
if(e.getKeyCode()==KeyEvent.VK_DOWN){
down=true;
if(lastpressed!=3)
newlastpressed=lastpressed;
lastpressed=3;
}
}
public void keyReleased(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_LEFT){
left=false;
if(up||right||down)
if(newlastpressed!=0)
lastpressed=newlastpressed;
}
if(e.getKeyCode()==KeyEvent.VK_UP){
up=false;
if(left||right||down)
if(newlastpressed!=0)
lastpressed=newlastpressed;
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
right=false;
if(up||left||down)
if(newlastpressed!=0)
lastpressed=newlastpressed;
}
if(e.getKeyCode()==KeyEvent.VK_DOWN){
down=false;
if(up||right||left)
if(newlastpressed!=0)
lastpressed=newlastpressed;
}
}
public void keyTyped(KeyEvent e) {
}
abstract void Update();
abstract void Paint(Graphics g);
}
main.java
package Game;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
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 java.util.ArrayList;
import javax.swing.JFrame;
public class Mainth extends GameCanvas{
private long timeDown = 0;
// private StopWatch t = new StopWatch();
static Collision coll=new Collision();
Character character=new Character();
static Image wallImage=ImageLoader.getImg().getImage("data/images/objects/brick_wall.png");
static Image bushImage=ImageLoader.getImg().getImage("data/images/objects/hedge_ver.png");
static ArrayList<Image> wallArray=new ArrayList<Image>();
static ArrayList<Image> wall2Array=new ArrayList<Image>();
static Sprite wallSprite;
static Sprite wall2Sprite;
static IndexCounter devIndex;
static Dude dev;
static Wall wall;
static Wall bush;
static Wall wall2;
/**not used*/
int x=0,y=0;
static ArrayList objects=new ArrayList<Entity>();
static ArrayList chars=new ArrayList<Dude>();
static ArrayList projectiles=new ArrayList<>();
public static void main(String[] args){
Mainth Canvas=new Mainth(1500,1000);
JFrame frame=new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(Canvas);
frame.pack();
frame.setSize(750, 400);
frame.setVisible(true);
Mainth.chars.add(dev);
Mainth.objects.add(wall);
Mainth.objects.add(bush);
Mainth.objects.add(wall2);
}
public Mainth(int w,int h){
super(w,h);
this.addKeyListener(this);
CharacterCreation();
}
public void CharacterCreation(){
wallArray.add(wallImage);
wall2Array.add(bushImage);
wallSprite=new Sprite(wallArray,1);
wall2Sprite=new Sprite(wall2Array,1);
dev=new Dude(character.LinkStandingDown,character.LinkStandingDown.getID(),100,300);
devIndex=new IndexCounter(character.LinkWalkingDownArray.size(),3);
wall=new Wall(wallSprite,1,100,50){};
bush=new Wall(wall2Sprite,1,185,55){};
wall2=new Wall(wallSprite,1,100,225){};
bush.setHardness(1);
}
Movement movem=new Movement();
void Update() {
movem.movement(dev, character, left, right, up, down, lastpressed, devIndex);
dev.move();
coll.objectCollision(chars,objects);
devIndex.Counter();
}
void Paint(Graphics g) {
bush.Draw(g,0);
wall.Draw(g,0);
wall2.Draw(g,0);
dev.Draw(g,devIndex.getIndex());
Graphics2D g2d= (Graphics2D) g;
}
public void animation(){
String[] animationSprites=dev.getImgs("walk_down");
int aniTime=0;
aniTime++;
}
public ArrayList<Entity> exportObjects(){
return objects;
}
public ArrayList<Dude> getMainChar(){
return chars;
}
}
What exactly isn't working in the game?
Basic side scrolling logic consists of moving the background, the characters, and the obstacles a certain increment as movement keys are held down. If the screen is "moving right," we are actually moving all of these elements to the left. If the screen is "moving left," then we are doing the opposite. Also, if an entity is moving and has a certain target point, make sure and update the coordinates of this point as you scroll, or the entity will keep moving until it reaches its original on-screen destination. You should also implement code that stops the screen from scrolling too far (thus losing the game).
There are many ways to use side-scrolling, such as scrolling when a character moves a certain distance from the center of the screen, or having controls that move the screen independently from a character (such as in an rts when one scrolls around the map). An easier way might be to always have the player be in the center of the screen, and just have the background and other entities scroll back and forth around him.
You need to coordinate systems:
world coordinates - are always constant
(local) frame coordinate - where objects should be shown in your window now
every object has only world coordinates. And you have a window in this big world. This window has its coordinates in world coordinates. To scroll the view in your window you just need to change it's world coordinates.
Of course you need a code, that renders all objects in you window for any correct position of your movable window. It can be like:
void renderFrame(Rectangle frame) {
for(GameObject go : gameObjects) {
if(frame.contains(go.getGlobalCoordinates())) {
Rectangle windowCoordinates = new Rectangle();
windowCoordinates.x = go.getGlobalCoordinates().x - frame.x;
windowCoordinates.x = go.getGlobalCoordinates().y - frame.y;
windowCoordinates.x = go.getGlobalCoordinates().width - frame.width;
windowCoordinates.x = go.getGlobalCoordinates().height - frame.height;
go.paint(g2, windowCoordinates);
}
}
}