Main.java
public class Main {
public static void main(String args[]) {
new Frame();
} }
BaseObj.java
/**
* ベースオブジェクト オブジェクトはタスクなどとも呼びます。
* ここからキャラクタ用のオブジェクトに派生します。
*/
public abstract class BaseObj { //各方向
protected final int DOWN = 0;
protected final int LEFT = 1;
protected final int UP = 2;
protected final int RIGHT = 3;
DrawManager m_Draw;
//キャラクタ方向
public int m_Dir;
//キャラクタ位置 マップ上 public int m_Px;
public int m_Py;
//キャラクタ移動量
public float m_AddPx;
public float m_AddPy;
protected int m_MoveX;
protected int m_MoveY;
protected int m_Animcnt;
protected int m_Anim;
BaseObj() {
}
BaseObj(int x,int y,int sizeX,int sizeY) { //キャラデータ
m_Dir = DOWN;
m_Px = x;
m_Py = y;
m_AddPx = 0;
m_AddPy = 0;
m_Draw = new DrawManager(m_Px*32,m_Py*32,sizeX,sizeY,-1);
} /*
* オブジェクトの動作 */
void exe() {
//移動処理 moveChara();
//描画座標作成
m_Draw.m_DrawX = (int) (m_Px * 32 + m_AddPx);
m_Draw.m_DrawY = (int) (m_Py * 32 + m_AddPy);
m_Animcnt += 1;
if(m_Animcnt > 5) { m_Animcnt = 0;
m_Anim ^= 1;
}
//各派生先で個別の処理を埋めていく }
/*
* 一マス移動処理 */
protected void moveChara() {
if(m_MoveX != 0){
m_AddPx += m_MoveX;
if(m_AddPx < -32){
m_MoveX = 0;
m_AddPx = 0;
m_Px --;
}else if(m_AddPx > 32){
m_MoveX = 0;
m_AddPx = 0;
m_Px ++;
}
}else if(m_MoveY != 0){
m_AddPy += m_MoveY;
if(m_AddPy < -32){
m_MoveY = 0;
m_AddPy = 0;
m_Py --;
}else if(m_AddPy > 32){
m_MoveY = 0;
m_AddPy = 0;
m_Py ++;
} }
} }
DrawManager.java
public class DrawManager { //キャラクタ座標
public int m_DrawX;
public int m_DrawY;
//キャラクタサイズ
public int m_SizeX;
public int m_SizeY;
//キャラクタIMAGEID
//キャラクタを描画する際にはこの値を使って描画する public int m_ImgId;
/**
* @param px * @param py * @param dir * @param sizeX * @param sizeY * @param imgId */
public DrawManager(int px, int py, int sizeX, int sizeY, int imgId) { m_DrawX = px;
m_DrawY = py;
m_SizeX = sizeX;
m_SizeY = sizeY;
m_ImgId = imgId;
} }
E neObj.java
/**
* 敵のオブジェクト
* BaseObjを継承して作成する */
public class EneObj extends BaseObj {
/*
* 初期化処理 * 基本的には値の代入 */
EneObj(int x,int y,int sizeX,int sizeY) { super(x, y, sizeY, sizeY);
}
/*
* キャラクタが行うメイン処理 */
public void exe() {
super.exe();
//描画ID変更
m_Draw.m_ImgId = 2 + (m_Dir * 4) + m_Anim;
} /*
* 敵AI処理
* とりあえず壁にぶつかったらランダムで方向変更 */
private int thinkAi() {
if(m_Dir == UP && Map.getMap(m_Px,m_Py-1) == Map.MAP_WALL) return (int) (Math.random()*4);
else if(m_Dir == DOWN && Map.getMap(m_Px,m_Py+1) == Map.MAP_WALL) return (int) (Math.random()*4);
else if(m_Dir == LEFT && Map.getMap(m_Px-1,m_Py) == Map.MAP_WALL) return (int) (Math.random()*4);
else if(m_Dir == RIGHT && Map.getMap(m_Px+1,m_Py) == Map.MAP_WALL) return (int) (Math.random()*4);
return m_Dir;
} /*
* 移動方向決定 *
*/
public void emuMove() {
int mapdata;
int speed = 4;
//マスに収まっているときだけ方向転換 if(m_MoveX == 0 && m_MoveY == 0){
//移動ルーチン ここを切り替えることでパターン変更可能 m_Dir = thinkAi();
if(m_Dir == UP && Map.getMap(m_Px,m_Py-1) == Map.MAP_WAY) m_MoveY = -speed;
else if(m_Dir == DOWN && Map.getMap(m_Px,m_Py+1) == Map.MAP_WAY) m_MoveY = speed;
else if(m_Dir == LEFT && Map.getMap(m_Px-1,m_Py) == Map.MAP_WAY) m_MoveX = -speed;
else if(m_Dir == RIGHT && Map.getMap(m_Px+1,m_Py) == Map.MAP_WAY) m_MoveX = speed;
} } }
Frame.java
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class Frame extends JFrame { public Frame()
{
setTitle("おにごっこ? created by nagi");
getContentPane().add(new View());
setVisible(true);
//
Insets insets = this.getInsets();
setSize(11*32 + insets.left + insets.right,11*32 + insets.top + insets.bottom);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
} }
JadgeObj.java
/*
* 当たり判定等を制御する */
public class JadgeObj extends BaseObj{
boolean m_GameClear;
/*
* 初期化処理 * 基本的には値の代入 */
JadgeObj(int x,int y,int sizeX,int sizeY) { //描画属性設定
m_Draw = new DrawManager(x*32,y*32,sizeX,sizeY,-1);
//クリアフラグ 設定 m_GameClear = false;
} /*
* キャラクタが行うメイン処理 */
public void exe() {
//描画ID変更 if(m_GameClear){
m_Draw.m_ImgId = 16;
}else{
m_Draw.m_ImgId = -1;
}
} /*
* 当たり判定チェック */
public boolean checkObj(DrawManager ply,DrawManager enemy) {
if( ply.m_DrawX < enemy.m_DrawX + enemy.m_SizeX &&
enemy.m_DrawX < ply.m_DrawX + ply.m_SizeX &&
ply.m_DrawY < enemy.m_DrawY + enemy.m_SizeY &&
enemy.m_DrawY < ply.m_DrawY + ply.m_SizeX ){
return true;
}else{
return false;
} } /*
* クリアの判定 */
public void checkClear(BaseObj task[]) {
//メインタスクから敵のオブジェクトを探す for(int i = 0 ; i < task.length ; i ++ ){
if(task[i] instanceof EneObj){
//一体でも敵が居れば未クリアとして考える。
m_GameClear = false;
return;
} }
//すべて捕まえた = 敵のオブジェクトが無いならクリア m_GameClear = true;
} }
Map.java
import java.awt.Graphics;
import java.awt.Image;
public class Map {
static final int MAP_X = 11;
static final int MAP_Y = 11;
static final int MAP_WALL = 1;
static final int MAP_WAY = 0;
static int m_MapData[][] = {
{1,1,1,1,1, 1,1,1,1,1,1,}, {1,0,0,0,0, 1,0,0,0,0,1,}, {1,0,1,0,1, 0,0,1,1,0,1,}, {1,1,0,0,0, 0,1,0,0,0,1,}, {1,0,0,1,1, 0,1,0,1,1,1,}, {1,0,1,0,0, 0,1,0,0,0,1,}, {1,0,1,0,1, 1,0,0,1,0,1,}, {1,0,1,0,1, 0,1,0,1,0,1,}, {1,0,1,0,1, 0,1,0,1,0,1,}, {1,0,0,0,1, 0,0,0,0,0,1,},
{1,1,1,1,1, 1,1,1,1,1,1,}, };
/*
* 各キャラクタ移動の際のチェックに使用する */
static int getMap(int x,int y){
return m_MapData[y][x];
} /*
* マップの描画
* ここではGraphicsオブジェクトとImageオブジェクトを受け取って描画する */
public void drawMap(Graphics g,Image img) {
for(int y = 0 ; y < MAP_Y ; y++){
for(int x = 0 ;x < MAP_X ; x++){
g.drawImage(img,x * 32, y * 32,x * 32 + 32, y * 32 + 32,
m_MapData[y][x] * 32,0,m_MapData[y][x] * 32 + 32 ,32 , null);
} }
} }
PlyObj.java
/**
* プレイヤーのオブジェクト * BaseObjを継承して作成する */
public class PlyObj extends BaseObj {
/*
* プレイヤーの初期化処理 * 基本的には値の代入 */
PlyObj(int x,int y,int sizeX,int sizeY) { super(x, y, sizeY, sizeY);
} /*
* キャラクタが行うメイン処理 */
public void exe() {
super.exe();
//描画ID変更
m_Draw.m_ImgId = (m_Dir * 4) + m_Anim;
}
//移動速度 //可変
private int SPEED = 8;
/**
* 移動セット */
public void moveSetDown() {
if(Map.getMap(m_Px,m_Py + 1) == Map.MAP_WAY){
if(m_MoveX == 0){
m_MoveY = SPEED;
m_Dir = DOWN;
} }
} /**
* */
public void moveSetUp() {
if(Map.getMap(m_Px,m_Py - 1) == Map.MAP_WAY){
if(m_MoveX == 0){
m_MoveY = -SPEED;
m_Dir = UP;
} }
} /**
* */
public void moveSetLeft() {
if(Map.getMap(m_Px -1 ,m_Py) == Map.MAP_WAY){
if(m_MoveY == 0){
m_MoveX = -SPEED;
m_Dir = LEFT;
} }
} /**
* */
public void moveSetRight() {
if(Map.getMap(m_Px + 1,m_Py) == Map.MAP_WAY){
if(m_MoveY == 0){
m_MoveX = SPEED;
m_Dir = RIGHT;
} }
} }
View.java
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.Timer;
public class View extends JComponent implements ActionListener,KeyListener{
// private Timer m_Timer=new Timer(1000/60, this);
private Timer m_Timer=new Timer(1000/30, this);
private int m_X=0;
//メインタスク
private BaseObj m_Task[] = { new PlyObj(1,1,32,32), new EneObj(9,9,32,32), new EneObj(1,9,32,32), new EneObj(9,1,32,32), new JadgeObj(2,4,96,32), };
private Map map = new Map();
//使用画像データ
private Image m_MainImg = null,m_BackImg = null;
//画像データロード
private void loadGraphicsData(){
try {
m_MainImg = ImageIO.read(getClass().getResource( "main.png"));
m_BackImg = ImageIO.read(getClass().getResource( "map.png"));
} catch (IOException e) {
JOptionPane.showMessageDialog(this,
"画像データが読み込めませんでした。プログラムを終了しま す\n"+e.getMessage());
System.exit(0);
} /*
//JARファイルではロードできない File f;
try {
f = new File("res\\main.png");
m_MainImg = (Image)ImageIO.read(f);
f = new File("res\\map.gif");
m_BackImg = (Image)ImageIO.read(f);
} catch (IOException e) {
JOptionPane.showMessageDialog(this,
"画像データが読み込めませんでした。プログラムを終了しま す\n"+e.getMessage());
System.exit(0);
}
*/
} /*
* ゲーム起動時の初期化処理 */
public View() {
//画像データの読み込み loadGraphicsData();
//キー初期化
this.addKeyListener(this);
setFocusable(true);
requestFocusInWindow();
//ダブルバッファOn
setDoubleBuffered(true);
//メインスレッド起動 m_Timer.start();
}
/*
* ゲーム内の更新を行う
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */
PlyObj ply = null;
JadgeObj jadge = null;
private void update() {
//配列に登録されている全オブジェクト処理 for(int i = 0 ; i < m_Task.length ; i ++){
if(m_Task[i] != null){
//移動等処理 m_Task[i].exe();
//各キャラクタ固有処理 //プレイヤーキャラ
if(m_Task[i] instanceof PlyObj) {
//当たり判定用
ply = (PlyObj)m_Task[i];
//キー入力による移動処理 controlKey(ply);
}
//敵キャラ
else if(m_Task[i] instanceof EneObj) {
//敵移動処理
((EneObj)m_Task[i]).emuMove();
//あたり判定
//ジャッジのオブジェクトが取得できていないこともあるので //null判定
if(jadge != null){
if(jadge.checkObj(ply.m_Draw,m_Task[i].m_Draw)){
//あたっていれば配列から消す。
m_Task[i] = null;
} }
} //
else if(m_Task[i] instanceof JadgeObj){
jadge = (JadgeObj)m_Task[i];
//終了チェック
jadge.checkClear(m_Task);
} }
} } /*
* メインループトリガー */
public void actionPerformed(ActionEvent arg0) { //ゲーム内更新
update();
//paintComponent呼び出し要求 repaint();
} /*
* オブジェクトすべての描画 */
private void drawTaskObject(Graphics g,int i){
//各オブジェクトから描画属性取得
DrawManager draw = m_Task[i].m_Draw;
//ImgIDが-1は描画無し if(draw.m_ImgId != -1){
g.drawImage(m_MainImg,(int)draw.m_DrawX,(int)draw.m_DrawY,
(int)draw.m_DrawX+draw.m_SizeX,(int)draw.m_DrawY+draw.m_SizeY, draw.m_ImgId%4*32,draw.m_ImgId/4*32,
draw.m_ImgId%4*32+draw.m_SizeX, draw.m_ImgId/4*32+draw.m_SizeY,this);
} } /*
* キー処理関連 */
private void controlKey(PlyObj ply){
if(m_KeyTable[UP]){
ply.moveSetUp();
}
if(m_KeyTable[DOWN]){
ply.moveSetDown();
}
if(m_KeyTable[LEFT]){
ply.moveSetLeft();
}
if(m_KeyTable[RIGHT]){
ply.moveSetRight();
} } /*
* paint ハンドラ
* ゲームの処理はここに記述 */
public void paintComponent(Graphics aGraphics) {
//背景マップの描画
map.drawMap(aGraphics,m_BackImg);
//配列に登録されている全オブジェクト処理 for(int i = 0 ; i < m_Task.length ; i ++){
if(m_Task[i] != null){
//描画処理
drawTaskObject(aGraphics,i);
} }
} /*
* キー状態チェック */
final int ENTER = 0;
final int UP = 1;
final int DOWN = 2;
final int LEFT = 3;
final int RIGHT = 4;
final int SPACE = 5;
boolean m_KeyTable[] = new boolean[6];
public void keyTyped(KeyEvent arg0) {}
public void keyPressed(KeyEvent arg0) { int useKeyList[]={
KeyEvent.VK_ENTER,
KeyEvent.VK_UP, KeyEvent.VK_DOWN, KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT, KeyEvent.VK_SPACE, };
int key = arg0.getKeyCode();
for(int k = 0; k < useKeyList.length ; k++){
if(key == useKeyList[k]){
m_KeyTable[k] = true;
} }
}
public void keyReleased(KeyEvent arg0) { int key = arg0.getKeyCode();
int useKeyList[]={
KeyEvent.VK_ENTER, KeyEvent.VK_UP, KeyEvent.VK_DOWN, KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT, KeyEvent.VK_SPACE, };
for(int k = 0; k < useKeyList.length ; k++){
if(key == useKeyList[k]){
m_KeyTable[k] = false;
} }
} }
Dot E ater Dot E ater
@DARL_Japan
遊び 方
迷路の中を敵から逃げながらドット(点)をすべて取って行きます。
すべてのドットを取ったらゲームクリアです。
打ち込む 環境
•
.Net Framekwork SDK 3.5 以上•
XNA Game Studio 4.0 以上•
Visual C# Express 2010 以上打ち込み方
Visual C#で「Windows ゲーム (4.0)」を新規作成します。ゲーム名は
「DotEater」にします。
あとは「ソリューションエクスプローラ」の DotEater プロジェクトを右クリックして
「追加->クラス」として作っていきます。ファイル名は.cs までを指定します
(PlayerObj.cs,DrawObj.cs など)。なお、ソリューション名を正しくつけている限り、
Program.cs は変更の必要はありません。
書いたグラフィックは、DotEater Content プロジェクトにファイルを「追加->既存 の項目の追加」として追加してください。
リソース
Byakko.PNG(32 x 32)
Dot.PNG(8 x 8)
GameOver.PNG(424 x 64)
Genbu.PNG(64 x 64)
Player.PNG(16 x 32)
R ock.PNG(64 x 64)
Seiryu.PNG(20 x 64)
Su z aku.PNG(64 x 64)
T itle.PNG(424 x 64)
C lear.PNG(2 5 6 x 64)
ソース
Program.cs
using System;
namespace DotEater {
#if WINDOWS || XBOX static class Program {
/// <summary>
/// アプリケーションのメイン エントリー ポイントです。
/// </summary>
static void Main(string[] args) {
using (Game1 game = new Game1()) {
game.Run();
} } }
#endif }
PlayerObj.cs
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace DotEater {
class PlayerObj : DrawObj {
public Vector2 AtkPos {
get { return Pos + Vector2.Transform(new Vector2(0, -8), Matrix.CreateRotationZ(Rotate)); }
}
public float AtkRad {
get { return 8; } }
public PlayerObj(Game1 game)
: base(game, "Player", Vector2.Zero) {
}
public override void Init() {
Rotate = 0;
base.Init();
}
public override void Update() {
var idx = PlayerIndex.One;
var pad = GamePad.GetState(idx).DPad;
var kb = Keyboard.GetState(idx);
var move = Vector2.Zero;
if (pad.Left == ButtonState.Pressed || kb.IsKeyDown(Keys.Left)) move.X--;
else if (pad.Right == ButtonState.Pressed || kb.IsKeyDown(Keys.Right)) move.X++;
if (pad.Up == ButtonState.Pressed || kb.IsKeyDown(Keys.Up)) move.Y--;
else if (pad.Down == ButtonState.Pressed || kb.IsKeyDown(Keys.Down)) move.Y++;
if (move != Vector2.Zero)
Rotate = (float)Math.Atan2(-move.Y, -move.X) - MathHelper.PiOver2;
Vector2 pos = new Vector2(Pos.X + move.X, Pos.Y + move.Y);
if (Game.IsMove(new Rectangle(
(int)pos.X - Rect.Height / 2,
(int)pos.Y - Rect.Height / 2, Rect.Height, Rect.Height), false))
Pos = pos;
} } }
Game1.cs
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace DotEater {
public enum Mode {
Title, Game, Clear, Over, }
struct Dot {
public bool dead;
public int x, y;
}
public class Game1 : Game {
GraphicsDeviceManager graphics;
public static int ScrWidth { get; set; } public static int ScrHeight { get; set; } SpriteBatch SB { get; set; }
public Random Rand { get; set; } bool prevA = true;
bool prevSpc = true;
Mode mode;
DrawObj title;
PlayerObj player;
public Vector2 PlayerPos { get { return player.Pos; } } BossObj[] bosses = new BossObj[4];
BossObj boss;
const int dotCnt = 50;
Dot[] dot = new Dot[dotCnt];
Texture2D dotTex;
Vector2[] rockPos = new Vector2[2];
int dotSize;
Texture2D rockTex;
int rockRad;
DrawObj clear;
DrawObj over;
bool next;
public Game1() {
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize() {
ScrWidth = graphics.PreferredBackBufferWidth;
ScrHeight = graphics.PreferredBackBufferHeight;
Rand = new Random();
mode = Mode.Title;
title = new DrawObj(this, "Title", new Vector2(ScrWidth / 2, 128));
clear = new DrawObj(this, "Clear", new Vector2(ScrWidth / 2, ScrHeight / 2));
over = new DrawObj(this, "GameOver", new Vector2(ScrWidth / 2, ScrHeight / 2));
player = new PlayerObj(this);
for (int i = 0; i < 4; i++)
bosses[i] = new BossObj(this, (Type)i);
base.Initialize();
}
protected override void LoadContent() {
SB = new SpriteBatch(GraphicsDevice);
title.Load();
player.Load();
foreach (var item in bosses) item.Load();
dotTex = Content.Load<Texture2D>("Dot");
dotSize = dotTex.Width / 2;
rockTex = Content.Load<Texture2D>("Rock");
rockRad = rockTex.Width / 2;
clear.Load();
over.Load();
base.LoadContent();
}
void UpdateTitle() {
if (next) {
InitStage();
mode = Mode.Game;
} }
void InitStage() {
player.Init();
player.Pos = new Vector2(ScrWidth / 2, ScrHeight - 128);
boss = bosses[Rand.Next(4)];
boss.Init();
boss.Pos = new Vector2(ScrWidth / 2, 128);
rockPos[0] = new Vector2(72, 16 + Rand.Next(ScrHeight / 3));
rockPos[1] = new Vector2(ScrWidth - 72, ScrHeight - 16 - Rand.Next(ScrHeight / 3));
for (int i = 0; i < dotCnt; i++) {
dot[i].dead = false;
var rect = new Rectangle(0, 0, dotSize * 2, dotSize * 2);
while (true) {
rect.X = dotSize * 2
+ (int)(Rand.NextDouble() * (ScrWidth - dotSize * 4));
rect.Y = dotSize * 2
+ (int)(Rand.NextDouble() * (ScrHeight - dotSize * 4));
if (IsMove(rect, false)) break;
}
dot[i].x = rect.Left + dotSize;
dot[i].y = rect.Top + dotSize;
} }
public bool IsMove(Rectangle rect, bool fly) {
if (rect.Left < 0 || rect.Top < 0 || rect.Right > ScrWidth || rect.Bottom >
ScrHeight)
return false;
if (fly)
return true;
foreach (var item in rockPos) {
if (!(rect.Left > item.X + rockRad
|| rect.Top > item.Y + rockRad
|| rect.Right < item.X - rockRad
|| rect.Bottom < item.Y - rockRad)) return false;
}
return true;
}
bool IsHit(int x, int y, int size) {
var xDist = player.AtkPos.X - x;
var yDist = player.AtkPos.Y - y;
var hitDist = player.AtkRad + size;
return (xDist * xDist + yDist * yDist < hitDist * hitDist);
}
void UpdateGame() {
player.Update();
boss.Update();
bool clear = true;
for (int i = 0; i < dotCnt; i++) {
if (dot[i].dead) continue;
if (IsHit(dot[i].x, dot[i].y, dotSize * 2)) dot[i].dead = true;
else
clear = false;
}
if (clear)
mode = Mode.Clear;
else if (IsHit((int)boss.AtkPos.X, (int)boss.AtkPos.Y, boss.AtkRad)) mode = Mode.Over;
}
void UpdateClear() {
if (next) {
InitStage();
mode = Mode.Game;
} }
void UpdateOver() {
if (next)
mode = Mode.Title;
}
protected override void Update(GameTime gameTime) {
var idx = PlayerIndex.One;
var a = (GamePad.GetState(idx).Buttons.A == ButtonState.Pressed);
var spc = Keyboard.GetState(idx).IsKeyDown(Keys.Space);
next = ((a && !prevA) || (spc && !prevSpc));
prevA = a;
prevSpc = spc;
switch (mode) {
case Mode.Title:
UpdateTitle();
break;
case Mode.Game:
UpdateGame();
break;
case Mode.Clear:
UpdateClear();
break;
case Mode.Over:
UpdateOver();
break;
}
base.Update(gameTime);
}
void DrawTitle() {
GraphicsDevice.Clear(Color.LightGray);
title.Draw(SB);
}
void DrawGame() {
GraphicsDevice.Clear(Color.LightGreen);
SB.Begin();
foreach (var item in rockPos)
SB.Draw(rockTex, new Vector2(item.X - rockRad, item.Y - rockRad), Color.Red);
foreach (var item in dot) {
if (item.dead) continue;
SB.Draw(dotTex, new Vector2(item.x - dotSize, item.y - dotSize), Color.Red);
}
SB.End();
player.Draw(SB);
boss.Draw(SB);
}
protected override void Draw(GameTime gameTime) {
if (mode == Mode.Title) DrawTitle();
else {
DrawGame();
switch (mode) {
case Mode.Clear:
clear.Draw(SB);
break;
case Mode.Over:
over.Draw(SB);
break;
} }
base.Draw(gameTime);
} } }
DrawObj.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace DotEater {
class DrawObj {
protected Game1 Game { get; set; } protected string TexName;
Texture2D Tex { get; set; } public Vector2 Pos { get; set; } protected Rectangle Rect { get; set; } protected float Rotate { get; set; }
protected SpriteEffects Effect { get; set; }
public DrawObj(Game1 game) {
Game = game;
}
public DrawObj(Game1 game, string texName, Vector2 location) : this(game)
{
TexName = texName;
Pos = location;
}
public virtual void Init() { } public virtual void Load() {
Tex = Game.Content.Load<Texture2D>(TexName);
Rect = new Rectangle(0, 0, Tex.Width, Tex.Height);
}
public virtual void Update() { }
public virtual void Draw(SpriteBatch sb) {
sb.Begin();
sb.Draw(Tex,
new Vector2(Pos.X, Pos.Y), Rect,
Color.White, Rotate,
new Vector2(Tex.Width / 2, Tex.Height / 2), 1, Effect, 0);
sb.End();
} } }
Bo s sObj.cs
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace DotEater {
enum Type {
Genbu, Seiryu, Byakko, Suzaku, }
enum Status {
Wait, Move, Chase, }
class BossObj : DrawObj {
int[] atkYs = { 24, 22, 16, 8 };
float[] speeds = { 0.2f, 0.5f, 1, 1 };
string[] names = { "Genbu", "Seiryu", "Byakko", "Suzaku" };
float speed;
int atkY;
int timer;
Status status = Status.Wait;
Vector2 moveVec = Vector2.Zero;
Status Status {
get {
return status;
} set {
var rand = Game.Rand;
double setTime = rand.NextDouble();
switch (value) {
case Status.Wait:
setTime = 30 + 60 * setTime;
break;
case Status.Move:
setTime = 120 + 120 * setTime;
moveVec.X = rand.Next(3) * speed - speed;
moveVec.Y = rand.Next(3) * speed - speed;
break;
case Status.Chase:
setTime = 240 + 120 * setTime;
break;
}
timer = (int)setTime;
status = value;
} }
public Vector2 AtkPos {
get { return Pos + Vector2.Transform(new Vector2(0, atkY), Matrix.CreateRotationZ(Rotate)); } }
public int AtkRad {
get { return (32 + atkY); } }
bool fly;
int anime;
public BossObj(Game1 game, Type type) : base(game)
{
var idx = (int)type;
atkY = -atkYs[idx];
TexName = names[idx];
speed = speeds[idx];
fly = (type == Type.Seiryu || type == Type.Suzaku);
}
public override void Init() {
Rotate = 0;
Status = Status.Wait;
anime = 0;
base.Init();
}
public override void Update() {
var move = Vector2.Zero;
var player = Game.PlayerPos;
switch (status) {
case Status.Move:
move = moveVec;
break;
case Status.Chase:
if (player.X + 8 < Pos.X) move.X = -speed;
else if (player.X - 8 > Pos.X) move.X = speed;
if (player.Y + 8 < Pos.Y) move.Y = -speed;
else if (player.Y - 8 > Pos.Y) move.Y = speed;
break;
}
anime++;
if (anime % 60 == 0 && status != Status.Wait) {
if ((anime / 60) % 2 == 0)
Effect = SpriteEffects.None;
else
Effect = SpriteEffects.FlipHorizontally;
}
timer--;
if (timer < 0) {
switch (Status) {
case Status.Wait:
Status = Status.Move;
break;
case Status.Move:
var xDist = player.X - Pos.X;
var yDist = player.Y - Pos.Y;
var rnd = Game.Rand.Next(100);
if ((rnd < 25)
|| (xDist * xDist + yDist * yDist < 40000 && rnd
< 75))
Status = Status.Chase;
else
Status = Status.Wait;
break;
case Status.Chase:
Status = Status.Wait;
break;
} }
if (move != Vector2.Zero)
Rotate = (float)Math.Atan2(-move.Y, -move.X) - MathHelper.PiOver2;
Vector2 pos = new Vector2(Pos.X + move.X, Pos.Y + move.Y);
if (Game.IsMove(
new Rectangle((int)pos.X - Rect.Height / 2,
(int)pos.Y - Rect.Height / 2, Rect.Height, Rect.Height), fly))
Pos = pos;
else if (status == Status.Chase) Status = Status.Wait;
base.Update();
} } }
ライフゲーム ライフゲーム
@KoyaKzy
遊び 方
生命の誕生、進化、淘汰のプロセスをシミュレーションするソフトです。マウスで フィールド上に「タネ」を植え付けます。これがまるで生物のように振る舞います。
ゲームとついていますが、勝ち負けはありません。生存競争を繰り広げる小さな生 物の姿をお楽しみください。
操 作
マウス左ボタン タネを置く マウス右ボタン
シミュレーション開始
参 考
コンウェイのライフゲーム
http://ja.wikipedia.org/wiki/
%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC
%E3%83%A0
打ち込む 環境
•
Java Development Kit(JDK)6.0 以上•
NetBeans IDE for JavaSE 6.9以上打ち込み方
まず、「新規作成->プロジェクト」として、プロジェクト名を lifegame とします。
このとき「パッケージ名」は空に、「mainクラス」は「Main」にしておきます。
あとは「ソースパッケージ」を右クリックして「新規クラス」を作っていきます。クラス 名はファイル名の.java の前までです(Main,Viewなど)。ファイル名に.java は自動 でつきます。
ソース
Main.java
public class Main {
public static void main(String args[]) {
new Frame();
} }
View.java
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JComponent;
import javax.swing.Timer;
public class View extends JComponent implements ActionListener,MouseListener,MouseMotionListener{
// private Timer m_Timer=new Timer(1000/60, this);
private Timer m_Timer=new Timer(1000/30, this);
private Life life;