Processing, replacing text - java

I currently got this code for a poster I'm trying to make for a study (Gonna put it all, as it might be relevant):
package interactiveposter;
import processing.core.PApplet;
import processing.core.PImage;
public class InteractivePoster extends PApplet {
// Declare variables:
PImage[] imgs = new PImage[12];
int i = 0;
boolean introduction = true;
boolean storyboardtext = true;
boolean features = true;
int picWidth = 300;
int picHeight = 200;
PImage storyboard;
PImage phone;
// Set size of window and load images:
public void setup() {
size(750,900);
smooth();
storyboard = loadImage("C:/Users/Frederik/Desktop/Medialogy AAU/Images/storyboardfixed.png");
storyboard.resize(270, 757);
phone = loadImage("C:/Users/Frederik/Desktop/Medialogy AAU/Images/phone.PNG");
phone.resize(300, 500);
}
// All that should run continuously goes in draw:
public void draw() {
background(255,255,255);
textAlign(CENTER);
textSize(24);
fill(0);
text("Creative Play - Applied Technology",width/2,50);
textSize(16);
fill(120);
text("B-341",width/2,900);
image(storyboard, 50, 100);
image(phone, 385, 140);
int tboxPos = 50;
tboxPos=tboxPos+335;
if(introduction == false) {
features = true;
text("Text 1...Introduction", 490, 230);
}
if(storyboardtext == false) {
text("Text 2...Storyboard", 480, 230);
}
if(features == false) {
text("Text 3...Features", 480, 230);
introduction = true;
}
fill(0,0,0);
rect(tboxPos,700, 300, 100, 7); //FrameRect
fill(102,204,255);
rect(tboxPos, 700, 300, 50, 7); //IntroductionRect
fill(255,255,255);
textSize(20);
text("Introduction", tboxPos+150, 730);
fill(102,204,255);
rect(tboxPos, 750, 150, 50, 7); // StoryboardRect
fill(255,255,255);
textSize(20);
text("Storyboard", tboxPos+75, 780);
fill(102,204,255);
rect(tboxPos+150, 750, 150, 50, 7); //FeaturesRect
fill(255,255,255);
textSize(20);
text("Features", tboxPos+225, 780);
}
// Check if mouse is clicked on one of the images, then change that variable from true to false or opposite
public void mouseClicked() {
if(mouseX > 385 && mouseX < 685 && mouseY > 700 && mouseY < 750)
{
if(introduction == true) introduction = false;
else introduction = true;
}
if(mouseX > 385 && mouseX < 535 && mouseY > 750 && mouseY < 800)
{
if(storyboardtext == true) storyboardtext = false;
else storyboardtext = true;
}
if(mouseX > 535 && mouseX < 685 && mouseY > 750 && mouseY < 800)
{
if(features == true) features = false;
else features = true;
}
}
}
Poster:
So when you push the buttons below the smartphone, relevant text should appear. For now it works individually, I click introduction, but to see one of the others I have to click introduction again to make it dissapear first.
What I need to do is make the text replace the other when another button is clicked.
I tried putting the other texts to true in the if statements, but it only worked for some of them, the others got kind of blocked.
Another thought was doing something in void mouseClicked(), but I'm unsure what.
Help is highly appreciated, thank you =)

Right now, you're only setting one variable for each button. Instead, what you want to do is set all of the variables.
Here is one example:
if(mouseX > 385 && mouseX < 685 && mouseY > 700 && mouseY < 750){
if(introduction == true){
introduction = false;
}
else{
features = false
storyboardtext = false;
introduction = true;
}
}
By the way, you could shorten all of the above:
if(mouseX > 385 && mouseX < 685 && mouseY > 700 && mouseY < 750){
features = false
storyboardtext = false;
introduction = !introduction;
}
You might also consider using an enum instead of 3 separate boolean values.

