[JAVA] Unit catcher made by Processing

This article is a reorganization of the materials presented in the circle when I was a student. I plan to fix it from time to time

Advance preparation

Installation of Processing

Download from Official Site

Download image data

Borrowed from Irasutoya, change the image name to the following

What is a unit catcher?

A devilish web game developed by a friend when he was a student, where chimpanzees desperately take credits

1.png

You can play from the following site

https://ukya.tk/

What is Processing?

Open source graphics development environment and programming language

Strengths

--Simple and easy to understand in Java-based language --Light movement --Simple project structure --Easy to output to an executable file

weakness

--Not suitable for large-scale development due to development restrictions

Hello World

//Run only once
void setup() {
  //Create a 1280x720 screen
  size(1280, 720);
  //Displayed on the console screen
  println("Hello, World");
  //Displayed on the execution screen
  text("Hello, World", 100, 100);
}

Basic

Draw a line

void setup() {
  size(1280, 720);
  // (X, Y) = (0, 0)From
  // (X, Y) = (300, 300)Draw a line up to
  line(0, 0, 300, 300);
}

Draw an ellipse

void setup() {
  size(1280, 720);
  // (X, Y) = (80, 200)To
  //Width 50px,Create a circle with a height of 80px
  ellipse(80, 200, 50, 80);
}

Draw background

void setup() {
  size(1280, 720);
  //0 (black) to 255 (white)
  background(0);
}

Color

void setup() {
  size(1280, 720);
  // R, G, B
  background(240, 180, 200);
  // R, G, B,A (transparency)
  background(240, 180, 200, 75);
}

animation

Basic drawing frequency is 60fps

//Execute 60 times per second (update)
void draw() {
  //...
}

Draw a perfect circle that follows the mouse

A circle is drawn every frame

void setup() {
  size(1280, 720);
}

void draw() {
  ellipse(mouseX, mouseY, 50, 50);
}

Erase the drawing of the previous frame with the background fill

void setup() {
  size(1280, 720);
}

void draw() {
  background(255);
  ellipse(mouseX, mouseY, 50, 50);
}

variable

//Prepare a variable that can contain an integer
int number = 10;
//Change the value (only integers can be assigned)
number = -50;
//Code that increments the value of a variable by 1
number = number + 1;
number += 1;
number++;

Variable type

float   //Floating point
boolean //Boolean value
String  //String
PImage  //Image data (Processing original)

Moving circle

//Variable declaration
int positionX;

void setup() {
  //Variable initialization
  positionX = 0;

  size(500, 500);
}

void draw() {
  //The value increases by 1 for each frame
  positionX += 2;
  
  background(255);
  //Use variables instead of numbers
  ellipse(positionX, 100, 50, 50);
}

Conditional branch

int positionX;
//Whether to move to the left
boolean leftMove;

void setup() {
  positionX = 0;
  size(500, 500);
  leftMove = false;
}

void draw() {
  //Change the value calculation by moving to the right
  if (leftMove == false) {
    positionX += 2;
  } else {
    positionX -= 2;
  }
  
  //Move to the left when it exceeds 500
  if (500 < positionX) {
    leftMove = true;
  }

  background(255);
  ellipse(positionX, 100, 50, 50);
}

Conditional branch

Value evaluation notes

a == b // 「=Note that if there is only one, it will be an assignment.
a <= b //Greater equal. "=Is right

Multiple evaluation

S && T             //S and T
S || T             //S or T
(a < b) && (b < c) // a < b <Synonymous with c

Conditional branch of the same value

if / else statement

if (number == 0) {
  // ...
} else if (number == 1) {
  // ...
} else {
  // ...
}

switch statement

switch (number) {
  case: 0 {
    // ...
    break; //Be careful not to forget to put it on!
  }
  case: 1 {
    // ...
    break;
  }
  default: {
    // ....
  }
}

The for statement is not used this time, so it is omitted.

Let's make a game

Put image data

Put the image in (project file) / data

2.png

