I have a really odd problem where the JPanel I am making does not update every time. This is the method I use to update a JPanel which contains the map of my game. Calling on MapView creates a JPanel with the map inside it. However, sometimes the map refreshes with all the tiles in it displaying properly, and sometimes it only shows the tile in the top right.
public void updateMap(char[][] map){
remove(mapView);
revalidate();
repaint();
mapView = new MapView(logic, oCreator, 240, 240, map);
mapView.setBounds(40, 80, 240, 240);
add(mapView);
}
And the method inside the MapPanel class that draws the map:
public JPanel addMapPanel(char[][] map){
int mapLength = map.length;
int mapHeight = map[0].length;
int tileSize = Math.min((length / mapLength), (height / mapHeight));
absoluteMapHeight = tileSize * mapHeight;
absoluteMapLength = tileSize * mapLength;
JPanel mapFrame = new JPanel(new GridLayout(mapHeight, mapLength));
mapFrame.setBackground(oCreator.getColorMedium());
int counter = 0;
for(int yIndex = 0; yIndex < mapHeight; yIndex++){
for(int xIndex = 0; xIndex < mapLength; xIndex++){
char charAtPos = map[xIndex][yIndex];
JPanel tile;
//A tile is just a JPanel with the correct background.
switch(charAtPos){
//TODO Colours are placeholders.
case '.':
tile = createMapTile(Color.DARK_GRAY, tileSize);
break;
case '#':
tile = createMapTile(Color.black, tileSize);
break;
case 'G':
tile = createMapTile(Color.yellow, tileSize);
break;
case 'P':
tile = createMapTile(Color.MAGENTA, tileSize);
break;
case 'E':
tile = createMapTile(Color.RED, tileSize);
break;
default:
tile = createMapTile(Color.blue, tileSize);
}
mapFrame.add(tile);
counter++;
}
}
System.out.println(counter);
return mapFrame;
}
Sometimes it draws this: http://puu.sh/7Xcxo.png
And sometimes it draws the whole map: http://puu.sh/7XcAm.png
I am not sure why.
Related
Here's my code that the error points to:
shipX = shipOne.getX();
EDIT2: Specifically it cannot find shipOne.
The Ship object, shipOne, is initialized inside a Switch statement not ten lines prior to the above code. I'm fairly certain that the error is appearing due to the object being initialized inside the Switch statement, and I don't know what to do about that. There are a total of eight Ship objects that are initialized via a loop and as such the above code needs to either be in a Switch statement or an If statement, both of which I'm sure would cause the same error. Is there an exception I can throw or something that would cause my program to run? The Ship objects do get initialized 100% of the time so there's no worry there.
EDIT: I was asked for the rest of the code so here it be:
(This isn't the entirety of it, as you can't see the return statement but the remainder isn't relevant to my problem).
public static String[][] createFleet()
{
//Initialize Variables
//Ship Variables
boolean isHoriz = true; //Is true if ship is Horizontal, false if Vertical
char ID;
int posX = 0; //Origin of the ship (x coordinate [row])
int posY = 0; //Origin of the ship (y coordinate [column])
int size = 0; //Either 2, 3, or 4
//Associated Variables
Random randomGen = new Random(); //Random number generator
String[][] board = new String[10][10]; //Gameboard, populated with ships
int orientationRand = 0; //If 0, Ship Horizontal. If 1, Ship Vertical
int posRand = 0; //Assigned to posX or posY
int sizeRand = 0; //If 0 <= x < 10, size = 2
//If 10 <= x < 40, size = 3
//If 40 <= x < 100, size = 4
//Create Ships
for (int i = 0; i < 8; i++)
{
//Size
sizeRand = randomGen.nextInt(100);
if (sizeRand < 10)
{
size = 2;
}
else if (sizeRand < 40)
{
size = 3;
}
else size = 4;
//Orientation & Position
orientationRand = randomGen.nextInt(2);
if (orientationRand == 0)
{
//Orientation
isHoriz = true;
//Position (horizontal)
//x position
switch (size)
{
case 2:
posRand = randomGen.nextInt(9);
posX = posRand;
break;
case 3:
posRand = randomGen.nextInt(8);
posX = posRand;
break;
case 4:
posRand = randomGen.nextInt(7);
posX = posRand;
break;
}
//y position
posRand = randomGen.nextInt(10);
posY = posRand;
}
else
{
//Orientation
isHoriz = false;
//Position (vertical)
//x position
posRand = randomGen.nextInt(10);
posX = posRand;
//y position
switch (size)
{
case 2:
posRand = randomGen.nextInt(9);
posY = posRand;
break;
case 3:
posRand = randomGen.nextInt(8);
posY = posRand;
break;
case 4:
posRand = randomGen.nextInt(7);
posY = posRand;
break;
}
}
//Assign Size, Orientation, and Position to each ship
switch (i)
{
case 0:
ID = 'A';
Ship shipOne = new Ship(posX, posY, size, isHoriz, ID);
break;
case 1:
ID = 'B';
Ship shipTwo = new Ship(posX, posY, size, isHoriz, ID);
break;
case 2:
ID = 'C';
Ship shipThree = new Ship(posX, posY, size, isHoriz, ID);
break;
case 3:
ID = 'D';
Ship shipFour = new Ship(posX, posY, size, isHoriz, ID);
break;
case 4:
ID = 'E';
Ship shipFive = new Ship(posX, posY, size, isHoriz, ID);
break;
case 5:
ID = 'F';
Ship shipSix = new Ship(posX, posY, size, isHoriz, ID);
break;
case 6:
ID = 'G';
Ship shipSeven = new Ship(posX, posY, size, isHoriz, ID);
break;
case 7:
ID = 'H';
Ship shipEight = new Ship(posX, posY, size, isHoriz, ID);
break;
}
}
In your code, 'ID' variable is not getting declared anywhere. You must declare variable before using it.
Initialize the objects to null before the switch or if statements. I think this should solve your problem.
It will be possible to provide a better solution if the entire code was posted.
I'm still relatively new to Java. Also, this is a school project.
Goal: When run, the program is SUPPOSED TO create and display 3 ea. 25x25 images. Then, whenever a button is pushed, various transforms are to be applied to each of the images. My problem is that none of the transforms are being applied.
I have 3 classes: a drawing area, a GUI builder, and a main run class.
So far the GUI is coming up,the initial images are displayed, and the listeners for buttons are good to go. When the buttons are pushed, the appropriate messages appear but nothing changes with my images.
Here's the GUI builder:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.text.ParseException;
import javax.swing.border.Border;
//#SuppressWarnings("serial")
public class Project1 extends JFrame implements ActionListener {
public static JButton nextTransformBtn;
public static JButton closeBtn;
//public static JLabel label;
public static JFrame window;
public static JPanel topPanel;
public static DrawArea panel;
public static Border blackLine;
private int frameNumber; // A counter that increases by one in each frame.
private long elapsedTimeMillis; // The time, in milliseconds, since the animation started.
private float pixelSize; // This is the measure of a pixel in the coordinate system
// set up by calling the applyWindowToViewportTransformation method. It can be used
// for setting line widths, for example.
public static final int CANVAS_WIDTH = 800;
public static final int CANVAS_HEIGHT = 600;
public static int count ;
int num ;
//public static final String TITLE = " Project 1";
/** constructor
* #param args
*/
public Project1() throws ParseException {
/**
* Set properties of Project1 JFrame
*/
super("Project 1");
setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
setLocationRelativeTo(null);
setResizable(false);
setBackground( Color.lightGray );
setDefaultCloseOperation(EXIT_ON_CLOSE);
/**
* Creates black line for border
*/
blackLine = BorderFactory.createLineBorder(Color.BLACK);
/**
* Create a JPanel to display Graphics
*/
panel = new DrawArea();
panel.setBackground(Color.white);
panel.setBorder(blackLine);
/**
* Create components for topPanel
*/
//label = new JLabel(" Project 1 ");
nextTransformBtn = new JButton("Next transform");
closeBtn= new JButton("Exit Program");
/**
* Create a topPanel for text box and
* set its properties
*/
topPanel = new JPanel();
FlowLayout layout = new FlowLayout();
topPanel.setLayout(layout);
topPanel.setBorder(blackLine);
//topPanel.add(label);
topPanel.add(nextTransformBtn);
topPanel.add(closeBtn);
/**
* Add topPanel and panel to JFrame
*/
add(topPanel, BorderLayout.NORTH);
getContentPane().add(panel);
/**
* Create ActionListeners for buttons
*/
closeBtn.addActionListener(e-> System.exit(0));
nextTransformBtn.addActionListener(e-> {
System.out.print (count + " - ");
panel.doTransform(count);
panel.redrawComponent();
count++;
if(count == 6) count = 0;
});
}// end constructor method
#Override
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
And here's the drawing area:
public class DrawArea extends JPanel{
BufferedImage boxImage;
AffineTransform at = new AffineTransform();
public Graphics2D g2;
public DrawArea(){
setBackground(Color.white);
setSize(800,600);
}
public void doTransform(int count){
switch(count){
case 0:
at.translate(-5, 0);
System.out.println("Translate images -5 in X direction.");
break;
case 1:
at.translate(0,7);
System.out.println("Translate images 7 in Y direction.");
break;
case 2:
System.out.println("Rotates images 45 degrees counter clockwise.");
at.rotate(Math.toRadians(45));
break;
case 3:
at.rotate(Math.toRadians(-90));
System.out.println("Rotates images 90 degrees clockwise.");
break;
case 4:
at.scale(2, 0);
System.out.println("Scales images 2 times for X component.");
break;
case 5:
at.scale(0, 0.5);
System.out.println("Scales images 0.5 times for Y component.");
break;
}
g2.setTransform(at);
}
public void redrawComponent(){
repaint();
}
#Override
public void paintComponent(Graphics g) {
g2 = (Graphics2D)g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(Color.WHITE);
g2.fillRect(0,0,getWidth(),getHeight()); // From the old graphics API!
setPixelSize(g2, -100, 100, -100, 100, true);
/*
* Create images and store in 2d array
*/
int blk = Color.BLACK.getRGB();
int boxData[][]= newint[25][25];
for(int x = 0 ; x<25 ; x++){
for(int y = 0 ; y<25 ; y++){
if( x==0 || y==0 || x == 24 || y == 24){
boxData[x][y] = Color.BLACK.getRGB();
} else if (x>y){
boxData[x][y] = Color.red.getRGB();
} else if (x<y){
boxData[x][y] = Color.blue.getRGB();
}
}
}
boxImage = new BufferedImage(25, 25 ,BufferedImage.TYPE_INT_RGB);
//box
for (int x = 0 ; x<25 ; x++){
for(int y = 0 ; y<25 ; y++){
boxImage.setRGB(x,y,boxData[x][y]);
}
}
g2.drawImage(boxImage, -13, -40, this);
AffineTransform saveXform = g2.getTransform();
AffineTransform toCenterAt = new AffineTransform();
toCenterAt.concatenate(at);
g2.transform(toCenterAt);
g2.setTransform(saveXform);
}
private void setPixelSize(Graphics2D g2,
double left, double right, double bottom, double top,
boolean preserveAspect) {
int width = getWidth(); // The width of this drawing area, in pixels.
int height = getHeight(); // The height of this drawing area, in pixels.
if (preserveAspect) {
// Adjust the limits to match the aspect ratio of the drawing area.
double displayAspect = Math.abs((double)height / width);
double requestedAspect = Math.abs(( bottom-top ) / ( right-left ));
if (displayAspect > requestedAspect) {
// Expand the viewport vertically.
double excess = (bottom-top) * (displayAspect/requestedAspect - 1);
bottom += excess/2;
top -= excess/2;
}
else if (displayAspect < requestedAspect) {
// Expand the viewport vertically.
double excess = (right-left) * (requestedAspect/displayAspect - 1);
right += excess/2;
left -= excess/2;
}
}
g2.scale( width / (right-left), height / (bottom-top) );
g2.translate( -left, -top );
double pixelWidth = Math.abs(( right - left ) / width);
double pixelHeight = Math.abs(( bottom - top ) / height);
pixelSize = (float)Math.max(pixelWidth,pixelHeight);
}// end setPixelSize method
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
And now my main class...
import java.text.ParseException;
public class runProject1 {
public static void main(String[] args) throws ParseException{
final Project1 panel = new Project1();
panel.setVisible(true);
}
}
Your problems start here:
public Graphics2D g2;
There is no reason to maintain a reference to the system Graphics context, let alone make it public. The Graphics is controlled by the paint system and you will be given a instance to paint to when the system needs you to update the component.
So, instead, update your transform as you need and call repaint on the component, apply the transform to the Graphics context passed to the paintComponent method
public class DrawArea extends JPanel {
BufferedImage boxImage;
AffineTransform at = new AffineTransform();
public DrawArea() {
setBackground(Color.white);
setSize(800, 600);
}
public void doTransform(int count) {
at = new AffineTransform();
switch (count) {
case 0:
at.translate(-5, 0);
System.out.println("Translate images -5 in X direction.");
break;
case 1:
at.translate(0, 7);
System.out.println("Translate images 7 in Y direction.");
break;
case 2:
System.out.println("Rotates images 45 degrees counter clockwise.");
at.rotate(Math.toRadians(45));
break;
case 3:
at.rotate(Math.toRadians(-90));
System.out.println("Rotates images 90 degrees clockwise.");
break;
case 4:
at.scale(2, 0);
System.out.println("Scales images 2 times for X component.");
break;
case 5:
at.scale(0, 0.5);
System.out.println("Scales images 0.5 times for Y component.");
break;
}
repaint();
}
public void redrawComponent() {
repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
#Override
protected void paintComponent(Graphics g) {
// Let the API fill the background
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
AffineTransform toCenterAt = new AffineTransform();
// This centers the transform in the available space
toCenterAt.translate(getWidth() / 2, getHeight() / 2);
toCenterAt.concatenate(at);
g2.transform(toCenterAt);
/*
Create images and store in 2d array
*/
int blk = Color.BLACK.getRGB();
int boxData[][] = new int[25][25];
for (int x = 0; x < 25; x++) {
for (int y = 0; y < 25; y++) {
if (x == 0 || y == 0 || x == 24 || y == 24) {
boxData[x][y] = Color.BLACK.getRGB();
} else if (x > y) {
boxData[x][y] = Color.red.getRGB();
} else if (x < y) {
boxData[x][y] = Color.blue.getRGB();
}
}
}
boxImage = new BufferedImage(25, 25, BufferedImage.TYPE_INT_RGB);
//box
for (int x = 0; x < 25; x++) {
for (int y = 0; y < 25; y++) {
boxImage.setRGB(x, y, boxData[x][y]);
}
}
g2.drawImage(boxImage, -13, -40, this);
g2.dispose();
}
}
This code resets the transform each time, remember transformations are cumulative
You may also like to have a look at this example for some more ideas
I might also point out the overuse of static is very dangerous and could cause no end of issues if you're not careful. static is not a means for cross object communication and you should use it sparingly
Here try this. It's transforming now. I changed a few things, so go back and see what I changed to see what was wrong in the first place. Also moved the repaint into the doTransform method.
public class DrawArea extends JPanel{
float pixelSize;
BufferedImage boxImage;
AffineTransform at = new AffineTransform();
public DrawArea(){
setBackground(Color.white);
setSize(800,600);
}
public void doTransform(int count){
switch(count){
case 0:
at.translate(-5, 0);
System.out.println("Translate images -5 in X direction.");
break;
case 1:
at.translate(0,7);
System.out.println("Translate images 7 in Y direction.");
break;
case 2:
System.out.println("Rotates images 45 degrees counter clockwise.");
at.rotate(Math.toRadians(45));
break;
case 3:
at.rotate(Math.toRadians(-90));
System.out.println("Rotates images 90 degrees clockwise.");
break;
case 4:
at.scale(2, 0);
System.out.println("Scales images 2 times for X component.");
break;
case 5:
at.scale(0, 0.5);
System.out.println("Scales images 0.5 times for Y component.");
break;
}
repaint();
}
public void redrawComponent(){
repaint();
}
#Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(Color.WHITE);
g2.fillRect(0,0,getWidth(),getHeight()); // From the old graphics API!
setPixelSize(g2, -100, 100, -100, 100, true);
/*
* Create images and store in 2d array
*/
int blk = Color.BLACK.getRGB();
int boxData[][]= new int[25][25];
for(int x = 0 ; x<25 ; x++){
for(int y = 0 ; y<25 ; y++){
if( x==0 || y==0 || x == 24 || y == 24){
boxData[x][y] = Color.BLACK.getRGB();
} else if (x>y){
boxData[x][y] = Color.red.getRGB();
} else if (x<y){
boxData[x][y] = Color.blue.getRGB();
}
}
}
boxImage = new BufferedImage(25, 25 ,BufferedImage.TYPE_INT_RGB);
//box
for (int x = 0 ; x<25 ; x++){
for(int y = 0 ; y<25 ; y++){
boxImage.setRGB(x,y,boxData[x][y]);
}
}
AffineTransform saveXform = g2.getTransform();
AffineTransform toCenterAt = new AffineTransform();
toCenterAt.concatenate(at);
g2.transform(toCenterAt);
g2.setTransform(saveXform);
g2.setTransform(at);
g2.drawImage(boxImage, 100, 100, this);
}
private void setPixelSize(Graphics2D g2,
double left, double right, double bottom, double top,
boolean preserveAspect) {
int width = getWidth(); // The width of this drawing area, in pixels.
int height = getHeight(); // The height of this drawing area, in pixels.
if (preserveAspect) {
// Adjust the limits to match the aspect ratio of the drawing area.
double displayAspect = Math.abs((double)height / width);
double requestedAspect = Math.abs(( bottom-top ) / ( right-left ));
if (displayAspect > requestedAspect) {
// Expand the viewport vertically.
double excess = (bottom-top) * (displayAspect/requestedAspect - 1);
bottom += excess/2;
top -= excess/2;
}
else if (displayAspect < requestedAspect) {
// Expand the viewport vertically.
double excess = (right-left) * (requestedAspect/displayAspect - 1);
right += excess/2;
left -= excess/2;
}
}
g2.scale( width / (right-left), height / (bottom-top) );
g2.translate( -left, -top );
double pixelWidth = Math.abs(( right - left ) / width);
double pixelHeight = Math.abs(( bottom - top ) / height);
pixelSize = (float)Math.max(pixelWidth,pixelHeight);
}// end setPixelSize method
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
I'm brand new to game development and have chosen to start working on a 2D top-down scroller game. I'm using the Slick2D library for this game.
My question is about best practices for taking multiple direction input for sprite movement (UP + RIGHT = Diagonal)
Currently, I have a rather ugly looking if/elseif chain to read in the input from the keyboard that is then checked in the 'Mob' class to determine how the sprite will move. The current setup works just fine, but my question is if there is another, better way of going about taking multiple inputs for diagonals (or any combo of keys, for that matter)
Here is the main class's update method that reads the input (blooper is the instance of 'Mob'):
public void update(GameContainer container, StateBasedGame arg1, int delta) throws SlickException {
Input input = container.getInput();
if(input.isKeyDown(Input.KEY_RIGHT)) { //RIGHT
if(input.isKeyDown(Input.KEY_UP)){ //RIGHT + UP
blooper.direction = 2;
} else if(input.isKeyDown(Input.KEY_DOWN)){ //RIGHT + DOWN
blooper.direction = 3;
}
else {
blooper.direction = 1;
}
} else if(input.isKeyDown(Input.KEY_LEFT)){ //LEFT
if(input.isKeyDown(Input.KEY_UP)){ //LEFT + UP
blooper.direction = 5;
} else if(input.isKeyDown(Input.KEY_DOWN)){ //LEFT + DOWN
blooper.direction = 6;
} else{
blooper.direction = 4;
}
} else if(input.isKeyDown(Input.KEY_UP)){ //UP
if(input.isKeyDown(Input.KEY_RIGHT)){ //UP + RIGHT
blooper.direction = 8;
} else if(input.isKeyDown(Input.KEY_LEFT)){ //UP + LEFT
blooper.direction = 9;
} else{
blooper.direction = 7;
}
} else if(input.isKeyDown(Input.KEY_DOWN)){ //DOWN
if(input.isKeyDown(Input.KEY_RIGHT)){ //DOWN + RIGHT
blooper.direction = 11;
} else if(input.isKeyDown(Input.KEY_LEFT)){ //DOWN + LEFT
blooper.direction = 12;
} else{
blooper.direction = 10;
}
} else{
blooper.direction = -1;
}
blooper.update(delta);
}
And here is how that input is processed in the Mob class:
public class Mob {
private final int RIGHT = 1;
private final int RIGHTUP = 2;
private final int RIGHTDOWN = 3;
private final int LEFT = 4;
private final int LEFTUP = 5;
private final int LEFTDOWN = 6;
private final int UP = 7;
private final int UPRIGHT = 8;
private final int UPLEFT = 9;
private final int DOWN = 10;
private final int DOWNRIGHT = 11;
private final int DOWNLEFT = 12;
private final int IDLE = -1;
int direction = IDLE;
int x, y;
Image sprite;
public Mob() throws SlickException{
x = 20;
y = 20;
sprite = new Image("res/blooper.png");
}
public void update(int delta){
move();
}
public void draw(){
sprite.draw(x, y);
}
public void move(){
switch(direction){
case RIGHT:
x += 1;
break;
case RIGHTUP:
x += 1;
y -= 1;
break;
case RIGHTDOWN:
x += 1;
y += 1;
break;
case LEFT:
x -= 1;
break;
case LEFTUP:
x -= 1;
y -= 1;
break;
case LEFTDOWN:
x -= 1;
y += 1;
break;
case UP:
y -= 1;
break;
case UPRIGHT:
y -= 1;
x += 1;
break;
case UPLEFT:
y -= 1;
x -= 1;
break;
case DOWN:
y += 1;
break;
case DOWNRIGHT:
y += 1;
x += 1;
break;
case DOWNLEFT:
y += 1;
x -= 1;
break;
case IDLE:
//nothing
}
}
}
Like I said...this works, but doesn't seem like the best way to go about it. Any tips?
Make left/right and up/down movement independent. You (or the framework - I'm unfamiliar with it) seems to work with x/y coordinates, which are mathematically independent.
Thus make one function that treats the up/down movement, and one function that treats the left/right movement, and you can get rid of their 'combinations'. Is there a reason why the directions are positive integers? Try making left = -1, right = 1, and no x-direction movement 0, and then do the same for y. That should hopefully make it more intuitive.
Happy coding
Make a blooper.direction a bitwise, like:
blooper.direction=0;
if(input.isKeyDown(Input.KEY_RIGHT)) blooper.direction|=1;
if(input.isKeyDown(Input.KEY_LEFT)) blooper.direction|=2;
if(input.isKeyDown(Input.KEY_UP)) blooper.direction|=4;
if(input.isKeyDown(Input.KEY_DOWN)) blooper.direction|=8;
then in move do the move, like:
if ((blooper.direction&1)!=0) x+=1;
if ((blooper.direction&2)!=0) x-=1;
if ((blooper.direction&4)!=0) y-=1;
if ((blooper.direction&8)!=0) y+=1;
I'm programming a little 2d game. Acutally I'm busy with the jumping-function. I want my player to jump, when i press the up-arrow key. I managed to make him jumping, but there is a delay of at least one second. This dealy is not existing for other actions like moving left or right. Do you know where it comes from?
The code for jumping is in the keyReaction method.
public class John<I> extends AbstractGame<I> {
//lists
List<ImageObject<I>> floor = new ArrayList<>();
//variables
double jumpHeight = 0;
//boolean
boolean jump = false;
//fix values
int blockHeight = 40;
int blockWidth = 40;
public John(double width, double height) {
//getPlayer()
super(new ImageObject<>("player.png", new Vertex(120, height - 200), new Vertex(0, 0)), width, height);
//floor objects
for(int i=0; i<getWidth(); i+=blockWidth)
floor.add(new ImageObject<>("brick.png", new Vertex(i, getHeight() - blockHeight)));
//add arrays to canvas
getGOss().add(floor);
}
#Override
public void doChecks() {
for(ImageObject<I> f:floor) {
//gravity
if(!(jump) && !(getPlayer().touches(f)))
getPlayer().getMotion().y++;
//stop y-motion on ground
if(getPlayer().touches(f)){
getPlayer().getPos().y = getHeight() - blockHeight - getPlayer().getHeight();
getPlayer().getMotion().y = 0;}
}
}
#Override
public boolean isStopped(){
return false;
}
#Override
public void keyReaction(KeyCode keycode){
switch (keycode) {
//move left
case LEFT_ARROW:
getPlayer().getMotion().x = -2;
break;
case VK_A:
getPlayer().getMotion().x = -2;
break;
//move right
case RIGHT_ARROW:
getPlayer().getMotion().x = 2;
break;
case VK_D:
getPlayer().getMotion().x = 2;
break;
//jump
case UP_ARROW:
jump = true;
if(jumpHeight < 100){
jumpHeight += 5;
getPlayer().getPos().y -=5;
} else if (jumpHeight < 200){
jumpHeight +=5;
getPlayer().getPos().y +=5;
}
break;
case VK_W:
break;
case SPACE:
break;
}
}
#Override
public void keyReactionReleased(KeyCode keycode){
switch (keycode) {
//move left
case LEFT_ARROW:
getPlayer().getMotion().x = 0;
break;
case VK_A:
getPlayer().getMotion().x = 0;
break;
//move right
case RIGHT_ARROW:
getPlayer().getMotion().x = 0;
break;
case VK_D:
getPlayer().getMotion().x = 0;
break;
//jump
case UP_ARROW:
jump = false;
jumpHeight = 0;
break;
case VK_W:
jump = false;
break;
case SPACE:
break;
}
}
//test main
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new SwingScreen(new John<>(1800, 600)));
f.pack();
f.setVisible(true);
}
}
Thank you for your help.
Code with the if:
case UP_ARROW:
if(jumpHeight < 20){
jumpHeight += 5;
getPlayer().getPos().y = -5;
} else if (jumpHeight < 40){
jumpHeight +=5;
getPlayer().getPos().y = 5;
}
break;
Code without the if:
case UP_ARROW:
getPlayer().getPos().y = -5;
break;
KeyReaction:
setOnKeyPressed((ev)->{
logic.keyReaction(KeyCode.fromCode(ev.getCode().impl_getCode()));
ev.consume();
});
setOnKeyReleased((ev)->{
logic.keyReactionReleased(KeyCode.fromCode(ev.getCode().impl_getCode()));
ev.consume();
});
In your jumpheight method you have
jump = true;
if(jumpHeight < 100){
jumpHeight += 5;
getPlayer().getPos().y -=5;
} else if (jumpHeight < 200){
jumpHeight +=5;
getPlayer().getPos().y +=5;
}
break;
On the 4th line there, you have a -=5 for the pos. There is likely another method that prevents the ypos from going under 0. What happens then is you press the up arrow, it gets sent 40 times(200/5), eventually the jumpheight is greater than 200, and only then does the player start moving up.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
memory game graphics java
I'm coding a program that is a 4x4 memory game. Within these 16 boxes will be a pair of integers from 0-7. I have all of that already randomized and coded correctly. Now I'm trying to figure out how to pair the colors with the corresponding integers each time the mouse clicks over the box.
Here most of the code. I know the logic for this game isn't started yet, but I'm more focused on the displayHit method and setColor method right now. Just posting the whole code because maybe I messed up somewhere else.
/*Sets the background of your memory board to black*/
public void init()
{
setSize(400,400);
setBackground(Color.BLACK);
buildBoard(4);
}
/*This is main in java applets
You may need to add (not change) a couple things in this method
*/
public void paint(Graphics canvas)
{
if(firstRun) //for the first run we need to build our random board
{
print2DArray(board);
buildBoard(4);
firstRun = false;
}
else // once our board is built we will display the game
{
displayGame(canvas);
if (mouseClicked) // if the mouse has been clicked
{
displayHit(canvas);//find which box the user clicked
mouseClicked = false;
}
}
}
/*
DO NOT change this method
determines if the mouse has been pressed
sets x and y Mouse to the location of the mouse arrow
redraws the image
*/
public boolean mouseDown(Event e, int x, int y )
{
mouseClicked = true;
xMouse = x;
yMouse = y;
repaint();
return true;
}
/*DO NOT change this method
redraws the scene
*/
public void update ( Graphics g )
{
paint(g);
}
/*
pre: none
post: build an array that holds the memory values for a board of size x size
the board will hold two of each int from 0 to size randomly placed in the array
*/
public void buildBoard(int s)
{
int a = 4;
for (int row = 0; row < a; row++)
for (int column = 0; column < a; column++)
{
board[row][column] = count++ % 8;
}
for(int row = 0; row < 4; row++)
for(int column = 0; column < 4; column ++)
{
int x = (int)Math.floor(Math.random()*4);
int y = (int)Math.floor(Math.random()*4);
temp = board[row][column];
board[row][column] = board[x][y];
board[x][y] = temp;
}
}
public static void print2DArray(int[][] arr)
{
for (int row = 0; row < arr.length; row++)
{
for (int col = 0; col < arr[row].length; col++)
{
System.out.print(arr[row][col] + " ");
}
System.out.println();
}
}
public void displayGame(Graphics canvas)
{
canvas.setColor(Color.WHITE);
for(int i =0; i < 400; i+= WIDTH)
for(int j = 0; j < 400; j+= WIDTH)
canvas.drawRect(i, j, WIDTH, WIDTH);
}
/*
Pre: xMouse and yMouse have been initialized
Post: A circle is displayed in the correct box on the screen
Currently the circle is displayed at the mouse location
*/
public void displayHit(Graphics g)
{
setColor(g);
centerHit(xMouse, xMouse);
g.fillOval(xMouse, yMouse, 40, 40);
}
public void setColor(Graphics g)
{
switch(temp)
{
case 0: g.setColor(Color.RED);
break;
case 1: g.setColor(Color.GREEN);
break;
case 2: g.setColor(Color.BLUE);
break;
case 3: g.setColor(Color.ORANGE);
break;
case 4: g.setColor(Color.CYAN);
break;
case 5: g.setColor(Color.MAGENTA);
break;
case 6: g.setColor(Color.PINK);
break;
case 7: g.setColor(Color.YELLOW);
break;
}
}
public void centerHit(int centerX, int centerY)
{
{
if ((xMouse > 0) && (xMouse <=100))
xMouse = 33;
else if ((xMouse > 100) && (xMouse <=200))
xMouse = 133;
else if ((xMouse > 200) && (xMouse <=300))
xMouse = 233;
else if ((xMouse > 300) && (xMouse <=400))
xMouse = 333;
}
{
if ((yMouse > 0) && (yMouse <=100))
yMouse = 33;
else if ((yMouse > 100) && (yMouse <=200))
yMouse = 133;
else if ((yMouse > 200) && (yMouse <=300))
yMouse = 233;
else if ((yMouse > 300) && (yMouse <=400))
yMouse = 333;
}
}
}
It looks like temp is never changed once buildBoard is called. Which is why you always see the same colour.
this code is fine
public void setColor(Graphics g)
{
switch(temp)
{
case 0: g.setColor(Color.RED);
break;
case 1: g.setColor(Color.GREEN);
break;
case 2: g.setColor(Color.BLUE);
break;
case 3: g.setColor(Color.ORANGE);
break;
case 4: g.setColor(Color.CYAN);
break;
case 5: g.setColor(Color.MAGENTA);
break;
case 6: g.setColor(Color.PINK);
break;
case 7: g.setColor(Color.YELLOW);
break;
}
}
but you are not setting temp anywhere in the code to choose which case/colour you want to use. you need to change temp when you click on a square either by hardcoding it or randomly generating a number between 0-7 to set the colour randomly