簡易電卓の実装
以下は、標準入力から2つの整数と演算子を受け取り、四則演算を行うJavaプログラムです。
import java.util.Scanner;
public class SimpleCalculator {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("2つの整数と演算子をスペース区切りで入力してください:");
int num1 = input.nextInt();
String op = input.next();
int num2 = input.nextInt();
switch (op) {
case "+":
System.out.printf("%d + %d = %d%n", num1, num2, add(num1, num2));
break;
case "-":
System.out.printf("%d - %d = %d%n", num1, num2, subtract(num1, num2));
break;
case "*":
System.out.printf("%d * %d = %d%n", num1, num2, multiply(num1, num2));
break;
case "/":
System.out.printf("%d / %d = %d%n", num1, num2, divide(num1, num2));
break;
}
}
}
private static int add(int a, int b) { return a + b; }
private static int subtract(int a, int b) { return a - b; }
private static int multiply(int a, int b) { return a * b; }
private static int divide(int a, int b) { return a / b; }
}
貪欲蛇(スネーク)ゲームの実装
リソースパスの確認
画像リソースの相対パスを確認するためのテストコードです。
import java.net.URL;
public class ResourcePathTest {
public static void main(String[] args) {
URL url = ResourcePathTest.class.getResource("/assets/body.png");
System.out.println("Body image path: " + url);
}
}
画像リソースの管理
ゲームで使用する画像を一元管理するクラスです。
import javax.swing.ImageIcon;
import java.net.URL;
public class GameImages {
public static final ImageIcon HEAD_UP = loadImage("/assets/head_up.png");
public static final ImageIcon HEAD_DOWN = loadImage("/assets/head_down.png");
public static final ImageIcon HEAD_LEFT = loadImage("/assets/head_left.png");
public static final ImageIcon HEAD_RIGHT = loadImage("/assets/head_right.png");
public static final ImageIcon BODY = loadImage("/assets/body.png");
public static final ImageIcon FOOD = loadImage("/assets/food.png");
private static ImageIcon loadImage(String path) {
URL url = GameImages.class.getResource(path);
return new ImageIcon(url);
}
}
メインウィンドウの作成
ゲームのメインフレームを初期化します。
import javax.swing.JFrame;
import java.awt.Toolkit;
public class SnakeGameLauncher {
public static void main(String[] args) {
JFrame window = new JFrame("貪欲蛇ゲーム");
int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
window.setBounds((screenWidth - 800) / 2, (screenHeight - 800) / 2, 800, 800);
window.setResizable(false);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.add(new GameBoard());
window.setVisible(true);
}
}
ゲームボードの描画
ゲームの描画ロジックを含むパネルクラスです。
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
public class GameBoard extends JPanel {
private static final int MAX_SNAKE_LENGTH = 300;
private static final int CELL_SIZE = 25;
private static final int BOARD_WIDTH = 770;
private static final int BOARD_HEIGHT = 685;
private static final int BOARD_X = 10;
private static final int BOARD_Y = 70;
private int[] snakeX = new int[MAX_SNAKE_LENGTH];
private int[] snakeY = new int[MAX_SNAKE_LENGTH];
private int snakeLength = 3;
private String direction = "RIGHT";
private boolean gameRunning = false;
private boolean gameOver = false;
private int foodX, foodY;
private int score = 0;
private Timer gameTimer;
public GameBoard() {
initializeGame();
setFocusable(true);
setupKeyControls();
startGameLoop();
}
private void initializeGame() {
snakeLength = 3;
snakeX[0] = 175; snakeY[0] = 275;
snakeX[1] = 150; snakeY[1] = 275;
snakeX[2] = 125; snakeY[2] = 275;
direction = "RIGHT";
generateFood();
score = 0;
gameOver = false;
}
private void setupKeyControls() {
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
if (gameOver) {
initializeGame();
gameRunning = true;
} else {
gameRunning = !gameRunning;
}
repaint();
} else if (gameRunning && !gameOver) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP: if (!"DOWN".equals(direction)) direction = "UP"; break;
case KeyEvent.VK_DOWN: if (!"UP".equals(direction)) direction = "DOWN"; break;
case KeyEvent.VK_LEFT: if (!"RIGHT".equals(direction)) direction = "LEFT"; break;
case KeyEvent.VK_RIGHT: if (!"LEFT".equals(direction)) direction = "RIGHT"; break;
}
}
}
});
}
private void startGameLoop() {
gameTimer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (gameRunning && !gameOver) {
moveSnake();
checkBoundaryCollision();
checkFoodCollision();
checkSelfCollision();
repaint();
}
}
});
gameTimer.start();
}
private void moveSnake() {
for (int i = snakeLength - 1; i > 0; i--) {
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
switch (direction) {
case "RIGHT": snakeX[0] += CELL_SIZE; break;
case "LEFT": snakeX[0] -= CELL_SIZE; break;
case "UP": snakeY[0] -= CELL_SIZE; break;
case "DOWN": snakeY[0] += CELL_SIZE; break;
}
}
private void checkBoundaryCollision() {
if (snakeX[0] > BOARD_X + BOARD_WIDTH - CELL_SIZE) snakeX[0] = BOARD_X;
if (snakeX[0] < BOARD_X) snakeX[0] = BOARD_X + BOARD_WIDTH - CELL_SIZE;
if (snakeY[0] < BOARD_Y) snakeY[0] = BOARD_Y + BOARD_HEIGHT - CELL_SIZE;
if (snakeY[0] > BOARD_Y + BOARD_HEIGHT - CELL_SIZE) snakeY[0] = BOARD_Y;
}
private void generateFood() {
Random rand = new Random();
foodX = (rand.nextInt(30) + 1) * CELL_SIZE;
foodY = (rand.nextInt(26) + 4) * CELL_SIZE;
}
private void checkFoodCollision() {
if (snakeX[0] == foodX && snakeY[0] == foodY) {
snakeLength++;
score += 10;
generateFood();
}
}
private void checkSelfCollision() {
for (int i = 1; i < snakeLength; i++) {
if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
gameOver = true;
break;
}
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(new Color(246, 240, 120));
drawHeader(g);
drawGameArea(g);
drawSnake(g);
drawFood(g);
drawScore(g);
drawStatusMessages(g);
}
private void drawHeader(Graphics g) {
GameImages.HEAD_RIGHT.paintIcon(this, g, 10, 10);
}
private void drawGameArea(Graphics g) {
g.setColor(new Color(154, 67, 205));
g.fillRect(BOARD_X, BOARD_Y, BOARD_WIDTH, BOARD_HEIGHT);
}
private void drawSnake(Graphics g) {
// Draw head
switch (direction) {
case "UP": GameImages.HEAD_UP.paintIcon(this, g, snakeX[0], snakeY[0]); break;
case "DOWN": GameImages.HEAD_DOWN.paintIcon(this, g, snakeX[0], snakeY[0]); break;
case "LEFT": GameImages.HEAD_LEFT.paintIcon(this, g, snakeX[0], snakeY[0]); break;
case "RIGHT": GameImages.HEAD_RIGHT.paintIcon(this, g, snakeX[0], snakeY[0]); break;
}
// Draw body
for (int i = 1; i < snakeLength; i++) {
GameImages.BODY.paintIcon(this, g, snakeX[i], snakeY[i]);
}
}
private void drawFood(Graphics g) {
GameImages.FOOD.paintIcon(this, g, foodX, foodY);
}
private void drawScore(Graphics g) {
g.setColor(Color.BLACK);
g.setFont(new Font("Meiryo", Font.BOLD, 20));
g.drawString("スコア: " + score, 620, 40);
}
private void drawStatusMessages(Graphics g) {
if (!gameRunning && !gameOver) {
g.setColor(new Color(47, 168, 184));
g.setFont(new Font("Meiryo", Font.BOLD, 40));
g.drawString("スペースキーで開始", 230, 330);
}
if (gameOver) {
g.setColor(new Color(193, 26, 26));
g.setFont(new Font("Meiryo", Font.BOLD, 20));
g.drawString("ゲームオーバー!スペースで再スタート", 180, 330);
}
}
}