How to load an image

PImage image = loadImage(file name);

Change the display size of the image

image.resize(width,height);

Screen generation & background setting

//Prepare variables for images
PImage backgroundImage;

void setup() {
  //Start in performance-oriented P2D mode
  size(1280, 720, P2D);
  //Read image data
  backgroundImage = loadImage("school.jpg ");
  //Processed to the same size as the screen size
  backgroundImage.resize(width, height);
}

void draw() {
  //Draw background
  background(backgroundImage);
}

width / height is the width / height of the execution screen, Same as the value specified by size ()

Arrangement of player images

/**Add the following*/
PImage playerImage;

void setup() {
  /**Add the following*/
  playerImage = loadImage("chimpanzee.png ");
  playerImage.resize(200, 200);
}

void draw() {
  /**Add the following*/
  //PImage to display,X coordinate,Y coordinate
  image(playerImage, 640, 520);
}

Allow horizontal movement with the mouse

void draw() {
  // image(playerImage, 640, 520);
  /**Changed the above to below*/
  image(playerImage, mouseX, 520);
}

Change the reference point of the coordinates of image drawing to the center point

void setup() {
  /**Add the following*/
  imageMode(CENTER);
}

3.png

Installation of units

/**Add the following*/
PImage tanniImage;

void setup() {
  /**Add the following*/
  tanniImage = loadImage("tanni.png ");
  tanniImage.resize(100, 100);
}

void draw() {
  /**Add the following*/
  image(tanniImage, 600, 300);
}

Drop the unit

/**Add the following*/
float tanniY;

void setup() {
  /**Add the following*/
  //If it is 0, it will stick out(Image vertical size/ 2)Installed on
  tanniY = -50;
}

void draw() {
  /**Add the following*/
  //Move down 8px every frame
  tanniY += 8;

  // image(tanniImage, 600, 300);
  /**Changed the above to below*/
  image(tanniImage, 600, tanniY);
}

Reappear the unit

void draw() {
  /**Add the following*/
  //When the image disappears from the screen
  if (height < tanniY - 50) {
    //Substitute the initial value
    tanniY = -50;
  }
}

Randomize the appearance position

Random number generation method

random(100);        //Float value between 0 and 100
random(-40.5, 10);  // -40.Float value between 5 and 10

Randomize the appearance position every time

/**Add the following*/
float tanniX;

void setup() {
  /**Add the following*/
  //Specify the range so that the image is not hidden
  tanniX = random(50, width - 50);
}

void draw() {
  // image(tanniImage, 600, tanniY);
  /**Changed the above to below*/
  image(tanniImage, tanniX, tanniY);

  if (height < tanniY - 50) {
    tanniY = -50;
    /**Add the following*/
    tanniX = random(50, width - 50);
  }
}

Collision detection with player

A method to calculate the distance between two coordinates

dist(A x coordinate,A y coordinate,B x coordinate,B y coordinate)

Abbreviation for distance

Make a collision detection with the player

void draw() {
  /**Add the following*/
  //Judgment distance set to 80 pixels
  if (dist(mouseX, 520, tanniX, tanniY) < 80) {
    tanniY = -50;
    tanniX = random(50, width - 50);
  }
}

Add score function

/**Add the following*/
//0 is set if nothing is specified
int score;

void draw() {
  if (dist(mouseX, 520, tanniX, tanniY) < 80) {
    tanniY = -50;
    tanniX = random(50, width - 50);
    /**Add the following*/
    score++;
    println("score: " + score);     
  }
}

The score is displayed on the console

Display the score on the execution screen

void setup() {
  /**Add the following*/
  //Fill in black
  fill(0);
  //Specify the font size
  textSize(50);
  //Set the reference point of the character in the upper right
  textAlign(RIGHT, TOP);
}

void draw() {
  if (dist(mouseX, 520, tanniX, tanniY) < 80) {
    tanniY = -50;
    tanniX = random(50, width - 50);
    score++;
    /**Deleted below*/
    // println("score: " + score);     
  }
  /**Add the following*/
  text("score: " + score, width, 0);
}