I recommend using an integer to keep track of states, with more states boolean become harder to manage and it's easier to make mistakes.
Here's a basic example:
final int INTRODUCTION = 0;
final int STORYBOARD = 1;
final int FEATURES = 2;
int state = INTRODUCTION;
void draw(){
switch(state){
case INTRODUCTION:
drawIntroduction();
break;
case STORYBOARD:
drawStoryboard();
break;
case FEATURES:
drawFeatures();
break;
}
}
void drawIntroduction(){
background(0);
fill(255);
text("Introduction",15,15);
}
void drawStoryboard(){
background(255);
fill(0);
text("Storyboard",15,55);
}
void drawFeatures(){
background(192);
fill(64);
text("Features",15,95);
}
void keyReleased(){
state = (state + 1) % 3;//cycle through states to test
}
I recommend using separate functions for drawing each state to keep the code tidier. Press any key to cycle through states.
The above, roughly adapted to your code, would look a bit like this:
package interactiveposter;
import processing.core.PApplet;
import processing.core.PImage;
public class InteractivePoster extends PApplet {
// Declare variables:
PImage[] imgs = new PImage[12];
int i = 0;
int picWidth = 300;
int picHeight = 200;
PImage storyboard;
PImage phone;
final int INTRODUCTION = 0;
final int STORYBOARD = 1;
final int FEATURES = 2;
int state = INTRODUCTION;
// Set size of window and load images:
public void setup() {
size(750,900);
smooth();
storyboard = loadImage("C:/Users/Frederik/Desktop/Medialogy AAU/Images/storyboardfixed.png");
storyboard.resize(270, 757);
phone = loadImage("C:/Users/Frederik/Desktop/Medialogy AAU/Images/phone.PNG");
phone.resize(300, 500);
}
// All that should run continuously goes in draw:
public void draw() {
background(255,255,255);
textAlign(CENTER);
textSize(24);
fill(0);
text("Creative Play - Applied Technology",width/2,50);
textSize(16);
fill(120);
text("B-341",width/2,900);
image(storyboard, 50, 100);
image(phone, 385, 140);
int tboxPos = 50;
tboxPos=tboxPos+335;
if(state == INTRODUCTION) {
text("Text 1...Introduction", 490, 230);
}
if(state == STORYBOARD) {
text("Text 2...Storyboard", 480, 230);
}
if(state == FEATURES) {
text("Text 3...Features", 480, 230);
}
fill(0,0,0);
rect(tboxPos,700, 300, 100, 7); //FrameRect
fill(102,204,255);
rect(tboxPos, 700, 300, 50, 7); //IntroductionRect
fill(255,255,255);
textSize(20);
text("Introduction", tboxPos+150, 730);
fill(102,204,255);
rect(tboxPos, 750, 150, 50, 7); // StoryboardRect
fill(255,255,255);
textSize(20);
text("Storyboard", tboxPos+75, 780);
fill(102,204,255);
rect(tboxPos+150, 750, 150, 50, 7); //FeaturesRect
fill(255,255,255);
textSize(20);
text("Features", tboxPos+225, 780);
}
// Check if mouse is clicked on one of the images, then change that variable from true to false or opposite
public void mouseClicked() {
if(mouseX > 385 && mouseX < 685 && mouseY > 700 && mouseY < 750)
{
state = INTRODUCTION;
}
if(mouseX > 385 && mouseX < 535 && mouseY > 750 && mouseY < 800)
{
state = STORYBOARD;
}
if(mouseX > 535 && mouseX < 685 && mouseY > 750 && mouseY < 800)
{
state = FEATURES;
}
}
}
Note that I'm unable to test this code(so there may be syntax errors), but the concept explained should be clear.
Also, check out this answer on a similar question and also the Button sample (under File > Examples > Topics > GUI > Button in Processing)

Related

Keylistener and actionlistener does not work, when calling it into main.

