Javaアプレットのゲームのソースです。
ソースの行数が長いので難解そうですが、ゲームのソースとしては必要最低限のことしか書いていません。
結局、色々なゲームを作ってきて思うのが、どんな難しいゲームもこういった単純なゲームの拡張でしかないのだと思うようになってきました。
まあ、3Dゲームとかとなってくると話しは別ですが。(行列の理解が必要になる)
下のソースはそのままコピペで動きます。
コンパイラにかけて、それから、音声ファイルと画像ファイル(キャラクター・・・36ピクセルぐらい)は自分で用意すれば動きます。
以下ソース
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
//キャラクタクラス
abstract class Chr {
protected static Game1229 app;//アプレット
protected Image img;//画像
protected int x, y;//座標
protected int w, h;//幅・高さ
private boolean dead;//死亡フラグ
//コンストラクタ
//引数 img:キャラクタ画像のImageオブジェクト
protected Chr(Image img) {
//画像設定
this.img = img;
//画像の幅 高さを習得
w = img.getWidth(app);
h = img.getHeight(app);
//死亡フラグクリア
dead = false;
}
//死亡チェック
boolean isDead() {return dead;}
//死亡する
void dead() {dead = true;}
//移動
abstract void move();
//当たり判定
//引数 t:判定キャラクター
//戻り値 当たり:true 外れ:false
boolean checkHit(Chr t) {
if (x > t.x - w && x < t.x + t.w && y > t.y - h && y < t.y + t.h) {
return true;
}
return false;
}
//描画
void draw(Graphics g) {
g.drawImage(img, x, y, app);
}
}
class Jiki extends Chr {
private int tamaIntCount;//弾と弾の発射間隔
private int power;//パワー
private int muteki;//無敵時間
//弾の速度配列
private static int tv[][] = {
{0, -8},
{-1, -1, 1, -1},
{-7, -7, 0, -8, 7, -7},
{-7, -7, 0, -8, 7, -7, -7, 7, 7, 7},
};
//コンストラクタ
Jiki() {
super(app.imgJiki);
//発射間隔をクリア
tamaIntCount = 0;
//パワー初期化
power = 0;
muteki = 0;
//初期座標を設定する
x = (app.getw() - w) / 2;
y = app.geth() - h - 16;
}
//移動
void move() {
//左移動
if (Key.left) {
x -= 4;
if (x < 0) x = 0;
}
//右移動
if (Key.right) {
x += 4;
if (x > app.getw() - w) x = app.getw() - w;
}
//上移動
if (Key.up) {
y -= 4;
if (y < 0) y = 0;
}
//下移動
if (Key.down) {
y += 4;
if (y > app.geth() - h) y = app.geth() - h;
}
//弾発射
if (tamaIntCount > 0) tamaIntCount--;
if (Key.space) {
if (tamaIntCount <= 0) {
for (int i = 0; i < tv[power].length; i += 2){
app.addList(new Tama(x + w / 2, y, tv[power][i], tv[power][i + 1]));
}
app.sndShot.play();
tamaIntCount = 7;
}
}
//無敵中なら無敵時間を減らす
if (muteki > 0) muteki--;
}
//当たり判定
//敵とアイテムに当たり判定を行う
boolean checkHit(Chr t) {
if (t instanceof Teki && muteki == 0){
if (super.checkHit(t)) {
//敵と当たったら爆発、死亡、ゲームオーバー画面に移る
power--;
app.sndBang.play();
t.dead();
muteki = 100;
if (power < 0) {
dead();
app.goOver();
}
return true;
}
}else if (t instanceof Item) {
if (super.checkHit(t)) {
//アイテムに当たったらパワーアップ
upPower();
t.dead();
return true;
}
}
return false;
}
//パワーアップ
void upPower() {
if (power >= tv.length - 1) {
//最大パワーまで達していたらボーナス追加
app.addScore(1000);
}else{
power++;
}
}
}
//アイテムクラス
class Item extends Chr {
//コンストラクタ
Item() {
super(app.imgItem);
//初期座標を設定する
//初期座標を設定する
x = (int)(Math.random() * (app.getw() - w));
y = -h;
}
//移動
void move() {
y += 4;
if (y > app.geth()) dead();
}
//当たり判定
//誰とも行わない
boolean checkHit(Chr t) {return false;}
}
//敵基本クラス
class Teki extends Chr {
//コンストラクタ
Teki(Image img) {
super(img);
}
//移動
void move() {
//画面外に出たら死亡
if (x < -w) dead();
else if (x > app.getw()) dead();
else if (y > app.geth()) dead();
}
//当たり判定
//弾にのみ当たり判定を行う
boolean checkHit(Chr t) {
if (t instanceof Tama) {
if (super.checkHit(t)) {
//弾と当たったら爆発、スコア追加、自分の弾死亡
app.sndBang.play();
app.addScore(100);
dead();
t.dead();
return true;
}
}
return false;
}
}
//ザコAクラスまっすぐ突っ込んでくる
class ZakoA extends Teki {
//コンストラクタ
ZakoA () {
super(app.imgZakoA);
//初期座標を設定する
x = (int)(Math.random() * (app.getw() - w));
y = -h;
}
//移動
void move() {
y += 8;
super.move();
}
}
//ザコBクラスななめに反射しながら動く
class ZakoB extends Teki {
private int vx;//横方向の速度
//コンストラクタ
ZakoB() {
super(app.imgZakoB);
//初期座標を設定する
x = (int)(Math.random() * (app.getw() - w));
y = -h;
//画面左から登場したら右、画面右から登場したら左に動く
if (x < (app.getw() - w) / 2) vx = 8;
else vx = -8;
}
//移動
void move() {
y += 4;
x += vx;
if (x < 0) vx = 8;
else if (x > app.getw() - w) vx = -8;
super.move();
}
}
//ザコCクラス自機を追尾する
class ZakoC extends Teki {
private double vx, vy;//速度
private double tv;//追尾速度
//コンストラクタ
ZakoC() {
super(app.imgZakoC);
//初期座標を設定する
x = (int)(Math.random() * (app.getw() - w));
y = -h;
vx = vy = 0;
tv = 0.2;
}
// 移動
void move() {
if (app.getJikix() > x) {
vx += tv;
if (vx > 8) vx = 8;
} else if (app.getJikix() < x) {
vx -= tv;
if (vx < -8) vx = -8;
}
if (app.getJikiy() > y) {
vy += tv;
if (vy > 8) vy = 8;
} else if (app.getJikiy() < y) {
vy -= tv;
if (vy < -8) vy = -8;
}
x += (int)vx;
y += (int)vy;
}
}
//ボスクラス
class Boss extends Teki {
private int vx, vy;//速度
private int power;//耐久力
//コンストラクタ
Boss() {
super(app.imgBoss);
//初期座標を設定する
x = (int)(Math.random() * (app.getw() - w));
y = -h;
//画面左から登場したら右、画面右から登場したら左に動く
if (x < (app.getw() - w) / 2) vx = 8;
else vx = -4;
vy = 4;
power = 30;
}
//移動
void move() {
x += vx;
y += vy;
if (x < 0) vx = 4;
else if (x > app.getw() - w) vx = -4;
if (y < 0) vy = 4;
else if (y > app.geth() - h) vy = -4;
super.move();
}
//死亡
void dead() {
power--;
if (power < 0) super.dead();
}
}
//弾クラス
class Tama extends Chr {
private int vx, vy;//速度
//コンストラクタ
//引数 xy座標(弾の中心を指定)vxvy速度
Tama(int x, int y, int vx, int vy) {
super(app.imgTama);
this.x = x - w / 2;
this.y = y - h /2;
this.vx = vx;
this.vy = vy;
}
//移動
void move() {
x += vx; y += vy;
//画面外に出たら死亡
if (x < -w || x > app.getw() || y < -h || y > app.geth()) dead();
}
//当たり判定
//誰とも行わない
boolean checkHit(Chr t) {return false;}
}
//キー入力クラス
class Key extends KeyAdapter {
static boolean left, right, up, down, space, enter;
//キーが押されたときの処理
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT: left = true; break;
case KeyEvent.VK_RIGHT: right = true; break;
case KeyEvent.VK_UP: up = true; break;
case KeyEvent.VK_DOWN: down = true; break;
case KeyEvent.VK_SPACE: space = true; break;
case KeyEvent.VK_ENTER: enter = true; break;
}
}
//キーが離されたときの処理
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT: left = false; break;
case KeyEvent.VK_RIGHT: right = false; break;
case KeyEvent.VK_UP: up = false; break;
case KeyEvent.VK_DOWN: down = false; break;
case KeyEvent.VK_SPACE: space = false; break;
case KeyEvent.VK_ENTER: enter = false; break;
}
}
}
//メイン
public class Game1229 extends Applet implements Runnable {
private Vector clist, clistTmp;//キャラクタリスト・仮キャラ
private volatile Thread gameThread;//ゲームスレッド
private Image offImage;//仮想画面
private Graphics gv;//仮想画面グラフィックオブジェクト
private final int SCENE_INIT = 0;//シーン初期化
private final int SCENE_TITLE = 1;//シーンタイトル
private final int SCENE_MAIN = 2;//シーンメイン
private final int SCENE_OVER = 3;//シーンゲームオーバー
private int scene;//シーン
private int score;//得点
private Font scoreFont;//得点用フォント
private int width, height;//アプレットの幅高さ
private MediaTracker mt;//画像読み込み用メディアトラッカー
private int tekiInterval;//敵出現間隔
private int tekiIntCount;//敵出現間隔カウンター
private int itemIntCount;//アイテム出現カウンター
private Jiki jiki;//自機オブジェクト
Image imgJiki, imgItem, imgTama;//
Image imgZakoA, imgZakoB, imgZakoC;//
Image imgBoss;//
AudioClip sndShot, sndBang;//音声
//初期化
public void init() {
width = getSize().width;
height = getSize().height;
scene = SCENE_INIT;
//得点用フォント生成
scoreFont = new Font("Arial", Font.BOLD, 12);
//背景色を黒色に設定
setBackground(Color.blue);
//前景色を白色に設定
setForeground(Color.white);
//仮想画面の生成
offImage = createImage(width, height);
gv = offImage.getGraphics();
//キー受付オブジェクト生成
addKeyListener(new Key());
//Chrクラスにアプレットを渡す
Chr.app = this;
//メディアトラッカー生成
mt = new MediaTracker(this);
//キャラクタリスト・仮キャラクタリスト生成
clist = new Vector();
clistTmp = new Vector();
//画像読み込み・メディアトラッカーに登録
imgJiki = getImage(getDocumentBase(), "jiki.gif" );
mt.addImage(imgJiki, 0);
imgItem = getImage(getDocumentBase(), "item.gif" );
mt.addImage(imgItem, 0);
imgZakoA = getImage(getDocumentBase(), "zakoa.gif"); // ザコA
mt.addImage(imgZakoA, 0);
imgZakoB = getImage(getDocumentBase(), "zakob.gif"); // ザコB
mt.addImage(imgZakoB, 0);
imgZakoC = getImage(getDocumentBase(), "zakoc.gif"); // ザコC
mt.addImage(imgZakoC, 0);
imgBoss = getImage(getDocumentBase(), "boss.gif"); // ボス
mt.addImage(imgBoss, 0);
imgTama = getImage(getDocumentBase(), "tama.gif"); // 弾
mt.addImage(imgTama, 0);
//サウンドの読み込み
//8000Hz,mono,8bit,μ-lawのSUN形式(.AU)
sndShot = getAudioClip(getDocumentBase(), "shot.au");
sndBang = getAudioClip(getDocumentBase(), "bang.au");
requestFocus();
}
//ゲームスレッドの開始
public void start() {
if(gameThread == null) {
gameThread = new Thread(this);
gameThread.start();
}
}
//ゲームスレッドの停止
public void stop() {
gameThread = null;
}
//ゲームスレッドのメイン
public void run() {
while(gameThread == Thread.currentThread()) {
//裏画面の消去
gv.clearRect(0, 0, width, height);
//各シーン処理
switch(scene){
case SCENE_INIT: gameInit(); break;
case SCENE_TITLE: gameTitle(); break;
case SCENE_MAIN: gameMain(); break;
case SCENE_OVER: gameOver(); break;
}
//再描画
repaint();
//20ミリ秒待つ
try{
Thread.sleep(20);
}catch (InterruptedException e) {
break;
}
}
}
//ゲーム初期化処理
private void gameInit(){
//画面描画
drawCenter("Loading...", 180);
//画像が完全に読み込まれるまで待つ
if (mt.statusAll(true) == MediaTracker.COMPLETE) {
//準備処理
ready();
//タイトル画面へ移行
scene = SCENE_TITLE;
}
}
//準備処理・・・ゲームが開始するたびに呼ばれる
private void ready(){
//得点クリア
score = 0;
//出現間隔を初期値に
tekiInterval = 50;
tekiIntCount = 0;
//キャラクタリストクリア
clist.setSize(0);
//テンポラリキャラクタリストクリア
clistTmp.setSize(0);
//自機オブジェクト追加
jiki = new Jiki();
addList(jiki);
}
//ゲームタイトル処理
private void gameTitle(){
//エンターキーが押されると
if(Key.enter){
//ガーベジコレクション依頼
System.gc();
//ゲームメインへ移行
scene = SCENE_MAIN;
}
//タイトル画面描画
gv.setFont(new Font("Arial", Font.BOLD, 28));
drawCenter("ARIGATA-MEIWAKU", 180);
gv.setFont(new Font("Arial", Font.PLAIN, 20));
drawCenter("Press the ENTER key", 350);
}
//ゲームメイン処理
private void gameMain(){
int i, j;
Chr c, c2;
//移動
for(i = 0; i < clist.size(); i++) {
c = (Chr)(clist.elementAt(i));
c.move();
}
//描画
for(i = 0; i < clist.size(); i++) {
c = (Chr)(clist.elementAt(i));
c.draw(gv);
}
//当たり判定
for (i = 0; i < clist.size(); i++) {
c = (Chr)(clist.elementAt(i));
for(j = 0; j < clist.size(); j++) {
c2 = (Chr)(clist.elementAt(j));
c.checkHit(c2);
}
}
//死亡チェック
i = 0;
while(i < clist.size()){
c = (Chr)(clist.elementAt(i));
//死亡していたらリストから削除
if (c.isDead()) clist.removeElementAt(i);
else i++;
}
//敵出現
tekiIntCount--;
if(tekiIntCount <= 0){
int kind = (int)(Math.random() * 3);
if(kind == 0) addList(new ZakoA());
if(kind == 1) addList(new ZakoB());
if(kind == 2) addList(new ZakoC());
if((int)(Math.random() * 50) == 0) addList(new Boss());
tekiInterval--;
if(tekiInterval < 1)tekiInterval = 20;
tekiIntCount = tekiInterval;
}
//アイテム出現
itemIntCount++;
if(itemIntCount > 300) {
addList(new Item());
itemIntCount = 0;
}
//キャラクタリストにテンポラリキャラクタを追加
for(i = 0; i < clistTmp.size(); i++){
clist.addElement(clistTmp.elementAt(i));
}
clistTmp.setSize(0);
gv.setFont(scoreFont);
gv.drawString("SCORE : " + String.valueOf(score), 10, 20);
}
//ゲームオーバー処理
private void gameOver(){
//エンターキーが押されたら
if(Key.enter){
//ゲーム準備処理
ready();
//タイトル画面へ移行
scene = SCENE_TITLE;
}
//ゲームオーバー画面描画
gv.setFont(new Font("Arial", Font.BOLD, 28));
drawCenter("GAMEOVER", 180);
gv.setFont(new Font("Arial", Font.PLAIN, 20));
drawCenter("SCORE : " + String.valueOf(score), 350 );
}
//アプレットの幅高さを得る
int getw(){return width;}
int geth(){return height;}
//自機の座標を取得
int getJikix(){return jiki.x;}
int getJikiy(){return jiki.y;}
//文字列を中央ぞろえで表示
//引数str文字列y:y座標
private void drawCenter(String str, int y){
FontMetrics fm = getFontMetrics(gv.getFont());
gv.drawString(str, (width - fm.stringWidth(str)) / 2, y);
}
//テンポラリキャラクタリストにキャラクタを追加する
void addList(Chr c){clistTmp.addElement(c);}
//ゲームオーバーに移行
void goOver(){scene = SCENE_OVER;}
//スコア追加
void addScore(int s){score += s;}
//描画
public void paint(Graphics g){
//裏画面から表画面へ転送
g.drawImage(offImage, 0, 0, this);
}
//更新
public void update(Graphics g){
paint(g);
}
}
・・・・・・・・・・・・
・・・・・・・・・・・・
VIDEO レイカーツワイル氏がGOOGLEのエンジニアリング部長に就任。
言語の階層的理解と、より直観的な人間との会話を可能にするAI技術の開発に携わる予定。今後その技術は、現在のGOOGLEサーチエンジンに搭載されるだろうと個人的に言及。
以下引用
Regarding the specific kind of artificial intelligence that a Kurzweil-led project will aim to do, he said, “It will know at a semantically deep level what you’re interested in, not just the topic…[but] the specific questions and concerns you have.” He added, “I envision some years from now that the majority of search queries will be answered without you actually asking. It’ll just know this is something that you’re going to want to see.” While it may be take some years to develop this technology, Kurzweil added that he personally thinks it will be embedded into what Google offers currently, rather than as a stand-alone product necessarily.
Now if you’ve been following Singularity Hub’s coverage of personal assistants like Siri, Evi, and the latest, Maluuba, as well as Google Voice Search, then you know that natural language recognition is one of the highest priorities for tech companies today. That’s exciting because it means that holding sophisticated conversations with computers — in much the same way that Dave Bowman does with HAL 9000 in the movie 2001 – is going to become a reality very soon.
As Kurzweil points out, the hurdle currently is that language is hierarchical, and the human brain processes language in a hierarchical way, depending on what stimuli it receives during key stages of development. Computers like IBM’s Watson are just now being programmed to process human information in a related way. Inevitably, the sophistication of this software will grow — slowly, at first, but in all likelihood become exponential, as with many other technological trends that Kurzweil himself has identified.
Though the video is only 10 minutes, it’s great to hear Ray download some more tidbits about what he’ll be doing once he enters Google’s doors. Odds are that when he reemerges, the ability of our computers to understand us is going to take a quantum leap.
引用元:http://singularityhub.com/2013/01/10/exclusive-interview-with-ray-kurzweil-on-future-ai-project-at-google/
・・・・・・・・・・・
・・・・・・・・・・・
人工知能の予言をするレイカーツワイル氏が、実際に人工知能を作っているGOOGLEにリクルートするというのが面白いです。
・・・・・・・・・・・
・・・・・・・・・・・
まあ、初めてですよ。
確かに、落ち着いてます。そう育てましたから。
でも、しっとりというのは初めての表現です。
うれしいものです。
静か、とか、まじめ、っていうと、逆を捉えると、抑圧されていて子供らしくないともとらえられますが、「しっとり」としているっていうのは、なんか「感性が育てられて、聴く耳を持っている、伸びようと幼いながらひたむきである」という印象を受けます。
・・・・・・・・・・・
・・・・・・・・・・・
日
感性が育つ
英
Sensitivity grows up.
韓
감성이 자란다
カムサンイ チャラダ
中
感性成长
gan3 xing4 cheng2 zhang3