Let's put together the same code

Added the following methods

/**Add the following*/
void resetTanni() {
  tanniY = -50;
  tanniX = random(50, width - 50);
}

Replace the following three codings with methods

  tanniY = -50;
  tanniX = random(50, width - 50);
  /**Changed the above to below*/
  resetTanni();

Let's make a title screen and a result screen

Manage which screen you are in by putting it in a variable

/**Add the following*/
int state;

state is managed as follows

state == 0 // =>title screen
state == 1 // =>Game screen
state == 2 // =>Result screen

Creating a function called each state

/**Add the following*/

void titleScene() {
  
}

void gameScene() {
  
}

void resultScene() {
  
}

Move some processing to gameScene ()

void setup() {
  /**Deleted below*/
  textSize(50);
  textAlign(RIGHT, TOP);  
}

void draw() {
  background(backgroundImage);
  /**Delete all of the following*/
  tanniY += 8;
  image(playerImage, mouseX, 520); 
  //(Omitted below)
}

void gameScene() {
  /**Add the following*/
  textSize(50);
  textAlign(RIGHT, TOP);  
  tanniY += 8;
  image(playerImage, mouseX, 520); 
}

Display characters in each scene

void titleScene() {
  textSize(70);
  //Set the coordinate reference point to the center of the text
  textAlign(CENTER, CENTER);
  //Draw text in the center of the screen
  text("Title Scene", width / 2, height / 2);
}

void resultScene() {
  textSize(70);
  textAlign(CENTER, CENTER);
  text("Result Scene", width / 2, height / 2);
}

Q. Are there any Japanese bugs?

A. Fonts need to be loaded

void setup() {
  /**Add the following*/
  //Generate and load Arial font of size 50
  textFont(createFont("Arial", 50));
}

Branch by the value of the state variable

void draw() {
  /**Add the following*/
  //Be careful not to forget to put a break
  switch(state) {
    case 0:
      titleScene();
      break;
    case 1:
      gameScene();
      break;
    case 2:
      resultScene();
      break;
  }
}

Since the initial value of state is 0, the title screen is displayed when starting

Keyboard judgment

Is the key pressed

isPressed()

Comparison of entered character keys

//Please note that the following two are treated differently
key == 'a'
key == 'A'

Comparison of entered modifier keys

keyCode == ENTER
keyCode == SHIFT

Title screen-> Game screen

Press Enter to proceed

void titleScene() {
  /**Add the following*/
  //Display below the title in small letters
  textSize(30);
  text("ENTER to Start", width / 2, height / 2 + 80);
  //Change the value when the pressed key is the ENTER key
  if (keyCode == ENTER) {
    state = 1;
  }
}

Game screen-> Result screen

Proceed after getting 10 credits

void gameScene() {
  /**Add the following*/
  //Let's do ≤ in case the score increases by 2 at one time
  if (10 <= score) {
    state = 2;
  }
}

Result screen

Enter key to exit the game screen, ESC key to exit

void resultScene() {
  /**Add the following*/
  textSize(30);
  text("ENTER to play again / ESC to exit", width / 2, height / 2 + 80);
  //Change the value when the pressed key is the ENTER key
  if (keyCode == ENTER) {
    //Reset score
    score = 0;
    state = 1;
  } else if (keyCode == ESC) {
    //End the game
    exit();
  }
}

Note that if you do not reset the score, it will loop.

Let's export the executable file

"File" / "Export as application"

Summary

You can make simple games using Processing

If you want to expand further from here ...

--Set a time limit --Drop multiple units --Make compulsory credits that cannot be dropped

etc…

Looking back

Processing was the first programming language I worked on properly, but I thought it was a good programming language to learn happily because it wraps Java, so it's linguistically friendly, and above all, you can quickly create graphical apps. ..

Recommended Posts

Unit catcher made by Processing
Presentation slides made with Processing