I am trying to make a little mini game, where u can move around. I have written a code, which did work. But when I tried to shorten my code and make it looks nicer, I stumble upon a error I could not solve by myself.
Main:
package eksamenstest;
import javax.swing.JFrame;
public class Eksamenstest extends JFrame {
public Eksamenstest() throws InterruptedException
{
JFrame SOJ = new JFrame("Sword Of Justice");
SOJ.pack();
SOJ.setSize(1000,700);
SOJ.setVisible(true);
SOJ.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SOJ.add(new Grafik());
}
public static void main(String[] args) throws InterruptedException
{
new Eksamenstest();
new Musik();
new SpillerOne();
}
}
Graphics:
package eksamenstest;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.JPanel;
public class Grafik extends JPanel
{
int Menu = 1;
int Player1Liv = 3;
int Player2Liv = 3;
int DødP1 = 1;
int DødP2 = 1;
int WeaponON2;
int WeaponON1;
int Skjold;
int Skjold1;
int x = 100;
int y = 360;
int x_1 = 820;
int y_1 = 360;
public Grafik(){}
public void paint(Graphics g)
{
//Grafikken af banen
Image Bane2 = Toolkit.getDefaultToolkit().getImage("Bane2.png");
g.drawImage(Bane2, 0, 0, 1000, 800, this);
Image Plank = Toolkit.getDefaultToolkit().getImage("Plank.jpg");
g.drawImage(Plank, 100, 500, 800, 10, this);
Image lava = Toolkit.getDefaultToolkit().getImage("lava.png");
g.drawImage(lava, 0, 520, 1000, 260, this);
if(Menu == 1)
{
Image Menu2 = Toolkit.getDefaultToolkit().getImage("Menu.png");
g.drawImage(Menu2, 100, -30, 900, 700, this);
}
//Player 1 - Grafikken der viser hvordan spilleren står.
if(WeaponON1 == 0){
Image PlayerStå = Toolkit.getDefaultToolkit().getImage("Stå.png");
g.drawImage(PlayerStå, x, y, 80, 140, this);
}
if(WeaponON1 == 1){
Image PlayerSværdOP = Toolkit.getDefaultToolkit().getImage("OP.png");
g.drawImage(PlayerSværdOP, x, y, 80, 140, this);
}
if(WeaponON1 == 2){
Image PlayerSværdFrem = Toolkit.getDefaultToolkit().getImage("Frem.png");
g.drawImage(PlayerSværdFrem, x, y, 80, 140, this);
}
if(Skjold == 1){
Image Player1Skjold = Toolkit.getDefaultToolkit().getImage("Player1Skjold.png");
g.drawImage(Player1Skjold, x, y, 80, 140, this);
}
if(Player1Liv == 0){
Image DødP = Toolkit.getDefaultToolkit().getImage("DødP.png");
g.drawImage(DødP, x, y, 80, 140, this);
}
if(Player2Liv == 0){
Image Jubel = Toolkit.getDefaultToolkit().getImage("Jubel.png");
g.drawImage(Jubel, x, y, 80, 140, this);
}
//Player 2 - Grafikken der viser hvordan spilleren står.
if(WeaponON2 == 0){
Image PlayerStå1 = Toolkit.getDefaultToolkit().getImage("Stå1.png");
g.drawImage(PlayerStå1, x_1, y_1, 80, 140, this);
}
if(WeaponON2 == 1){
Image PlayerSværdOP1 = Toolkit.getDefaultToolkit().getImage("OP1.png");
g.drawImage(PlayerSværdOP1, x_1, y_1, 80, 140, this);
}
if(WeaponON2 == 2){
Image PlayerSværdFrem1 = Toolkit.getDefaultToolkit().getImage("Frem1.png");
g.drawImage(PlayerSværdFrem1, x_1, y_1, 80, 140, this);
}
if(Skjold1 == 1){
Image Player2Skjold = Toolkit.getDefaultToolkit().getImage("Player2Skjold.png");
g.drawImage(Player2Skjold, x_1, y_1, 80, 140, this);
}
if(Player2Liv == 0){
Image DødPA = Toolkit.getDefaultToolkit().getImage("DødP.png");
g.drawImage(DødPA, x_1, y_1, 80, 140, this);
}
if(Player1Liv == 0){
Image Jubel = Toolkit.getDefaultToolkit().getImage("Jubel.png");
g.drawImage(Jubel, x_1, y_1, 80, 140, this);
}
//Health Bars / Stamina / Navne / Win
//Player 1
Image PlayerNavn = Toolkit.getDefaultToolkit().getImage("Player1Navn.png");
g.drawImage(PlayerNavn, 30, 50, 70, 30, this);
if(Player1Liv == 3){
Image Liv100B = Toolkit.getDefaultToolkit().getImage("Liv100B.png");
g.drawImage(Liv100B, 30, 80, 120, 40, this);
}
if(Player1Liv == 2){
Image Liv75B = Toolkit.getDefaultToolkit().getImage("Liv75B.png");
g.drawImage(Liv75B, 30, 80, 120, 40, this);
}
if(Player1Liv == 1){
Image Liv50B = Toolkit.getDefaultToolkit().getImage("Liv25B.png");
g.drawImage(Liv50B, 30, 80, 120, 40, this);
}
if(Player1Liv == 0){
Image Liv0B = Toolkit.getDefaultToolkit().getImage("Liv0B.png");
g.drawImage(Liv0B, 30, 80, 120, 40, this);
DødP1 = 0;
Image Player2Win = Toolkit.getDefaultToolkit().getImage("Player2Wins.png");
g.drawImage(Player2Win, 350, 80, 350, 110, this);
}
// Player 2
Image PlayerNavn1 = Toolkit.getDefaultToolkit().getImage("Player2Navn.png");
g.drawImage(PlayerNavn1, 900, 50, 70, 30,this);
if(Player2Liv == 3){
Image Liv100R = Toolkit.getDefaultToolkit().getImage("Liv100R.png");
g.drawImage(Liv100R, 850, 80, 120, 40, this);
}
if(Player2Liv == 2){
Image Liv75R = Toolkit.getDefaultToolkit().getImage("Liv75R.png");
g.drawImage(Liv75R, 850, 80, 120, 40, this);
}
if(Player2Liv == 1){
Image Liv50R = Toolkit.getDefaultToolkit().getImage("Liv25R.png");
g.drawImage(Liv50R, 850, 80, 120, 40, this);
}
if(Player2Liv == 0){
Image Liv0R = Toolkit.getDefaultToolkit().getImage("Liv0R.png");
g.drawImage(Liv0R, 850, 80, 120, 40, this);
DødP2 = 0;
Image Player1Win = Toolkit.getDefaultToolkit().getImage("Player1Wins.png");
g.drawImage(Player1Win, 350, 80, 350, 110, this);
}
}
}
Player Movement
package eksamenstest;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
public class SpillerOne extends JFrame implements ActionListener, KeyListener {
int x = 100;
int y = 360;
int xHøjre;
int xVenstre;
int DødP1;
int Player1Liv;
int iLava;
int x_1;
int Player2Liv;
int Skjold1;
int WeaponON1;
int Menu = 1;
int SværdTid;
int Sværd;
int Skjold;
public SpillerOne()
{
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
#Override
public void actionPerformed(ActionEvent e)
{
PlayerOneMove();
repaint();
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
int c = e.getKeyCode();
//Menu
if(c == KeyEvent.VK_O){
Menu = 1;
}
if(c == KeyEvent.VK_P){
Menu = 0;
}
// Player
if(DødP1 == 1){
if(c == KeyEvent.VK_A){
xVenstre = 1;
WeaponON1 = 0;
Sværd = 0;
}
if(c == KeyEvent.VK_D){
xHøjre = 1;
WeaponON1 = 0;
}
if(WeaponON1 == 1){
if(SværdTid < 3){
if(c == KeyEvent.VK_W){
WeaponON1 = 2;
SværdTid++;
}
}
}
if(c == KeyEvent.VK_S){
WeaponON1 = 1;
Sværd = 1;
}
if(c == KeyEvent.VK_Q){
Skjold = 1;
SværdTid++;
}
}
if(c == KeyEvent.VK_E){
SværdTid--;
WeaponON1 = 0;
}
}
#Override
public void keyReleased(KeyEvent e)
{
int c = e.getKeyCode();
// Spiller 1
if(c == KeyEvent.VK_A){
xVenstre = 0;
}
if(c == KeyEvent.VK_D){
xHøjre = 0;
}
if(c == KeyEvent.VK_Q){
Skjold = 0;
SværdTid = SværdTid;
}
if(c == KeyEvent.VK_W){
if(Sværd == 1)
WeaponON1 = 1;
}
if(c == KeyEvent.VK_E){
SværdTid = SværdTid;
WeaponON1 = 0;
}
}
public void PlayerOneMove()
{
// Spiller et Bevægelse
x = x + xHøjre; //Højre
x = x - xVenstre; //Venstre
if(WeaponON1 == 2){ //Tjekker om spilleren har våbnet fremme og hvis ja, så tjekker den om modspilleren har skjold på, hvis ikke, mister person 2 liv.
if(Skjold1 == 0){
if(x > x_1-80 && x < x_1 + 80){
x = 100;
x_1 = 820;
Player2Liv--;
}
}
if(WeaponON1 == 2){
if(Skjold1 == 1){
if(x > x_1-80 && x < x_1 + 80){
x_1 = x_1 + 60;
}
}
}
}
// Falder ned i lava
if(x < 100 && 100 > x + 80){ //Tjekker om player 1 er i lava ved venstre side.
DødP1 = 0;
Player1Liv = 0;
iLava = 1;
if(y < 500){
y++;
}
}
if(x > 900){ //Tjekker om player 1 er i lava ved højre side.
DødP1 = 0;
Player1Liv = 0;
iLava = 1;
if(y < 500){
y++;
}
}
}
}
I have a feeling that this error is caused because I have not repainted somewhere.
So, a list of issues...
First
There are two JFrames - which one is actually been used for what? As far as I can tell, SpillerOne is never displayed, so there is no possible way for it to be able to react to key events. Equally, your ActionListener doesn't seem to be attached to anything which can actually generate actions.
This also raises a bunch of questions about the relationship between SpillerOne and Grafik. They seem to be sharing variable names, but there is no way for them to be sharing state, so even if the KeyListener worked, Grafik would never reflect the changes in SpillerOnes state
Second
You've implemented your custom painting the wrong way. It's highly discouraged to override paint, instead, you should be overriding paintComponent AND calling super.paintComponent to ensure that requirements of the paint chain are upheld
See Performing Custom Painting and Painting in AWT and Swing for more details
You also seem to be putting a lot of state logic into your Grafik class, this is going to become exponentially more difficult to maintain as the complexity increases. Instead, each distinct operation should be it's own class, focused on performing as few dedicated operations as possible
Thirdly
KeyListener is a poor choice for monitoring for key events. While there are "hacks" that attempt to "solve" the focus related issues with KeyListener, none of them can achieve a reliable result.
If you do any research into KeyListener related issues, you will quickly find that the Key bindings API is often sighted as the most reliable solution to the problem
Overall
You code makes no sense. Why are there two frames? What is the ActionListener for and how is it attached to something that generates actions? Why doesn't the Grafik act as the key/action listener?
I think you have some significant thinking and redesigning to do

How to loop something in my paint function? [duplicate]

This question already has answers here:
Image change on hover Java
(2 answers)
Closed 5 years ago.
So I am trying to set up this thing that changes an image when hovered over. I have already set up the mouseListener to know if the mouse is over my image. I have a variable that has the image location stored in it and it changes when the image is hovered over. When my paint command is run it paints the default image and when I hover over it, it doesn't change because it is not painted again. How can I make it so that it repaints it again when the image location is changed. BTW the mouseListener is in a different class than the image.
My image:
private String settingsConfig = snake.settingsConfig;
settingsImage = new ImageIcon(getClass().getResource(settingsConfig));
settingsImage.paintIcon(this, g, 700, 23);
My main class (painting method is in the other class)
public class snake implements MouseListener{
public static int mouseX;
public static int mouseY;
public static String settingsConfig = "/assets/settings.png";
public static void main(String[] args) {
// JFrame
JFrame obj = new JFrame("Snake");
gameplay Gameplay = new gameplay();
obj.setBounds(10, 10, 905, 700);
obj.setBackground(Color.DARK_GRAY);
obj.setResizable(false);
obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
obj.add(Gameplay);
obj.setVisible(true);
obj.addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
if(mouseX > 699 && mouseX < 761 && mouseY > 22 + 25 && mouseY < 54 + 25) {
settingsConfig = "/assets/settingshover.png";
}
else {
settingsConfig = "/assets/settings.png";
}
}
});
}
Very small piece of paint(Graphics g) (In a different class):
public void paint (Graphics g) {
if(moves == 0) {
snakexlength[2] = 50;
snakexlength[1] = 75;
snakexlength[0] = 100;
snakeylength[2] = 100;
snakeylength[1] = 100;
snakeylength[0] = 100;
}
if(moves >= 1) {
playing = true;
}
// Draw title image border
g.setColor(Color.WHITE);
g.drawRect(24, 10, 851, 55);
// Draw the title image and settings
titleImage = new ImageIcon(getClass().getResource("/assets/snaketitle.jpg"));
titleImage.paintIcon(this, g, 25, 11);
settingsImage = new ImageIcon(getClass().getResource(settingsConfig));
settingsImage.paintIcon(this, g, 700, 23);
// Draw the border for gameplay
g.setColor(Color.WHITE);
g.drawRect(24, 74, 851, 577);
// Draw background for the gameplay
g.setColor(Color.BLACK);
g.fillRect(25, 75, 850, 575);
// Draw score
g.setColor(Color.WHITE);
g.setFont(new Font("arial", Font.PLAIN, 14));
g.drawString("Score: " + score, 780, 30);
// Draw high score
g.drawString("High Score: " + highScore, 780, 50);
}
How can I make it so that it repaints it again when the image location is changed
Invoke reapint(); in the place where you need the paintings to be updated. For example in the listener when you mouse-over the image.
public void mouseMoved(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
if(mouseX > 699 && mouseX < 761 && mouseY > 22 + 25 && mouseY < 54 + 25){
settingsConfig = "/assets/settingshover.png";
}
else{
settingsConfig = "/assets/settings.png";
}
repaint();
}

Rock, paper, scissors game Java applet

I'm having problems with my java applet. I've made a Rock paper scissors game and i have 2 problems which I can't solve:
1. how to load the applet without the rock image on the left (players choice)
2. the score for player and computer does not reduce by 1 for every lost game
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class RockScissorsPaper extends Applet implements ActionListener
{
private Button rockButton;
private Button scissorsButton;
private Button paperButton;
private String buttonPressed = "";
private int computerValue = -1;
private int myValue;
private int playerScore = 10;
private int computerScore = 10;
private int drawScore = 0;
private Image imgRock;
private Image imgScissors;
private Image imgPaper;
public void init()
{
rockButton = new Button("Rock");
scissorsButton = new Button("Scissors");
paperButton = new Button("Paper");
add(rockButton);
add(scissorsButton);
add(paperButton);
rockButton.addActionListener(this);
scissorsButton.addActionListener(this);
paperButton.addActionListener(this);
imgRock = getImage(getCodeBase(), "rock.jpg");
imgScissors = getImage(getCodeBase(), "scissors.jpg");
imgPaper = getImage(getCodeBase(), "paper.jpg");
}
public void actionPerformed(ActionEvent event)
{
buttonPressed = ((Button)event.getSource()).getLabel();
computerValue = randomNumber012();
translator(buttonPressed);
repaint();
}
public void paint(Graphics g)
{
super.paint(g);
rockButton.setLocation(20,260);
rockButton.setSize(70,35);
paperButton.setLocation(210, 260);
paperButton.setSize(70, 35);
scissorsButton.setLocation(380, 260);
scissorsButton.setSize(90, 35);
choice(g);
g.drawString("Player's Wins: " + playerScore, 10, 20);
g.drawString("Computer's Wins: " + computerScore, 180, 20);
g.drawString("Draws: " + drawScore, 400, 20);
g.drawString("Your Choice: " + buttonPressed, 20, 60);
g.drawString("Computer's Pick: ", 350, 60);
winner(g, computerValue, myValue);
}
int randomNumber012()
{
return (int)(Math.random()*3);
}
public void translator(String s)
{
if(s.equals("Rock"))
{
myValue = 0;
}
else if(s.equals("Scissors"))
{
myValue = 1;
}
else if(s.equals("Paper"))
{
myValue = 2;
}
}
public void choice(Graphics g)
{
if(myValue == 0)
{
g.drawImage(imgRock, 20, 100, 100, 60, this);
}
else if(myValue == 1)
{
g.drawImage(imgScissors, 20, 100, 100, 60, this);
}
else if(myValue == 2)
{
g.drawImage(imgPaper, 20, 100, 100, 60, this);
}
if(computerValue == 0)
{
g.drawString("Computer's Pick: Rock", 350, 60);
g.drawImage(imgRock, 350, 100, 100, 60, this);
}
else if(computerValue == 1)
{
g.drawString("Computer's Pick: Scissors", 350, 60);
g.drawImage(imgScissors, 350, 100, 100, 60, this);
}
else if(computerValue == 2)
{
g.drawString("Computer's Pick: Paper", 350, 60);
g.drawImage(imgPaper, 350, 100, 100, 60, this);
}
}
public void winner(Graphics g, int cv, int mv)
{
if(cv == -1)
{
g.drawString("", 200, 100);
}
else if(cv == mv)
{
g.drawString("Draw", 200, 250);
drawScore = drawScore + 1;
}
else if(cv == 0 && mv == 1 || cv == 2 && mv == 0 || cv == 1 && mv == 2)
{
g.drawString("Computer Wins", 200, 250);
playerScore = playerScore - 1;
}
else
{
g.drawString("You Win!", 200, 250);
computerScore = computerScore - 1;
}
if (playerScore == 0)
{
System.out.println("You lost!");
playerScore = 10;
computerScore = 10;
drawScore = 0;
}
else if(computerScore == 0)
{
System.out.println("You won!");
playerScore = 10;
computerScore = 10;
drawScore = 0;
}
}
}
how to load the applet without the rock image on the left (players choice)
You need to have a fourth case for your myValue variable, when the player has not made a choice yet. Right now you only have three potential values, and the default is 0, which is why you see a rock image before you make a choice.
the score for player and computer does not reduce by 1 for every lost game
You're using ints where you should be using enums and booleans, which is making your code harder to understand. I'd highly recommend refactoring your code to use enums and booleans instead of ints.
Also, you're always calling every method from the paint() method. Don't do that. Instead, only call the functions that check for a winner when the player actually makes a choice, presumably from a button click.
Finally, you're also calling setLocation() inside your paint() method, which is a bad idea. You should only call setLocation() once, or better yet, use a layout manager.

JLabel and JLayeredPane - How to display an image over another image?

I try to create a little game in java but I'm in trouble.
When I draw a map, I'm not able to display the characters without overwrite the titlesets of the squares.
My goal is to be able to display many pictures on the same square (like the titleset of the grass, the character and a tree), so I have to deal with the transparency of my pictures (this is not the problem) and the layer (it is the problem).
So how can I display an image on another image?
How can I explain to java that I need to display this image on or under another image?
This is my source code. I don't know is that can help you. Your help can be really helpfull for me if you give me a clue or a function who is able to manage the layers. That is useless to rewrite all the code for me x)
This program is not complete, I use it only for test my program right now. I know that he refresh two times the map so he overwrite the square of the character (and he have many others littles glitchs), but that is not the purpose of my question. I try to done my game by step!
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class Window extends Thread
{
private static JFrame window = new JFrame("game");
public void run()
{
Map map = new Map();
Characters characters = new Characters();
window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
window.setSize(Settings.sizeX, Settings.sizeY);
window.setLocationRelativeTo(null);
window.setResizable(false);
window.setVisible(true);
map.start();
characters.start();
}
private static void reload() throws Exception
{
SwingUtilities.updateComponentTreeUI(window);
}
private static class Map extends Thread
{
private int numberSquareX = Settings.sizeX / 20 + 1;
private int numberSquareY = Settings.sizeY / 20 + 1;
private JLabel square[][] = new JLabel[numberSquareX][numberSquareY];
public void run()
{
for (int x = 0, y = 0; y < numberSquareY; x++)
{
square[x][y] = new JLabel(new ImageIcon("grass_1.png"));
square[x][y].setBounds(x * 20, y * 20, 20, 20);
window.add(square[x][y]);
if (x == numberSquareX - 1)
{
y++;
x = -1;
}
}
square[numberSquareX - 1][numberSquareY - 1] = new JLabel(new ImageIcon("grass_1.png"));
square[numberSquareX - 1][numberSquareY - 1].setBounds(numberSquareX * 20, numberSquareY * 20, 20, 20);
window.add(square[numberSquareX - 1][numberSquareY - 1]);
try
{
reload();
}
catch (Exception e)
{
}
return;
}
}
private class Characters extends Thread
{
private JLabel square[][] = new JLabel[1][1];
public void run()
{
square[0][0] = new JLabel(new ImageIcon("character_1.png"));
square[0][0].setBounds(Test.posX, Test.posX, 20, 20);
window.add(square[0][0]);
try
{
reload();
}
catch (Exception e)
{
}
return;
}
}
}
I have already find this subjects: How to use JLayered Pane to display an image on top of another image? and this one Best practice for creating a composite image output for Java Swing but they haven't really help me...
I continue to search the answer. If I find it, I will come back for post it here.
Solved.
Thanks to MadProgrammer for his comments.
Render the title map to a BufferedImage, either in it's entirety or based on the available viewable area, which ever is more efficient. Paint this to the screen, then paint your character on top it – MadProgrammer
In 15+ years of professional Java/Swing development, I've never found a need to use SwingUtilities.updateComponentTreeUI(window);, instead, simply call repaint on the component which is responsible for renderer the output, I'm pretty sure, you'll find this more efficient. – MadProgrammer
Swing is also a single threaded environment AND is not thread safe, you should NOT be update the UI from outside of the context of the Event Dispatching Thread, as this will setup a race condition and could result in unwanted and difficult to resolve graphical issues. – MadProgrammer
Hint. JLabel is a descendent of Container, which means it can contain other components ;) – MadProgrammer
Thanks a lot MadProgrammer! So I have replace SwingUtilities.updateComponentTreeUI(window) by window.repaint(). You had right for the Thread safe, my map had some bugs but I wasn't able to find where they was from. And what about the BufferedImage? If I create two BufferedImage, the last one can be automatically on the top of the first one? Or I just want to render the title map to a BufferedImage (so I am limited by 2 layers)? – Celine
It will depend on what it is you want to achieve. Using BufferedImages gives you complete control over the placement of the images and yes, one can be rendered over the other, painting is like a artists canvas, as you add things to it, they are added on top of what is already there, BUT, you might find it easier to add a JLabel to another JLabel - just remember, JLabel doesn't have a layout manager by default – MadProgrammer
Code example:
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
public class Window extends Thread
{
private static JFrame window = new JFrame("game");
private int numberSquareX = Settings.sizeX / 20 + 1;
private int numberSquareY = Settings.sizeY / 20 + 1;
private JLabel titlesetLayer1[][] = new JLabel[numberSquareX][numberSquareY];
private JLabel titlesetLayer2[] = new JLabel[1];
private JLabel titlesetLayer3[] = new JLabel[1];
private JLabel titlesetLayer4[] = new JLabel[0];
private JLabel titlesetLayer5[] = new JLabel[0];
private JLabel characters[] = new JLabel[2];
public void run()
{
window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
window.setSize(Settings.sizeX, Settings.sizeY);
window.setLocationRelativeTo(null);
window.setResizable(false);
// draw layer5 (on the layer4)
// draw layer4 (on the layer3)
// draw layer3 (on the characters)
titlesetLayer3[0] = new JLabel(new ImageIcon("tree_1.png"));
titlesetLayer3[0].setBounds(130, 120, 126, 160);
window.add(titlesetLayer3[0]);
// draw the charaters
characters[1] = new JLabel(new ImageIcon("character_1.png"));
characters[1].setBounds(600, 500, 100, 100);
window.add(characters[1]);
characters[0] = new JLabel(new ImageIcon("character_1.png"));
characters[0].setBounds(100, 100, 100, 100);
window.add(characters[0]);
// draw layer2 (under the characters)
titlesetLayer2[0] = new JLabel(new ImageIcon("tree_1.png"));
titlesetLayer2[0].setBounds(570, 400, 126, 160);
window.add(titlesetLayer2[0]);
// draw layer1 (under the layer2)
for (int x = 0, y = 0; y < numberSquareY; x++)
{
titlesetLayer1[x][y] = new JLabel(new ImageIcon("grass_1.png"));
titlesetLayer1[x][y].setBounds(x * 20, y * 20, 20, 20);
window.add(titlesetLayer1[x][y]);
if (x == numberSquareX - 1)
{
y++;
x = -1;
}
}
titlesetLayer1[numberSquareX - 1][numberSquareY - 1] = new JLabel(new ImageIcon("grass_1.png"));
titlesetLayer1[numberSquareX - 1][numberSquareY - 1].setBounds(numberSquareX * 20, numberSquareY * 20, 20, 20);
window.add(titlesetLayer1[numberSquareX - 1][numberSquareY - 1]);
window.setVisible(true);
// window.repaint();
}
}
Screen capture:
1
Another solution is to use JLayeredPane!
JLayeredPane layers = new JLayeredPane();
layers.add(tilesetsUnderCharacter, 0); // Layer 0
layers.add(character, 1); // Layer 1
layers.add(tilesetsOnCharacter, 2); // Layer 2
frame.setContentPane(layers);
Code example:
private void init()
{
frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
frame.setSize(Settings.getX(), Settings.getY());
frame.setResizable(false);
frame.setLocationRelativeTo(null);
for (int i = 0; i < y ; i++)
{
for (int j = 0; j < x; j++)
{
for (int k = 0; k < tilesetsOnCharactersSize; k++)
{
tilesetsOnCharacters[i][j][k] = new javax.swing.JLabel(new javax.swing.ImageIcon(Resources.getTileset(Maps.getMapTileset(mapNumber, 1, k, i, j))));
tilesetsOnCharacters[i][j][k].setBounds(j * tilesetX, i * tilesetY, tilesetX, tilesetY);
map.add(tilesetsOnCharacters[i][j][k], 4);
}
for (int k = 0; k < tilesetsUnderCharactersSize; k++)
{
tilesetsUnderCharacters[i][j][k] = new javax.swing.JLabel(new javax.swing.ImageIcon(Resources.getTileset(Maps.getMapTileset(mapNumber, 0, k, i, j))));
tilesetsUnderCharacters[i][j][k].setBounds(j * tilesetX, i * tilesetY, tilesetX, tilesetY);
map.add(tilesetsUnderCharacters[i][j][k], 0);
}
for (int k = 0; k < mapAttributeSize; k++)
{
if (Maps.getMapTileset(mapNumber, 2, k, i, j) == 1)
{
blocked[i][j] = true;
}
}
}
}
for (int i = 0; i < charactersNumber; i++)
{
characters[i] = new Character(0, 0, 64, 64, 0, 0, 0, 0, 5);
tilesetsCharacters[i] = new javax.swing.JLabel(new javax.swing.ImageIcon(Characters.getCharacter(characters[i].getCharacterSkin(), characters[i].getDirection())));
tilesetsCharacters[i].setBounds(characters[i].getX(), characters[i].getY(), characters[i].getSizeX(), characters[i].getSizeY());
map.add(tilesetsCharacters[i], 1);
charactersRender[i] = false;
}
frame.addKeyListener(new java.awt.event.KeyAdapter()
{
#Override
public void keyTyped(java.awt.event.KeyEvent keyEvent)
{
}
#Override
public void keyPressed(java.awt.event.KeyEvent keyEvent)
{
if((keyEventInt = keyEvent.getKeyCode()) == java.awt.event.KeyEvent.VK_F)
{
right = true;
}
else if(keyEventInt == java.awt.event.KeyEvent.VK_S)
{
left = true;
}
else if(keyEventInt == java.awt.event.KeyEvent.VK_E)
{
up = true;
}
else if(keyEventInt == java.awt.event.KeyEvent.VK_D)
{
down = true;
}
}
#Override
public void keyReleased(java.awt.event.KeyEvent keyEvent)
{
if((keyEventInt = keyEvent.getKeyCode()) == java.awt.event.KeyEvent.VK_F)
{
right = false;
}
else if(keyEventInt == java.awt.event.KeyEvent.VK_S)
{
left = false;
}
else if(keyEventInt == java.awt.event.KeyEvent.VK_E)
{
up = false;
}
else if(keyEventInt == java.awt.event.KeyEvent.VK_D)
{
down = false;
}
}
});
frame.setContentPane(map);
frame.setVisible(true);
}
private void update()
{
if (exit && characters[0].getX() < x * tilesetX - characters[0].getSizeX() - characters[0].getMovementSpeed() && characters[0].getX() > 0 && characters[0].getY() > 0 && characters[0].getY() < y * tilesetY - characters[0].getSizeY() - characters[0].getMovementSpeed())
{
exit = false;
}
if (right && (exit || (characters[0].getX() < x * tilesetX - characters[0].getSizeX() - characters[0].getMovementSpeed() && !blocked[characters[0].getY() / tilesetY][(characters[0].getX() + characters[0].getSizeX() + characters[0].getMovementSpeed()) / tilesetX] && !blocked[(characters[0].getY() + characters[0].getSizeY()) / tilesetY][(characters[0].getX() + characters[0].getSizeX() + characters[0].getMovementSpeed()) / tilesetX])))
{
characters[0].right();
characters[0].setScaleX(5);
if (allowExitRight && characters[0].getX() > x * tilesetX - characters[0].getSizeX() - characters[0].getMovementSpeed() - 1)
exit = true;
charactersRender[0] = true;
}
if (left && (exit || (characters[0].getX() > 0 && !blocked[characters[0].getY() / tilesetY][(characters[0].getX() - characters[0].getMovementSpeed()) / tilesetX] && !blocked[(characters[0].getY() + characters[0].getSizeY()) / tilesetY][(characters[0].getX() - characters[0].getMovementSpeed()) / tilesetX])))
{
characters[0].left();
characters[0].setScaleX(-3);
if (allowExitLeft && characters[0].getX() <= 0)
exit = true;
charactersRender[0] = true;
}
if (jumped || up && (exit || (characters[0].getY() > 0 && !blocked[(characters[0].getY() - characters[0].getMovementSpeed()) / tilesetY][characters[0].getX() / tilesetX] && !blocked[(characters[0].getY() - characters[0].getMovementSpeed()) / tilesetY][(characters[0].getX() + characters[0].getSizeX()) / tilesetX])))
{
if (!jump)
{
characters[0].up();
characters[0].setScaleY(-3);
if (allowExitUp && characters[0].getY() <= 0)
exit = true;
charactersRender[0] = true;
}
else if (!jumped && !falling)
{
jumpCurrentDuration = jumpDuration;
jumped = true;
}
else if (--jumpCurrentDuration > 0)
{
if (exit || (characters[0].getY() > 0 && !blocked[(characters[0].getY() - characters[0].getMovementSpeed()) / tilesetY][characters[0].getX() / tilesetX] && !blocked[(characters[0].getY() - characters[0].getMovementSpeed()) / tilesetY][(characters[0].getX() + characters[0].getSizeX()) / tilesetX]))
{
characters[0].up();
characters[0].setScaleY(-3);
if (allowExitUp && characters[0].getY() <= 0)
exit = true;
charactersRender[0] = true;
}
}
else
{
jumped = false;
}
}
if (((down && !jumped) || (gravity && !jumped)) && (exit || (characters[0].getY() < y * tilesetY - characters[0].getSizeY() - characters[0].getMovementSpeed() && !blocked[(characters[0].getY() + characters[0].getSizeY() + characters[0].getMovementSpeed()) / tilesetX][characters[0].getX() / tilesetX] && !blocked[(characters[0].getY() + characters[0].getSizeY() + characters[0].getMovementSpeed()) / tilesetY][(characters[0].getX() + characters[0].getSizeX()) / tilesetX])))
{
characters[0].down();
characters[0].setScaleY(5);
if (allowExitDown && characters[0].getY() > y * tilesetY - characters[0].getSizeY() - characters[0].getMovementSpeed())
exit = true;
if (jump)
falling = true;
charactersRender[0] = true;
}
else if (jump)
falling = false;
}
private void render()
{
for (int i = 0; i < charactersNumber; i++)
{
if (charactersRender[i])
{
tilesetsCharacters[i].setIcon(new javax.swing.ImageIcon(Characters.getCharacter(characters[i].getCharacterSkin(), characters[i].getDirection())));
tilesetsCharacters[i].setBounds(characters[i].getX() + characters[i].getScaleX(), characters[i].getY() + characters[i].getScaleY(), characters[i].getSizeX(), characters[i].getSizeY());
charactersRender[i] = false;
}
}
}
Screen Capture:
Edit: I also found a library called Slick2D who work with TiledMapEditor:
http://slick.ninjacave.com/
http://www.mapeditor.org/
How to setup Slick2D: How to install Slick2d?
How to use Slick2D and TiledMapEditor: Slick2D + Tiled cant load map
Where started: https://thejavablog.wordpress.com/2008/06/08/using-slick-2d-to-write-a-game/

for-each loop in Java for different objects

i created a pacman game with everything in it but the problem is that the ghosts and their animation require a lot of code.
example:
every ghost needs 3 if statements at the moment that is 20 lines of code per ghost and if i have 3 ghosts in the game that is 3 x 20 = 60 lines of useless coding..
with my php experience i would say.. use a foreach loop or something similar.. but how should i do this in Java? can someone give me an example? the way i do it now is published below:
creating ghost objects;
DrawPacMan ghost1 = new DrawPacMan();
DrawPacMan ghost2 = new DrawPacMan();
and the painting goes like:
int g1x = 0;
boolean g1r = true;
public void paintComponent(Graphics g) {
super.paintComponent(g);
// pacman movement
diameter = 75;
pacman.drawPacMan(g, getHorPlaats(), getVerPlaats(), diameter, getView(), Color.yellow);
// ghosts movement
if(g1r == true) {
g1x += ghostSpeed;
}
if(g1r == false) {
g1x -= ghostSpeed;
}
if(g1x == 500 || g1x == 0) {
g1r = !g1r;
}
System.out.println(g1r);
ghost1.drawGhost(g, g1x, 40, diameter, Color.red);
ghost2.drawGhost(g, 170, 70, diameter, Color.blue);
}
It looks to me like you're not approaching this in a object-oriented fashion. Why not use a collection of ghosts eg. List<Ghost> and define a Ghost object with it's location, colour etc?
This line:
ghost1.drawGhost(g, g1x, 40, diameter, Color.red);
would then be replace with
ghost.draw(g);
and you'd iterate through the list, calling draw() for each.
for(Ghost ghost : ghosts) {
ghost.draw(g); // pass in the graphics context
}
Each ghost knows it's location, colour, state etc. and you can create as many as you like:
List<Ghost> ghosts = new ArrayList<Ghost>();
for (int i = 0; i < 10; i++) {
ghosts.add(new Ghost());
}
Since you seem to be new to Java and still getting to know the best idioms, I'll advise on something that is not directly an answer to your question, but is so in a more general sense. Your code
if(g1r == true) {
g1x += ghostSpeed;
}
if(g1r == false) {
g1x -= ghostSpeed;
}
can be rewritten as just
g1x += ghostSpeed * (g1r? 1 : -1);
A general note: never compare booleans to literal values. b == true is the same as just b and b == false is the same as !b.
This code
if (g1x == 500 || g1x == 0) {
g1r = !g1r;
}
will probably result in a bug at runtime as you don't precede it with fencing-in code: g1x can easily step over your limits. You should write instead
if (g1x >= 500) { g1x = 500; g1r = false; }
else if (g1x <= 0) { g1x = 0; g1r = true; }
Pass the ghost object as another parameter in the same function paintComponent(Graphics g, Ghost gr)
You can make the conditional statements inline, e.g. g1r == true ? g1x += ghostSpeed : g1x -= ghostSpeed

Categories

Resources