Skip to content

Instantly share code, notes, and snippets.

@kishida
Created July 18, 2022 03:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kishida/3745c92e0798942397d9e37b611f8a76 to your computer and use it in GitHub Desktop.
Save kishida/3745c92e0798942397d9e37b611f8a76 to your computer and use it in GitHub Desktop.
Night Bird
//******************************************************************************
// NightBirdFrame.java: JFrame
//
//******************************************************************************
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.Timer;
//==============================================================================
// アプレット NightBird のメインクラス
//
//==============================================================================
public class NightBirdFrame extends JFrame{
public static void main(String[] args) {
new NightBirdFrame().init();
}
//
//--- 鳥の形のデータ ---
//
//胴体
static final double bPolyBodyX[] = {
0, 6, 12, 22, 24, 24, 22, 12, 6};
static final double bPolyBodyY[] = {
0, 4, 4, 1, 4, -4, -1, -4, -4};
//はね
static final double bPolyWingX[] = {
6, 12, 10, 6};
static final double bPolyWingY[] = {
-4, -4, -20, -10};
private static final long serialVersionUID = 1L;
double polyBodyX[] = new double[9];
double polyBodyY[] = new double[9];
double polyLWingX[] = new double[4];
double polyLWingY[] = new double[4];
double polyRWingX[] = new double[4];
double polyRWingY[] = new double[4];
//
//--- 定数 ---
//
static final double pai = 6.283;
static final double eyeY = 100; //視点の高さ
static final double scrZ = 100; //画面の距離
static final int rotMax = 300; //回転の精度
static final int wingMax = 5; //はねの動きの精度
static final double birdY = 40; //鳥の高さ
static final double birdRate = 1.8;//鳥の大きさ
//
//--- 変数 ---
//
transient Image backbuf;
transient Graphics backbufgra; //内部描画バッファ
int m_width, m_height; //画面の大きさ
int centerX, centerY; //画面の中心
double rot;
double eyeX; //視点の座標
int ground[][] = new int[80][80];//地面のつぶつぶ
double birdX; //鳥の位置
int roll; //回転の長さ
int birdmove; //鳥の動き
int wing; //はねの角度
//--------------------------------------------------------------------------
public void init() {
setTitle("Night Bird");
setSize(600, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
m_width = getSize().width;
m_height = getSize().height;
centerX = m_width / 2;
centerY = m_height / 2;
rot = rotMax / 8;
//内部描画バッファの用意
if (backbuf == null) {
backbuf = new BufferedImage(m_width, m_height, BufferedImage.TYPE_INT_RGB);
backbufgra = backbuf.getGraphics();
}
//地面
for (int i = 0; i < 80; i++) {
for (int j = 0; j < 80; j++) {
if (Math.random() > .99) {
ground[i][j] = 1;
} else {
ground[i][j] = 0;
}
}
}
//鳥のデータ
for (int i = 0; i < 9; i++) {
polyBodyX[i] = bPolyBodyX[i] * birdRate;
polyBodyY[i] = bPolyBodyY[i] * birdRate;
}
for (int i = 0; i < 4; i++) {
polyLWingX[i] = bPolyWingX[i] * birdRate;
polyLWingY[i] = bPolyWingY[i] * birdRate;
polyRWingX[i] = polyLWingX[i];
polyRWingY[i] = -polyLWingY[i];
}
new Timer(50, ev -> {
draw();
}).start();
setVisible(true);
}
// NightBird 描画ハンドラ
//--------------------------------------------------------------------------
@Override
public void paint(Graphics g) {
g.drawImage(backbuf, 0, 0, this);
}
//描画
//----------------------------------------------------------------------------
public void draw() {
double co, si;
//前に進む
eyeX += 4;
while (eyeX > 80) {
eyeX -= 80;
}
//視点の回転
if (roll > 0) {
//回転中
rot++;
if (rot >= rotMax) {
rot = 0;
}
roll--;
} else {
if (Math.random() > .98) {
//回転開始
roll = (int) (Math.random() * 20) + 10;
}
}
if (birdmove == 0) {
//鳥がはばたいているとき
wing++;
if (wing >= wingMax) {
wing = 0;
//後ろに下がるかどうか判定
if (Math.random() > .92) {
birdmove = (int) (Math.random() * 15) + 10;
}
}
if (birdX < 0) {
birdX += 1;
}
} else {
//鳥が後ろに下がっているとき
birdmove--;
birdX -= 1;
}
//
//--- 画面描画 ---
//
//画面のクリア
backbufgra.setColor(Color.black);
backbufgra.fillRect(0, 0, m_width, m_height);
//地面の描画
backbufgra.setColor(Color.yellow);
co = Math.cos(Math.PI * 2 * rot / rotMax);
si = Math.sin(Math.PI * 2 * rot / rotMax);
for (int y = centerY + 20; y < m_height; y++) {
double dispx, dispy;
double groundx, groundz;
double matx, matz;
int meshx, meshz;
dispy = centerY - y;
groundz = -eyeY * scrZ / dispy;
if (groundz > 250) {
continue;
}
for (int x = 0; x < m_width; x++) {
dispx = x - centerX;
groundx = (dispx * groundz / scrZ);
matz = (groundx * co + (groundz - scrZ) * si + scrZ) / 4;
while (matz < 0) {
matz += 80;
}
meshz = (int) matz % 80;
matx = (-groundx * si + groundz * co) / 4 + eyeX;
while (matx < 0) {
matx += 80;
}
meshx = (int) matx % 80;
if (ground[meshx][meshz] == 1) {
//backbufgra.drawRect(x,y,1,1);
backbufgra.drawLine(x, y, x, y);
}
}
}
//鳥の描画
backbufgra.setColor(new Color(192, 192, 192));
int polyX[] = new int[10];
int polyY[] = new int[10];
double bx, by, bz;
double px, py, pz;
double ax, ay, az;//計算用
double wco, wsi;
double wpi;//はねの角度
double bodyY;//胴体の位置
//はねの角度の計算
wpi = pai * (.22 * Math.sin(pai * wing / wingMax) + .25);
wsi = Math.sin(wpi);
wco = Math.cos(wpi);
//鳥の上下運動
bodyY = -wco * 2;
//胴体
for (int i = 0; i < 9; i++) {
bx = -polyBodyX[i] + birdX;
bz = polyBodyY[i];
px = -bx * si + bz * co;
pz = bx * co + bz * si;
polyX[i] = (int) (px * scrZ / (scrZ + pz)) + centerX;
polyY[i] = -(int) ((birdY + bodyY) * scrZ / (scrZ + pz)) + centerY;
}
backbufgra.fillPolygon(polyX, polyY, 9);
//右の翼
for (int i = 0; i < 4; i++) {
bx = -polyRWingX[i] + birdX;
bz = polyRWingY[i];
az = bz - polyRWingY[0];
ay = 0;
bz = wsi * az + polyRWingY[0];
by = wco * az;
px = -bx * si + bz * co;
pz = bx * co + bz * si;
polyX[i] = (int) (px * scrZ / (scrZ + pz)) + centerX;
polyY[i] = -(int) ((birdY + by + bodyY) * scrZ / (scrZ + pz)) + centerY;
}
backbufgra.fillPolygon(polyX, polyY, 4);
//左の翼
for (int i = 0; i < 4; i++) {
bx = -polyLWingX[i] + birdX;
bz = polyLWingY[i];
az = bz - polyLWingY[0];
ay = 0;
bz = wsi * az + polyLWingY[0];
by = -wco * az;
px = -bx * si + bz * co;
pz = bx * co + bz * si;
polyX[i] = (int) (px * scrZ / (scrZ + pz)) + centerX;
polyY[i] = -(int) ((birdY + by + bodyY) * scrZ / (scrZ + pz)) + centerY;
}
backbufgra.fillPolygon(polyX, polyY, 4);
repaint();
}
}
@kishida
Copy link
Author

kishida commented Jul 18, 2022

bandicam.2022-07-18.12-55-21-833nightbird.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment