-
I see what you mean makes more sense loading the image once than every time an instance of Frog is created. One thing still elludes me, If I am invoking the Frog class with these new arguments "Image FrogIm and theFrogsPlace" what values are being passed, If I remember correctly arguments do not need to have the same name when invoking other methods as long as they are of the same type, so that would suggest declaring "Image frogpic" then calling Frog like so but I tried it and it didn't like the fact that it was a non static variable being referenced from a static. and as for theFrogsPlace I am somewhat flumoxed by that one
this is what i did to try and call Frog before realising i didn't quite know what to do about this panel thingy.
Code:
Image FrogIm;
Panel frogsplace= ??;
public static Frog [] Frogs = {
new Frog(15, 110, frogpic, ??)
^ Presumably I would just put "frogsplace" in here
Last edited by pwnedjoo; 04-19-2005 at 06:17 PM.
-
theFrogsPlace: this is the Panel/Applet that you use for drawing the frogs
into. As for the static, you are right about that. If we were to declare a
static Frog array like in the rollThemOut Applet, and the Frog constructor
required a Panel as one of the parameters, then this would require that
that Panel also had to be static (and declared prior to the Frog array).
There is absolutely no connection between the names chosen for a
method's parameters and the names used by the caller. I'll get a little
technical here; When a method is called the caller pushes the parameters'
pointers (or values if it is primitives) on to a 'calling stack'. This works the
same way as a pile of plates in a restaurant's plate-storage box (...), -
last in-first out. The invoked method then pops these values off
the calling stack, one by one, and names them according to the sequence
and names of its own parameter list.
Anyway, lets get rid of that static mess and do it the dynamic way. To
illustrate what I mean I am including a de-staticed (hehe) version of your rollerball game. It includes an additional image that is added to each ball.
Check it out, the only thing that is static here is the set of parameters.
(hope I haven't been too complicated here...)
Code:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.util.*;
/**
* A ball w. a diameter, a color and a location
*/
class Ball {
private Rectangle rect=null;
private Color color=null;
private Image picture=null;
private Panel panel=null;
public Ball (int x, int y, int diameter,
Color color, Image anImage,
Panel aPanel) {
rect=new Rectangle(x,y,diameter, diameter);
this.color=color;
picture=anImage;
panel=aPanel;
}
public void draw(Graphics g) {
Color c = g.getColor();
g.setColor(color);
g.fillOval(rect.x, rect.y, rect.width, rect.height);
g.drawImage(picture,rect.x+10, rect.y+10, panel);
g.setColor(c);
}
public boolean isHit(Point p) {
return rect.contains(p);
}
public Rectangle getRectangle() {
return rect;
}
public void moveBall(Point p) {
rect.x += p.x;
/**
* include next statement to allow vertical dragging, possibly
* only allowed under the arc...some positional test perhaps ?
*/
//rect.y += p.y;
}
}
/**
* Your applet as a panel
*/
class RollThemOut extends Panel
implements MouseListener, MouseMotionListener, Comparator {
/**
* I prefer uppercased names to have a clear visual difference
* between static and dynamic variables.
*
* The first one here is a 2D array, the inner brackets delimits the
* rows of this array.
* BALL_PARAMS.length = number of rows (balls)
* BALL_PARAMS[0].length = number of columns
*
* This setup requires that the number of rows in the 2D array equals
* the number of rows in the color array....
*
*/
public static int [][] BALL_PARAMS = { // numeric parameter array
{ 15, 110, 45 },
{ 60, 110, 45 },
{ 105, 110, 45 },
{ 150, 110, 45 },
{ 195, 106, 55 },
{ 250, 106, 55 },
{ 305, 106, 55 },
{ 360, 106, 55 }
};
public static Color [] BALL_COLORS = { // color parameter array
Color.black,
Color.black,
Color.black,
Color.black,
Color.white,
Color.white,
Color.white,
Color.white
};
public static ArrayList bList=new ArrayList();
public Ball [] balls=null; // a non static array of balls
public Image img=null; // a little image to add on to each ball
private Point lastPos; // last dragging position
private Point moveOffset=new Point(); // dragging distance
private int selectedIndex=-1; // index of currently selected ball
public void init() {
img=getAnImage("c:\\tmp\\miniSjalle.jpg");
balls=makeBalls(BALL_PARAMS, BALL_COLORS, img); // zap !
this.addMouseMotionListener(this);
this.addMouseListener(this);
selectedIndex = -1;
}
/**
* Get an image from file
* @param filePath
*/
private Image getAnImage(String filePath) {
ImageIcon imgIcon=new ImageIcon(filePath);
MediaTracker mt=new MediaTracker(this);
mt.addImage(imgIcon.getImage(),0);
try {
mt.waitForAll();
}
catch (InterruptedException ex) {
System.out.println("Image load failed");
ex.printStackTrace();
return null;
}
return imgIcon.getImage();
}
/**
* Make a set of balls
* Note: Im passing the Applets pointer to the Ball constructor.
* This constructor requires a Panel as the last parameter, but
* the Applet class is a descendant of the Panel class so
* that works just fine.
* @param ballParameters
* @param ballColors
*/
private Ball [] makeBalls(int [][] numericParameters,
Color [] ballColors,
Image bzz) {
Ball [] newBalls=new Ball[numericParameters.length];
for (int i=0; i<newBalls.length; i++) {
newBalls[i]=new Ball(numericParameters[i][0],
numericParameters[i][1],
numericParameters[i][2],
ballColors[i],
bzz, this);
}
return newBalls;
}
public void paint(Graphics g) {
update (g);
}
public void update(Graphics g) {
Color c = g.getColor();
g.setColor(Color.blue);
g.fillRect(0, 0, this.getSize().width, this.getSize().height);
drawBox(g);
drawBalls(g);
g.setColor(c);
}
private void drawBalls(Graphics g) {
for (int i = 0; i < balls.length; i++) {
balls[i].draw(g);
}
}
public void drawBox(Graphics g) {
g.setColor(Color.black);
g.fillRect(10, 100, 685, 68);
g.fillOval(410, 55, 65, 65);
g.fillRect(410, 85, 65, 25);
g.fillRect(690, 107, 20, 55);
g.setColor(Color.darkGray);
g.fillRect(15, 105, 675, 58);
g.fillOval(415, 60, 55, 55);
g.fillRect(415, 90, 55, 20);
g.fillRect(690, 112, 30, 45);
}
public void mouseDragged(MouseEvent e) {
if (selectedIndex == -1) {
return;
}
moveOffset.x = e.getPoint().x - lastPos.x;
moveOffset.y = e.getPoint().y - lastPos.y;
balls[selectedIndex].moveBall(moveOffset);
repaint();
lastPos=e.getPoint();
}
/**
* I dont know all the rules here but I've added a sort of the
* balls array to simplify checking of move-space
* @param e
*/
public void mouseReleased(MouseEvent e) {
if (selectedIndex >= 0) { // dragging may have occurred
sortBalls();
}
selectedIndex = -1;
}
/**
* Sort the ball array on x-position
*/
private void sortBalls() {
bList.clear();
for (int i = 0; i < balls.length; i++) {
bList.add(balls[i]);
}
Collections.sort(bList, this);
for (int i = 0; i < bList.size(); i++) {
balls[i] = (Ball) bList.get(i);
}
}
public int compare(Object o1, Object o2) {
Ball b1 = (Ball) o1;
Ball b2 = (Ball) o2;
return b1.getRectangle().x - b2.getRectangle().x;
}
public boolean equals(Object obj) {
return false;
}
/**
* Check for a hit
* @param e
*/
public void mousePressed(MouseEvent e) {
lastPos = e.getPoint();
selectedIndex = -1;
for (int i=0; i<balls.length; i++) {
if (balls[i].isHit(lastPos)) {
selectedIndex = i;
break;
}
}
System.out.println("Select:"+selectedIndex+"\r\n");
}
public void mouseClicked(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
public class RollDriver {
/**
* ************* MAIN ***************************
* Sets up a jframe and a textarea for running the applet code
* @param args
*/
public static void main (String [] args) {
Frame f=new Frame();
f.setLayout(new GridLayout());
RollThemOut p=new RollThemOut();
p.init();
f.add(p);
f.setSize(780, 600);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.validate();
f.setVisible(true);
}
}
-
okay I'm back on the balls puzzle, I have set about controlling movement within the chute and the arch by seting two new rects r1 and r2 which overlap like so:
I have set theseup in init() and have also put the following code in alongside it
Code:
if (insideR1)
{
//not sure what goes in here
}
if (insideR2)
{
//not sure what goes in here
}
and then also included the method
Code:
public boolean mouseMove(Event e,int x,int y)
{
//submit the mouse coordinates to our instance variables
this.x=x;
this.y=y;
//"inside" is a method of the Rectangle class
if(r1.inside(x,y))
insideR1=true;
else
insideR1=false;
if(r2.inside(x,y))
insideR2=true;
else
insideR2=false;
repaint();
return true;
}
I figure I can say something along the lines of
if (inside r1)
{
rect.x += p.x;
}
else if (inside r2)
{
rect.y+= p.y;
}
The problem I have now is like i said above I'm not sure what to put in the if statement in init() to pass on to the class to control movement,
ie the :
Code:
public void moveBall(Point p) {
rect.y += p.x;
rect.x += p.x;
}
also I now get an error like this
Note: RollThemOut.java uses or overrides a deprecated API.
Note: Recompile with -deprecation for details.
Now as you will have gathered, I am no expert but that seems a bit on the serious side even to me
Last edited by pwnedjoo; 04-20-2005 at 04:43 PM.
-
Well, we will take it from the top
In the code i posted I have commented away the logics for allowing the player
to move the ball vertically.
What you have to do is to check the current moving-ball's (rectangle's) position
relative to your chute rectangle (inside chute?,at top of shute?) and adjust
the moving-ball rectangle's coordinate manipulation accordingly.
Your mouseMove method can never respond to a mouse move.
What you need is to let theForgsPlace implement the MouseListener
interface, i.e. implement a handfull of methods, but you only need to
give one of them a code body:
public void mouseReleased(MouseEvent e)]
Read up un that, and I'll get back to you.
Last edited by sjalle; 04-20-2005 at 07:25 PM.
-
just one more quick question about one of the methods
Code:
public int compare(Object o1, Object o2) {
Ball b1 = (Ball) o1;
Ball b2 = (Ball) o2;
return b1.getRectangle().x - b2.getRectangle().x;
}
have been right through code putting system.outs every where to see what each bit does and the only thing I cant figure out is what is this doing
-
That is one of the two methods that have to be implemented by a class that is
going to be a Comparator. As you cas see I use the Collections' static
method sort(List list, Comparator comparator) to sort the list. The comparator used
as parameter is the applet (that implements Comparator). This means that the sort
job done by Collections.sort uses the Comparator's implemetation of the compare method
every time this sort algorithm is going to determine the sequence of two elements
in the list. So, in other words; he two Objects passed to this method are two
elements from the list. If the method returns zero they are equal, if it returns a positive
number the first one has the highest rank, and vice versa. E.g using this means that
you don't have to code the sort algorithm, you just have to code the method (rule)
that determines what element of two elements in the sortlist comes first.
In this case it is the x-position value of the balls.
-
Woohoo! It works
Finally completed my project, just want to say a big thanks to Sjalle for all his advise and help, I now have a fully functioning game and while it is completeley different to the one I started out on the methods I picked up here were invaluable to solving my problem, so thankyou.
One thing still remains though......How do i get rid of the screen flicker when I move objects around, have tried a couple of techniques, none of which work, if anyone has any answers to this I would love to hear em as it would put the finishing touch to my game.
-
Heres is a basic setup for double buffering an image grid
Its a piece of some other code I posted in this forum
Code:
import java.util.*;
import java.awt.*;
import java.applet.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.swing.*;
/****************************************************
* Class for drawing a 2d array of images on
* screen as a grid.
* Atoformatting: Images a are not required to be of same size
* @author sjalle
* @version 0.9
*
*/
class ImageGridPanel
extends JPanel {
// grid h-v space
public final static int VSPACE = 4;
public final static int HSPACE = 4;
public static Font imageGridFont = new Font("SansSerif", Font.BOLD, 12);
private Graphics memG = null;
private BufferedImage memImg = null;
private ImageCell[][] imageGrid = null;
/**
* Constructors
*/
public ImageGridPanel() {}
public ImageGridPanel(ImageCell[][] imageGrid) {
this.imageGrid = imageGrid;
}
/**
* invoked on startup (and resize ?)
*/
public void initializePanel() {
Dimension dim = getSize();
memImg = new BufferedImage(dim.width, dim.height,
BufferedImage.TYPE_INT_RGB);
MediaTracker mt = new MediaTracker(this);
mt.addImage(memImg, 0);
try {
mt.waitForAll();
}
catch (InterruptedException ex) {
ex.printStackTrace();
return;
}
memG = memImg.getGraphics();
memG.setFont(imageGridFont);
repaint();
}
/**
* Switches images
* @param imageGrid
*/
public void setImageGrid(ImageCell[][] imageGrid) {
this.imageGrid = imageGrid;
repaint();
}
/**
* Paint the imageGrid
* @param g
*/
public void paint(Graphics g) {
update(g);
}
public void update(Graphics g) {
if (memG != null) {
Color oldColor = g.getColor();
paintImageGrid(memG);
g.setColor(Color.black);
g.drawImage(memImg, 0, 0, this.getWidth(), this.getHeight(), this);
g.setColor(oldColor);
}
else {
drawMessage(g, "Memory grapics not ready yet");
}
}
/**
* Message on screen
* @param g
* @param msg
*/
private void drawMessage(Graphics g, String msg) {
g.drawString(msg, 10, 20);
}
/**
* Draw the image grid if available
* @param g
*/
private void paintImageGrid(Graphics g) {
if (imageGrid == null) {
drawMessage(g, "No ImageGrid to display");
return;
}
Point p = new Point(0, 0);
int maxHeight = 0;
for (int row = 0; row < imageGrid.length; row++) {
p.x = HSPACE;
p.y += maxHeight + VSPACE;
for (int col = 0; col < imageGrid[row].length; col++) {
imageGrid[row][col].draw(g, p, this);
maxHeight = (maxHeight > imageGrid[row][col].getSize().height) ?
maxHeight :
imageGrid[row][col].getSize().height;
p.x += imageGrid[row][col].getSize().width + HSPACE;
}
}
}
}
/**************************************************
* A cell in an ImageGridPanel
* @author sjalle
* @version 0.9
*/
class ImageCell {
private Image img;
private Dimension dim;
/**
* Forced size constructor
* @param img
* @param dim
*/
public ImageCell(Image img, Dimension dim) {
this.img = img;
this.dim = dim;
}
/**
* Actual size constructor
* @param img
*/
public ImageCell(Image img) {
this.img = img;
}
/**
* Will create the dim object if actual size constructor was used
* @param g
* @param p
* @param pan
*/
public void draw(Graphics g, Point p, ImageGridPanel pan) {
if (dim == null) {
dim = new Dimension(img.getWidth(pan), img.getHeight(pan));
}
g.drawImage(img, p.x, p.y, dim.width, dim.height, pan);
}
/**
* Will return null if actual size constructor was used and
* draw() has not yet been invoked. This is programmers error, no
* exception handling here.
* @return
*/
public Dimension getSize() {
return dim;
}
public Image getImage() {
return img;
}
public void setImage(Image img) {
this.img = img;
}
public void setSize(Dimension dim) {
this.dim = dim;
}
}
Last edited by sjalle; 04-28-2005 at 09:03 AM.
-
I cant see anything,
-
now you can.. (need a cup of cofee...)
-
aaah, now I see,
cheers
-
okay, I am going to shoot myself in the head, this is not going well at all,
I am trying to convert my panel back to an applet and hav eit compiling nicely but when I open it in a browser it says
Code:
java.security.AccessControlException: access denied (java.io.FilePermission BlkFrog.gif read)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkRead(Unknown Source)
at sun.awt.SunToolkit.getImageFromHash(Unknown Source)
at sun.awt.SunToolkit.getImage(Unknown Source)
at javax.swing.ImageIcon.<init>(Unknown Source)
at javax.swing.ImageIcon.<init>(Unknown Source)
at Frogs.getAnImage(Frogs.java:93)
at Frogs.<init>(Frogs.java:11)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at sun.applet.AppletPanel.createApplet(Unknown Source)
at sun.plugin.AppletViewer.createApplet(Unknown Source)
at sun.applet.AppletPanel.runLoader(Unknown Source)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I am asuming it doesn't like the getAnImage method but can't see why
-
Wait a mo, I think I may have tracked down the problem, ImageIcon comes in the swing pakcage by the looks of it, now <clutching at straws here> would swing be picked up in a web browser/applet type situation or am I well off the mark... 
right have killed off swing, now using getImage(etc...), got rid of some of the errors, however these still remain
Code:
java.lang.NullPointerException
at java.applet.Applet.getCodeBase(Unknown Source)
at Frogs.<init>(Frogs.java:11)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at sun.applet.AppletPanel.createApplet(Unknown Source)
at sun.plugin.AppletViewer.createApplet(Unknown Source)
at sun.applet.AppletPanel.runLoader(Unknown Source)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Last edited by pwnedjoo; 04-28-2005 at 01:58 PM.
-
Yes, off the mark by good measure 
You will have to do it the applet way, using Applet.getImage and MediaTracker. ..
Ap applet cannot read files like an application, its not allowed, luckily.
-
this leaves me with something of a problem to alleviate an error I was getting to do with illegal forward references I declared and loaded two images before the declaration of the array, and more importantly before init();
I have commented out the 2 lines and left a simple declaration of two images with no path to load them, the applet now loads no problem but I cant see a way round this, If I then try to load the images withing init() nothing changes, i.e. I have the background for my image but no frogs.
cant move the array into init(), - not going to like that at all as far as i can see
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks